source: trunk/qmake/generators/os2/gnumake.cpp@ 54

Last change on this file since 54 was 54, checked in by Dmitry A. Kuminov, 16 years ago

qmake: os2/GNUMAKE: Add missing QMAKESPECDIR to the compiler response file.

File size: 23.2 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the qmake application of the Qt Toolkit.
7**
8** Copyright (C) 2009 netlabs.org. OS/2 parts.
9**
10** $QT_BEGIN_LICENSE:LGPL$
11** Commercial Usage
12** Licensees holding valid Qt Commercial licenses may use this file in
13** accordance with the Qt Commercial License Agreement provided with the
14** Software or, alternatively, in accordance with the terms contained in
15** a written agreement between you and Nokia.
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, Nokia gives you certain
26** additional rights. These rights are described in the Nokia Qt LGPL
27** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
28** package.
29**
30** GNU General Public License Usage
31** Alternatively, this file may be used under the terms of the GNU
32** General Public License version 3.0 as published by the Free Software
33** Foundation and appearing in the file LICENSE.GPL included in the
34** packaging of this file. Please review the following information to
35** ensure the GNU General Public License version 3.0 requirements will be
36** met: http://www.gnu.org/copyleft/gpl.html.
37**
38** If you are unsure which license is appropriate for your use, please
39** contact the sales department at [email protected].
40** $QT_END_LICENSE$
41**
42****************************************************************************/
43
44#include "gnumake.h"
45#include "option.h"
46#include "meta.h"
47#include <qregexp.h>
48#include <qdir.h>
49#include <stdlib.h>
50#include <time.h>
51
52QT_BEGIN_NAMESPACE
53
54GNUMakefileGenerator::GNUMakefileGenerator() : Win32MakefileGenerator(), init_flag(false)
55{
56 if (isDosLikeShell())
57 quote = "\"";
58 else
59 quote = "'";
60}
61
62bool GNUMakefileGenerator::isDosLikeShell() const
63{
64#ifdef Q_OS_OS2
65 return Option::shellPath.isEmpty();
66#else
67 return Win32MakefileGenerator::isDosLikeShell();
68#endif
69}
70
71QString GNUMakefileGenerator::escapeFilePath(const QString &path) const
72{
73 QString ret = path;
74 if (!isDosLikeShell()) {
75 ret.remove('\"');
76 ret.replace('\\', "/");
77 ret.replace(' ', "\\ ");
78 } else {
79 ret.replace(QRegExp("\""), "");
80 ret.replace(QRegExp("[\\\\/]$"), "");
81 if (ret.contains(QRegExp("[ +&;%]")))
82 ret = quote + ret + quote;
83 }
84 return ret;
85}
86
87QString GNUMakefileGenerator::escapeDependencyPath(const QString &path) const
88{
89 /* dependency escaping is always done Unix-way since this is a requirement
90 * of GNU make which allows " and ' to be part of the file name */
91 QString ret = path;
92 ret.remove('\"');
93 ret.replace(' ', "\\ ");
94 return ret;
95}
96
97bool GNUMakefileGenerator::findLibraries()
98{
99 QStringList &l = project->values("QMAKE_LIBS");
100
101 QList<QMakeLocalFileName> dirs;
102 {
103 QStringList &libpaths = project->values("QMAKE_LIBDIR");
104 for(QStringList::Iterator libpathit = libpaths.begin();
105 libpathit != libpaths.end(); ++libpathit)
106 dirs.append(QMakeLocalFileName((*libpathit)));
107 }
108
109 QStringList::Iterator it = l.begin();
110 while (it != l.end()) {
111 if ((*it).startsWith("-l")) {
112 QString steam = (*it).mid(2), out;
113 QString suffix;
114 if (!project->isEmpty("QMAKE_" + steam.toUpper() + "_SUFFIX"))
115 suffix = project->first("QMAKE_" + steam.toUpper() + "_SUFFIX");
116 for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) {
117 QString extension;
118 int ver = findHighestVersion((*dir_it).local(), steam, "dll.lib|lib");
119 if (ver != -1)
120 extension += QString::number(ver);
121 extension += suffix;
122 if(QMakeMetaInfo::libExists((*dir_it).local() + Option::dir_sep + steam) ||
123 exists((*dir_it).local() + Option::dir_sep + steam + extension + ".lib") ||
124 exists((*dir_it).local() + Option::dir_sep + steam + extension + ".dll.lib")) {
125 out = (*it) + extension;
126 break;
127 }
128 }
129 if (!out.isEmpty()) // We assume if it never finds it that its correct
130 (*it) = out;
131 } else if((*it).startsWith("-L")) {
132 dirs.append(QMakeLocalFileName((*it).mid(2)));
133 }
134
135 ++it;
136 }
137 return true;
138}
139
140bool GNUMakefileGenerator::writeMakefile(QTextStream &t)
141{
142 writeHeader(t);
143
144 /* function to convert from DOS-like to Unix-like space escaping in file
145 * names */
146 t << "q = $(subst %,\\%,$(subst ;,\\;,$(subst &,\\&,"
147 "$(subst +,\\+,$(subst $(space),\\ ,$(subst \",,$(1)))))))" << endl << endl;
148
149 if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) {
150 t << "all clean:" << "\n\t"
151 << "@echo \"Some of the required modules ("
152 << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
153 << "@echo \"Skipped.\"" << endl << endl;
154 writeMakeQmake(t);
155 return true;
156 }
157
158 if(project->first("TEMPLATE") == "app" ||
159 project->first("TEMPLATE") == "lib") {
160 if(Option::mkfile::do_stub_makefile) {
161 t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
162 QStringList &qut = project->values("QMAKE_EXTRA_TARGETS");
163 for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it)
164 t << *it << " ";
165 t << "first all clean install distclean uninstall: qmake" << endl
166 << "qmake_all:" << endl;
167 writeMakeQmake(t);
168 if(project->isEmpty("QMAKE_NOFORCE"))
169 t << "FORCE:" << endl << endl;
170 return true;
171 }
172 writeGNUParts(t);
173 return MakefileGenerator::writeMakefile(t);
174 }
175 else if(project->first("TEMPLATE") == "subdirs") {
176 writeSubDirs(t);
177 return true;
178 }
179 return false;
180 }
181
182void GNUMakefileGenerator::writeGNUParts(QTextStream &t)
183{
184 t << "QMAKESPECDIR = " << quote << specdir() << quote << endl << endl;
185
186 writeStandardParts(t);
187
188 if (!preCompHeaderOut.isEmpty()) {
189 QString header = project->first("PRECOMPILED_HEADER");
190 QString cHeader = preCompHeaderOut + Option::dir_sep + "c";
191 t << escapeDependencyPath(cHeader) << ": " << escapeDependencyPath(header) << " "
192 << escapeDependencyPaths(findDependencies(header)).join(" \\\n\t\t")
193 << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
194 << "\n\t" << "$(CC) -x c-header -c $(CFLAGS) $(INCPATH) -o " << cHeader << " " << header
195 << endl << endl;
196 QString cppHeader = preCompHeaderOut + Option::dir_sep + "c++";
197 t << escapeDependencyPath(cppHeader) << ": " << escapeDependencyPath(header) << " "
198 << escapeDependencyPaths(findDependencies(header)).join(" \\\n\t\t")
199 << "\n\t" << mkdir_p_asstring(preCompHeaderOut)
200 << "\n\t" << "$(CXX) -x c++-header -c $(CXXFLAGS) $(INCPATH) -o " << cppHeader << " " << header
201 << endl << endl;
202 }
203}
204
205void GNUMakefileGenerator::init()
206{
207 if(init_flag)
208 return;
209 init_flag = true;
210
211 if(project->first("TEMPLATE") == "app") {
212 mode = App;
213 project->values("QMAKE_APP_FLAG").append("1");
214 } else if(project->first("TEMPLATE") == "lib") {
215 mode = project->isActiveConfig("staticlib") ? StaticLib : DLL;
216 project->values("QMAKE_LIB_FLAG").append("1");
217 } else if(project->first("TEMPLATE") == "subdirs") {
218 MakefileGenerator::init();
219 if(project->isEmpty("QMAKE_COPY_FILE"))
220 project->values("QMAKE_COPY_FILE").append("$(COPY)");
221 if(project->isEmpty("QMAKE_COPY_DIR"))
222 project->values("QMAKE_COPY_DIR").append("$(COPY)");
223 if(project->isEmpty("QMAKE_INSTALL_FILE"))
224 project->values("QMAKE_INSTALL_FILE").append("$(COPY_FILE)");
225 if(project->isEmpty("QMAKE_INSTALL_PROGRAM"))
226 project->values("QMAKE_INSTALL_PROGRAM").append("$(COPY_FILE)");
227 if(project->isEmpty("QMAKE_INSTALL_DIR"))
228 project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)");
229 if(project->values("MAKEFILE").isEmpty())
230 project->values("MAKEFILE").append("Makefile");
231 if(project->values("QMAKE_QMAKE").isEmpty())
232 project->values("QMAKE_QMAKE").append("qmake");
233 return;
234 }
235
236 project->values("TARGET_PRL").append(project->first("TARGET"));
237
238 processVars();
239
240 // LIBS defined in Profile comes first for gcc
241 project->values("QMAKE_LIBS") += escapeFilePaths(project->values("LIBS"));
242
243 QString targetfilename = project->values("TARGET").first();
244 QStringList &configs = project->values("CONFIG");
245
246 if(project->isActiveConfig("qt_dll"))
247 if(configs.indexOf("qt") == -1)
248 configs.append("qt");
249
250 if(project->isActiveConfig("dll")) {
251 QString destDir = "";
252 if(!project->first("DESTDIR").isEmpty())
253 destDir = Option::fixPathToTargetOS(project->first("DESTDIR") + Option::dir_sep, false, false);
254 }
255
256 MakefileGenerator::init();
257
258 // precomp
259 if (!project->first("PRECOMPILED_HEADER").isEmpty()
260 && project->isActiveConfig("precompile_header")) {
261 QString preCompHeader = var("PRECOMPILED_DIR")
262 + QFileInfo(project->first("PRECOMPILED_HEADER")).fileName();
263 preCompHeaderOut = preCompHeader + ".gch";
264 project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c");
265 project->values("QMAKE_CLEAN").append(preCompHeaderOut + Option::dir_sep + "c++");
266
267 project->values("QMAKE_RUN_CC").clear();
268 project->values("QMAKE_RUN_CC").append("$(CC) -c -include " + preCompHeader +
269 " $(CFLAGS) $(INCPATH) -o $obj $src");
270 project->values("QMAKE_RUN_CC_IMP").clear();
271 project->values("QMAKE_RUN_CC_IMP").append("$(CC) -c -include " + preCompHeader +
272 " $(CFLAGS) $(INCPATH) -o $@ $<");
273 project->values("QMAKE_RUN_CXX").clear();
274 project->values("QMAKE_RUN_CXX").append("$(CXX) -c -include " + preCompHeader +
275 " $(CXXFLAGS) $(INCPATH) -o $obj $src");
276 project->values("QMAKE_RUN_CXX_IMP").clear();
277 project->values("QMAKE_RUN_CXX_IMP").append("$(CXX) -c -include " + preCompHeader +
278 " $(CXXFLAGS) $(INCPATH) -o $@ $<");
279 }
280}
281
282void GNUMakefileGenerator::fixTargetExt()
283{
284 if (mode == App)
285 project->values("TARGET_EXT").append(".exe");
286 else if (mode == DLL)
287 project->values("TARGET_EXT").append(project->first("TARGET_VERSION_EXT") + ".dll");
288 else
289 project->values("TARGET_EXT").append(".lib");
290}
291
292void GNUMakefileGenerator::writeIncPart(QTextStream &t)
293{
294 t << "INCPATH =";
295
296 QString opt = var("QMAKE_CFLAGS_INCDIR");
297 QStringList &incs = project->values("INCLUDEPATH");
298 QString incsSemicolon;
299 for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) {
300 QString inc = escapeFilePath(*incit);
301 t << " " << opt << inc;
302 incsSemicolon += inc + Option::dirlist_sep;
303 }
304 t << " " << opt << "$(QMAKESPECDIR)" << endl;
305 incsSemicolon += "$(QMAKESPECDIR)";
306 t << "INCLUDEPATH = " << incsSemicolon << endl;
307 /* createCompilerResponseFiles() will need QAKESPECDIR expanded) */
308 project->values("INCLUDEPATH").append(specdir());
309}
310
311void GNUMakefileGenerator::writeLibsPart(QTextStream &t)
312{
313 if (mode == StaticLib) {
314 t << "LIB = " << var("QMAKE_LIB") << endl;
315 } else {
316 t << "LINK = " << var("QMAKE_LINK") << endl;
317 t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl;
318 t << "LIBS =";
319 if(!project->values("QMAKE_LIBDIR").isEmpty())
320 writeLibDirPart(t);
321 QString opt = var("QMAKE_LFLAGS_LIB");
322 QStringList libs = project->values("QMAKE_LIBS");
323 for(QStringList::Iterator it = libs.begin(); it != libs.end(); ++it) {
324 QString lib = escapeFilePath(*it);
325 /* lib may be prefixed with -l which is commonly used in e.g. PRF
326 * (feature) files on all platforms; remove it before prepending
327 * the compiler-specific option */
328 if (lib.startsWith("-l"))
329 lib = lib.mid(2);
330 t << " " << opt << lib;
331 }
332 t << endl;
333 }
334}
335
336void GNUMakefileGenerator::writeLibDirPart(QTextStream &t)
337{
338 QString opt = var("QMAKE_LFLAGS_LIBDIR");
339 QStringList libDirs = project->values("QMAKE_LIBDIR");
340 for(QStringList::Iterator it = libDirs.begin(); it != libDirs.end(); ++it) {
341 QString libDir = escapeFilePath(*it);
342 /* libDir may be prefixed with -L which is commonly used in e.g. PRF
343 * (feature) files on all platforms; remove it before prepending
344 * the compiler-specific option */
345 if (libDir.startsWith("-L"))
346 libDir = libDir.mid(2);
347 t << " " << opt << libDir;
348 }
349}
350
351void GNUMakefileGenerator::writeObjectsPart(QTextStream &t)
352{
353 Win32MakefileGenerator::writeObjectsPart(t);
354 createLinkerResponseFiles(t);
355
356 /* this function is a nice place to also handle compiler options response
357 * files */
358 createCompilerResponseFiles(t);
359}
360
361void GNUMakefileGenerator::writeBuildRulesPart(QTextStream &t)
362{
363 t << "first: all" << endl;
364 t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName())) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS"))," "," "," ") << escapeFileVars(" $(DESTDIR_TARGET)") << endl << endl;
365 t << escapeFileVars("$(DESTDIR_TARGET): ") << var("PRE_TARGETDEPS") << " $(OBJECTS) " << var("POST_TARGETDEPS");
366 if (!project->isEmpty("QMAKE_PRE_LINK"))
367 t << "\n\t" <<var("QMAKE_PRE_LINK");
368 if (mode == StaticLib) {
369 /* static library */
370 t << "\n\t" << var("QMAKE_RUN_LIB");
371 } else {
372 /* application or DLL */
373 t << "\n\t" << var("QMAKE_RUN_LINK");
374 if (!project->isEmpty("RES_FILE") && !project->isEmpty("QMAKE_RUN_RC2EXE")) {
375 t << "\n\t" << var("QMAKE_RUN_RC2EXE");
376 }
377 if (mode == DLL && !project->isEmpty("QMAKE_RUN_IMPLIB")) {
378 t << "\n\t" << var("QMAKE_RUN_IMPLIB");
379 }
380 }
381 if(!project->isEmpty("QMAKE_POST_LINK"))
382 t << "\n\t" <<var("QMAKE_POST_LINK");
383 t << endl;
384}
385
386void GNUMakefileGenerator::writeRcAndDefVariables(QTextStream &t)
387{
388 if (!project->isEmpty("RC_FILE")) {
389 t << "RC_FILE = " << escapeFilePath(var("RC_FILE")) << endl;
390 }
391 if (!project->isEmpty("RES_FILE")) {
392 t << "RES_FILE = " << valList(escapeFilePaths(project->values("RES_FILE"))) << endl;
393 }
394 if (mode == DLL && !project->isEmpty("QMAKE_RUN_IMPLIB")) {
395 t << "TARGET_IMPLIB = $(basename $(DESTDIR_TARGET)).lib" << endl;
396 project->values("QMAKE_CLEAN").append("$(TARGET_IMPLIB)");
397 }
398
399 if (project->isEmpty("DEF_FILE")) {
400 /* no DEF file supplied, we will generate one */
401 if (mode == DLL) {
402 t << "DEF_FILE = $(basename $(DESTDIR_TARGET)).def" << endl;
403 project->values("QMAKE_CLEAN").append("$(DEF_FILE)");
404 project->values("POST_TARGETDEPS") += escapeFileVars("$(DEF_FILE)");
405 if (!project->isEmpty("DEF_FILE_TEMPLATE")) {
406 t << "DEF_FILE_TEMPLATE = " << escapeFilePath(var("DEF_FILE_TEMPLATE")) << endl;
407 project->values("QMAKE_GENDEF_DEPS") += escapeFileVars("$(DEF_FILE_TEMPLATE)");
408 }
409 if (!project->isEmpty("DEF_FILE_MAP")) {
410 t << "DEF_FILE_MAP = " << escapeFilePath(var("DEF_FILE_MAP")) << endl;
411 project->values("QMAKE_GENDEF_DEPS") += escapeFileVars("$(DEF_FILE_MAP)");
412 }
413 }
414 } else {
415 if (!project->isEmpty("DEF_FILE_TEMPLATE")) {
416 fprintf(stderr, "Both DEF_FILE and DEF_FILE_TEMPLATE are specified.\n");
417 fprintf(stderr, "Please specify one of them, not both.");
418 exit(1);
419 }
420 t << "DEF_FILE = " << escapeFilePath(var("DEF_FILE")) << endl;
421 project->values("POST_TARGETDEPS") += escapeFileVars("$(DEF_FILE)");
422 }
423}
424
425void GNUMakefileGenerator::writeRcAndDefPart(QTextStream &t)
426{
427 if (!project->isEmpty("RC_FILE") && !project->isEmpty("RES_FILE") &&
428 !project->isEmpty("QMAKE_RUN_RC2RES")) {
429 t << escapeFileVars("$(RES_FILE): $(RC_FILE)\n\t");
430 t << var("QMAKE_RUN_RC2RES") << endl;
431 }
432
433 if (project->isEmpty("DEF_FILE") && mode == DLL) {
434 /* generate a DEF file for the DLL when not supplied */
435 t << escapeFileVars("$(DEF_FILE): ") << var("QMAKE_GENDEF_DEPS");
436 t << valGlue(var("QMAKE_RUN_GENDEF").split(";;"), "\n\t", "\n\t", "") << endl;
437 }
438}
439
440void GNUMakefileGenerator::processRcFileVar()
441{
442 if (Option::qmake_mode == Option::QMAKE_GENERATE_NOTHING)
443 return;
444
445 if (!project->isEmpty("RC_FILE")) {
446 if (!project->isEmpty("RES_FILE")) {
447 fprintf(stderr, "Both rc and res file specified.\n");
448 fprintf(stderr, "Please specify one of them, not both.");
449 exit(1);
450 }
451 project->values("RES_FILE").prepend(escapeFilePath(QString("$(OBJECTS_DIR)") +
452 QDir::separator() +
453 QFileInfo(var("RC_FILE")).baseName() +
454 ".res"));
455 project->values("CLEAN_FILES") += "$(RES_FILE)";
456 }
457
458 if (!project->isEmpty("RES_FILE"))
459 project->values("POST_TARGETDEPS") += escapeFileVars("$(RES_FILE)");
460}
461
462void GNUMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
463{
464 if (var == "QMAKE_PRL_LIBS") {
465 QString where = "QMAKE_LIBS";
466 if (!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
467 where = project->first("QMAKE_INTERNAL_PRL_LIBS");
468 QStringList &out = project->values(where);
469 for (QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) {
470 out.removeAll((*it));
471 out.append((*it));
472 }
473 } else {
474 Win32MakefileGenerator::processPrlVariable(var, l);
475 }
476}
477
478QStringList &GNUMakefileGenerator::findDependencies(const QString &file)
479{
480 QStringList &aList = MakefileGenerator::findDependencies(file);
481 // Note: The QMAKE_IMAGE_COLLECTION file have all images
482 // as dependency, so don't add precompiled header then
483 if (file == project->first("QMAKE_IMAGE_COLLECTION")
484 || preCompHeaderOut.isEmpty())
485 return aList;
486 for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) {
487 if (file.endsWith(*it)) {
488 QString cHeader = preCompHeaderOut + Option::dir_sep + "c";
489 if (!aList.contains(cHeader))
490 aList += cHeader;
491 break;
492 }
493 }
494 for (QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) {
495 if (file.endsWith(*it)) {
496 QString cppHeader = preCompHeaderOut + Option::dir_sep + "c++";
497 if (!aList.contains(cppHeader))
498 aList += cppHeader;
499 break;
500 }
501 }
502 return aList;
503}
504
505void GNUMakefileGenerator::writeProjectVarToStream(QTextStream &t, const QString &var)
506{
507 QStringList &list = project->values(var);
508 for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) {
509 t << (*it) << endl;
510 }
511}
512
513QString GNUMakefileGenerator::makeResponseFileName(const QString &base)
514{
515 QString fileName = base + "." + var("TARGET");
516 if (!var("BUILD_NAME").isEmpty()) {
517 fileName += "." + var("BUILD_NAME");
518 }
519 fileName += ".rsp";
520 QString filePath = project->first("OBJECTS_DIR");
521 if (filePath.isEmpty())
522 filePath = Option::output_dir;
523 filePath = Option::fixPathToTargetOS(filePath + QDir::separator() + fileName);
524 return filePath;
525}
526
527void GNUMakefileGenerator::createCompilerResponseFiles(QTextStream &t)
528{
529 static const char *vars[] = { "CFLAGS", /*<=*/ "QMAKE_CFLAGS",
530 "CXXFLAGS", /*<=*/ "QMAKE_CXXFLAGS",
531 "INCPATH", /*<=*/ "INCLUDEPATH" };
532
533 /* QMAKE_XXX_RSP_VAR is used as a flag whether it is necessary to
534 * generate response files to overcome the 1024 chars CMD.EXE limitation.
535 * When this variable is defined, a response file with the relevant
536 * information will be generated and its full path will be stored in an
537 * environment variable with the given name which can then be referred to in
538 * other places of qmake.conf (e.g. rules) */
539
540 for (size_t i = 0; i < sizeof(vars)/sizeof(vars[0]); i+=2) {
541 QString rspVar =
542 project->first(QString().sprintf("QMAKE_%s_RSP_VAR", vars[i]));
543 if (!rspVar.isEmpty()) {
544 QString fileName = makeResponseFileName(vars[i]);
545 t << rspVar.leftJustified(14) << "= " << fileName << endl;
546 QFile file(fileName);
547 if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
548 QTextStream rt(&file);
549 if (!qstrcmp(vars[i+1], "INCLUDEPATH")) {
550 QString opt = var("QMAKE_CFLAGS_INCDIR");
551 rt << varGlue(vars[i+1], opt, "\n" + opt, QString::null);
552 } else
553 rt << varGlue(vars[i+1], QString::null, "\n", QString::null);
554 rt.flush();
555 file.close();
556 }
557 project->values("QMAKE_DISTCLEAN").append("$(" + rspVar + ")");
558 }
559 }
560}
561
562void GNUMakefileGenerator::createLinkerResponseFiles(QTextStream &t)
563{
564 /* see createCompilerResponseFiles() */
565 QString var = project->first("QMAKE_OBJECTS_RSP_VAR");
566 if (!var.isEmpty()) {
567 QString fileName = makeResponseFileName("OBJECTS");
568 t << var.leftJustified(14) << "= " << fileName << endl;
569 QFile file(fileName);
570 if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
571 QTextStream rt(&file);
572 rt << varGlue("OBJECTS", QString::null, "\n", QString::null);
573 rt.flush();
574 file.close();
575 }
576 project->values("QMAKE_DISTCLEAN").append("$(" + var + ")");
577 }
578}
579
580QString GNUMakefileGenerator::escapeFileVars(const QString &vars)
581{
582 /* In DOS environment, we escape spaces and other illegal characters in
583 * filenames with double quotes. However, this is not appropriate for make
584 * rule definitions (targets/dependencies) where Unix escaping is
585 * expected. For this reason, we must convert escaping to Unix mode using
586 * the q function that we define in writeMakefile() */
587 if (isDosLikeShell()) {
588 QString ret = vars;
589 ret.replace(QRegExp("\\$\\((.+)\\)"), "$(call q,$(\\1))");
590 return ret;
591 }
592 return vars;
593}
594
595QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.