summaryrefslogtreecommitdiff
path: root/qmake/option.cpp
Unidiff
Diffstat (limited to 'qmake/option.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--qmake/option.cpp449
1 files changed, 449 insertions, 0 deletions
diff --git a/qmake/option.cpp b/qmake/option.cpp
new file mode 100644
index 0000000..34b3ee2
--- a/dev/null
+++ b/qmake/option.cpp
@@ -0,0 +1,449 @@
1/****************************************************************************
2** $Id$
3**
4** Definition of ________ class.
5**
6** Created : 970521
7**
8** Copyright (C) 1992-2000 Trolltech AS. All rights reserved.
9**
10** This file is part of the network module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition licenses may use this
22** file in accordance with the Qt Commercial License Agreement provided
23** with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "option.h"
39#include <qdir.h>
40#include <qregexp.h>
41#include <stdlib.h>
42#include <stdarg.h>
43
44//convenience
45QString Option::prf_ext;
46QString Option::prl_ext;
47QString Option::ui_ext;
48QStringList Option::h_ext;
49QString Option::moc_ext;
50QStringList Option::cpp_ext;
51QString Option::obj_ext;
52QString Option::lex_ext;
53QString Option::yacc_ext;
54QString Option::dir_sep;
55QString Option::moc_mod;
56QString Option::yacc_mod;
57QString Option::lex_mod;
58
59//mode
60Option::QMAKE_MODE Option::qmake_mode = Option::QMAKE_GENERATE_NOTHING;
61
62//all modes
63int Option::warn_level = WarnLogic;
64int Option::debug_level = 0;
65QFile Option::output;
66QString Option::output_dir;
67QStringList Option::before_user_vars;
68QStringList Option::after_user_vars;
69QString Option::user_template;
70QString Option::user_template_prefix;
71#if defined(Q_OS_WIN32)
72Option::TARG_MODE Option::target_mode = Option::TARG_WIN_MODE;
73#elif defined(Q_OS_MAC9)
74Option::TARG_MODE Option::target_mode = Option::TARG_MAC9_MODE;
75#elif defined(Q_OS_MACX)
76Option::TARG_MODE Option::target_mode = Option::TARG_MACX_MODE;
77#elif defined(Q_OS_QNX6)
78Option::TARG_MODE Option::target_mode = Option::TARG_QNX6_MODE;
79#else
80Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE;
81#endif
82
83//QMAKE_GENERATE_PROJECT stuff
84bool Option::projfile::do_pwd = TRUE;
85bool Option::projfile::do_recursive = FALSE;
86QStringList Option::projfile::project_dirs;
87
88//QMAKE_GENERATE_MAKEFILE stuff
89QString Option::mkfile::qmakespec;
90int Option::mkfile::cachefile_depth = -1;
91bool Option::mkfile::do_deps = TRUE;
92bool Option::mkfile::do_mocs = TRUE;
93bool Option::mkfile::do_dep_heuristics = TRUE;
94bool Option::mkfile::do_preprocess = FALSE;
95bool Option::mkfile::do_cache = TRUE;
96QString Option::mkfile::cachefile;
97QStringList Option::mkfile::project_files;
98QString Option::mkfile::qmakespec_commandline;
99
100bool usage(const char *a0)
101{
102 fprintf(stdout, "Usage: %s [mode] [options] [files]\n"
103 "\n"
104 " QMake has two modes, one mode for generating project files based on\n"
105 "some heuristics, and the other for generating makefiles. Normally you\n"
106 "shouldn't need to specify a mode, as makefile generation is the default\n"
107 "mode for qmake, but you may use this to test qmake on an existing project\n"
108 "\n"
109 "Mode:\n"
110 "\t-project Put qmake into project file generation mode\n"
111 "\t In this mode qmake interprets files as files to\n"
112 "\t be built,\n"
113 "\t defaults to *.cpp; *.l; *.y; *.ui\n"
114 "\t-makefile Put qmake into makefile generation mode (default)\n"
115 "\t In this mode qmake interprets files as project files to\n"
116 "\t be processed, if skipped qmake will try to find a project\n"
117 "\t file in your current working directory\n"
118 "\n"
119 "Warnings Options:\n"
120 "\t-Wnone Turn off all warnings\n"
121 "\t-Wall Turn on all warnings\n"
122 "\t-Wparser Turn on parser warnings\n"
123 "\t-Wlogic Turn on logic warnings\n"
124 "\n"
125 "Options:\n"
126 "\t * You can place any variable assignment in options and it will be *\n"
127 "\t * processed as if it was in [files]. These assignments will be parsed *\n"
128 "\t * before [files]. *\n"
129 "\t-o file Write output to file\n"
130 "\t-unix Run in unix mode\n"
131 "\t-win32 Run in win32 mode\n"
132 "\t-macx Run in Mac OS X mode\n"
133 "\t-d Increase debug level\n"
134 "\t-t templ Overrides TEMPLATE as templ\n"
135 "\t-tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n"
136 "\t-help This help\n"
137 "\t-v Version information\n"
138 "\t-after All variable assignments after this will be\n"
139 "\t parsed after [files] [makefile mode only]\n"
140 "\t-cache file Use file as cache [makefile mode only]\n"
141 "\t-spec spec Use spec as QMAKESPEC [makefile mode only]\n"
142 "\t-nocache Don't use a cache file [makefile mode only]\n"
143 "\t-nodepend Don't generate dependencies [makefile mode only]\n"
144 "\t-nomoc Don't generate moc targets [makefile mode only]\n"
145 "\t-nopwd Don't look for files in pwd [ project mode only]\n"
146 "\t-r Recursive search [ project mode only]\n"
147 ,a0);
148 return FALSE;
149}
150static Option::QMAKE_MODE default_mode(QString progname)
151{
152 int s = progname.findRev(Option::dir_sep);
153 if(s != -1)
154 progname = progname.right(progname.length() - (s + 1));
155 if(progname == "qmakegen")
156 return Option::QMAKE_GENERATE_PROJECT;
157 return Option::QMAKE_GENERATE_MAKEFILE;
158}
159
160
161bool
162Option::parseCommandLine(int argc, char **argv)
163{
164 bool before = TRUE;
165 for(int x = 1; x < argc; x++) {
166 if(*argv[x] == '-' && strlen(argv[x]) > 1) { /* options */
167 QString opt = argv[x] + 1;
168
169 //first param is a mode, or we default
170 if(x == 1) {
171 bool specified = TRUE;
172 if(opt == "project") {
173 Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT;
174 } else if(opt == "prl") {
175 Option::mkfile::do_deps = FALSE;
176 Option::mkfile::do_mocs = FALSE;
177 Option::qmake_mode = Option::QMAKE_GENERATE_PRL;
178 } else if(opt == "makefile") {
179 Option::qmake_mode = Option::QMAKE_GENERATE_MAKEFILE;
180 } else {
181 specified = FALSE;
182 Option::qmake_mode = default_mode(argv[0]);
183 }
184 if(specified)
185 continue;
186 }
187 //all modes
188 if(opt == "o" || opt == "output") {
189 Option::output.setName(argv[++x]);
190 } else if(opt == "after") {
191 before = FALSE;
192 } else if(opt == "t" || opt == "template") {
193 Option::user_template = argv[++x];
194 } else if(opt == "tp" || opt == "template_prefix") {
195 Option::user_template_prefix = argv[++x];
196 } else if(opt == "mac9") {
197 Option::target_mode = TARG_MAC9_MODE;
198 } else if(opt == "macx") {
199 Option::target_mode = TARG_MACX_MODE;
200 } else if(opt == "unix") {
201 Option::target_mode = TARG_UNIX_MODE;
202 } else if(opt == "win32") {
203 Option::target_mode = TARG_WIN_MODE;
204 } else if(opt == "d") {
205 Option::debug_level++;
206 } else if(opt == "version" || opt == "v" || opt == "-version") {
207 fprintf(stderr, "Qmake version: %s\n", qmake_version());
208 fprintf(stderr, "Qmake is free software from Trolltech AS.\n");
209 return FALSE;
210 } else if(opt == "h" || opt == "help") {
211 return usage(argv[0]);
212 } else if(opt == "Wall") {
213 Option::warn_level |= WarnAll;
214 } else if(opt == "Wparser") {
215 Option::warn_level |= WarnParser;
216 } else if(opt == "Wlogic") {
217 Option::warn_level |= WarnLogic;
218 } else if(opt == "Wnone") {
219 Option::warn_level = WarnNone;
220 } else {
221 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
222 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
223 if(opt == "nodepend") {
224 Option::mkfile::do_deps = FALSE;
225 } else if(opt == "nomoc") {
226 Option::mkfile::do_mocs = FALSE;
227 } else if(opt == "nocache") {
228 Option::mkfile::do_cache = FALSE;
229 } else if(opt == "nodependheuristics") {
230 Option::mkfile::do_dep_heuristics = FALSE;
231 } else if(opt == "E") {
232 Option::mkfile::do_preprocess = TRUE;
233 } else if(opt == "cache") {
234 Option::mkfile::cachefile = argv[++x];
235 } else if(opt == "platform" || opt == "spec") {
236 Option::mkfile::qmakespec = argv[++x];
237 Option::mkfile::qmakespec_commandline = argv[x];
238 } else {
239 fprintf(stderr, "***Unknown option -%s\n", opt.latin1());
240 return usage(argv[0]);
241 }
242 } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) {
243 if(opt == "nopwd") {
244 Option::projfile::do_pwd = FALSE;
245 } else if(opt == "r") {
246 Option::projfile::do_recursive = TRUE;
247 } else {
248 fprintf(stderr, "***Unknown option -%s\n", opt.latin1());
249 return usage(argv[0]);
250 }
251 }
252 }
253 } else {
254 if(x == 1)
255 Option::qmake_mode = default_mode(argv[0]);
256
257 QString arg = argv[x];
258 if(arg.find('=') != -1) {
259 if(before)
260 Option::before_user_vars.append(arg);
261 else
262 Option::after_user_vars.append(arg);
263 } else {
264 QFileInfo fi(arg);
265 if(!fi.convertToAbs()) //strange
266 arg = fi.filePath();
267 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
268 Option::qmake_mode == Option::QMAKE_GENERATE_PRL)
269 Option::mkfile::project_files.append(arg);
270 else
271 Option::projfile::project_dirs.append(arg);
272 }
273 }
274 }
275 if(Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
276 Option::qmake_mode = default_mode(argv[0]);
277
278 //last chance for defaults
279 if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE ||
280 Option::qmake_mode == Option::QMAKE_GENERATE_PRL) {
281 if(Option::mkfile::qmakespec.isNull() || Option::mkfile::qmakespec.isEmpty())
282 Option::mkfile::qmakespec = getenv("QMAKESPEC");
283
284 //try REALLY hard to do it for them, lazy..
285 if(Option::mkfile::project_files.isEmpty()) {
286 QString proj = QDir::currentDirPath();
287 proj = proj.right(proj.length() - (proj.findRev('/') + 1)) + ".pro";
288 if(QFile::exists(proj))
289 Option::mkfile::project_files.append(proj);
290 else
291 return usage(argv[0]);
292 }
293 }
294
295 //defaults for globals
296 Option::moc_mod = "moc_";
297 Option::lex_mod = "_lex";
298 Option::yacc_mod = "_yacc";
299 Option::prl_ext = ".prl";
300 Option::prf_ext = ".prf";
301 Option::ui_ext = ".ui";
302 Option::h_ext << ".h" << ".hpp" << ".hh" << ".H" << ".hxx";
303 Option::moc_ext = ".moc";
304 Option::cpp_ext << ".cpp" << ".cc" << ".cxx" << ".C";
305 Option::lex_ext = ".l";
306 Option::yacc_ext = ".y";
307 if(Option::target_mode == Option::TARG_WIN_MODE) {
308 Option::dir_sep = "\\";
309 Option::obj_ext = ".obj";
310 } else {
311 if(Option::target_mode == Option::TARG_MAC9_MODE)
312 Option::dir_sep = ":";
313 else
314 Option::dir_sep = "/";
315 Option::obj_ext = ".o";
316 }
317 return TRUE;
318}
319
320bool Option::postProcessProject(QMakeProject *project)
321{
322 Option::cpp_ext = project->variables()["QMAKE_EXT_CPP"];
323 if(cpp_ext.isEmpty())
324 cpp_ext << ".cpp"; //something must be there
325 Option::h_ext = project->variables()["QMAKE_EXT_H"];
326 if(h_ext.isEmpty())
327 h_ext << ".h";
328
329 if(!project->isEmpty("QMAKE_EXT_PRL"))
330 Option::prl_ext = project->first("QMAKE_EXT_PRL");
331 if(!project->isEmpty("QMAKE_EXT_PRF"))
332 Option::prf_ext = project->first("QMAKE_EXT_PRF");
333 if(!project->isEmpty("QMAKE_EXT_UI"))
334 Option::ui_ext = project->first("QMAKE_EXT_UI");
335 if(!project->isEmpty("QMAKE_EXT_MOC"))
336 Option::moc_ext = project->first("QMAKE_EXT_MOC");
337 if(!project->isEmpty("QMAKE_EXT_LEX"))
338 Option::lex_ext = project->first("QMAKE_EXT_LEX");
339 if(!project->isEmpty("QMAKE_EXT_YACC"))
340 Option::yacc_ext = project->first("QMAKE_EXT_YACC");
341 if(!project->isEmpty("QMAKE_EXT_OBJ"))
342 Option::obj_ext = project->first("QMAKE_EXT_OBJ");
343 if(!project->isEmpty("QMAKE_MOD_MOC"))
344 Option::moc_mod = project->first("QMAKE_MOD_MOC");
345 if(!project->isEmpty("QMAKE_MOD_LEX"))
346 Option::lex_mod = project->first("QMAKE_MOD_LEX");
347 if(!project->isEmpty("QMAKE_MOD_YACC"))
348 Option::yacc_mod = project->first("QMAKE_MOD_YACC");
349 if(!project->isEmpty("QMAKE_DIR_SEP"))
350 Option::dir_sep = project->first("QMAKE_DIR_SEP");
351 return TRUE;
352}
353
354void fixEnvVariables(QString &x)
355{
356 int rep;
357 QRegExp reg_var("\\$\\(.*\\)");
358 reg_var.setMinimal( TRUE );
359 while((rep = reg_var.search(x)) != -1)
360 x.replace(rep, reg_var.matchedLength(), QString(getenv(x.mid(rep + 2, reg_var.matchedLength() - 3).latin1())));
361}
362static QString fixPath(QString x)
363{
364#if 0
365 QFileInfo fi(x);
366 if(fi.isDir()) {
367 QDir dir(x);
368 x = dir.canonicalPath();
369 } else {
370 QString dir = fi.dir().canonicalPath();
371 if(!dir.isEmpty() && dir.right(1) != Option::dir_sep)
372 dir += Option::dir_sep;
373 x = dir + fi.fileName();
374 }
375#endif
376 return QDir::cleanDirPath(x);
377}
378
379
380QString
381Option::fixPathToTargetOS(const QString& in, bool fix_env, bool canonical)
382{
383 QString tmp(in);
384 if(fix_env)
385 fixEnvVariables(tmp);
386 if(canonical)
387 tmp = fixPath(tmp);
388 QString rep;
389 if(Option::target_mode == TARG_MAC9_MODE)
390 rep = "[/\\\\]";
391 else if(Option::target_mode == TARG_WIN_MODE)
392 rep = "[/]";
393 else
394 rep = "[\\\\]";
395 return tmp.replace(QRegExp(rep), Option::dir_sep);
396}
397
398QString
399Option::fixPathToLocalOS(const QString& in, bool fix_env, bool canonical)
400{
401 QString tmp(in);
402 if(fix_env)
403 fixEnvVariables(tmp);
404 if(canonical)
405 tmp = fixPath(tmp);
406#if defined(Q_OS_WIN32)
407 return tmp.replace('/', '\\');
408#else
409 return tmp.replace('\\', '/');
410#endif
411}
412
413const char *qmake_version()
414{
415 static char *ret = NULL;
416 if(ret)
417 return ret;
418 ret = (char *)malloc(15);
419 sprintf(ret, "%d.%02d%c", QMAKE_VERSION_MAJOR, QMAKE_VERSION_MINOR, 'a' + QMAKE_VERSION_PATCH);
420 return ret;
421}
422
423void debug_msg(int level, const char *fmt, ...)
424{
425 if(Option::debug_level < level)
426 return;
427 fprintf(stderr, "DEBUG %d: ", level);
428 {
429 va_list ap;
430 va_start(ap, fmt);
431 vfprintf(stderr, fmt, ap);
432 va_end(ap);
433 }
434 fprintf(stderr, "\n");
435}
436
437void warn_msg(QMakeWarn type, const char *fmt, ...)
438{
439 if(!(Option::warn_level & type))
440 return;
441 fprintf(stderr, "WARNING: ");
442 {
443 va_list ap;
444 va_start(ap, fmt);
445 vfprintf(stderr, fmt, ap);
446 va_end(ap);
447 }
448 fprintf(stderr, "\n");
449}