Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies). |
4 | ** Contact: http://www.qt-project.org/legal |
5 | ** |
6 | ** This file is part of the qmake application of the Qt Toolkit. |
7 | ** |
8 | ** $QT_BEGIN_LICENSE:LGPL$ |
9 | ** Commercial License Usage |
10 | ** Licensees holding valid commercial Qt licenses may use this file in |
11 | ** accordance with the commercial license agreement provided with the |
12 | ** Software or, alternatively, in accordance with the terms contained in |
13 | ** a written agreement between you and Digia. For licensing terms and |
14 | ** conditions see http://qt.digia.com/licensing. For further information |
15 | ** use the contact form at http://qt.digia.com/contact-us. |
16 | ** |
17 | ** GNU Lesser General Public License Usage |
18 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
19 | ** General Public License version 2.1 as published by the Free Software |
20 | ** Foundation and appearing in the file LICENSE.LGPL included in the |
21 | ** packaging of this file. Please review the following information to |
22 | ** ensure the GNU Lesser General Public License version 2.1 requirements |
23 | ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
24 | ** |
25 | ** In addition, as a special exception, Digia gives you certain additional |
26 | ** rights. These rights are described in the Digia Qt LGPL Exception |
27 | ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
28 | ** |
29 | ** GNU General Public License Usage |
30 | ** Alternatively, this file may be used under the terms of the GNU |
31 | ** General Public License version 3.0 as published by the Free Software |
32 | ** Foundation and appearing in the file LICENSE.GPL included in the |
33 | ** packaging of this file. Please review the following information to |
34 | ** ensure the GNU General Public License version 3.0 requirements will be |
35 | ** met: http://www.gnu.org/copyleft/gpl.html. |
36 | ** |
37 | ** |
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 | |
52 | QT_BEGIN_NAMESPACE |
53 | |
54 | //convenience |
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; |
81 | |
82 | //mode |
83 | Option::QMAKE_MODE Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING; |
84 | |
85 | //all modes |
86 | QString Option::qmake_abslocation; |
87 | int Option::warn_level = WarnLogic | WarnDeprecated; |
88 | int Option::debug_level = 0; |
89 | QFile Option::output; |
90 | QString Option::output_dir; |
91 | Option::QMAKE_RECURSIVE Option::recursive = Option::QMAKE_RECURSIVE_DEFAULT; |
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 | Option::HOST_MODE Option::host_mode = Option::HOST_UNKNOWN_MODE; |
100 | Option::TARG_MODE Option::target_mode = Option::TARG_UNKNOWN_MODE; |
101 | bool Option::target_mode_overridden = false; |
102 | |
103 | //QMAKE_*_PROPERTY stuff |
104 | QStringList Option::prop::properties; |
105 | |
106 | //QMAKE_GENERATE_PROJECT stuff |
107 | bool Option::projfile::do_pwd = true; |
108 | QStringList Option::projfile::project_dirs; |
109 | |
110 | //QMAKE_GENERATE_MAKEFILE stuff |
111 | QString Option::mkfile::qmakespec; |
112 | int Option::mkfile::cachefile_depth = -1; |
113 | bool Option::mkfile::do_deps = true; |
114 | bool Option::mkfile::do_mocs = true; |
115 | bool Option::mkfile::do_dep_heuristics = true; |
116 | bool Option::mkfile::do_preprocess = false; |
117 | bool Option::mkfile::do_stub_makefile = false; |
118 | bool Option::mkfile::do_cache = true; |
119 | QString Option::mkfile::cachefile; |
120 | QStringList Option::mkfile::project_files; |
121 | QString Option::mkfile::qmakespec_commandline; |
122 | |
123 | static 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 | |
135 | static 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 | |
149 | QString project_builtin_regx(); |
150 | bool 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 | " -unset <prop> Unset persistent property\n" |
196 | " -query <prop> Query persistent property. Show all if <prop> is empty.\n" |
197 | " -cache file Use file as cache [makefile mode only]\n" |
198 | " -spec spec Use spec as QMAKESPEC [makefile mode only]\n" |
199 | " -nocache Don't use a cache file [makefile mode only]\n" |
200 | " -nodepend Don't generate dependencies [makefile mode only]\n" |
201 | " -nomoc Don't generate moc targets [makefile mode only]\n" |
202 | " -nopwd Don't look for files in pwd [project mode only]\n" |
203 | ,a0, |
204 | default_mode(a0) == Option::QMAKE_GENERATE_PROJECT ? " (default)": "", project_builtin_regx().toLatin1().constData(), |
205 | default_mode(a0) == Option::QMAKE_GENERATE_MAKEFILE ? " (default)": "" |
206 | ); |
207 | return false; |
208 | } |
209 | |
210 | int |
211 | Option::parseCommandLine(int argc, char **argv, int skip) |
212 | { |
213 | bool before = true; |
214 | for(int x = skip; x < argc; x++) { |
215 | if(*argv[x] == |
216 | QString opt = argv[x] + 1; |
217 | |
218 | //first param is a mode, or we default |
219 | if(x == 1) { |
220 | bool specified = true; |
221 | if(opt == "project") { |
222 | Option::recursive = Option::QMAKE_RECURSIVE_YES; |
223 | Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT; |
224 | } else if(opt == "prl") { |
225 | Option::mkfile::do_deps = false; |
226 | Option::mkfile::do_mocs = false; |
227 | Option::qmake_mode = Option::QMAKE_GENERATE_PRL; |
228 | } else if(opt == "set") { |
229 | Option::qmake_mode = Option::QMAKE_SET_PROPERTY; |
230 | } else if(opt == "unset") { |
231 | Option::qmake_mode = Option::QMAKE_UNSET_PROPERTY; |
232 | } else if(opt == "query") { |
233 | Option::qmake_mode = Option::QMAKE_QUERY_PROPERTY; |
234 | } else if(opt == "makefile") { |
235 | Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE; |
236 | } else { |
237 | specified = false; |
238 | } |
239 | if(specified) |
240 | continue; |
241 | } |
242 | //all modes |
243 | if(opt == "o"|| opt == "output") { |
244 | Option::output.setFileName(argv[++x]); |
245 | } else if(opt == "after") { |
246 | before = false; |
247 | } else if(opt == "t"|| opt == "template") { |
248 | Option::user_template = argv[++x]; |
249 | } else if(opt == "tp"|| opt == "template_prefix") { |
250 | Option::user_template_prefix = argv[++x]; |
251 | } else if(opt == "macx") { |
252 | fprintf(stderr, "-macx is deprecated.\n"); |
253 | Option::host_mode = HOST_MACX_MODE; |
254 | Option::target_mode = TARG_MACX_MODE; |
255 | Option::target_mode_overridden = true; |
256 | } else if(opt == "unix") { |
257 | fprintf(stderr, "-unix is deprecated.\n"); |
258 | Option::host_mode = HOST_UNIX_MODE; |
259 | Option::target_mode = TARG_UNIX_MODE; |
260 | Option::target_mode_overridden = true; |
261 | } else if(opt == "win32") { |
262 | fprintf(stderr, "-win32 is deprecated.\n"); |
263 | Option::host_mode = HOST_WIN_MODE; |
264 | Option::target_mode = TARG_WIN_MODE; |
265 | Option::target_mode_overridden = true; |
266 | } else if(opt == "integrity") { |
267 | Option::target_mode = TARG_INTEGRITY_MODE; |
268 | } else if(opt == "d") { |
269 | Option::debug_level++; |
270 | } else if(opt == "version"|| opt == "v"|| opt == "-version") { |
271 | fprintf(stdout, |
272 | "QMake version %s\n" |
273 | "Using Qt version %s in %s\n", |
274 | qmake_version(), QT_VERSION_STR, |
275 | QLibraryInfo::location(QLibraryInfo::LibrariesPath).toLatin1().constData()); |
276 | #ifdef QMAKE_OPENSOURCE_VERSION |
277 | fprintf(stdout, "QMake is Open Source software from Nokia Corporation and/or its subsidiary(-ies).\n"); |
278 | #endif |
279 | return Option::QMAKE_CMDLINE_BAIL; |
280 | } else if(opt == "h"|| opt == "help") { |
281 | return Option::QMAKE_CMDLINE_SHOW_USAGE; |
282 | } else if(opt == "Wall") { |
283 | Option::warn_level |= WarnAll; |
284 | } else if(opt == "Wparser") { |
285 | Option::warn_level |= WarnParser; |
286 | } else if(opt == "Wlogic") { |
287 | Option::warn_level |= WarnLogic; |
288 | } else if(opt == "Wdeprecated") { |
289 | Option::warn_level |= WarnDeprecated; |
290 | } else if(opt == "Wnone") { |
291 | Option::warn_level = WarnNone; |
292 | } else if(opt == "r"|| opt == "recursive") { |
293 | Option::recursive = Option::QMAKE_RECURSIVE_YES; |
294 | } else if(opt == "nr"|| opt == "norecursive") { |
295 | Option::recursive = Option::QMAKE_RECURSIVE_NO; |
296 | } else if(opt == "config") { |
297 | Option::user_configs += argv[++x]; |
298 | } else { |
299 | if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || |
300 | Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { |
301 | if(opt == "nodepend"|| opt == "nodepends") { |
302 | Option::mkfile::do_deps = false; |
303 | } else if(opt == "nomoc") { |
304 | Option::mkfile::do_mocs = false; |
305 | } else if(opt == "nocache") { |
306 | Option::mkfile::do_cache = false; |
307 | } else if(opt == "createstub") { |
308 | Option::mkfile::do_stub_makefile = true; |
309 | } else if(opt == "nodependheuristics") { |
310 | Option::mkfile::do_dep_heuristics = false; |
311 | } else if(opt == "E") { |
312 | fprintf(stderr, "-E is deprecated. Use -d instead.\n"); |
313 | Option::mkfile::do_preprocess = true; |
314 | } else if(opt == "cache") { |
315 | Option::mkfile::cachefile = argv[++x]; |
316 | } else if(opt == "platform"|| opt == "spec") { |
317 | Option::mkfile::qmakespec = argv[++x]; |
318 | Option::mkfile::qmakespec_commandline = argv[x]; |
319 | } else { |
320 | fprintf(stderr, "***Unknown option -%s\n", opt.toLatin1().constData()); |
321 | return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR; |
322 | } |
323 | } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { |
324 | if(opt == "nopwd") { |
325 | Option::projfile::do_pwd = false; |
326 | } else { |
327 | fprintf(stderr, "***Unknown option -%s\n", opt.toLatin1().constData()); |
328 | return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR; |
329 | } |
330 | } |
331 | } |
332 | } else { |
333 | QString arg = argv[x]; |
334 | if(arg.indexOf( |
335 | if(before) |
336 | Option::before_user_vars.append(arg); |
337 | else |
338 | Option::after_user_vars.append(arg); |
339 | } else { |
340 | bool handled = true; |
341 | if(Option::qmake_mode == Option::QMAKE_QUERY_PROPERTY || |
342 | Option::qmake_mode == Option::QMAKE_SET_PROPERTY || |
343 | Option::qmake_mode == Option::QMAKE_UNSET_PROPERTY) { |
344 | Option::prop::properties.append(arg); |
345 | } else { |
346 | QFileInfo fi(arg); |
347 | if(!fi.makeAbsolute()) //strange |
348 | arg = fi.filePath(); |
349 | if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || |
350 | Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { |
351 | if(fi.isDir()) { |
352 | QString proj = detectProjectFile(arg); |
353 | if (!proj.isNull()) |
354 | arg = proj; |
355 | } |
356 | Option::mkfile::project_files.append(arg); |
357 | } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { |
358 | Option::projfile::project_dirs.append(arg); |
359 | } else { |
360 | handled = false; |
361 | } |
362 | } |
363 | if(!handled) { |
364 | return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR; |
365 | } |
366 | } |
367 | } |
368 | } |
369 | |
370 | return Option::QMAKE_CMDLINE_SUCCESS; |
371 | } |
372 | |
373 | #ifdef Q_OS_WIN |
374 | static QStringList detectShellPath() |
375 | { |
376 | QStringList paths; |
377 | QString path = qgetenv("PATH"); |
378 | QStringList pathlist = path.toLower().split(";"); |
379 | for (int i = 0; i < pathlist.count(); i++) { |
380 | QString maybeSh = pathlist.at(i) + "/sh.exe"; |
381 | if (QFile::exists(maybeSh)) { |
382 | paths.append(maybeSh); |
383 | } |
384 | } |
385 | return paths; |
386 | } |
387 | #endif |
388 | |
389 | int |
390 | Option::init(int argc, char **argv) |
391 | { |
392 | Option::application_argv0 = 0; |
393 | Option::cpp_moc_mod = ""; |
394 | Option::h_moc_mod = "moc_"; |
395 | Option::lex_mod = "_lex"; |
396 | Option::yacc_mod = "_yacc"; |
397 | Option::prl_ext = ".prl"; |
398 | Option::libtool_ext = ".la"; |
399 | Option::pkgcfg_ext = ".pc"; |
400 | Option::prf_ext = ".prf"; |
401 | Option::js_ext = ".js"; |
402 | Option::ui_ext = ".ui"; |
403 | Option::h_ext << ".h"<< ".hpp"<< ".hh"<< ".hxx"; |
404 | Option::c_ext << ".c"; |
405 | #ifndef Q_OS_WIN |
406 | Option::h_ext << ".H"; |
407 | #endif |
408 | Option::cpp_moc_ext = ".moc"; |
409 | Option::h_moc_ext = ".cpp"; |
410 | Option::cpp_ext << ".cpp"<< ".cc"<< ".cxx"; |
411 | #ifndef Q_OS_WIN |
412 | Option::cpp_ext << ".C"; |
413 | #endif |
414 | Option::lex_ext = ".l"; |
415 | Option::yacc_ext = ".y"; |
416 | Option::pro_ext = ".pro"; |
417 | Option::mmp_ext = ".mmp"; |
418 | #ifdef Q_OS_WIN |
419 | Option::dirlist_sep = ";"; |
420 | Option::shellPath = detectShellPath(); |
421 | Option::res_ext = ".res"; |
422 | #else |
423 | Option::dirlist_sep = ":"; |
424 | Option::shellPath = QStringList("sh"); |
425 | #endif |
426 | Option::sysenv_mod = "QMAKE_ENV_"; |
427 | Option::field_sep = |
428 | |
429 | if(argc && argv) { |
430 | Option::application_argv0 = argv[0]; |
431 | QString argv0 = argv[0]; |
432 | if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING) |
433 | Option::qmake_mode = default_mode(argv0); |
434 | if(!argv0.isEmpty() && !QFileInfo(argv0).isRelative()) { |
435 | Option::qmake_abslocation = argv0; |
436 | } else if (argv0.contains(QLatin1Char( |
437 | #ifdef Q_OS_WIN |
438 | || argv0.contains(QLatin1Char( |
439 | #endif |
440 | ) { //relative PWD |
441 | Option::qmake_abslocation = QDir::current().absoluteFilePath(argv0); |
442 | } else { //in the PATH |
443 | QByteArray pEnv = qgetenv("PATH"); |
444 | QDir currentDir = QDir::current(); |
445 | #ifdef Q_OS_WIN |
446 | QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(";")); |
447 | paths.prepend(QLatin1String(".")); |
448 | #else |
449 | QStringList paths = QString::fromLocal8Bit(pEnv).split(QLatin1String(":")); |
450 | #endif |
451 | for (QStringList::const_iterator p = paths.constBegin(); p != paths.constEnd(); ++p) { |
452 | if ((*p).isEmpty()) |
453 | continue; |
454 | QString candidate = currentDir.absoluteFilePath(*p + QLatin1Char( |
455 | #ifdef Q_OS_WIN |
456 | candidate += ".exe"; |
457 | #endif |
458 | if (QFile::exists(candidate)) { |
459 | Option::qmake_abslocation = candidate; |
460 | break; |
461 | } |
462 | } |
463 | } |
464 | if(!Option::qmake_abslocation.isNull()) |
465 | Option::qmake_abslocation = QDir::cleanPath(Option::qmake_abslocation); |
466 | } else { |
467 | Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE; |
468 | } |
469 | |
470 | const QByteArray envflags = qgetenv("QMAKEFLAGS"); |
471 | if (!envflags.isNull()) { |
472 | int env_argc = 0, env_size = 0, currlen=0; |
473 | char quote = 0, **env_argv = NULL; |
474 | for (int i = 0; i < envflags.size(); ++i) { |
475 | if (!quote && (envflags.at(i) == |
476 | quote = envflags.at(i); |
477 | } else if (envflags.at(i) == quote) { |
478 | quote = 0; |
479 | } else if (!quote && envflags.at(i) == |
480 | if (currlen && env_argv && env_argv[env_argc]) { |
481 | env_argv[env_argc][currlen] = |
482 | currlen = 0; |
483 | env_argc++; |
484 | } |
485 | } else { |
486 | if(!env_argv || env_argc > env_size) { |
487 | env_argv = (char **)realloc(env_argv, sizeof(char *)*(env_size+=10)); |
488 | for(int i2 = env_argc; i2 < env_size; i2++) |
489 | env_argv[i2] = NULL; |
490 | } |
491 | if(!env_argv[env_argc]) { |
492 | currlen = 0; |
493 | env_argv[env_argc] = (char*)malloc(255); |
494 | } |
495 | if(currlen < 255) |
496 | env_argv[env_argc][currlen++] = envflags.at(i); |
497 | } |
498 | } |
499 | if(env_argv) { |
500 | if(env_argv[env_argc]) { |
501 | env_argv[env_argc][currlen] = |
502 | currlen = 0; |
503 | env_argc++; |
504 | } |
505 | parseCommandLine(env_argc, env_argv); |
506 | for(int i2 = 0; i2 < env_size; i2++) { |
507 | if(env_argv[i2]) |
508 | free(env_argv[i2]); |
509 | } |
510 | free(env_argv); |
511 | } |
512 | } |
513 | if(argc && argv) { |
514 | int ret = parseCommandLine(argc, argv, 1); |
515 | if(ret != Option::QMAKE_CMDLINE_SUCCESS) { |
516 | if ((ret & Option::QMAKE_CMDLINE_SHOW_USAGE) != 0) |
517 | usage(argv[0]); |
518 | return ret; |
519 | //return ret == QMAKE_CMDLINE_SHOW_USAGE ? usage(argv[0]) : false; |
520 | } |
521 | } |
522 | |
523 | //last chance for defaults |
524 | if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || |
525 | Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { |
526 | if(Option::mkfile::qmakespec.isNull() || Option::mkfile::qmakespec.isEmpty()) |
527 | Option::mkfile::qmakespec = QString::fromLocal8Bit(qgetenv("QMAKESPEC").constData()); |
528 | |
529 | //try REALLY hard to do it for them, lazy.. |
530 | if(Option::mkfile::project_files.isEmpty()) { |
531 | QString proj = detectProjectFile(qmake_getpwd()); |
532 | if(!proj.isNull()) |
533 | Option::mkfile::project_files.append(proj); |
534 | #ifndef QT_BUILD_QMAKE_LIBRARY |
535 | if(Option::mkfile::project_files.isEmpty()) { |
536 | usage(argv[0]); |
537 | return Option::QMAKE_CMDLINE_ERROR; |
538 | } |
539 | #endif |
540 | } |
541 | } else if (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { |
542 | #if defined(Q_OS_MAC) |
543 | Option::host_mode = Option::HOST_MACX_MODE; |
544 | Option::target_mode = Option::TARG_MACX_MODE; |
545 | #elif defined(Q_OS_UNIX) |
546 | Option::host_mode = Option::HOST_UNIX_MODE; |
547 | Option::target_mode = Option::TARG_UNIX_MODE; |
548 | #else |
549 | Option::host_mode = Option::HOST_WIN_MODE; |
550 | Option::target_mode = Option::TARG_WIN_MODE; |
551 | #endif |
552 | } |
553 | |
554 | //defaults for globals |
555 | if (Option::host_mode != Option::HOST_UNKNOWN_MODE) |
556 | applyHostMode(); |
557 | return QMAKE_CMDLINE_SUCCESS; |
558 | } |
559 | |
560 | void Option::applyHostMode() |
561 | { |
562 | if (Option::host_mode == Option::HOST_WIN_MODE) { |
563 | Option::dir_sep = "\\"; |
564 | Option::obj_ext = ".obj"; |
565 | } else { |
566 | Option::dir_sep = "/"; |
567 | Option::obj_ext = ".o"; |
568 | } |
569 | } |
570 | |
571 | bool Option::postProcessProject(QMakeProject *project) |
572 | { |
573 | Option::cpp_ext = project->variables()["QMAKE_EXT_CPP"]; |
574 | if(cpp_ext.isEmpty()) |
575 | cpp_ext << ".cpp"; //something must be there |
576 | Option::h_ext = project->variables()["QMAKE_EXT_H"]; |
577 | if(h_ext.isEmpty()) |
578 | h_ext << ".h"; |
579 | Option::c_ext = project->variables()["QMAKE_EXT_C"]; |
580 | if(c_ext.isEmpty()) |
581 | c_ext << ".c"; //something must be there |
582 | |
583 | if(!project->isEmpty("QMAKE_EXT_RES")) |
584 | Option::res_ext = project->first("QMAKE_EXT_RES"); |
585 | if(!project->isEmpty("QMAKE_EXT_PKGCONFIG")) |
586 | Option::pkgcfg_ext = project->first("QMAKE_EXT_PKGCONFIG"); |
587 | if(!project->isEmpty("QMAKE_EXT_LIBTOOL")) |
588 | Option::libtool_ext = project->first("QMAKE_EXT_LIBTOOL"); |
589 | if(!project->isEmpty("QMAKE_EXT_PRL")) |
590 | Option::prl_ext = project->first("QMAKE_EXT_PRL"); |
591 | if(!project->isEmpty("QMAKE_EXT_PRF")) |
592 | Option::prf_ext = project->first("QMAKE_EXT_PRF"); |
593 | if(!project->isEmpty("QMAKE_EXT_JS")) |
594 | Option::prf_ext = project->first("QMAKE_EXT_JS"); |
595 | if(!project->isEmpty("QMAKE_EXT_UI")) |
596 | Option::ui_ext = project->first("QMAKE_EXT_UI"); |
597 | if(!project->isEmpty("QMAKE_EXT_CPP_MOC")) |
598 | Option::cpp_moc_ext = project->first("QMAKE_EXT_CPP_MOC"); |
599 | if(!project->isEmpty("QMAKE_EXT_H_MOC")) |
600 | Option::h_moc_ext = project->first("QMAKE_EXT_H_MOC"); |
601 | if(!project->isEmpty("QMAKE_EXT_LEX")) |
602 | Option::lex_ext = project->first("QMAKE_EXT_LEX"); |
603 | if(!project->isEmpty("QMAKE_EXT_YACC")) |
604 | Option::yacc_ext = project->first("QMAKE_EXT_YACC"); |
605 | if(!project->isEmpty("QMAKE_EXT_OBJ")) |
606 | Option::obj_ext = project->first("QMAKE_EXT_OBJ"); |
607 | if(!project->isEmpty("QMAKE_H_MOD_MOC")) |
608 | Option::h_moc_mod = project->first("QMAKE_H_MOD_MOC"); |
609 | if(!project->isEmpty("QMAKE_CPP_MOD_MOC")) |
610 | Option::cpp_moc_mod = project->first("QMAKE_CPP_MOD_MOC"); |
611 | if(!project->isEmpty("QMAKE_MOD_LEX")) |
612 | Option::lex_mod = project->first("QMAKE_MOD_LEX"); |
613 | if(!project->isEmpty("QMAKE_MOD_YACC")) |
614 | Option::yacc_mod = project->first("QMAKE_MOD_YACC"); |
615 | if(!project->isEmpty("QMAKE_DIR_SEP")) |
616 | Option::dir_sep = project->first("QMAKE_DIR_SEP"); |
617 | if(!project->isEmpty("QMAKE_DIRLIST_SEP")) |
618 | Option::dirlist_sep = project->first("QMAKE_DIRLIST_SEP"); |
619 | if(!project->isEmpty("QMAKE_MOD_SYSTEM_ENV")) |
620 | Option::sysenv_mod = project->first("QMAKE_MOD_SYSTEM_ENV"); |
621 | return true; |
622 | } |
623 | |
624 | QString |
625 | Option::fixString(QString string, uchar flags) |
626 | { |
627 | //const QString orig_string = string; |
628 | static QHash<FixStringCacheKey, QString> *cache = 0; |
629 | if(!cache) { |
630 | cache = new QHash<FixStringCacheKey, QString>; |
631 | qmakeAddCacheClear(qmakeDeleteCacheClear<QHash<FixStringCacheKey, QString> >, (void**)&cache); |
632 | } |
633 | FixStringCacheKey cacheKey(string, flags); |
634 | |
635 | QHash<FixStringCacheKey, QString>::const_iterator it = cache->constFind(cacheKey); |
636 | |
637 | if (it != cache->constEnd()) { |
638 | //qDebug() << "Fix (cached) " << orig_string << "->" << it.value(); |
639 | return it.value(); |
640 | } |
641 | |
642 | //fix the environment variables |
643 | if(flags & Option::FixEnvVars) { |
644 | int rep; |
645 | static QRegExp reg_var("\\$\\(.*\\)"); |
646 | reg_var.setMinimal(true); |
647 | while((rep = reg_var.indexIn(string)) != -1) |
648 | string.replace(rep, reg_var.matchedLength(), |
649 | QString::fromLocal8Bit(qgetenv(string.mid(rep + 2, reg_var.matchedLength() - 3).toLatin1().constData()).constData())); |
650 | } |
651 | |
652 | //canonicalize it (and treat as a path) |
653 | if(flags & Option::FixPathCanonicalize) { |
654 | #if 0 |
655 | string = QFileInfo(string).canonicalFilePath(); |
656 | #endif |
657 | string = QDir::cleanPath(string); |
658 | } |
659 | |
660 | if(string.length() > 2 && string[0].isLetter() && string[1] == QLatin1Char( |
661 | string[0] = string[0].toLower(); |
662 | |
663 | //fix separators |
664 | Q_ASSERT(!((flags & Option::FixPathToLocalSeparators) && (flags & Option::FixPathToTargetSeparators))); |
665 | if(flags & Option::FixPathToLocalSeparators) { |
666 | #if defined(Q_OS_WIN32) |
667 | string = string.replace( |
668 | #else |
669 | string = string.replace( |
670 | #endif |
671 | } else if(flags & Option::FixPathToTargetSeparators) { |
672 | string = string.replace( |
673 | } |
674 | |
675 | if ((string.startsWith("\"") && string.endsWith( "\"")) || |
676 | (string.startsWith("\'") && string.endsWith( "\'"))) |
677 | string = string.mid(1, string.length()-2); |
678 | |
679 | //cache |
680 | //qDebug() << "Fix" << orig_string << "->" << string; |
681 | cache->insert(cacheKey, string); |
682 | return string; |
683 | } |
684 | |
685 | const char *qmake_version() |
686 | { |
687 | static char *ret = NULL; |
688 | if(ret) |
689 | return ret; |
690 | ret = (char *)malloc(15); |
691 | qmakeAddCacheClear(qmakeFreeCacheClear, (void**)&ret); |
692 | #if defined(_MSC_VER) && _MSC_VER >= 1400 |
693 | sprintf_s(ret, 15, "%d.%02d%c", QMAKE_VERSION_MAJOR, QMAKE_VERSION_MINOR, |
694 | #else |
695 | sprintf(ret, "%d.%02d%c", QMAKE_VERSION_MAJOR, QMAKE_VERSION_MINOR, |
696 | #endif |
697 | return ret; |
698 | } |
699 | |
700 | void debug_msg_internal(int level, const char *fmt, ...) |
701 | { |
702 | if(Option::debug_level < level) |
703 | return; |
704 | fprintf(stderr, "DEBUG %d: ", level); |
705 | { |
706 | va_list ap; |
707 | va_start(ap, fmt); |
708 | vfprintf(stderr, fmt, ap); |
709 | va_end(ap); |
710 | } |
711 | fprintf(stderr, "\n"); |
712 | } |
713 | |
714 | void warn_msg(QMakeWarn type, const char *fmt, ...) |
715 | { |
716 | if(!(Option::warn_level & type)) |
717 | return; |
718 | fprintf(stderr, "WARNING: "); |
719 | { |
720 | va_list ap; |
721 | va_start(ap, fmt); |
722 | vfprintf(stderr, fmt, ap); |
723 | va_end(ap); |
724 | } |
725 | fprintf(stderr, "\n"); |
726 | } |
727 | |
728 | class QMakeCacheClearItem { |
729 | private: |
730 | qmakeCacheClearFunc func; |
731 | void **data; |
732 | public: |
733 | QMakeCacheClearItem(qmakeCacheClearFunc f, void **d) : func(f), data(d) { } |
734 | ~QMakeCacheClearItem() { |
735 | (*func)(*data); |
736 | *data = 0; |
737 | } |
738 | }; |
739 | static QList<QMakeCacheClearItem*> cache_items; |
740 | |
741 | void |
742 | qmakeClearCaches() |
743 | { |
744 | qDeleteAll(cache_items); |
745 | cache_items.clear(); |
746 | } |
747 | |
748 | void |
749 | qmakeAddCacheClear(qmakeCacheClearFunc func, void **data) |
750 | { |
751 | cache_items.append(new QMakeCacheClearItem(func, data)); |
752 | } |
753 | |
754 | QString qmake_libraryInfoFile() |
755 | { |
756 | if(!Option::qmake_abslocation.isEmpty()) |
757 | return QDir(QFileInfo(Option::qmake_abslocation).absolutePath()).filePath("qt.conf"); |
758 | return QString(); |
759 | } |
760 | |
761 | QT_END_NAMESPACE |
762 |
Warning: That file was not part of the compilation database. It may have many parsing errors.