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$
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 QString
project_builtin_regx();
140 bool usage(const char *a0
)
142 fprintf(stdout
, "Usage: %s [mode] [options] [files]\n"
144 "QMake has two modes, one mode for generating project files based on\n"
145 "some heuristics, and the other for generating makefiles. Normally you\n"
146 "shouldn't need to specify a mode, as makefile generation is the default\n"
147 "mode for qmake, but you may use this to test qmake on an existing project\n"
150 " -project Put qmake into project file generation mode%s\n"
151 " In this mode qmake interprets files as files to\n"
154 " Note: The created .pro file probably will \n"
155 " need to be edited. For example add the QT variable to \n"
156 " specify what modules are required.\n"
157 " -makefile Put qmake into makefile generation mode%s\n"
158 " In this mode qmake interprets files as project files to\n"
159 " be processed, if skipped qmake will try to find a project\n"
160 " file in your current working directory\n"
162 "Warnings Options:\n"
163 " -Wnone Turn off all warnings\n"
164 " -Wall Turn on all warnings\n"
165 " -Wparser Turn on parser warnings\n"
166 " -Wlogic Turn on logic warnings\n"
169 " * You can place any variable assignment in options and it will be *\n"
170 " * processed as if it was in [files]. These assignments will be parsed *\n"
171 " * before [files]. *\n"
172 " -o file Write output to file\n"
173 " -unix Run in unix mode\n"
174 " -win32 Run in win32 mode\n"
175 " -macx Run in Mac OS X mode\n"
176 " -d Increase debug level\n"
177 " -t templ Overrides TEMPLATE as templ\n"
178 " -tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n"
180 " -v Version information\n"
181 " -after All variable assignments after this will be\n"
182 " parsed after [files]\n"
183 " -norecursive Don't do a recursive search\n"
184 " -recursive Do a recursive search\n"
185 " -set <prop> <value> Set persistent property\n"
186 " -query <prop> Query persistent property. Show all if <prop> is empty.\n"
187 " -cache file Use file as cache [makefile mode only]\n"
188 " -spec spec Use spec as QMAKESPEC [makefile mode only]\n"
189 " -nocache Don't use a cache file [makefile mode only]\n"
190 " -nodepend Don't generate dependencies [makefile mode only]\n"
191 " -nomoc Don't generate moc targets [makefile mode only]\n"
192 " -nopwd Don't look for files in pwd [project mode only]\n"
194 default_mode(a0
) == Option::QMAKE_GENERATE_PROJECT
? " (default)" : "", project_builtin_regx().toLatin1().constData(),
195 default_mode(a0
) == Option::QMAKE_GENERATE_MAKEFILE
? " (default)" : ""
201 Option::parseCommandLine(int argc
, char **argv
, int skip
)
204 for(int x
= skip
; x
< argc
; x
++) {
205 if(*argv
[x
] == '-' && strlen(argv
[x
]) > 1) { /* options */
206 QString opt
= argv
[x
] + 1;
208 //first param is a mode, or we default
210 bool specified
= true;
211 if(opt
== "project") {
212 Option::recursive
= true;
213 Option::qmake_mode
= Option::QMAKE_GENERATE_PROJECT
;
214 } else if(opt
== "prl") {
215 Option::mkfile::do_deps
= false;
216 Option::mkfile::do_mocs
= false;
217 Option::qmake_mode
= Option::QMAKE_GENERATE_PRL
;
218 } else if(opt
== "set") {
219 Option::qmake_mode
= Option::QMAKE_SET_PROPERTY
;
220 } else if(opt
== "query") {
221 Option::qmake_mode
= Option::QMAKE_QUERY_PROPERTY
;
222 } else if(opt
== "makefile") {
223 Option::qmake_mode
= Option::QMAKE_GENERATE_MAKEFILE
;
231 if(opt
== "o" || opt
== "output") {
232 Option::output
.setFileName(argv
[++x
]);
233 } else if(opt
== "after") {
235 } else if(opt
== "t" || opt
== "template") {
236 Option::user_template
= argv
[++x
];
237 } else if(opt
== "tp" || opt
== "template_prefix") {
238 Option::user_template_prefix
= argv
[++x
];
239 } else if(opt
== "mac9") {
240 Option::target_mode
= TARG_MAC9_MODE
;
241 } else if(opt
== "macx") {
242 Option::target_mode
= TARG_MACX_MODE
;
243 } else if(opt
== "unix") {
244 Option::target_mode
= TARG_UNIX_MODE
;
245 } else if(opt
== "win32") {
246 Option::target_mode
= TARG_WIN_MODE
;
247 } else if(opt
== "d") {
248 Option::debug_level
++;
249 } else if(opt
== "version" || opt
== "v" || opt
== "-version") {
252 "Using Qt version %s in %s\n",
253 qmake_version(), QT_VERSION_STR
,
254 QLibraryInfo::location(QLibraryInfo::LibrariesPath
).toLatin1().constData());
255 #ifdef QMAKE_OPENSOURCE_VERSION
256 fprintf(stdout
, "QMake is Open Source software from Nokia Corporation and/or its subsidiary(-ies).\n");
258 return Option::QMAKE_CMDLINE_BAIL
;
259 } else if(opt
== "h" || opt
== "help") {
260 return Option::QMAKE_CMDLINE_SHOW_USAGE
;
261 } else if(opt
== "Wall") {
262 Option::warn_level
|= WarnAll
;
263 } else if(opt
== "Wparser") {
264 Option::warn_level
|= WarnParser
;
265 } else if(opt
== "Wlogic") {
266 Option::warn_level
|= WarnLogic
;
267 } else if(opt
== "Wnone") {
268 Option::warn_level
= WarnNone
;
269 } else if(opt
== "r" || opt
== "recursive") {
270 Option::recursive
= true;
271 } else if(opt
== "norecursive") {
272 Option::recursive
= false;
273 } else if(opt
== "config") {
274 Option::user_configs
+= argv
[++x
];
276 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
277 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
) {
278 if(opt
== "nodepend" || opt
== "nodepends") {
279 Option::mkfile::do_deps
= false;
280 } else if(opt
== "nomoc") {
281 Option::mkfile::do_mocs
= false;
282 } else if(opt
== "nocache") {
283 Option::mkfile::do_cache
= false;
284 } else if(opt
== "createstub") {
285 Option::mkfile::do_stub_makefile
= true;
286 } else if(opt
== "nodependheuristics") {
287 Option::mkfile::do_dep_heuristics
= false;
288 } else if(opt
== "E") {
289 Option::mkfile::do_preprocess
= true;
290 } else if(opt
== "cache") {
291 Option::mkfile::cachefile
= argv
[++x
];
292 } else if(opt
== "platform" || opt
== "spec") {
293 Option::mkfile::qmakespec
= argv
[++x
];
294 Option::mkfile::qmakespec_commandline
= argv
[x
];
296 fprintf(stderr
, "***Unknown option -%s\n", opt
.toLatin1().constData());
297 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
299 } else if(Option::qmake_mode
== Option::QMAKE_GENERATE_PROJECT
) {
301 Option::projfile::do_pwd
= false;
303 fprintf(stderr
, "***Unknown option -%s\n", opt
.toLatin1().constData());
304 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
309 QString arg
= argv
[x
];
310 if(arg
.indexOf('=') != -1) {
312 Option::before_user_vars
.append(arg
);
314 Option::after_user_vars
.append(arg
);
317 if(Option::qmake_mode
== Option::QMAKE_QUERY_PROPERTY
||
318 Option::qmake_mode
== Option::QMAKE_SET_PROPERTY
) {
319 Option::prop::properties
.append(arg
);
322 if(!fi
.makeAbsolute()) //strange
324 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
325 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
)
326 Option::mkfile::project_files
.append(arg
);
327 else if(Option::qmake_mode
== Option::QMAKE_GENERATE_PROJECT
)
328 Option::projfile::project_dirs
.append(arg
);
333 return Option::QMAKE_CMDLINE_SHOW_USAGE
| Option::QMAKE_CMDLINE_ERROR
;
339 return Option::QMAKE_CMDLINE_SUCCESS
;
343 static QStringList
detectShellPath()
346 QString path
= qgetenv("PATH");
347 QStringList pathlist
= path
.toLower().split(";");
348 for (int i
= 0; i
< pathlist
.count(); i
++) {
349 QString maybeSh
= pathlist
.at(i
) + "/sh.exe";
350 if (QFile::exists(maybeSh
)) {
351 paths
.append(maybeSh
);
359 Option::init(int argc
, char **argv
)
361 Option::application_argv0
= 0;
362 Option::cpp_moc_mod
= "";
363 Option::h_moc_mod
= "moc_";
364 Option::lex_mod
= "_lex";
365 Option::yacc_mod
= "_yacc";
366 Option::prl_ext
= ".prl";
367 Option::libtool_ext
= ".la";
368 Option::pkgcfg_ext
= ".pc";
369 Option::prf_ext
= ".prf";
370 Option::js_ext
= ".js";
371 Option::ui_ext
= ".ui";
372 Option::h_ext
<< ".h" << ".hpp" << ".hh" << ".hxx";
373 Option::c_ext
<< ".c";
375 Option::h_ext
<< ".H";
377 Option::cpp_moc_ext
= ".moc";
378 Option::h_moc_ext
= ".cpp";
379 Option::cpp_ext
<< ".cpp" << ".cc" << ".cxx";
381 Option::cpp_ext
<< ".C";
383 Option::lex_ext
= ".l";
384 Option::yacc_ext
= ".y";
385 Option::pro_ext
= ".pro";
386 Option::mmp_ext
= ".mmp";
388 Option::dirlist_sep
= ";";
389 Option::shellPath
= detectShellPath();
391 Option::dirlist_sep
= ":";
393 Option::sysenv_mod
= "QMAKE_ENV_";
394 Option::field_sep
= ' ';
397 Option::application_argv0
= argv
[0];
398 QString argv0
= argv
[0];
399 if(Option::qmake_mode
== Option::QMAKE_GENERATE_NOTHING
)
400 Option::qmake_mode
= default_mode(argv0
);
401 if(!argv0
.isEmpty() && !QFileInfo(argv0
).isRelative()) {
402 Option::qmake_abslocation
= argv0
;
403 } else if (argv0
.contains(QLatin1Char('/'))
405 || argv0
.contains(QLatin1Char('\\'))
408 Option::qmake_abslocation
= QDir::current().absoluteFilePath(argv0
);
409 } else { //in the PATH
410 QByteArray pEnv
= qgetenv("PATH");
411 QDir currentDir
= QDir::current();
413 QStringList paths
= QString::fromLocal8Bit(pEnv
).split(QLatin1String(";"));
415 QStringList paths
= QString::fromLocal8Bit(pEnv
).split(QLatin1String(":"));
417 for (QStringList::const_iterator p
= paths
.constBegin(); p
!= paths
.constEnd(); ++p
) {
420 QString candidate
= currentDir
.absoluteFilePath(*p
+ QLatin1Char('/') + argv0
);
424 if (QFile::exists(candidate
)) {
425 Option::qmake_abslocation
= candidate
;
430 if(!Option::qmake_abslocation
.isNull())
431 Option::qmake_abslocation
= QDir::cleanPath(Option::qmake_abslocation
);
433 Option::qmake_mode
= Option::QMAKE_GENERATE_MAKEFILE
;
436 const QByteArray envflags
= qgetenv("QMAKEFLAGS");
437 if (!envflags
.isNull()) {
438 int env_argc
= 0, env_size
= 0, currlen
=0;
439 char quote
= 0, **env_argv
= NULL
;
440 for (int i
= 0; i
< envflags
.size(); ++i
) {
441 if (!quote
&& (envflags
.at(i
) == '\'' || envflags
.at(i
) == '"')) {
442 quote
= envflags
.at(i
);
443 } else if (envflags
.at(i
) == quote
) {
445 } else if (!quote
&& envflags
.at(i
) == ' ') {
446 if (currlen
&& env_argv
&& env_argv
[env_argc
]) {
447 env_argv
[env_argc
][currlen
] = '\0';
452 if(!env_argv
|| env_argc
> env_size
) {
453 env_argv
= (char **)realloc(env_argv
, sizeof(char *)*(env_size
+=10));
454 for(int i2
= env_argc
; i2
< env_size
; i2
++)
457 if(!env_argv
[env_argc
]) {
459 env_argv
[env_argc
] = (char*)malloc(255);
462 env_argv
[env_argc
][currlen
++] = envflags
.at(i
);
466 if(env_argv
[env_argc
]) {
467 env_argv
[env_argc
][currlen
] = '\0';
471 parseCommandLine(env_argc
, env_argv
);
472 for(int i2
= 0; i2
< env_size
; i2
++) {
480 int ret
= parseCommandLine(argc
, argv
, 1);
481 if(ret
!= Option::QMAKE_CMDLINE_SUCCESS
) {
482 if ((ret
& Option::QMAKE_CMDLINE_SHOW_USAGE
) != 0)
485 //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false;
489 //last chance for defaults
490 if(Option::qmake_mode
== Option::QMAKE_GENERATE_MAKEFILE
||
491 Option::qmake_mode
== Option::QMAKE_GENERATE_PRL
) {
492 if(Option::mkfile::qmakespec
.isNull() || Option::mkfile::qmakespec
.isEmpty())
493 Option::mkfile::qmakespec
= QString::fromLocal8Bit(qgetenv("QMAKESPEC").constData());
495 //try REALLY hard to do it for them, lazy..
496 if(Option::mkfile::project_files
.isEmpty()) {
497 QString pwd
= qmake_getpwd(),
498 proj
= pwd
+ "/" + pwd
.right(pwd
.length() - (pwd
.lastIndexOf('/') + 1)) + Option::pro_ext
;
499 if(QFile::exists(proj
)) {
500 Option::mkfile::project_files
.append(proj
);
501 } else { //last try..
502 QStringList profiles
= QDir(pwd
).entryList(QStringList("*" + Option::pro_ext
));
503 if(profiles
.count() == 1)
504 Option::mkfile::project_files
.append(pwd
+ "/" + profiles
[0]);
506 #ifndef QT_BUILD_QMAKE_LIBRARY
507 if(Option::mkfile::project_files
.isEmpty()) {
509 return Option::QMAKE_CMDLINE_ERROR
;
515 //defaults for globals
516 if(Option::target_mode
== Option::TARG_WIN_MODE
) {
517 Option::dir_sep
= "\\";
518 Option::obj_ext
= ".obj";
519 Option::res_ext
= ".res";
521 if(Option::target_mode
== Option::TARG_MAC9_MODE
)
522 Option::dir_sep
= ":";
524 Option::dir_sep
= "/";
525 Option::obj_ext
= ".o";
527 Option::qmake_abslocation
= Option::fixPathToTargetOS(Option::qmake_abslocation
);
528 return QMAKE_CMDLINE_SUCCESS
;
531 bool Option::postProcessProject(QMakeProject
*project
)
533 Option::cpp_ext
= project
->variables()["QMAKE_EXT_CPP"];
534 if(cpp_ext
.isEmpty())
535 cpp_ext
<< ".cpp"; //something must be there
536 Option::h_ext
= project
->variables()["QMAKE_EXT_H"];
539 Option::c_ext
= project
->variables()["QMAKE_EXT_C"];
541 c_ext
<< ".c"; //something must be there
543 if(!project
->isEmpty("QMAKE_EXT_RES"))
544 Option::res_ext
= project
->first("QMAKE_EXT_RES");
545 if(!project
->isEmpty("QMAKE_EXT_PKGCONFIG"))
546 Option::pkgcfg_ext
= project
->first("QMAKE_EXT_PKGCONFIG");
547 if(!project
->isEmpty("QMAKE_EXT_LIBTOOL"))
548 Option::libtool_ext
= project
->first("QMAKE_EXT_LIBTOOL");
549 if(!project
->isEmpty("QMAKE_EXT_PRL"))
550 Option::prl_ext
= project
->first("QMAKE_EXT_PRL");
551 if(!project
->isEmpty("QMAKE_EXT_PRF"))
552 Option::prf_ext
= project
->first("QMAKE_EXT_PRF");
553 if(!project
->isEmpty("QMAKE_EXT_JS"))
554 Option::prf_ext
= project
->first("QMAKE_EXT_JS");
555 if(!project
->isEmpty("QMAKE_EXT_UI"))
556 Option::ui_ext
= project
->first("QMAKE_EXT_UI");
557 if(!project
->isEmpty("QMAKE_EXT_CPP_MOC"))
558 Option::cpp_moc_ext
= project
->first("QMAKE_EXT_CPP_MOC");
559 if(!project
->isEmpty("QMAKE_EXT_H_MOC"))
560 Option::h_moc_ext
= project
->first("QMAKE_EXT_H_MOC");
561 if(!project
->isEmpty("QMAKE_EXT_LEX"))
562 Option::lex_ext
= project
->first("QMAKE_EXT_LEX");
563 if(!project
->isEmpty("QMAKE_EXT_YACC"))
564 Option::yacc_ext
= project
->first("QMAKE_EXT_YACC");
565 if(!project
->isEmpty("QMAKE_EXT_OBJ"))
566 Option::obj_ext
= project
->first("QMAKE_EXT_OBJ");
567 if(!project
->isEmpty("QMAKE_H_MOD_MOC"))
568 Option::h_moc_mod
= project
->first("QMAKE_H_MOD_MOC");
569 if(!project
->isEmpty("QMAKE_CPP_MOD_MOC"))
570 Option::cpp_moc_mod
= project
->first("QMAKE_CPP_MOD_MOC");
571 if(!project
->isEmpty("QMAKE_MOD_LEX"))
572 Option::lex_mod
= project
->first("QMAKE_MOD_LEX");
573 if(!project
->isEmpty("QMAKE_MOD_YACC"))
574 Option::yacc_mod
= project
->first("QMAKE_MOD_YACC");
575 if(!project
->isEmpty("QMAKE_DIR_SEP"))
576 Option::dir_sep
= project
->first("QMAKE_DIR_SEP");
577 if(!project
->isEmpty("QMAKE_DIRLIST_SEP"))
578 Option::dirlist_sep
= project
->first("QMAKE_DIRLIST_SEP");
579 if(!project
->isEmpty("QMAKE_MOD_SYSTEM_ENV"))
580 Option::sysenv_mod
= project
->first("QMAKE_MOD_SYSTEM_ENV");
585 Option::fixString(QString string
, uchar flags
)
587 const QString orig_string
= string
;
588 static QHash
<FixStringCacheKey
, QString
> *cache
= 0;
590 cache
= new QHash
<FixStringCacheKey
, QString
>;
591 qmakeAddCacheClear(qmakeDeleteCacheClear_QHashFixStringCacheKeyQString
, (void**)&cache
);
593 FixStringCacheKey
cacheKey(string
, flags
);
594 if(cache
->contains(cacheKey
)) {
595 const QString ret
= cache
->value(cacheKey
);
596 //qDebug() << "Fix (cached) " << orig_string << "->" << ret;
600 //fix the environment variables
601 if(flags
& Option::FixEnvVars
) {
603 QRegExp
reg_var("\\$\\(.*\\)");
604 reg_var
.setMinimal(true);
605 while((rep
= reg_var
.indexIn(string
)) != -1)
606 string
.replace(rep
, reg_var
.matchedLength(),
607 QString::fromLocal8Bit(qgetenv(string
.mid(rep
+ 2, reg_var
.matchedLength() - 3).toLatin1().constData()).constData()));
610 //canonicalize it (and treat as a path)
611 if(flags
& Option::FixPathCanonicalize
) {
613 string
= QFileInfo(string
).canonicalFilePath();
615 string
= QDir::cleanPath(string
);
618 if(string
.length() > 2 && string
[0].isLetter() && string
[1] == QLatin1Char(':'))
619 string
[0] = string
[0].toLower();
622 Q_ASSERT(!((flags
& Option::FixPathToLocalSeparators
) && (flags
& Option::FixPathToTargetSeparators
)));
623 if(flags
& Option::FixPathToLocalSeparators
) {
624 #if defined(Q_OS_WIN32)
625 string
= string
.replace('/', '\\');
627 string
= string
.replace('\\', '/');
629 } else if(flags
& Option::FixPathToTargetSeparators
) {
630 string
= string
.replace('/', Option::dir_sep
).replace('\\', Option::dir_sep
);
633 if (string
.startsWith("\"") && string
.endsWith("\"") ||
634 string
.startsWith("\'") && string
.endsWith("\'"))
635 string
= string
.mid(1, string
.length()-2);
638 //qDebug() << "Fix" << orig_string << "->" << string;
639 cache
->insert(cacheKey
, string
);
643 const char *qmake_version()
645 static char *ret
= NULL
;
648 ret
= (char *)malloc(15);
649 qmakeAddCacheClear(qmakeFreeCacheClear
, (void**)&ret
);
650 #if defined(_MSC_VER) && _MSC_VER >= 1400
651 sprintf_s(ret
, 15, "%d.%02d%c", QMAKE_VERSION_MAJOR
, QMAKE_VERSION_MINOR
, 'a' + QMAKE_VERSION_PATCH
);
653 sprintf(ret
, "%d.%02d%c", QMAKE_VERSION_MAJOR
, QMAKE_VERSION_MINOR
, 'a' + QMAKE_VERSION_PATCH
);
658 void debug_msg_internal(int level
, const char *fmt
, ...)
660 if(Option::debug_level
< level
)
662 fprintf(stderr
, "DEBUG %d: ", level
);
666 vfprintf(stderr
, fmt
, ap
);
669 fprintf(stderr
, "\n");
672 void warn_msg(QMakeWarn type
, const char *fmt
, ...)
674 if(!(Option::warn_level
& type
))
676 fprintf(stderr
, "WARNING: ");
680 vfprintf(stderr
, fmt
, ap
);
683 fprintf(stderr
, "\n");
686 class QMakeCacheClearItem
{
688 qmakeCacheClearFunc func
;
691 QMakeCacheClearItem(qmakeCacheClearFunc f
, void **d
) : func(f
), data(d
) { }
692 ~QMakeCacheClearItem() {
697 static QList
<QMakeCacheClearItem
*> cache_items
;
702 qDeleteAll(cache_items
);
707 qmakeAddCacheClear(qmakeCacheClearFunc func
, void **data
)
709 cache_items
.append(new QMakeCacheClearItem(func
, data
));
713 # include <windows.h>
718 QString
qmake_libraryInfoFile()
721 #if defined( Q_OS_WIN )
722 wchar_t module_name
[MAX_PATH
];
723 GetModuleFileName(0, module_name
, MAX_PATH
);
724 QFileInfo filePath
= QString::fromWCharArray(module_name
);
725 ret
= filePath
.filePath();
727 QString argv0
= QFile::decodeName(QByteArray(Option::application_argv0
));
730 if (!argv0
.isEmpty() && argv0
.at(0) == QLatin1Char('/')) {
732 If argv0 starts with a slash, it is already an absolute
736 } else if (argv0
.contains(QLatin1Char('/'))) {
738 If argv0 contains one or more slashes, it is a file path
739 relative to the current directory.
741 absPath
= QDir::current().absoluteFilePath(argv0
);
744 Otherwise, the file path has to be determined using the
745 PATH environment variable.
747 QByteArray pEnv
= qgetenv("PATH");
748 QDir currentDir
= QDir::current();
749 QStringList paths
= QString::fromLocal8Bit(pEnv
.constData()).split(QLatin1String(":"));
750 for (QStringList::const_iterator p
= paths
.constBegin(); p
!= paths
.constEnd(); ++p
) {
753 QString candidate
= currentDir
.absoluteFilePath(*p
+ QLatin1Char('/') + argv0
);
754 QFileInfo
candidate_fi(candidate
);
755 if (candidate_fi
.exists() && !candidate_fi
.isDir()) {
762 absPath
= QDir::cleanPath(absPath
);
764 QFileInfo
fi(absPath
);
765 ret
= fi
.exists() ? fi
.canonicalFilePath() : QString();
768 ret
= QDir(QFileInfo(ret
).absolutePath()).filePath("qt.conf");