1 /****************************************************************************
3 ** Copyright (C) 2010 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$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
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 ** If you have questions regarding the use of this file, please contact
29 ** 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::mmp_ext
;
72 QString
Option::dir_sep
;
73 QString
Option::dirlist_sep
;
74 QString
Option::h_moc_mod
;
75 QString
Option::cpp_moc_mod
;
76 QString
Option::yacc_mod
;
77 QString
Option::lex_mod
;
78 QString
Option::sysenv_mod
;
79 QString
Option::res_ext
;
80 char Option::field_sep
;
83 Option::QMAKE_MODE
Option::qmake_mode
= Option::QMAKE_GENERATE_NOTHING
;
86 QString
Option::qmake_abslocation
;
87 int Option::warn_level
= WarnLogic
;
88 int Option::debug_level
= 0;
90 QString
Option::output_dir
;
91 bool Option::recursive
= false;
92 QStringList
Option::before_user_vars
;
93 QStringList
Option::after_user_vars
;
94 QStringList
Option::user_configs
;
95 QStringList
Option::after_user_configs
;
96 QString
Option::user_template
;
97 QString
Option::user_template_prefix
;
98 QStringList
Option::shellPath
;
99 #if defined(Q_OS_WIN32)
100 Option::TARG_MODE
Option::target_mode
= Option::TARG_WIN_MODE
;
101 #elif defined(Q_OS_MAC)
102 Option::TARG_MODE
Option::target_mode
= Option::TARG_MACX_MODE
;
104 Option::TARG_MODE
Option::target_mode
= Option::TARG_UNIX_MODE
;
107 //QMAKE_*_PROPERTY stuff
108 QStringList
Option::prop::properties
;
110 //QMAKE_GENERATE_PROJECT stuff
111 bool Option::projfile::do_pwd
= true;
112 QStringList
Option::projfile::project_dirs
;
114 //QMAKE_GENERATE_MAKEFILE stuff
115 QString
Option::mkfile::qmakespec
;
116 int Option::mkfile::cachefile_depth
= -1;
117 bool Option::mkfile::do_deps
= true;
118 bool Option::mkfile::do_mocs
= true;
119 bool Option::mkfile::do_dep_heuristics
= true;
120 bool Option::mkfile::do_preprocess
= false;
121 bool Option::mkfile::do_stub_makefile
= false;
122 bool Option::mkfile::do_cache
= true;
123 QString
Option::mkfile::cachefile
;
124 QStringList
Option::mkfile::project_files
;
125 QString
Option::mkfile::qmakespec_commandline
;
127 static Option::QMAKE_MODE
default_mode(QString progname
)
129 int s
= progname
.lastIndexOf(Option::dir_sep
);
131 progname
= progname
.right(progname
.length() - (s
+ 1));
132 if(progname
== "qmakegen")
133 return Option::QMAKE_GENERATE_PROJECT
;
134 else if(progname
== "qt-config")
135 return Option::QMAKE_QUERY_PROPERTY
;
136 return Option::QMAKE_GENERATE_MAKEFILE
;
139 static QString
detectProjectFile(const QString
&path
)
143 if(dir
.exists(dir
.dirName() + Option::pro_ext
)) {
144 ret
= dir
.filePath(dir
.dirName()) + Option::pro_ext
;
145 } else { //last try..
146 QStringList profiles
= dir
.entryList(QStringList("*" + Option::pro_ext
));
147 if(profiles
.count() == 1)
148 ret
= dir
.filePath(profiles
.at(0));
153 QString
project_builtin_regx();
154 bool usage(const char *a0
)
156 fprintf(stdout
, "Usage: %s [mode] [options] [files]\n"
158 "QMake has two modes, one mode for generating project files based on\n"
159 "some heuristics, and the other for generating makefiles. Normally you\n"
160 "shouldn't need to specify a mode, as makefile generation is the default\n"
161 "mode for qmake, but you may use this to test qmake on an existing project\n"
164 " -project Put qmake into project file generation mode%s\n"
165 " In this mode qmake interprets files as files to\n"
168 " Note: The created .pro file probably will \n"
169 " need to be edited. For example add the QT variable to \n"
170 " specify what modules are required.\n"
171 " -makefile Put qmake into makefile generation mode%s\n"
172 " In this mode qmake interprets files as project files to\n"
173 " be processed, if skipped qmake will try to find a project\n"
174 " file in your current working directory\n"
176 "Warnings Options:\n"
177 " -Wnone Turn off all warnings\n"
178 " -Wall Turn on all warnings\n"
179 " -Wparser Turn on parser warnings\n"
180 " -Wlogic Turn on logic warnings\n"
183 " * You can place any variable assignment in options and it will be *\n"
184 " * processed as if it was in [files]. These assignments will be parsed *\n"
185 " * before [files]. *\n"
186 " -o file Write output to file\n"
187 " -unix Run in unix mode\n"
188 " -win32 Run in win32 mode\n"
189 " -macx Run in Mac OS X mode\n"
190 " -d Increase debug level\n"
191 " -t templ Overrides TEMPLATE as templ\n"
192 " -tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n"
194 " -v Version information\n"
195 " -after All variable assignments after this will be\n"
196 " parsed after [files]\n"
197 " -norecursive Don't do a recursive search\n"
198 " -recursive Do a recursive search\n"
199 " -set <prop> <value> Set persistent property\n"
200 " -query <prop> Query persistent property. Show all if <prop> is empty.\n"
201 " -cache file Use file as cache [makefile mode only]\n"
202 " -spec spec Use spec as QMAKESPEC [makefile mode only]\n"
203 " -nocache Don't use a cache file [makefile mode only]\n"
204 " -nodepend Don't generate dependencies [makefile mode only]\n"
205 " -nomoc Don't generate moc targets [makefile mode only]\n"
206 " -nopwd Don't look for files in pwd [project mode only]\n"
208 default_mode(a0
) == Option::QMAKE_GENERATE_PROJECT
? " (default)" : "", project_builtin_regx().toLatin1().constData(),
209 default_mode(a0
) == Option::QMAKE_GENERATE_MAKEFILE
? " (default)" : ""
215 Option::parseCommandLine(int argc
, char **argv
, int skip
)
218 for(int x
= skip
; x
< argc
; x
++) {
219 if(*argv
[x
] == '-' && strlen(argv
[x
]) > 1) { /* options */
220 QString opt
= argv
[x
] + 1;
222 //first param is a mode, or we default
224 bool specified
= true;
225 if(opt
== "project") {
226 Option::recursive
= true;
227 Option::qmake_mode
= Option::QMAKE_GENERATE_PROJECT
;
228 } else if(opt
== "prl") {
229 Option::mkfile::do_deps
= false;
230 Option::mkfile::do_mocs
= false;
231 Option::qmake_mode
= Option::QMAKE_GENERATE_PRL
;
232 } else if(opt
== "set") {
233 Option::qmake_mode
= Option::QMAKE_SET_PROPERTY
;
234 } else if(opt
== "query") {
235 Option::qmake_mode
= Option::QMAKE_QUERY_PROPERTY
;
236 } else if(opt
== "makefile") {
237 Option::qmake_mode
= Option::QMAKE_GENERATE_MAKEFILE
;
245 if(opt
== "o" || opt
== "output") {
246 Option::output
.setFileName(argv
[++x
]);
247 } else if(opt
== "after") {
249 } else if(opt
== "t" || opt
== "template") {
250 Option::user_template
= argv
[++x
];
251 } else if(opt
== "tp" || opt
== "template_prefix") {
252 Option::user_template_prefix
= argv
[++x
];
253 } else if(opt
== "mac9") {
254 Option::target_mode
= TARG_MAC9_MODE
;
255 } else if(opt
== "macx") {
256 Option::target_mode
= TARG_MACX_MODE
;
257 } else if(opt
== "unix") {
258 Option::target_mode
= TARG_UNIX_MODE
;
259 } else if(opt
== "win32") {
260 Option::target_mode
= TARG_WIN_MODE
;
261 } else if(opt
== "d") {
262 Option::debug_level
++;
263 } else if(opt
== "version" || opt
== "v" || opt
== "-version") {
266 "Using Qt version %s in %s\n",
267 qmake_version(), QT_VERSION_STR
,
268 QLibraryInfo::location(QLibraryInfo::LibrariesPath
).toLatin1().constData());
269 #ifdef QMAKE_OPENSOURCE_VERSION
270 fprintf(stdout
, "QMake is Open Source software from Nokia Corporation and/or its subsidiary(-ies).\n");
272 return Option::QMAKE_CMDLINE_BAIL
;
273 } else if(opt
== "h" || opt
== "help") {
274 return Option::QMAKE_CMDLINE_SHOW_USAGE
;
275 } else if(opt
== "Wall") {
276 Option::warn_level
|= WarnAll
;
277 } else if(opt
== "Wparser") {
278 Option::warn_level
|= WarnParser
;
279 } else if(opt
== "Wlogic") {
280 Option::warn_level
|= WarnLogic
;
281 } else if(opt
== "Wnone") {
282 Option::warn_level
= WarnNone
;
283 } else if(opt
== "r" || opt
== "recursive") {
284 Option::recursive
= true;
285 } else if(opt
== "norecursive") {
286 Option::recursive
= false;
287 } else if(opt
== "config") {
288 Option::user_configs
+= argv
[++x
];
290 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
291 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
) {
292 if(opt
== "nodepend" || opt
== "nodepends") {
293 Option::mkfile::do_deps
= false;
294 } else if(opt
== "nomoc") {
295 Option::mkfile::do_mocs
= false;
296 } else if(opt
== "nocache") {
297 Option::mkfile::do_cache
= false;
298 } else if(opt
== "createstub") {
299 Option::mkfile::do_stub_makefile
= true;
300 } else if(opt
== "nodependheuristics") {
301 Option::mkfile::do_dep_heuristics
= false;
302 } else if(opt
== "E") {
303 Option::mkfile::do_preprocess
= true;
304 } else if(opt
== "cache") {
305 Option::mkfile::cachefile
= argv
[++x
];
306 } else if(opt
== "platform" || opt
== "spec") {
307 Option::mkfile::qmakespec
= argv
[++x
];
308 Option::mkfile::qmakespec_commandline
= argv
[x
];
310 fprintf(stderr
, "***Unknown option -%s\n", opt
.toLatin1().constData());
311 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
313 } else if(Option::qmake_mode
== Option::QMAKE_GENERATE_PROJECT
) {
315 Option::projfile::do_pwd
= false;
317 fprintf(stderr
, "***Unknown option -%s\n", opt
.toLatin1().constData());
318 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
323 QString arg
= argv
[x
];
324 if(arg
.indexOf('=') != -1) {
326 Option::before_user_vars
.append(arg
);
328 Option::after_user_vars
.append(arg
);
331 if(Option::qmake_mode
== Option::QMAKE_QUERY_PROPERTY
||
332 Option::qmake_mode
== Option::QMAKE_SET_PROPERTY
) {
333 Option::prop::properties
.append(arg
);
336 if(!fi
.makeAbsolute()) //strange
338 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
339 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
) {
341 QString proj
= detectProjectFile(arg
);
345 Option::mkfile::project_files
.append(arg
);
346 } else if(Option::qmake_mode
== Option::QMAKE_GENERATE_PROJECT
) {
347 Option::projfile::project_dirs
.append(arg
);
353 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
359 return Option::QMAKE_CMDLINE_SUCCESS
;
363 static QStringList
detectShellPath()
366 QString path
= qgetenv("PATH");
367 QStringList pathlist
= path
.toLower().split(";");
368 for (int i
= 0; i
< pathlist
.count(); i
++) {
369 QString maybeSh
= pathlist
.at(i
) + "/sh.exe";
370 if (QFile::exists(maybeSh
)) {
371 paths
.append(maybeSh
);
379 Option::init(int argc
, char **argv
)
381 Option::application_argv0
= 0;
382 Option::cpp_moc_mod
= "";
383 Option::h_moc_mod
= "moc_";
384 Option::lex_mod
= "_lex";
385 Option::yacc_mod
= "_yacc";
386 Option::prl_ext
= ".prl";
387 Option::libtool_ext
= ".la";
388 Option::pkgcfg_ext
= ".pc";
389 Option::prf_ext
= ".prf";
390 Option::js_ext
= ".js";
391 Option::ui_ext
= ".ui";
392 Option::h_ext
<< ".h" << ".hpp" << ".hh" << ".hxx";
393 Option::c_ext
<< ".c";
395 Option::h_ext
<< ".H";
397 Option::cpp_moc_ext
= ".moc";
398 Option::h_moc_ext
= ".cpp";
399 Option::cpp_ext
<< ".cpp" << ".cc" << ".cxx";
401 Option::cpp_ext
<< ".C";
403 Option::lex_ext
= ".l";
404 Option::yacc_ext
= ".y";
405 Option::pro_ext
= ".pro";
406 Option::mmp_ext
= ".mmp";
408 Option::dirlist_sep
= ";";
409 Option::shellPath
= detectShellPath();
411 Option::dirlist_sep
= ":";
413 Option::sysenv_mod
= "QMAKE_ENV_";
414 Option::field_sep
= ' ';
417 Option::application_argv0
= argv
[0];
418 QString argv0
= argv
[0];
419 if(Option::qmake_mode
== Option::QMAKE_GENERATE_NOTHING
)
420 Option::qmake_mode
= default_mode(argv0
);
421 if(!argv0
.isEmpty() && !QFileInfo(argv0
).isRelative()) {
422 Option::qmake_abslocation
= argv0
;
423 } else if (argv0
.contains(QLatin1Char('/'))
425 || argv0
.contains(QLatin1Char('\\'))
428 Option::qmake_abslocation
= QDir::current().absoluteFilePath(argv0
);
429 } else { //in the PATH
430 QByteArray pEnv
= qgetenv("PATH");
431 QDir currentDir
= QDir::current();
433 QStringList paths
= QString::fromLocal8Bit(pEnv
).split(QLatin1String(";"));
435 QStringList paths
= QString::fromLocal8Bit(pEnv
).split(QLatin1String(":"));
437 for (QStringList::const_iterator p
= paths
.constBegin(); p
!= paths
.constEnd(); ++p
) {
440 QString candidate
= currentDir
.absoluteFilePath(*p
+ QLatin1Char('/') + argv0
);
444 if (QFile::exists(candidate
)) {
445 Option::qmake_abslocation
= candidate
;
450 if(!Option::qmake_abslocation
.isNull())
451 Option::qmake_abslocation
= QDir::cleanPath(Option::qmake_abslocation
);
453 Option::qmake_mode
= Option::QMAKE_GENERATE_MAKEFILE
;
456 const QByteArray envflags
= qgetenv("QMAKEFLAGS");
457 if (!envflags
.isNull()) {
458 int env_argc
= 0, env_size
= 0, currlen
=0;
459 char quote
= 0, **env_argv
= NULL
;
460 for (int i
= 0; i
< envflags
.size(); ++i
) {
461 if (!quote
&& (envflags
.at(i
) == '\'' || envflags
.at(i
) == '"')) {
462 quote
= envflags
.at(i
);
463 } else if (envflags
.at(i
) == quote
) {
465 } else if (!quote
&& envflags
.at(i
) == ' ') {
466 if (currlen
&& env_argv
&& env_argv
[env_argc
]) {
467 env_argv
[env_argc
][currlen
] = '\0';
472 if(!env_argv
|| env_argc
> env_size
) {
473 env_argv
= (char **)realloc(env_argv
, sizeof(char *)*(env_size
+=10));
474 for(int i2
= env_argc
; i2
< env_size
; i2
++)
477 if(!env_argv
[env_argc
]) {
479 env_argv
[env_argc
] = (char*)malloc(255);
482 env_argv
[env_argc
][currlen
++] = envflags
.at(i
);
486 if(env_argv
[env_argc
]) {
487 env_argv
[env_argc
][currlen
] = '\0';
491 parseCommandLine(env_argc
, env_argv
);
492 for(int i2
= 0; i2
< env_size
; i2
++) {
500 int ret
= parseCommandLine(argc
, argv
, 1);
501 if(ret
!= Option::QMAKE_CMDLINE_SUCCESS
) {
502 if ((ret
& Option::QMAKE_CMDLINE_SHOW_USAGE
) != 0)
505 //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
509 //last chance for defaults
510 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
511 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
) {
512 if(Option::mkfile::qmakespec
.isNull() || Option::mkfile::qmakespec
.isEmpty())
513 Option::mkfile::qmakespec
= QString::fromLocal8Bit(qgetenv("QMAKESPEC").constData());
515 //try REALLY hard to do it for them, lazy..
516 if(Option::mkfile::project_files
.isEmpty()) {
517 QString proj
= detectProjectFile(qmake_getpwd());
519 Option::mkfile::project_files
.append(proj
);
520 #ifndef QT_BUILD_QMAKE_LIBRARY
521 if(Option::mkfile::project_files
.isEmpty()) {
523 return Option::QMAKE_CMDLINE_ERROR
;
529 //defaults for globals
530 if(Option::target_mode
== Option::TARG_WIN_MODE
) {
531 Option::dir_sep
= "\\";
532 Option::obj_ext
= ".obj";
533 Option::res_ext
= ".res";
535 if(Option::target_mode
== Option::TARG_MAC9_MODE
)
536 Option::dir_sep
= ":";
538 Option::dir_sep
= "/";
539 Option::obj_ext
= ".o";
541 Option::qmake_abslocation
= Option::fixPathToTargetOS(Option::qmake_abslocation
);
542 return QMAKE_CMDLINE_SUCCESS
;
545 bool Option::postProcessProject(QMakeProject
*project
)
547 Option::cpp_ext
= project
->variables()["QMAKE_EXT_CPP"];
548 if(cpp_ext
.isEmpty())
549 cpp_ext
<< ".cpp"; //something must be there
550 Option::h_ext
= project
->variables()["QMAKE_EXT_H"];
553 Option::c_ext
= project
->variables()["QMAKE_EXT_C"];
555 c_ext
<< ".c"; //something must be there
557 if(!project
->isEmpty("QMAKE_EXT_RES"))
558 Option::res_ext
= project
->first("QMAKE_EXT_RES");
559 if(!project
->isEmpty("QMAKE_EXT_PKGCONFIG"))
560 Option::pkgcfg_ext
= project
->first("QMAKE_EXT_PKGCONFIG");
561 if(!project
->isEmpty("QMAKE_EXT_LIBTOOL"))
562 Option::libtool_ext
= project
->first("QMAKE_EXT_LIBTOOL");
563 if(!project
->isEmpty("QMAKE_EXT_PRL"))
564 Option::prl_ext
= project
->first("QMAKE_EXT_PRL");
565 if(!project
->isEmpty("QMAKE_EXT_PRF"))
566 Option::prf_ext
= project
->first("QMAKE_EXT_PRF");
567 if(!project
->isEmpty("QMAKE_EXT_JS"))
568 Option::prf_ext
= project
->first("QMAKE_EXT_JS");
569 if(!project
->isEmpty("QMAKE_EXT_UI"))
570 Option::ui_ext
= project
->first("QMAKE_EXT_UI");
571 if(!project
->isEmpty("QMAKE_EXT_CPP_MOC"))
572 Option::cpp_moc_ext
= project
->first("QMAKE_EXT_CPP_MOC");
573 if(!project
->isEmpty("QMAKE_EXT_H_MOC"))
574 Option::h_moc_ext
= project
->first("QMAKE_EXT_H_MOC");
575 if(!project
->isEmpty("QMAKE_EXT_LEX"))
576 Option::lex_ext
= project
->first("QMAKE_EXT_LEX");
577 if(!project
->isEmpty("QMAKE_EXT_YACC"))
578 Option::yacc_ext
= project
->first("QMAKE_EXT_YACC");
579 if(!project
->isEmpty("QMAKE_EXT_OBJ"))
580 Option::obj_ext
= project
->first("QMAKE_EXT_OBJ");
581 if(!project
->isEmpty("QMAKE_H_MOD_MOC"))
582 Option::h_moc_mod
= project
->first("QMAKE_H_MOD_MOC");
583 if(!project
->isEmpty("QMAKE_CPP_MOD_MOC"))
584 Option::cpp_moc_mod
= project
->first("QMAKE_CPP_MOD_MOC");
585 if(!project
->isEmpty("QMAKE_MOD_LEX"))
586 Option::lex_mod
= project
->first("QMAKE_MOD_LEX");
587 if(!project
->isEmpty("QMAKE_MOD_YACC"))
588 Option::yacc_mod
= project
->first("QMAKE_MOD_YACC");
589 if(!project
->isEmpty("QMAKE_DIR_SEP"))
590 Option::dir_sep
= project
->first("QMAKE_DIR_SEP");
591 if(!project
->isEmpty("QMAKE_DIRLIST_SEP"))
592 Option::dirlist_sep
= project
->first("QMAKE_DIRLIST_SEP");
593 if(!project
->isEmpty("QMAKE_MOD_SYSTEM_ENV"))
594 Option::sysenv_mod
= project
->first("QMAKE_MOD_SYSTEM_ENV");
599 Option::fixString(QString string
, uchar flags
)
601 const QString orig_string
= string
;
602 static QHash
<FixStringCacheKey
, QString
> *cache
= 0;
604 cache
= new QHash
<FixStringCacheKey
, QString
>;
605 qmakeAddCacheClear(qmakeDeleteCacheClear_QHashFixStringCacheKeyQString
, (void**)&cache
);
607 FixStringCacheKey
cacheKey(string
, flags
);
608 if(cache
->contains(cacheKey
)) {
609 const QString ret
= cache
->value(cacheKey
);
610 //qDebug() << "Fix (cached) " << orig_string << "->" << ret;
614 //fix the environment variables
615 if(flags
& Option::FixEnvVars
) {
617 QRegExp
reg_var("\\$\\(.*\\)");
618 reg_var
.setMinimal(true);
619 while((rep
= reg_var
.indexIn(string
)) != -1)
620 string
.replace(rep
, reg_var
.matchedLength(),
621 QString::fromLocal8Bit(qgetenv(string
.mid(rep
+ 2, reg_var
.matchedLength() - 3).toLatin1().constData()).constData()));
624 //canonicalize it (and treat as a path)
625 if(flags
& Option::FixPathCanonicalize
) {
627 string
= QFileInfo(string
).canonicalFilePath();
629 string
= QDir::cleanPath(string
);
632 if(string
.length() > 2 && string
[0].isLetter() && string
[1] == QLatin1Char(':'))
633 string
[0] = string
[0].toLower();
636 Q_ASSERT(!((flags
& Option::FixPathToLocalSeparators
) && (flags
& Option::FixPathToTargetSeparators
)));
637 if(flags
& Option::FixPathToLocalSeparators
) {
638 #if defined(Q_OS_WIN32)
639 string
= string
.replace('/', '\\');
641 string
= string
.replace('\\', '/');
643 } else if(flags
& Option::FixPathToTargetSeparators
) {
644 string
= string
.replace('/', Option::dir_sep
).replace('\\', Option::dir_sep
);
647 if (string
.startsWith("\"") && string
.endsWith("\"") ||
648 string
.startsWith("\'") && string
.endsWith("\'"))
649 string
= string
.mid(1, string
.length()-2);
652 //qDebug() << "Fix" << orig_string << "->" << string;
653 cache
->insert(cacheKey
, string
);
657 const char *qmake_version()
659 static char *ret
= NULL
;
662 ret
= (char *)malloc(15);
663 qmakeAddCacheClear(qmakeFreeCacheClear
, (void**)&ret
);
664 #if defined(_MSC_VER) && _MSC_VER >= 1400
665 sprintf_s(ret
, 15, "%d.%02d%c", QMAKE_VERSION_MAJOR
, QMAKE_VERSION_MINOR
, 'a' + QMAKE_VERSION_PATCH
);
667 sprintf(ret
, "%d.%02d%c", QMAKE_VERSION_MAJOR
, QMAKE_VERSION_MINOR
, 'a' + QMAKE_VERSION_PATCH
);
672 void debug_msg_internal(int level
, const char *fmt
, ...)
674 if(Option::debug_level
< level
)
676 fprintf(stderr
, "DEBUG %d: ", level
);
680 vfprintf(stderr
, fmt
, ap
);
683 fprintf(stderr
, "\n");
686 void warn_msg(QMakeWarn type
, const char *fmt
, ...)
688 if(!(Option::warn_level
& type
))
690 fprintf(stderr
, "WARNING: ");
694 vfprintf(stderr
, fmt
, ap
);
697 fprintf(stderr
, "\n");
700 class QMakeCacheClearItem
{
702 qmakeCacheClearFunc func
;
705 QMakeCacheClearItem(qmakeCacheClearFunc f
, void **d
) : func(f
), data(d
) { }
706 ~QMakeCacheClearItem() {
711 static QList
<QMakeCacheClearItem
*> cache_items
;
716 qDeleteAll(cache_items
);
721 qmakeAddCacheClear(qmakeCacheClearFunc func
, void **data
)
723 cache_items
.append(new QMakeCacheClearItem(func
, data
));
727 # include <windows.h>
732 QString
qmake_libraryInfoFile()
735 #if defined( Q_OS_WIN )
736 wchar_t module_name
[MAX_PATH
];
737 GetModuleFileName(0, module_name
, MAX_PATH
);
738 QFileInfo filePath
= QString::fromWCharArray(module_name
);
739 ret
= filePath
.filePath();
741 QString argv0
= QFile::decodeName(QByteArray(Option::application_argv0
));
744 if (!argv0
.isEmpty() && argv0
.at(0) == QLatin1Char('/')) {
746 If argv0 starts with a slash, it is already an absolute
750 } else if (argv0
.contains(QLatin1Char('/'))) {
752 If argv0 contains one or more slashes, it is a file path
753 relative to the current directory.
755 absPath
= QDir::current().absoluteFilePath(argv0
);
758 Otherwise, the file path has to be determined using the
759 PATH environment variable.
761 QByteArray pEnv
= qgetenv("PATH");
762 QDir currentDir
= QDir::current();
763 QStringList paths
= QString::fromLocal8Bit(pEnv
.constData()).split(QLatin1String(":"));
764 for (QStringList::const_iterator p
= paths
.constBegin(); p
!= paths
.constEnd(); ++p
) {
767 QString candidate
= currentDir
.absoluteFilePath(*p
+ QLatin1Char('/') + argv0
);
768 QFileInfo
candidate_fi(candidate
);
769 if (candidate_fi
.exists() && !candidate_fi
.isDir()) {
776 absPath
= QDir::cleanPath(absPath
);
778 QFileInfo
fi(absPath
);
779 ret
= fi
.exists() ? fi
.canonicalFilePath() : QString();
782 ret
= QDir(QFileInfo(ret
).absolutePath()).filePath("qt.conf");