source: branches/vendor/nokia/qt/4.7.3/qmake/option.cpp@ 890

Last change on this file since 890 was 844, checked in by Dmitry A. Kuminov, 15 years ago

vendor: Imported qt-everywhere-opensource-src-4.7.2 from Nokia (excluding doc/html and doc/qch dirs generated from doc/src, and imports and templates dirs which are emtpy).

File size: 30.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the qmake application of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "option.h"
43#include "cachekeys.h"
44#include <qdir.h>
45#include <qregexp.h>
46#include <qhash.h>
47#include <qdebug.h>
48#include <qsettings.h>
49#include <stdlib.h>
50#include <stdarg.h>
51
52QT_BEGIN_NAMESPACE
53
54//convenience
55const char *Option::application_argv0 = 0;
56QString Option::prf_ext;
57QString Option::js_ext;
58QString Option::prl_ext;
59QString Option::libtool_ext;
60QString Option::pkgcfg_ext;
61QString Option::ui_ext;
62QStringList Option::h_ext;
63QString Option::cpp_moc_ext;
64QString Option::h_moc_ext;
65QStringList Option::cpp_ext;
66QStringList Option::c_ext;
67QString Option::obj_ext;
68QString Option::lex_ext;
69QString Option::yacc_ext;
70QString Option::pro_ext;
71QString Option::mmp_ext;
72QString Option::dir_sep;
73QString Option::dirlist_sep;
74QString Option::h_moc_mod;
75QString Option::cpp_moc_mod;
76QString Option::yacc_mod;
77QString Option::lex_mod;
78QString Option::sysenv_mod;
79QString Option::res_ext;
80char Option::field_sep;
81
82//mode
83Option::QMAKE_MODE Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING;
84
85//all modes
86QString Option::qmake_abslocation;
87int Option::warn_level = WarnLogic | WarnDeprecated;
88int Option::debug_level = 0;
89QFile Option::output;
90QString Option::output_dir;
91Option::QMAKE_RECURSIVE Option::recursive = Option::QMAKE_RECURSIVE_DEFAULT;
92QStringList Option::before_user_vars;
93QStringList Option::after_user_vars;
94QStringList Option::user_configs;
95QStringList Option::after_user_configs;
96QString Option::user_template;
97QString Option::user_template_prefix;
98QStringList Option::shellPath;
99Option::HOST_MODE Option::host_mode = Option::HOST_UNKNOWN_MODE;
100Option::TARG_MODE Option::target_mode = Option::TARG_UNKNOWN_MODE;
101bool Option::target_mode_overridden = false;
102
103//QMAKE_*_PROPERTY stuff
104QStringList Option::prop::properties;
105
106//QMAKE_GENERATE_PROJECT stuff
107bool Option::projfile::do_pwd = true;
108QStringList Option::projfile::project_dirs;
109
110//QMAKE_GENERATE_MAKEFILE stuff
111QString Option::mkfile::qmakespec;
112int Option::mkfile::cachefile_depth = -1;
113bool Option::mkfile::do_deps = true;
114bool Option::mkfile::do_mocs = true;
115bool Option::mkfile::do_dep_heuristics = true;
116bool Option::mkfile::do_preprocess = false;
117bool Option::mkfile::do_stub_makefile = false;
118bool Option::mkfile::do_cache = true;
119QString Option::mkfile::cachefile;
120QStringList Option::mkfile::project_files;
121QString Option::mkfile::qmakespec_commandline;
122
123static Option::QMAKE_MODE default_mode(QString progname)
124{
125 int s = progname.lastIndexOf(QDir::separator());
126 if(s != -1)
127 progname = progname.right(progname.length() - (s + 1));
128 if(progname == "qmakegen")
129 return Option::QMAKE_GENERATE_PROJECT;
130 else if(progname == "qt-config")
131 return Option::QMAKE_QUERY_PROPERTY;
132 return Option::QMAKE_GENERATE_MAKEFILE;
133}
134
135static QString detectProjectFile(const QString &path)
136{
137 QString ret;
138 QDir dir(path);
139 if(dir.exists(dir.dirName() + Option::pro_ext)) {
140 ret = dir.filePath(dir.dirName()) + Option::pro_ext;
141 } else { //last try..
142 QStringList profiles = dir.entryList(QStringList("*" + Option::pro_ext));
143 if(profiles.count() == 1)
144 ret = dir.filePath(profiles.at(0));
145 }
146 return ret;
147}
148
149QString project_builtin_regx();
150bool usage(const char *a0)
151{
152 fprintf(stdout, "Usage: %s [mode] [options] [files]\n"
153 "\n"
154 "QMake has two modes, one mode for generating project files based on\n"
155 "some heuristics, and the other for generating makefiles. Normally you\n"
156 "shouldn't need to specify a mode, as makefile generation is the default\n"
157 "mode for qmake, but you may use this to test qmake on an existing project\n"
158 "\n"
159 "Mode:\n"
160 " -project Put qmake into project file generation mode%s\n"
161 " In this mode qmake interprets files as files to\n"
162 " be built,\n"
163 " defaults to %s\n"
164 " Note: The created .pro file probably will \n"
165 " need to be edited. For example add the QT variable to \n"
166 " specify what modules are required.\n"
167 " -makefile Put qmake into makefile generation mode%s\n"
168 " In this mode qmake interprets files as project files to\n"
169 " be processed, if skipped qmake will try to find a project\n"
170 " file in your current working directory\n"
171 "\n"
172 "Warnings Options:\n"
173 " -Wnone Turn off all warnings; specific ones may be re-enabled by\n"
174 " later -W options\n"
175 " -Wall Turn on all warnings\n"
176 " -Wparser Turn on parser warnings\n"
177 " -Wlogic Turn on logic warnings (on by default)\n"
178 " -Wdeprecated Turn on deprecation warnings (on by default)\n"
179 "\n"
180 "Options:\n"
181 " * You can place any variable assignment in options and it will be *\n"
182 " * processed as if it was in [files]. These assignments will be parsed *\n"
183 " * before [files]. *\n"
184 " -o file Write output to file\n"
185 " -d Increase debug level\n"
186 " -t templ Overrides TEMPLATE as templ\n"
187 " -tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n"
188 " -help This help\n"
189 " -v Version information\n"
190 " -after All variable assignments after this will be\n"
191 " parsed after [files]\n"
192 " -norecursive Don't do a recursive search\n"
193 " -recursive Do a recursive search\n"
194 " -set <prop> <value> Set persistent property\n"
195 " -query <prop> Query persistent property. Show all if <prop> is empty.\n"
196 " -cache file Use file as cache [makefile mode only]\n"
197 " -spec spec Use spec as QMAKESPEC [makefile mode only]\n"
198 " -nocache Don't use a cache file [makefile mode only]\n"
199 " -nodepend Don't generate dependencies [makefile mode only]\n"
200 " -nomoc Don't generate moc targets [makefile mode only]\n"
201 " -nopwd Don't look for files in pwd [project mode only]\n"
202 ,a0,
203 default_mode(a0) == Option::QMAKE_GENERATE_PROJECT ? " (default)" : "", project_builtin_regx().toLatin1().constData(),
204 default_mode(a0) == Option::QMAKE_GENERATE_MAKEFILE ? " (default)" : ""
205 );
206 return false;
207}
208
209int
210Option::parseCommandLine(int argc, char **argv, int skip)
211{
212 bool before = true;
213 for(int x = skip; x < argc; x++) {
214 if(*argv[x] == '-' && strlen(argv[x]) > 1) { /* options */
215 QString opt = argv[x] + 1;
216
217 //first param is a mode, or we default
218 if(x == 1) {
219 bool specified = true;
220 if(opt == "project") {
221 Option::recursive = Option::QMAKE_RECURSIVE_YES;
222 Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT;
223 } else if(opt == "prl") {
224 Option::mkfile::do_deps = false;
225 Option::mkfile::do_mocs = false;
226 Option::qmake_mode = Option::QMAKE_GENERATE_PRL;
227 } else if(opt == "set") {
228 Option::qmake_mode = Option::QMAKE_SET_PROPERTY;
229 } else if(opt == "query") {
230 Option::qmake_mode = Option::QMAKE_QUERY_PROPERTY;
231 } else if(opt == "makefile") {
232 Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
233 } else {
234 specified = false;
235 }
236 if(specified)
237 continue;
238 }
239 //all modes
240 if(opt == "o" || opt == "output") {
241 Option::output.setFileName(argv[++x]);
242 } else if(opt == "after") {
243 before = false;
244 } else if(opt == "t" || opt == "template") {
245 Option::user_template = argv[++x];
246 } else if(opt == "tp" || opt == "template_prefix") {
247 Option::user_template_prefix = argv[++x];
248 } else if(opt == "macx") {
249 fprintf(stderr, "-macx is deprecated.\n");
250 Option::host_mode = HOST_MACX_MODE;
251 Option::target_mode = TARG_MACX_MODE;
252 Option::target_mode_overridden = true;
253 } else if(opt == "unix") {
254 fprintf(stderr, "-unix is deprecated.\n");
255 Option::host_mode = HOST_UNIX_MODE;
256 Option::target_mode = TARG_UNIX_MODE;
257 Option::target_mode_overridden = true;
258 } else if(opt == "win32") {
259 fprintf(stderr, "-win32 is deprecated.\n");
260 Option::host_mode = HOST_WIN_MODE;
261 Option::target_mode = TARG_WIN_MODE;
262 Option::target_mode_overridden = true;
263 } else if(opt == "d") {
264 Option::debug_level++;
265 } else if(opt == "version" || opt == "v" || opt == "-version") {
266 fprintf(stdout,
267 "QMake version %s\n"
268 "Using Qt version %s in %s\n",
269 qmake_version(), QT_VERSION_STR,
270 QLibraryInfo::location(QLibraryInfo::LibrariesPath).toLatin1().constData());
271#ifdef QMAKE_OPENSOURCE_VERSION
272 fprintf(stdout, "QMake is Open Source software from Nokia Corporation and/or its subsidiary(-ies).\n");
273#endif
274 return Option::QMAKE_CMDLINE_BAIL;
275 } else if(opt == "h" || opt == "help") {
276 return Option::QMAKE_CMDLINE_SHOW_USAGE;
277 } else if(opt == "Wall") {
278 Option::warn_level |= WarnAll;
279 } else if(opt == "Wparser") {
280 Option::warn_level |= WarnParser;
281 } else if(opt == "Wlogic") {
282 Option::warn_level |= WarnLogic;
283 } else if(opt == "Wdeprecated") {
284 Option::warn_level |= WarnDeprecated;
285 } else if(opt == "Wnone") {
286 Option::warn_level = WarnNone;
287 } else if(opt == "r" || opt == "recursive") {
288 Option::recursive = Option::QMAKE_RECURSIVE_YES;
289 } else if(opt == "nr" || opt == "norecursive") {
290 Option::recursive = Option::QMAKE_RECURSIVE_NO;
291 } else if(opt == "config") {
292 Option::user_configs += argv[++x];
293 } else {
294 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
295 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
296 if(opt == "nodepend" || opt == "nodepends") {
297 Option::mkfile::do_deps = false;
298 } else if(opt == "nomoc") {
299 Option::mkfile::do_mocs = false;
300 } else if(opt == "nocache") {
301 Option::mkfile::do_cache = false;
302 } else if(opt == "createstub") {
303 Option::mkfile::do_stub_makefile = true;
304 } else if(opt == "nodependheuristics") {
305 Option::mkfile::do_dep_heuristics = false;
306 } else if(opt == "E") {
307 fprintf(stderr, "-E is deprecated. Use -d instead.\n");
308 Option::mkfile::do_preprocess = true;
309 } else if(opt == "cache") {
310 Option::mkfile::cachefile = argv[++x];
311 } else if(opt == "platform" || opt == "spec") {
312 Option::mkfile::qmakespec = argv[++x];
313 Option::mkfile::qmakespec_commandline = argv[x];
314 } else {
315 fprintf(stderr, "***Unknown option -%s\n", opt.toLatin1().constData());
316 return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
317 }
318 } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
319 if(opt == "nopwd") {
320 Option::projfile::do_pwd = false;
321 } else {
322 fprintf(stderr, "***Unknown option -%s\n", opt.toLatin1().constData());
323 return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
324 }
325 }
326 }
327 } else {
328 QString arg = argv[x];
329 if(arg.indexOf('=') != -1) {
330 if(before)
331 Option::before_user_vars.append(arg);
332 else
333 Option::after_user_vars.append(arg);
334 } else {
335 bool handled = true;
336 if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY ||
337 Option::qmake_mode == Option::QMAKE_SET_PROPERTY) {
338 Option::prop::properties.append(arg);
339 } else {
340 QFileInfo fi(arg);
341 if(!fi.makeAbsolute()) //strange
342 arg = fi.filePath();
343 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
344 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
345 if(fi.isDir()) {
346 QString proj = detectProjectFile(arg);
347 if (!proj.isNull())
348 arg = proj;
349 }
350 Option::mkfile::project_files.append(arg);
351 } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
352 Option::projfile::project_dirs.append(arg);
353 } else {
354 handled = false;
355 }
356 }
357 if(!handled) {
358 return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR;
359 }
360 }
361 }
362 }
363
364 return Option::QMAKE_CMDLINE_SUCCESS;
365}
366
367#ifdef Q_OS_WIN
368static QStringList detectShellPath()
369{
370 QStringList paths;
371 QString path = qgetenv("PATH");
372 QStringList pathlist = path.toLower().split(";");
373 for (int i = 0; i < pathlist.count(); i++) {
374 QString maybeSh = pathlist.at(i) + "/sh.exe";
375 if (QFile::exists(maybeSh)) {
376 paths.append(maybeSh);
377 }
378 }
379 return paths;
380}
381#endif
382
383int
384Option::init(int argc, char **argv)
385{
386 Option::application_argv0 = 0;
387 Option::cpp_moc_mod = "";
388 Option::h_moc_mod = "moc_";
389 Option::lex_mod = "_lex";
390 Option::yacc_mod = "_yacc";
391 Option::prl_ext = ".prl";
392 Option::libtool_ext = ".la";
393 Option::pkgcfg_ext = ".pc";
394 Option::prf_ext = ".prf";
395 Option::js_ext = ".js";
396 Option::ui_ext = ".ui";
397 Option::h_ext << ".h" << ".hpp" << ".hh" << ".hxx";
398 Option::c_ext << ".c";
399#ifndef Q_OS_WIN
400 Option::h_ext << ".H";
401#endif
402 Option::cpp_moc_ext = ".moc";
403 Option::h_moc_ext = ".cpp";
404 Option::cpp_ext << ".cpp" << ".cc" << ".cxx";
405#ifndef Q_OS_WIN
406 Option::cpp_ext << ".C";
407#endif
408 Option::lex_ext = ".l";
409 Option::yacc_ext = ".y";
410 Option::pro_ext = ".pro";
411 Option::mmp_ext = ".mmp";
412#ifdef Q_OS_WIN
413 Option::dirlist_sep = ";";
414 Option::shellPath = detectShellPath();
415 Option::res_ext = ".res";
416#else
417 Option::dirlist_sep = ":";
418 Option::shellPath = QStringList("sh");
419#endif
420 Option::sysenv_mod = "QMAKE_ENV_";
421 Option::field_sep = ' ';
422
423 if(argc && argv) {
424 Option::application_argv0 = argv[0];
425 QString argv0 = argv[0];
426 if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
427 Option::qmake_mode = default_mode(argv0);
428 if(!argv0.isEmpty() && !QFileInfo(argv0).isRelative()) {
429 Option::qmake_abslocation = argv0;
430 } else if (argv0.contains(QLatin1Char('/'))
431#ifdef Q_OS_WIN
432 || argv0.contains(QLatin1Char('\\'))
433#endif
434 ) { //relative PWD
435 Option::qmake_abslocation = QDir::current().absoluteFilePath(argv0);
436 } else { //in the PATH
437 QByteArray pEnv = qgetenv("PATH");
438 QDir currentDir = QDir::current();
439#ifdef Q_OS_WIN
440 QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";"));
441#else
442 QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":"));
443#endif
444 for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
445 if ((*p).isEmpty())
446 continue;
447 QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
448#ifdef Q_OS_WIN
449 candidate += ".exe";
450#endif
451 if (QFile::exists(candidate)) {
452 Option::qmake_abslocation = candidate;
453 break;
454 }
455 }
456 }
457 if(!Option::qmake_abslocation.isNull())
458 Option::qmake_abslocation = QDir::cleanPath(Option::qmake_abslocation);
459 } else {
460 Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
461 }
462
463 const QByteArray envflags = qgetenv("QMAKEFLAGS");
464 if (!envflags.isNull()) {
465 int env_argc = 0, env_size = 0, currlen=0;
466 char quote = 0, **env_argv = NULL;
467 for (int i = 0; i < envflags.size(); ++i) {
468 if (!quote && (envflags.at(i) == '\'' || envflags.at(i) == '"')) {
469 quote = envflags.at(i);
470 } else if (envflags.at(i) == quote) {
471 quote = 0;
472 } else if (!quote && envflags.at(i) == ' ') {
473 if (currlen && env_argv && env_argv[env_argc]) {
474 env_argv[env_argc][currlen] = '\0';
475 currlen = 0;
476 env_argc++;
477 }
478 } else {
479 if(!env_argv || env_argc > env_size) {
480 env_argv = (char **)realloc(env_argv, sizeof(char *)*(env_size+=10));
481 for(int i2 = env_argc; i2 < env_size; i2++)
482 env_argv[i2] = NULL;
483 }
484 if(!env_argv[env_argc]) {
485 currlen = 0;
486 env_argv[env_argc] = (char*)malloc(255);
487 }
488 if(currlen < 255)
489 env_argv[env_argc][currlen++] = envflags.at(i);
490 }
491 }
492 if(env_argv) {
493 if(env_argv[env_argc]) {
494 env_argv[env_argc][currlen] = '\0';
495 currlen = 0;
496 env_argc++;
497 }
498 parseCommandLine(env_argc, env_argv);
499 for(int i2 = 0; i2 < env_size; i2++) {
500 if(env_argv[i2])
501 free(env_argv[i2]);
502 }
503 free(env_argv);
504 }
505 }
506 if(argc && argv) {
507 int ret = parseCommandLine(argc, argv, 1);
508 if(ret != Option::QMAKE_CMDLINE_SUCCESS) {
509 if ((ret & Option::QMAKE_CMDLINE_SHOW_USAGE) != 0)
510 usage(argv[0]);
511 return ret;
512 //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
513 }
514 }
515
516 //last chance for defaults
517 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
518 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
519 if(Option::mkfile::qmakespec.isNull() || Option::mkfile::qmakespec.isEmpty())
520 Option::mkfile::qmakespec = QString::fromLocal8Bit(qgetenv("QMAKESPEC").constData());
521
522 //try REALLY hard to do it for them, lazy..
523 if(Option::mkfile::project_files.isEmpty()) {
524 QString proj = detectProjectFile(qmake_getpwd());
525 if(!proj.isNull())
526 Option::mkfile::project_files.append(proj);
527#ifndef QT_BUILD_QMAKE_LIBRARY
528 if(Option::mkfile::project_files.isEmpty()) {
529 usage(argv[0]);
530 return Option::QMAKE_CMDLINE_ERROR;
531 }
532#endif
533 }
534 } else if (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
535#if defined(Q_OS_MAC)
536 Option::host_mode = Option::HOST_MACX_MODE;
537 Option::target_mode = Option::TARG_MACX_MODE;
538#elif defined(Q_OS_UNIX)
539 Option::host_mode = Option::HOST_UNIX_MODE;
540 Option::target_mode = Option::TARG_UNIX_MODE;
541#else
542 Option::host_mode = Option::HOST_WIN_MODE;
543 Option::target_mode = Option::TARG_WIN_MODE;
544#endif
545 }
546
547 //defaults for globals
548 if (Option::host_mode != Option::HOST_UNKNOWN_MODE)
549 applyHostMode();
550 return QMAKE_CMDLINE_SUCCESS;
551}
552
553void Option::applyHostMode()
554{
555 if (Option::host_mode == Option::HOST_WIN_MODE) {
556 Option::dir_sep = "\\";
557 Option::obj_ext = ".obj";
558 } else {
559 Option::dir_sep = "/";
560 Option::obj_ext = ".o";
561 }
562}
563
564bool Option::postProcessProject(QMakeProject *project)
565{
566 Option::cpp_ext = project->variables()["QMAKE_EXT_CPP"];
567 if(cpp_ext.isEmpty())
568 cpp_ext << ".cpp"; //something must be there
569 Option::h_ext = project->variables()["QMAKE_EXT_H"];
570 if(h_ext.isEmpty())
571 h_ext << ".h";
572 Option::c_ext = project->variables()["QMAKE_EXT_C"];
573 if(c_ext.isEmpty())
574 c_ext << ".c"; //something must be there
575
576 if(!project->isEmpty("QMAKE_EXT_RES"))
577 Option::res_ext = project->first("QMAKE_EXT_RES");
578 if(!project->isEmpty("QMAKE_EXT_PKGCONFIG"))
579 Option::pkgcfg_ext = project->first("QMAKE_EXT_PKGCONFIG");
580 if(!project->isEmpty("QMAKE_EXT_LIBTOOL"))
581 Option::libtool_ext = project->first("QMAKE_EXT_LIBTOOL");
582 if(!project->isEmpty("QMAKE_EXT_PRL"))
583 Option::prl_ext = project->first("QMAKE_EXT_PRL");
584 if(!project->isEmpty("QMAKE_EXT_PRF"))
585 Option::prf_ext = project->first("QMAKE_EXT_PRF");
586 if(!project->isEmpty("QMAKE_EXT_JS"))
587 Option::prf_ext = project->first("QMAKE_EXT_JS");
588 if(!project->isEmpty("QMAKE_EXT_UI"))
589 Option::ui_ext = project->first("QMAKE_EXT_UI");
590 if(!project->isEmpty("QMAKE_EXT_CPP_MOC"))
591 Option::cpp_moc_ext = project->first("QMAKE_EXT_CPP_MOC");
592 if(!project->isEmpty("QMAKE_EXT_H_MOC"))
593 Option::h_moc_ext = project->first("QMAKE_EXT_H_MOC");
594 if(!project->isEmpty("QMAKE_EXT_LEX"))
595 Option::lex_ext = project->first("QMAKE_EXT_LEX");
596 if(!project->isEmpty("QMAKE_EXT_YACC"))
597 Option::yacc_ext = project->first("QMAKE_EXT_YACC");
598 if(!project->isEmpty("QMAKE_EXT_OBJ"))
599 Option::obj_ext = project->first("QMAKE_EXT_OBJ");
600 if(!project->isEmpty("QMAKE_H_MOD_MOC"))
601 Option::h_moc_mod = project->first("QMAKE_H_MOD_MOC");
602 if(!project->isEmpty("QMAKE_CPP_MOD_MOC"))
603 Option::cpp_moc_mod = project->first("QMAKE_CPP_MOD_MOC");
604 if(!project->isEmpty("QMAKE_MOD_LEX"))
605 Option::lex_mod = project->first("QMAKE_MOD_LEX");
606 if(!project->isEmpty("QMAKE_MOD_YACC"))
607 Option::yacc_mod = project->first("QMAKE_MOD_YACC");
608 if(!project->isEmpty("QMAKE_DIR_SEP"))
609 Option::dir_sep = project->first("QMAKE_DIR_SEP");
610 if(!project->isEmpty("QMAKE_DIRLIST_SEP"))
611 Option::dirlist_sep = project->first("QMAKE_DIRLIST_SEP");
612 if(!project->isEmpty("QMAKE_MOD_SYSTEM_ENV"))
613 Option::sysenv_mod = project->first("QMAKE_MOD_SYSTEM_ENV");
614 return true;
615}
616
617QString
618Option::fixString(QString string, uchar flags)
619{
620 //const QString orig_string = string;
621 static QHash<FixStringCacheKey, QString> *cache = 0;
622 if(!cache) {
623 cache = new QHash<FixStringCacheKey, QString>;
624 qmakeAddCacheClear(qmakeDeleteCacheClear_QHashFixStringCacheKeyQString, (void**)&cache);
625 }
626 FixStringCacheKey cacheKey(string, flags);
627 if(cache->contains(cacheKey)) {
628 const QString ret = cache->value(cacheKey);
629 //qDebug() << "Fix (cached) " << orig_string << "->" << ret;
630 return ret;
631 }
632
633 //fix the environment variables
634 if(flags & Option::FixEnvVars) {
635 int rep;
636 QRegExp reg_var("\\$\\(.*\\)");
637 reg_var.setMinimal(true);
638 while((rep = reg_var.indexIn(string)) != -1)
639 string.replace(rep, reg_var.matchedLength(),
640 QString::fromLocal8Bit(qgetenv(string.mid(rep + 2, reg_var.matchedLength() - 3).toLatin1().constData()).constData()));
641 }
642
643 //canonicalize it (and treat as a path)
644 if(flags & Option::FixPathCanonicalize) {
645#if 0
646 string = QFileInfo(string).canonicalFilePath();
647#endif
648 string = QDir::cleanPath(string);
649 }
650
651 if(string.length() > 2 && string[0].isLetter() && string[1] == QLatin1Char(':'))
652 string[0] = string[0].toLower();
653
654 //fix separators
655 Q_ASSERT(!((flags & Option::FixPathToLocalSeparators) && (flags & Option::FixPathToTargetSeparators)));
656 if(flags & Option::FixPathToLocalSeparators) {
657#if defined(Q_OS_WIN32)
658 string = string.replace('/', '\\');
659#else
660 string = string.replace('\\', '/');
661#endif
662 } else if(flags & Option::FixPathToTargetSeparators) {
663 string = string.replace('/', Option::dir_sep).replace('\\', Option::dir_sep);
664 }
665
666 if ((string.startsWith("\"") && string.endsWith("\"")) ||
667 (string.startsWith("\'") && string.endsWith("\'")))
668 string = string.mid(1, string.length()-2);
669
670 //cache
671 //qDebug() << "Fix" << orig_string << "->" << string;
672 cache->insert(cacheKey, string);
673 return string;
674}
675
676const char *qmake_version()
677{
678 static char *ret = NULL;
679 if(ret)
680 return ret;
681 ret = (char *)malloc(15);
682 qmakeAddCacheClear(qmakeFreeCacheClear, (void**)&ret);
683#if defined(_MSC_VER) && _MSC_VER >= 1400
684 sprintf_s(ret, 15, "%d.%02d%c", QMAKE_VERSION_MAJOR, QMAKE_VERSION_MINOR, 'a' + QMAKE_VERSION_PATCH);
685#else
686 sprintf(ret, "%d.%02d%c", QMAKE_VERSION_MAJOR, QMAKE_VERSION_MINOR, 'a' + QMAKE_VERSION_PATCH);
687#endif
688 return ret;
689}
690
691void debug_msg_internal(int level, const char *fmt, ...)
692{
693 if(Option::debug_level < level)
694 return;
695 fprintf(stderr, "DEBUG %d: ", level);
696 {
697 va_list ap;
698 va_start(ap, fmt);
699 vfprintf(stderr, fmt, ap);
700 va_end(ap);
701 }
702 fprintf(stderr, "\n");
703}
704
705void warn_msg(QMakeWarn type, const char *fmt, ...)
706{
707 if(!(Option::warn_level & type))
708 return;
709 fprintf(stderr, "WARNING: ");
710 {
711 va_list ap;
712 va_start(ap, fmt);
713 vfprintf(stderr, fmt, ap);
714 va_end(ap);
715 }
716 fprintf(stderr, "\n");
717}
718
719class QMakeCacheClearItem {
720private:
721 qmakeCacheClearFunc func;
722 void **data;
723public:
724 QMakeCacheClearItem(qmakeCacheClearFunc f, void **d) : func(f), data(d) { }
725 ~QMakeCacheClearItem() {
726 (*func)(*data);
727 *data = 0;
728 }
729};
730static QList<QMakeCacheClearItem*> cache_items;
731
732void
733qmakeClearCaches()
734{
735 qDeleteAll(cache_items);
736 cache_items.clear();
737}
738
739void
740qmakeAddCacheClear(qmakeCacheClearFunc func, void **data)
741{
742 cache_items.append(new QMakeCacheClearItem(func, data));
743}
744
745#ifdef Q_OS_WIN
746# include <windows.h>
747
748QT_USE_NAMESPACE
749#endif
750
751QString qmake_libraryInfoFile()
752{
753 QString ret;
754#if defined( Q_OS_WIN )
755 wchar_t module_name[MAX_PATH];
756 GetModuleFileName(0, module_name, MAX_PATH);
757 QFileInfo filePath = QString::fromWCharArray(module_name);
758 ret = filePath.filePath();
759#else
760 QString argv0 = QFile::decodeName(QByteArray(Option::application_argv0));
761 QString absPath;
762
763 if (!argv0.isEmpty() && argv0.at(0) == QLatin1Char('/')) {
764 /*
765 If argv0 starts with a slash, it is already an absolute
766 file path.
767 */
768 absPath = argv0;
769 } else if (argv0.contains(QLatin1Char('/'))) {
770 /*
771 If argv0 contains one or more slashes, it is a file path
772 relative to the current directory.
773 */
774 absPath = QDir::current().absoluteFilePath(argv0);
775 } else {
776 /*
777 Otherwise, the file path has to be determined using the
778 PATH environment variable.
779 */
780 QByteArray pEnv = qgetenv("PATH");
781 QDir currentDir = QDir::current();
782 QStringList paths = QString::fromLocal8Bit(pEnv.constData()).split(QLatin1String(":"));
783 for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) {
784 if ((*p).isEmpty())
785 continue;
786 QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char('/') + argv0);
787 QFileInfo candidate_fi(candidate);
788 if (candidate_fi.exists() && !candidate_fi.isDir()) {
789 absPath = candidate;
790 break;
791 }
792 }
793 }
794
795 absPath = QDir::cleanPath(absPath);
796
797 QFileInfo fi(absPath);
798 ret = fi.exists() ? fi.canonicalFilePath() : QString();
799#endif
800 if(!ret.isEmpty())
801 ret = QDir(QFileInfo(ret).absolutePath()).filePath("qt.conf");
802 return ret;
803}
804
805QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.