1 /****************************************************************************
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the qmake application of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
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.
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.
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.
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.
36 ** If you have questions regarding the use of this file, please contact
37 ** Nokia at qt-info@nokia.com.
40 ****************************************************************************/
43 #include "cachekeys.h"
48 #include <qsettings.h>
55 const char *Option::application_argv0
= 0;
56 QString
Option::prf_ext
;
57 QString
Option::js_ext
;
58 QString
Option::prl_ext
;
59 QString
Option::libtool_ext
;
60 QString
Option::pkgcfg_ext
;
61 QString
Option::ui_ext
;
62 QStringList
Option::h_ext
;
63 QString
Option::cpp_moc_ext
;
64 QString
Option::h_moc_ext
;
65 QStringList
Option::cpp_ext
;
66 QStringList
Option::c_ext
;
67 QString
Option::obj_ext
;
68 QString
Option::lex_ext
;
69 QString
Option::yacc_ext
;
70 QString
Option::pro_ext
;
71 QString
Option::dir_sep
;
72 QString
Option::dirlist_sep
;
73 QString
Option::h_moc_mod
;
74 QString
Option::cpp_moc_mod
;
75 QString
Option::yacc_mod
;
76 QString
Option::lex_mod
;
77 QString
Option::sysenv_mod
;
78 QString
Option::res_ext
;
79 char Option::field_sep
;
82 Option::QMAKE_MODE
Option::qmake_mode
= Option::QMAKE_GENERATE_NOTHING
;
85 QString
Option::qmake_abslocation
;
86 int Option::warn_level
= WarnLogic
;
87 int Option::debug_level
= 0;
89 QString
Option::output_dir
;
90 bool Option::recursive
= false;
91 QStringList
Option::before_user_vars
;
92 QStringList
Option::after_user_vars
;
93 QStringList
Option::user_configs
;
94 QStringList
Option::after_user_configs
;
95 QString
Option::user_template
;
96 QString
Option::user_template_prefix
;
97 QStringList
Option::shellPath
;
98 #if defined(Q_OS_WIN32)
99 Option::TARG_MODE
Option::target_mode
= Option::TARG_WIN_MODE
;
100 #elif defined(Q_OS_MAC)
101 Option::TARG_MODE
Option::target_mode
= Option::TARG_MACX_MODE
;
102 #elif defined(Q_OS_QNX6)
103 Option::TARG_MODE
Option::target_mode
= Option::TARG_QNX6_MODE
;
105 Option::TARG_MODE
Option::target_mode
= Option::TARG_UNIX_MODE
;
108 //QMAKE_*_PROPERTY stuff
109 QStringList
Option::prop::properties
;
111 //QMAKE_GENERATE_PROJECT stuff
112 bool Option::projfile::do_pwd
= true;
113 QStringList
Option::projfile::project_dirs
;
115 //QMAKE_GENERATE_MAKEFILE stuff
116 QString
Option::mkfile::qmakespec
;
117 int Option::mkfile::cachefile_depth
= -1;
118 bool Option::mkfile::do_deps
= true;
119 bool Option::mkfile::do_mocs
= true;
120 bool Option::mkfile::do_dep_heuristics
= true;
121 bool Option::mkfile::do_preprocess
= false;
122 bool Option::mkfile::do_stub_makefile
= false;
123 bool Option::mkfile::do_cache
= true;
124 QString
Option::mkfile::cachefile
;
125 QStringList
Option::mkfile::project_files
;
126 QString
Option::mkfile::qmakespec_commandline
;
128 static Option::QMAKE_MODE
default_mode(QString progname
)
130 int s
= progname
.lastIndexOf(Option::dir_sep
);
132 progname
= progname
.right(progname
.length() - (s
+ 1));
133 if(progname
== "qmakegen")
134 return Option::QMAKE_GENERATE_PROJECT
;
135 else if(progname
== "qt-config")
136 return Option::QMAKE_QUERY_PROPERTY
;
137 return Option::QMAKE_GENERATE_MAKEFILE
;
140 QString
project_builtin_regx();
141 bool usage(const char *a0
)
143 fprintf(stdout
, "Usage: %s [mode] [options] [files]\n"
145 "QMake has two modes, one mode for generating project files based on\n"
146 "some heuristics, and the other for generating makefiles. Normally you\n"
147 "shouldn't need to specify a mode, as makefile generation is the default\n"
148 "mode for qmake, but you may use this to test qmake on an existing project\n"
151 " -project Put qmake into project file generation mode%s\n"
152 " In this mode qmake interprets files as files to\n"
155 " -makefile Put qmake into makefile generation mode%s\n"
156 " In this mode qmake interprets files as project files to\n"
157 " be processed, if skipped qmake will try to find a project\n"
158 " file in your current working directory\n"
160 "Warnings Options:\n"
161 " -Wnone Turn off all warnings\n"
162 " -Wall Turn on all warnings\n"
163 " -Wparser Turn on parser warnings\n"
164 " -Wlogic Turn on logic warnings\n"
167 " * You can place any variable assignment in options and it will be *\n"
168 " * processed as if it was in [files]. These assignments will be parsed *\n"
169 " * before [files]. *\n"
170 " -o file Write output to file\n"
171 " -unix Run in unix mode\n"
172 " -win32 Run in win32 mode\n"
173 " -macx Run in Mac OS X mode\n"
174 " -d Increase debug level\n"
175 " -t templ Overrides TEMPLATE as templ\n"
176 " -tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n"
178 " -v Version information\n"
179 " -after All variable assignments after this will be\n"
180 " parsed after [files]\n"
181 " -norecursive Don't do a recursive search\n"
182 " -recursive Do a recursive search\n"
183 " -set <prop> <value> Set persistent property\n"
184 " -query <prop> Query persistent property. Show all if <prop> is empty.\n"
185 " -cache file Use file as cache [makefile mode only]\n"
186 " -spec spec Use spec as QMAKESPEC [makefile mode only]\n"
187 " -nocache Don't use a cache file [makefile mode only]\n"
188 " -nodepend Don't generate dependencies [makefile mode only]\n"
189 " -nomoc Don't generate moc targets [makefile mode only]\n"
190 " -nopwd Don't look for files in pwd [project mode only]\n"
192 default_mode(a0
) == Option::QMAKE_GENERATE_PROJECT
? " (default)" : "", project_builtin_regx().toLatin1().constData(),
193 default_mode(a0
) == Option::QMAKE_GENERATE_MAKEFILE
? " (default)" : ""
199 Option::parseCommandLine(int argc
, char **argv
, int skip
)
202 for(int x
= skip
; x
< argc
; x
++) {
203 if(*argv
[x
] == '-' && strlen(argv
[x
]) > 1) { /* options */
204 QString opt
= argv
[x
] + 1;
206 //first param is a mode, or we default
208 bool specified
= true;
209 if(opt
== "project") {
210 Option::recursive
= true;
211 Option::qmake_mode
= Option::QMAKE_GENERATE_PROJECT
;
212 } else if(opt
== "prl") {
213 Option::mkfile::do_deps
= false;
214 Option::mkfile::do_mocs
= false;
215 Option::qmake_mode
= Option::QMAKE_GENERATE_PRL
;
216 } else if(opt
== "set") {
217 Option::qmake_mode
= Option::QMAKE_SET_PROPERTY
;
218 } else if(opt
== "query") {
219 Option::qmake_mode
= Option::QMAKE_QUERY_PROPERTY
;
220 } else if(opt
== "makefile") {
221 Option::qmake_mode
= Option::QMAKE_GENERATE_MAKEFILE
;
229 if(opt
== "o" || opt
== "output") {
230 Option::output
.setFileName(argv
[++x
]);
231 } else if(opt
== "after") {
233 } else if(opt
== "t" || opt
== "template") {
234 Option::user_template
= argv
[++x
];
235 } else if(opt
== "tp" || opt
== "template_prefix") {
236 Option::user_template_prefix
= argv
[++x
];
237 } else if(opt
== "mac9") {
238 Option::target_mode
= TARG_MAC9_MODE
;
239 } else if(opt
== "macx") {
240 Option::target_mode
= TARG_MACX_MODE
;
241 } else if(opt
== "unix") {
242 Option::target_mode
= TARG_UNIX_MODE
;
243 } else if(opt
== "win32") {
244 Option::target_mode
= TARG_WIN_MODE
;
245 } else if(opt
== "d") {
246 Option::debug_level
++;
247 } else if(opt
== "version" || opt
== "v" || opt
== "-version") {
250 "Using Qt version %s in %s\n",
251 qmake_version(), QT_VERSION_STR
,
252 QLibraryInfo::location(QLibraryInfo::LibrariesPath
).toLatin1().constData());
253 #ifdef QMAKE_OPENSOURCE_VERSION
254 fprintf(stdout
, "QMake is Open Source software from Nokia Corporation and/or its subsidiary(-ies).\n");
256 return Option::QMAKE_CMDLINE_BAIL
;
257 } else if(opt
== "h" || opt
== "help") {
258 return Option::QMAKE_CMDLINE_SHOW_USAGE
;
259 } else if(opt
== "Wall") {
260 Option::warn_level
|= WarnAll
;
261 } else if(opt
== "Wparser") {
262 Option::warn_level
|= WarnParser
;
263 } else if(opt
== "Wlogic") {
264 Option::warn_level
|= WarnLogic
;
265 } else if(opt
== "Wnone") {
266 Option::warn_level
= WarnNone
;
267 } else if(opt
== "r" || opt
== "recursive") {
268 Option::recursive
= true;
269 } else if(opt
== "norecursive") {
270 Option::recursive
= false;
271 } else if(opt
== "config") {
272 Option::user_configs
+= argv
[++x
];
274 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
275 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
) {
276 if(opt
== "nodepend" || opt
== "nodepends") {
277 Option::mkfile::do_deps
= false;
278 } else if(opt
== "nomoc") {
279 Option::mkfile::do_mocs
= false;
280 } else if(opt
== "nocache") {
281 Option::mkfile::do_cache
= false;
282 } else if(opt
== "createstub") {
283 Option::mkfile::do_stub_makefile
= true;
284 } else if(opt
== "nodependheuristics") {
285 Option::mkfile::do_dep_heuristics
= false;
286 } else if(opt
== "E") {
287 Option::mkfile::do_preprocess
= true;
288 } else if(opt
== "cache") {
289 Option::mkfile::cachefile
= argv
[++x
];
290 } else if(opt
== "platform" || opt
== "spec") {
291 Option::mkfile::qmakespec
= argv
[++x
];
292 Option::mkfile::qmakespec_commandline
= argv
[x
];
294 fprintf(stderr
, "***Unknown option -%s\n", opt
.toLatin1().constData());
295 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
297 } else if(Option::qmake_mode
== Option::QMAKE_GENERATE_PROJECT
) {
299 Option::projfile::do_pwd
= false;
301 fprintf(stderr
, "***Unknown option -%s\n", opt
.toLatin1().constData());
302 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
307 QString arg
= argv
[x
];
308 if(arg
.indexOf('=') != -1) {
310 Option::before_user_vars
.append(arg
);
312 Option::after_user_vars
.append(arg
);
315 if(Option::qmake_mode
== Option::QMAKE_QUERY_PROPERTY
||
316 Option::qmake_mode
== Option::QMAKE_SET_PROPERTY
) {
317 Option::prop::properties
.append(arg
);
320 if(!fi
.makeAbsolute()) //strange
322 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
323 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
)
324 Option::mkfile::project_files
.append(arg
);
325 else if(Option::qmake_mode
== Option::QMAKE_GENERATE_PROJECT
)
326 Option::projfile::project_dirs
.append(arg
);
331 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
337 return Option::QMAKE_CMDLINE_SUCCESS
;
341 static QStringList
detectShellPath()
344 QString path
= qgetenv("PATH");
345 QStringList pathlist
= path
.toLower().split(";");
346 for (int i
= 0; i
< pathlist
.count(); i
++) {
347 QString maybeSh
= pathlist
.at(i
) + "/sh.exe";
348 if (QFile::exists(maybeSh
)) {
349 paths
.append(maybeSh
);
357 Option::init(int argc
, char **argv
)
359 Option::application_argv0
= 0;
360 Option::cpp_moc_mod
= "";
361 Option::h_moc_mod
= "moc_";
362 Option::lex_mod
= "_lex";
363 Option::yacc_mod
= "_yacc";
364 Option::prl_ext
= ".prl";
365 Option::libtool_ext
= ".la";
366 Option::pkgcfg_ext
= ".pc";
367 Option::prf_ext
= ".prf";
368 Option::js_ext
= ".js";
369 Option::ui_ext
= ".ui";
370 Option::h_ext
<< ".h" << ".hpp" << ".hh" << ".hxx";
371 Option::c_ext
<< ".c";
373 Option::h_ext
<< ".H";
375 Option::cpp_moc_ext
= ".moc";
376 Option::h_moc_ext
= ".cpp";
377 Option::cpp_ext
<< ".cpp" << ".cc" << ".cxx";
379 Option::cpp_ext
<< ".C";
381 Option::lex_ext
= ".l";
382 Option::yacc_ext
= ".y";
383 Option::pro_ext
= ".pro";
385 Option::dirlist_sep
= ";";
386 Option::shellPath
= detectShellPath();
388 Option::dirlist_sep
= ":";
390 Option::sysenv_mod
= "QMAKE_ENV_";
391 Option::field_sep
= ' ';
394 Option::application_argv0
= argv
[0];
395 QString argv0
= argv
[0];
396 if(Option::qmake_mode
== Option::QMAKE_GENERATE_NOTHING
)
397 Option::qmake_mode
= default_mode(argv0
);
398 if(!argv0
.isEmpty() && !QFileInfo(argv0
).isRelative()) {
399 Option::qmake_abslocation
= argv0
;
400 } else if (argv0
.contains(QLatin1Char('/'))
402 || argv0
.contains(QLatin1Char('\\'))
405 Option::qmake_abslocation
= QDir::current().absoluteFilePath(argv0
);
406 } else { //in the PATH
407 QByteArray pEnv
= qgetenv("PATH");
408 QDir currentDir
= QDir::current();
410 QStringList paths
= QString::fromLocal8Bit(pEnv
).split(QLatin1String(";"));
412 QStringList paths
= QString::fromLocal8Bit(pEnv
).split(QLatin1String(":"));
414 for (QStringList::const_iterator p
= paths
.constBegin(); p
!= paths
.constEnd(); ++p
) {
417 QString candidate
= currentDir
.absoluteFilePath(*p
+ QLatin1Char('/') + argv0
);
421 if (QFile::exists(candidate
)) {
422 Option::qmake_abslocation
= candidate
;
427 if(!Option::qmake_abslocation
.isNull())
428 Option::qmake_abslocation
= QDir::cleanPath(Option::qmake_abslocation
);
430 Option::qmake_mode
= Option::QMAKE_GENERATE_MAKEFILE
;
433 const QByteArray envflags
= qgetenv("QMAKEFLAGS");
434 if (!envflags
.isNull()) {
435 int env_argc
= 0, env_size
= 0, currlen
=0;
436 char quote
= 0, **env_argv
= NULL
;
437 for (int i
= 0; i
< envflags
.size(); ++i
) {
438 if (!quote
&& (envflags
.at(i
) == '\'' || envflags
.at(i
) == '"')) {
439 quote
= envflags
.at(i
);
440 } else if (envflags
.at(i
) == quote
) {
442 } else if (!quote
&& envflags
.at(i
) == ' ') {
443 if (currlen
&& env_argv
&& env_argv
[env_argc
]) {
444 env_argv
[env_argc
][currlen
] = '\0';
449 if(!env_argv
|| env_argc
> env_size
) {
450 env_argv
= (char **)realloc(env_argv
, sizeof(char *)*(env_size
+=10));
451 for(int i2
= env_argc
; i2
< env_size
; i2
++)
454 if(!env_argv
[env_argc
]) {
456 env_argv
[env_argc
] = (char*)malloc(255);
459 env_argv
[env_argc
][currlen
++] = envflags
.at(i
);
463 if(env_argv
[env_argc
]) {
464 env_argv
[env_argc
][currlen
] = '\0';
468 parseCommandLine(env_argc
, env_argv
);
469 for(int i2
= 0; i2
< env_size
; i2
++) {
477 int ret
= parseCommandLine(argc
, argv
, 1);
478 if(ret
!= Option::QMAKE_CMDLINE_SUCCESS
) {
479 if ((ret
& Option::QMAKE_CMDLINE_SHOW_USAGE
) != 0)
482 //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
486 //last chance for defaults
487 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
488 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
) {
489 if(Option::mkfile::qmakespec
.isNull() || Option::mkfile::qmakespec
.isEmpty())
490 Option::mkfile::qmakespec
= QString::fromLocal8Bit(qgetenv("QMAKESPEC").constData());
492 //try REALLY hard to do it for them, lazy..
493 if(Option::mkfile::project_files
.isEmpty()) {
494 QString pwd
= qmake_getpwd(),
495 proj
= pwd
+ "/" + pwd
.right(pwd
.length() - (pwd
.lastIndexOf('/') + 1)) + Option::pro_ext
;
496 if(QFile::exists(proj
)) {
497 Option::mkfile::project_files
.append(proj
);
498 } else { //last try..
499 QStringList profiles
= QDir(pwd
).entryList(QStringList("*" + Option::pro_ext
));
500 if(profiles
.count() == 1)
501 Option::mkfile::project_files
.append(pwd
+ "/" + profiles
[0]);
503 #ifndef QT_BUILD_QMAKE_LIBRARY
504 if(Option::mkfile::project_files
.isEmpty()) {
506 return Option::QMAKE_CMDLINE_ERROR
;
512 //defaults for globals
513 if(Option::target_mode
== Option::TARG_WIN_MODE
) {
514 Option::dir_sep
= "\\";
515 Option::obj_ext
= ".obj";
516 Option::res_ext
= ".res";
518 if(Option::target_mode
== Option::TARG_MAC9_MODE
)
519 Option::dir_sep
= ":";
521 Option::dir_sep
= "/";
522 Option::obj_ext
= ".o";
524 Option::qmake_abslocation
= Option::fixPathToTargetOS(Option::qmake_abslocation
);
525 return QMAKE_CMDLINE_SUCCESS
;
528 bool Option::postProcessProject(QMakeProject
*project
)
530 Option::cpp_ext
= project
->variables()["QMAKE_EXT_CPP"];
531 if(cpp_ext
.isEmpty())
532 cpp_ext
<< ".cpp"; //something must be there
533 Option::h_ext
= project
->variables()["QMAKE_EXT_H"];
536 Option::c_ext
= project
->variables()["QMAKE_EXT_C"];
538 c_ext
<< ".c"; //something must be there
540 if(!project
->isEmpty("QMAKE_EXT_RES"))
541 Option::res_ext
= project
->first("QMAKE_EXT_RES");
542 if(!project
->isEmpty("QMAKE_EXT_PKGCONFIG"))
543 Option::pkgcfg_ext
= project
->first("QMAKE_EXT_PKGCONFIG");
544 if(!project
->isEmpty("QMAKE_EXT_LIBTOOL"))
545 Option::libtool_ext
= project
->first("QMAKE_EXT_LIBTOOL");
546 if(!project
->isEmpty("QMAKE_EXT_PRL"))
547 Option::prl_ext
= project
->first("QMAKE_EXT_PRL");
548 if(!project
->isEmpty("QMAKE_EXT_PRF"))
549 Option::prf_ext
= project
->first("QMAKE_EXT_PRF");
550 if(!project
->isEmpty("QMAKE_EXT_JS"))
551 Option::prf_ext
= project
->first("QMAKE_EXT_JS");
552 if(!project
->isEmpty("QMAKE_EXT_UI"))
553 Option::ui_ext
= project
->first("QMAKE_EXT_UI");
554 if(!project
->isEmpty("QMAKE_EXT_CPP_MOC"))
555 Option::cpp_moc_ext
= project
->first("QMAKE_EXT_CPP_MOC");
556 if(!project
->isEmpty("QMAKE_EXT_H_MOC"))
557 Option::h_moc_ext
= project
->first("QMAKE_EXT_H_MOC");
558 if(!project
->isEmpty("QMAKE_EXT_LEX"))
559 Option::lex_ext
= project
->first("QMAKE_EXT_LEX");
560 if(!project
->isEmpty("QMAKE_EXT_YACC"))
561 Option::yacc_ext
= project
->first("QMAKE_EXT_YACC");
562 if(!project
->isEmpty("QMAKE_EXT_OBJ"))
563 Option::obj_ext
= project
->first("QMAKE_EXT_OBJ");
564 if(!project
->isEmpty("QMAKE_H_MOD_MOC"))
565 Option::h_moc_mod
= project
->first("QMAKE_H_MOD_MOC");
566 if(!project
->isEmpty("QMAKE_CPP_MOD_MOC"))
567 Option::cpp_moc_mod
= project
->first("QMAKE_CPP_MOD_MOC");
568 if(!project
->isEmpty("QMAKE_MOD_LEX"))
569 Option::lex_mod
= project
->first("QMAKE_MOD_LEX");
570 if(!project
->isEmpty("QMAKE_MOD_YACC"))
571 Option::yacc_mod
= project
->first("QMAKE_MOD_YACC");
572 if(!project
->isEmpty("QMAKE_DIR_SEP"))
573 Option::dir_sep
= project
->first("QMAKE_DIR_SEP");
574 if(!project
->isEmpty("QMAKE_DIRLIST_SEP"))
575 Option::dirlist_sep
= project
->first("QMAKE_DIRLIST_SEP");
576 if(!project
->isEmpty("QMAKE_MOD_SYSTEM_ENV"))
577 Option::sysenv_mod
= project
->first("QMAKE_MOD_SYSTEM_ENV");
582 Option::fixString(QString string
, uchar flags
)
584 const QString orig_string
= string
;
585 static QHash
<FixStringCacheKey
, QString
> *cache
= 0;
587 cache
= new QHash
<FixStringCacheKey
, QString
>;
588 qmakeAddCacheClear(qmakeDeleteCacheClear_QHashFixStringCacheKeyQString
, (void**)&cache
);
590 FixStringCacheKey
cacheKey(string
, flags
);
591 if(cache
->contains(cacheKey
)) {
592 const QString ret
= cache
->value(cacheKey
);
593 //qDebug() << "Fix (cached) " << orig_string << "->" << ret;
597 //fix the environment variables
598 if(flags
& Option::FixEnvVars
) {
600 QRegExp
reg_var("\\$\\(.*\\)");
601 reg_var
.setMinimal(true);
602 while((rep
= reg_var
.indexIn(string
)) != -1)
603 string
.replace(rep
, reg_var
.matchedLength(),
604 QString::fromLocal8Bit(qgetenv(string
.mid(rep
+ 2, reg_var
.matchedLength() - 3).toLatin1().constData()).constData()));
607 //canonicalize it (and treat as a path)
608 if(flags
& Option::FixPathCanonicalize
) {
610 string
= QFileInfo(string
).canonicalFilePath();
612 string
= QDir::cleanPath(string
);
615 if(string
.length() > 2 && string
[0].isLetter() && string
[1] == QLatin1Char(':'))
616 string
[0] = string
[0].toLower();
619 Q_ASSERT(!((flags
& Option::FixPathToLocalSeparators
) && (flags
& Option::FixPathToTargetSeparators
)));
620 if(flags
& Option::FixPathToLocalSeparators
) {
621 #if defined(Q_OS_WIN32)
622 string
= string
.replace('/', '\\');
624 string
= string
.replace('\\', '/');
626 } else if(flags
& Option::FixPathToTargetSeparators
) {
627 string
= string
.replace('/', Option::dir_sep
).replace('\\', Option::dir_sep
);
630 if (string
.startsWith("\"") && string
.endsWith("\"") ||
631 string
.startsWith("\'") && string
.endsWith("\'"))
632 string
= string
.mid(1, string
.length()-2);
635 //qDebug() << "Fix" << orig_string << "->" << string;
636 cache
->insert(cacheKey
, string
);
640 const char *qmake_version()
642 static char *ret
= NULL
;
645 ret
= (char *)malloc(15);
646 qmakeAddCacheClear(qmakeFreeCacheClear
, (void**)&ret
);
647 #if defined(_MSC_VER) && _MSC_VER >= 1400
648 sprintf_s(ret
, 15, "%d.%02d%c", QMAKE_VERSION_MAJOR
, QMAKE_VERSION_MINOR
, 'a' + QMAKE_VERSION_PATCH
);
650 sprintf(ret
, "%d.%02d%c", QMAKE_VERSION_MAJOR
, QMAKE_VERSION_MINOR
, 'a' + QMAKE_VERSION_PATCH
);
655 void debug_msg_internal(int level
, const char *fmt
, ...)
657 if(Option::debug_level
< level
)
659 fprintf(stderr
, "DEBUG %d: ", level
);
663 vfprintf(stderr
, fmt
, ap
);
666 fprintf(stderr
, "\n");
669 void warn_msg(QMakeWarn type
, const char *fmt
, ...)
671 if(!(Option::warn_level
& type
))
673 fprintf(stderr
, "WARNING: ");
677 vfprintf(stderr
, fmt
, ap
);
680 fprintf(stderr
, "\n");
683 class QMakeCacheClearItem
{
685 qmakeCacheClearFunc func
;
688 QMakeCacheClearItem(qmakeCacheClearFunc f
, void **d
) : func(f
), data(d
) { }
689 ~QMakeCacheClearItem() {
694 static QList
<QMakeCacheClearItem
*> cache_items
;
699 qDeleteAll(cache_items
);
704 qmakeAddCacheClear(qmakeCacheClearFunc func
, void **data
)
706 cache_items
.append(new QMakeCacheClearItem(func
, data
));
710 # include <windows.h>
715 QString
qmake_libraryInfoFile()
718 #if defined( Q_OS_WIN )
721 unsigned short module_name
[256];
722 GetModuleFileNameW(0, reinterpret_cast<wchar_t *>(module_name
), sizeof(module_name
));
723 filePath
= QString::fromUtf16(module_name
);
725 char module_name
[256];
726 GetModuleFileNameA(0, module_name
, sizeof(module_name
));
727 filePath
= QString::fromLocal8Bit(module_name
);
729 ret
= filePath
.filePath();
731 QString argv0
= QFile::decodeName(QByteArray(Option::application_argv0
));
734 if (!argv0
.isEmpty() && argv0
.at(0) == QLatin1Char('/')) {
736 If argv0 starts with a slash, it is already an absolute
740 } else if (argv0
.contains(QLatin1Char('/'))) {
742 If argv0 contains one or more slashes, it is a file path
743 relative to the current directory.
745 absPath
= QDir::current().absoluteFilePath(argv0
);
748 Otherwise, the file path has to be determined using the
749 PATH environment variable.
751 QByteArray pEnv
= qgetenv("PATH");
752 QDir currentDir
= QDir::current();
753 QStringList paths
= QString::fromLocal8Bit(pEnv
.constData()).split(QLatin1String(":"));
754 for (QStringList::const_iterator p
= paths
.constBegin(); p
!= paths
.constEnd(); ++p
) {
757 QString candidate
= currentDir
.absoluteFilePath(*p
+ QLatin1Char('/') + argv0
);
758 QFileInfo
candidate_fi(candidate
);
759 if (candidate_fi
.exists() && !candidate_fi
.isDir()) {
766 absPath
= QDir::cleanPath(absPath
);
768 QFileInfo
fi(absPath
);
769 ret
= fi
.exists() ? fi
.canonicalFilePath() : QString();
772 ret
= QDir(QFileInfo(ret
).absolutePath()).filePath("qt.conf");