source: trunk/qmake/generators/unix/unixmake2.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 65.1 KB
Line 
1/****************************************************************************
2** $Id: unixmake2.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of UnixMakefileGenerator class.
5**
6** Copyright (C) 1992-2003 Trolltech AS. All rights reserved.
7**
8** This file is part of qmake.
9**
10** This file may be distributed under the terms of the Q Public License
11** as defined by Trolltech AS of Norway and appearing in the file
12** LICENSE.QPL included in the packaging of this file.
13**
14** This file may be distributed and/or modified under the terms of the
15** GNU General Public License version 2 as published by the Free Software
16** Foundation and appearing in the file LICENSE.GPL included in the
17** packaging of this file.
18**
19** Licensees holding valid Qt Enterprise Edition licenses may use this
20** file in accordance with the Qt Commercial License Agreement provided
21** with the Software.
22**
23** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
24** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
25**
26** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
27** information about Qt Commercial License Agreements.
28** See http://www.trolltech.com/qpl/ for QPL licensing information.
29** See http://www.trolltech.com/gpl/ for GPL licensing information.
30**
31** Contact info@trolltech.com if any conditions of this licensing are
32** not clear to you.
33**
34**********************************************************************/
35
36#include "unixmake.h"
37#include "option.h"
38#include "meta.h"
39#include <qregexp.h>
40#include <qfile.h>
41#include <qdir.h>
42#include <time.h>
43
44QString mkdir_p_asstring(const QString &dir);
45
46UnixMakefileGenerator::UnixMakefileGenerator(QMakeProject *p) : MakefileGenerator(p), init_flag(FALSE), include_deps(FALSE)
47{
48
49}
50
51void
52UnixMakefileGenerator::writePrlFile(QTextStream &t)
53{
54 MakefileGenerator::writePrlFile(t);
55 // libtool support
56 if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib") { //write .la
57 if(project->isActiveConfig("compile_libtool"))
58 warn_msg(WarnLogic, "create_libtool specified with compile_libtool can lead to conflicting .la\n"
59 "formats, create_libtool has been disabled\n");
60 else
61 writeLibtoolFile();
62 }
63 // pkg-config support
64 if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib")
65 writePkgConfigFile();
66}
67
68bool
69UnixMakefileGenerator::writeMakefile(QTextStream &t)
70{
71
72 writeHeader(t);
73 if(!project->variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) {
74 t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
75 { //write the extra unix targets..
76 QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
77 for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it)
78 t << *it << " ";
79 }
80 t << "all clean install distclean mocables uninstall uicables:" << "\n\t"
81 << "@echo \"Some of the required modules ("
82 << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
83 << "@echo \"Skipped.\"" << endl << endl;
84 writeMakeQmake(t);
85 return TRUE;
86 }
87
88 if (project->variables()["TEMPLATE"].first() == "app" ||
89 project->variables()["TEMPLATE"].first() == "lib") {
90 writeMakeParts(t);
91 return MakefileGenerator::writeMakefile(t);
92 } else if(project->variables()["TEMPLATE"].first() == "subdirs") {
93 writeSubdirs(t);
94 return TRUE;
95 }
96 return FALSE;
97}
98
99void
100UnixMakefileGenerator::writeExtraVariables(QTextStream &t)
101{
102 bool first = TRUE;
103 QMap<QString, QStringList> &vars = project->variables();
104 QStringList &exports = project->variables()["QMAKE_EXTRA_UNIX_VARIABLES"];
105 for(QMap<QString, QStringList>::Iterator it = vars.begin(); it != vars.end(); ++it) {
106 for(QStringList::Iterator exp_it = exports.begin(); exp_it != exports.end(); ++exp_it) {
107 QRegExp rx((*exp_it), FALSE, TRUE);
108 if(rx.exactMatch(it.key())) {
109 if(first) {
110 t << "\n####### Custom Variables" << endl;
111 first = FALSE;
112 }
113 t << "EXPORT_" << it.key() << " = " << it.data().join(" ") << endl;
114 }
115 }
116 }
117 if(!first)
118 t << endl;
119}
120
121void
122UnixMakefileGenerator::writeMakeParts(QTextStream &t)
123{
124 QString deps = fileFixify(Option::output.name()), target_deps, prl;
125 bool do_incremental = (project->isActiveConfig("incremental") &&
126 !project->variables()["QMAKE_INCREMENTAL"].isEmpty() &&
127 (!project->variables()["QMAKE_APP_FLAG"].isEmpty() ||
128 !project->isActiveConfig("staticlib"))),
129 src_incremental=FALSE, moc_incremental=FALSE;
130
131 t << "####### Compiler, tools and options" << endl << endl;
132 t << "CC = ";
133 if (project->isActiveConfig("thread") &&
134 ! project->variables()["QMAKE_CC_THREAD"].isEmpty())
135 t << var("QMAKE_CC_THREAD") << endl;
136 else
137 t << var("QMAKE_CC") << endl;
138
139 t << "CXX = ";
140 if (project->isActiveConfig("thread") &&
141 ! project->variables()["QMAKE_CXX_THREAD"].isEmpty())
142 t << var("QMAKE_CXX_THREAD") << endl;
143 else
144 t << var("QMAKE_CXX") << endl;
145
146 t << "LEX = " << var("QMAKE_LEX") << endl;
147 t << "YACC = " << var("QMAKE_YACC") << endl;
148 t << "CFLAGS = " << var("QMAKE_CFLAGS") << " "
149 << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
150 << varGlue("DEFINES","-D"," -D","") << endl;
151 t << "CXXFLAGS = " << var("QMAKE_CXXFLAGS") << " "
152 << varGlue("PRL_EXPORT_DEFINES","-D"," -D","") << " "
153 << varGlue("DEFINES","-D"," -D","") << endl;
154 t << "LEXFLAGS = " << var("QMAKE_LEXFLAGS") << endl;
155 t << "YACCFLAGS= " << var("QMAKE_YACCFLAGS") << endl;
156 t << "INCPATH = " << "-I" << specdir();
157 if(!project->isActiveConfig("no_include_pwd")) {
158 QString pwd = fileFixify(QDir::currentDirPath());
159 if(pwd.isEmpty())
160 pwd = ".";
161 t << " -I" << pwd;
162 }
163 t << varGlue("INCLUDEPATH"," -I", " -I", "") << endl;
164
165 if(!project->isActiveConfig("staticlib")) {
166 t << "LINK = ";
167 if (project->isActiveConfig("thread") &&
168 ! project->variables()["QMAKE_LINK_THREAD"].isEmpty())
169 t << var("QMAKE_LINK_THREAD") << endl;
170 else
171 t << var("QMAKE_LINK") << endl;
172
173 t << "LFLAGS = " << var("QMAKE_LFLAGS") << endl;
174 t << "LIBS = " << "$(SUBLIBS) " << var("QMAKE_LIBDIR_FLAGS") << " " << var("QMAKE_LIBS") << endl;
175 }
176
177 t << "AR = " << var("QMAKE_AR") << endl;
178 t << "RANLIB = " << var("QMAKE_RANLIB") << endl;
179 t << "MOC = " << var("QMAKE_MOC") << endl;
180 t << "UIC = " << var("QMAKE_UIC") << endl;
181 t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl;
182 t << "TAR = " << var("QMAKE_TAR") << endl;
183 t << "GZIP = " << var("QMAKE_GZIP") << endl;
184 if(project->isActiveConfig("compile_libtool"))
185 t << "LIBTOOL = " << var("QMAKE_LIBTOOL") << endl;
186 t << "COPY = " << var("QMAKE_COPY") << endl;
187 t << "COPY_FILE= " << var("QMAKE_COPY_FILE") << endl;
188 t << "COPY_DIR = " << var("QMAKE_COPY_DIR") << endl;
189 t << "INSTALL_FILE= " << var("QMAKE_INSTALL_FILE") << endl;
190 t << "INSTALL_DIR = " << var("QMAKE_INSTALL_DIR") << endl;
191
192 t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
193 t << "SYMLINK = " << var("QMAKE_SYMBOLIC_LINK") << endl;
194 t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl;
195 t << "MOVE = " << var("QMAKE_MOVE") << endl;
196 t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl;
197 t << "MKDIR = " << var("QMAKE_MKDIR") << endl;
198 t << endl;
199
200 t << "####### Output directory" << endl << endl;
201 if (! project->variables()["OBJECTS_DIR"].isEmpty())
202 t << "OBJECTS_DIR = " << var("OBJECTS_DIR") << endl;
203 else
204 t << "OBJECTS_DIR = ./" << endl;
205 t << endl;
206
207 /* files */
208 t << "####### Files" << endl << endl;
209 t << "HEADERS = " << varList("HEADERS") << endl;
210 t << "SOURCES = " << varList("SOURCES") << endl;
211 if(do_incremental) {
212 QStringList &objs = project->variables()["OBJECTS"], &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out;
213 t << "OBJECTS = ";
214 for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
215 bool increment = FALSE;
216 for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
217 if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) {
218 increment = TRUE;
219 incrs_out.append((*objit));
220 break;
221 }
222 }
223 if(!increment)
224 t << "\\\n\t\t" << (*objit);
225 }
226 if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
227 t << incrs_out.join(" \\\n\t\t") << endl;
228 } else if(!incrs_out.count()) {
229 t << endl;
230 } else {
231 src_incremental = TRUE;
232 t << endl;
233 t << "INCREMENTAL_OBJECTS = " << incrs_out.join(" \\\n\t\t") << endl;
234 }
235 } else {
236 t << "OBJECTS = " << varList("OBJECTS") << endl;
237 }
238 t << "FORMS = " << varList("FORMS") << endl;
239 t << "UICDECLS = " << varList("UICDECLS") << endl;
240 t << "UICIMPLS = " << varList("UICIMPLS") << endl;
241 QString srcMoc = varList("SRCMOC"), objMoc = varList("OBJMOC");
242 t << "SRCMOC = " << srcMoc << endl;
243 if(do_incremental) {
244 QStringList &objs = project->variables()["OBJMOC"],
245 &incrs = project->variables()["QMAKE_INCREMENTAL"], incrs_out;
246 t << "OBJMOC = ";
247 for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
248 bool increment = FALSE;
249 for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
250 if((*objit).find(QRegExp((*incrit), TRUE, TRUE)) != -1) {
251 increment = TRUE;
252 incrs_out.append((*objit));
253 break;
254 }
255 }
256 if(!increment)
257 t << "\\\n\t\t" << (*objit);
258 }
259 if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
260 t << incrs_out.join(" \\\n\t\t") << endl;
261 } else if(!incrs_out.count()) {
262 t << endl;
263 } else {
264 moc_incremental = TRUE;
265 t << endl;
266 t << "INCREMENTAL_OBJMOC = " << incrs_out.join(" \\\n\t\t") << endl;
267 }
268 } else {
269 t << "OBJMOC = " << objMoc << endl;
270 }
271 if(do_incremental && !moc_incremental && !src_incremental)
272 do_incremental = FALSE;
273 if(!project->isEmpty("QMAKE_EXTRA_UNIX_COMPILERS")) {
274 t << "OBJCOMP = " << varList("OBJCOMP") << endl;
275 target_deps += " $(OBJCOMP)";
276
277 QStringList &comps = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"];
278 for(QStringList::Iterator compit = comps.begin(); compit != comps.end(); ++compit) {
279 QStringList &vars = project->variables()[(*compit) + ".variables"];
280 for(QStringList::Iterator varit = vars.begin(); varit != vars.end(); ++varit) {
281 QStringList vals = project->variables()[(*varit)];
282 if(!vals.isEmpty())
283 t << "QMAKE_COMP_" << (*varit) << " = " << valList(vals) << endl;
284 }
285 }
286 }
287 t << "DIST = " << valList(fileFixify(project->variables()["DISTFILES"])) << endl;
288 t << "QMAKE_TARGET = " << var("QMAKE_ORIG_TARGET") << endl;
289 t << "DESTDIR = " << var("DESTDIR") << endl;
290 if(project->isActiveConfig("compile_libtool"))
291 t << "TARGETL = " << var("TARGET_la") << endl;
292 t << "TARGET = " << var("TARGET") << endl;
293 if(project->isActiveConfig("plugin") ) {
294 t << "TARGETD = " << var("TARGET") << endl;
295 } else if (!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
296 t << "TARGETA = " << var("TARGETA") << endl;
297 if (project->isEmpty("QMAKE_HPUX_SHLIB")) {
298 t << "TARGETD = " << var("TARGET_x.y.z") << endl;
299 t << "TARGET0 = " << var("TARGET_") << endl;
300 t << "TARGET1 = " << var("TARGET_x") << endl;
301 t << "TARGET2 = " << var("TARGET_x.y") << endl;
302 } else {
303 t << "TARGETD = " << var("TARGET_x") << endl;
304 t << "TARGET0 = " << var("TARGET_") << endl;
305 }
306 }
307 writeExtraVariables(t);
308 t << endl;
309
310 // blasted includes
311 QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"];
312 QStringList::Iterator it;
313 for( it = qeui.begin(); it != qeui.end(); ++it)
314 t << "include " << (*it) << endl;
315
316 /* rules */
317 t << "first: all" << endl;
318 t << "####### Implicit rules" << endl << endl;
319 t << ".SUFFIXES: .c " << Option::obj_ext;
320 QStringList::Iterator cppit;
321 for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit)
322 t << " " << (*cppit);
323 t << endl << endl;
324 for(cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit)
325 t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
326 t << ".c" << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
327
328 if(include_deps) {
329 QString cmd=var("QMAKE_CFLAGS_DEPS") + " ";
330 cmd += varGlue("DEFINES","-D"," -D","") + varGlue("PRL_EXPORT_DEFINES"," -D"," -D","");
331 if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH"))
332 cmd += " -I" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + " ";
333 cmd += " $(INCPATH) " + varGlue("DEPENDPATH", "-I", " -I", "");
334 QString odir;
335 if(!project->variables()["OBJECTS_DIR"].isEmpty())
336 odir = project->first("OBJECTS_DIR");
337 t << "###### Dependencies" << endl << endl;
338 t << odir << ".deps/%.d: %.cpp\n\t"
339 << "@echo Creating depend for $<" << "\n\t"
340 << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t"
341 << "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl;
342
343 t << odir << ".deps/%.d: %.c\n\t"
344 << "@echo Creating depend for $<" << "\n\t"
345 << "@test -d $(@D) || mkdir -p $(@D)" << "\n\t"
346 << "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl;
347
348 QString src[] = { "SOURCES", "UICIMPLS", "SRCMOC", QString::null };
349 for(int x = 0; !src[x].isNull(); x++) {
350 QStringList &l = project->variables()[src[x]];
351 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
352 if(!(*it).isEmpty()) {
353 QString d_file;
354 if((*it).endsWith(".c")) {
355 d_file = (*it).left((*it).length() - 2);
356 } else {
357 for(QStringList::Iterator cppit = Option::cpp_ext.begin();
358 cppit != Option::cpp_ext.end(); ++cppit) {
359 if((*it).endsWith((*cppit))) {
360 d_file = (*it).left((*it).length() - (*cppit).length());
361 break;
362 }
363 }
364 }
365 if(!d_file.isEmpty()) {
366 d_file = odir + ".deps/" + d_file + ".d";
367 QStringList deps = findDependencies((*it)).grep(QRegExp(Option::cpp_moc_ext + "$"));
368 if(!deps.isEmpty())
369 t << d_file << ": " << deps.join(" ") << endl;
370 t << var("QMAKE_CFLAGS_USE_PRECOMPILE") << " " << d_file << endl;
371 }
372 }
373 }
374 }
375 }
376
377 t << "####### Build rules" << endl << endl;
378 if(!project->variables()["SUBLIBS"].isEmpty()) {
379 QString libdir = "tmp/";
380 if(!project->isEmpty("SUBLIBS_DIR"))
381 libdir = project->first("SUBLIBS_DIR");
382 t << "SUBLIBS= ";
383 QStringList &l = project->variables()["SUBLIBS"];
384 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it)
385 t << libdir << "lib" << (*it) << ".a ";
386 t << endl << endl;
387 }
388 if(project->isActiveConfig("depend_prl") && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) {
389 QStringList &l = project->variables()["QMAKE_PRL_INTERNAL_FILES"];
390 QStringList::Iterator it;
391 for(it = l.begin(); it != l.end(); ++it) {
392 QMakeMetaInfo libinfo;
393 if(libinfo.readLib((*it)) && !libinfo.isEmpty("QMAKE_PRL_BUILD_DIR")) {
394 QString dir;
395 int slsh = (*it).findRev(Option::dir_sep);
396 if(slsh != -1)
397 dir = (*it).left(slsh + 1);
398 QString targ = dir + libinfo.first("QMAKE_PRL_TARGET");
399 deps += " " + targ;
400 t << targ << ":" << "\n\t"
401 << "@echo \"Creating '" << targ << "'\"" << "\n\t"
402 << "(cd " << libinfo.first("QMAKE_PRL_BUILD_DIR") << ";"
403 << "$(MAKE) )" << endl;
404 }
405 }
406 }
407 if(!project->variables()["QMAKE_APP_FLAG"].isEmpty()) {
408 QString destdir = project->first("DESTDIR");
409 if(do_incremental) {
410 //incremental target
411 QString incr_target = var("TARGET") + "_incremental";
412 if(incr_target.find(Option::dir_sep) != -1)
413 incr_target = incr_target.right(incr_target.length() -
414 (incr_target.findRev(Option::dir_sep) + 1));
415 QString incr_deps, incr_objs;
416 if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
417 QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
418 //actual target
419 t << incr_target_dir << ": $(OBJECTS)" << "\n\t"
420 << "ld -r -o "<< incr_target_dir << " $(OBJECTS)" << endl;
421 //communicated below
422 deps.prepend(incr_target_dir + " ");
423 incr_deps = "$(UICDECLS) $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC) $(OBJMOC)";
424 if(!incr_objs.isEmpty())
425 incr_objs += " ";
426 incr_objs += incr_target_dir;
427 } else {
428 //actual target
429 QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." +
430 project->variables()["QMAKE_EXTENSION_SHLIB"].first();
431 QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
432 if(project->isActiveConfig("debug"))
433 incr_lflags += var("QMAKE_LFLAGS_DEBUG");
434 else
435 incr_lflags += var("QMAKE_LFLAGS_RELEASE");
436 t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t";
437 if(!destdir.isEmpty())
438 t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
439 t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir <<
440 " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl;
441 //communicated below
442 if(!destdir.isEmpty()) {
443 if(!incr_objs.isEmpty())
444 incr_objs += " ";
445 incr_objs += "-L" + destdir;
446 } else {
447 if(!incr_objs.isEmpty())
448 incr_objs += " ";
449 incr_objs += "-L" + QDir::currentDirPath();
450 }
451 if(!incr_objs.isEmpty())
452 incr_objs += " ";
453 incr_objs += " -l" + incr_target;
454 deps.prepend(incr_target_dir + " ");
455 incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
456 }
457 t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)"
458 << endl << endl;
459
460 //real target
461 t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps << " " << target_deps
462 << " " << var("POST_TARGETDEPS") << "\n\t";
463 if(!destdir.isEmpty())
464 t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
465 if(!project->isEmpty("QMAKE_PRE_LINK"))
466 t << var("QMAKE_PRE_LINK") << "\n\t";
467 t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(OBJCOMP) $(LIBS)";
468 if(!project->isEmpty("QMAKE_POST_LINK"))
469 t << "\n\t" << var("QMAKE_POST_LINK");
470 t << endl << endl;
471 } else {
472 t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << "$(TARGET)"
473 << endl << endl;
474
475 t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) "
476 << target_deps << " " << var("POST_TARGETDEPS") << "\n\t";
477 if(!destdir.isEmpty())
478 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
479 if(!project->isEmpty("QMAKE_PRE_LINK"))
480 t << var("QMAKE_PRE_LINK") << "\n\t";
481 t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(OBJCOMP) $(LIBS)";
482 if(!project->isEmpty("QMAKE_POST_LINK"))
483 t << "\n\t" << var("QMAKE_POST_LINK");
484 t << endl << endl;
485 }
486 } else if(!project->isActiveConfig("staticlib")) {
487 QString destdir = project->first("DESTDIR"), incr_deps;
488 if(do_incremental) {
489 QString s_ext = project->variables()["QMAKE_EXTENSION_SHLIB"].first();
490 QString incr_target = var("QMAKE_ORIG_TARGET").replace(
491 QRegExp("\\." + s_ext), "").replace(QRegExp("^lib"), "") + "_incremental";
492 if(incr_target.find(Option::dir_sep) != -1)
493 incr_target = incr_target.right(incr_target.length() -
494 (incr_target.findRev(Option::dir_sep) + 1));
495
496 if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
497 QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
498 //actual target
499 const QString link_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
500 t << incr_target_dir << ": " << link_deps << "\n\t"
501 << "ld -r -o " << incr_target_dir << " " << link_deps << endl;
502 //communicated below
503 QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"];
504 cmd.first().replace("$(OBJECTS) $(OBJMOC)",
505 "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)"); //ick
506 cmd.append(incr_target_dir);
507 deps.prepend(incr_target_dir + " ");
508 incr_deps = "$(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
509 } else {
510 //actual target
511 QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." + s_ext;
512 QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
513 if(!project->isEmpty("QMAKE_LFLAGS_INCREMENTAL"))
514 incr_lflags += var("QMAKE_LFLAGS_INCREMENTAL") + " ";
515 if(project->isActiveConfig("debug"))
516 incr_lflags += var("QMAKE_LFLAGS_DEBUG");
517 else
518 incr_lflags += var("QMAKE_LFLAGS_RELEASE");
519 t << incr_target_dir << ": $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << "\n\t";
520 if(!destdir.isEmpty())
521 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
522 t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir <<
523 " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)" << endl;
524 //communicated below
525 QStringList &cmd = project->variables()["QMAKE_LINK_SHLIB_CMD"];
526 if(!destdir.isEmpty())
527 cmd.append(" -L" + destdir);
528 cmd.append(" -l" + incr_target);
529 deps.prepend(incr_target_dir + " ");
530 incr_deps = "$(UICDECLS) $(OBJECTS) $(OBJMOC)";
531 }
532
533 t << "all: " << " " << deps << " " << varGlue("ALL_DEPS",""," ","")
534 << " " << var("DESTDIR_TARGET") << endl << endl;
535
536 //real target
537 t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS") << " "
538 << incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS");
539 } else {
540 t << "all: " << deps << " " << varGlue("ALL_DEPS",""," ","") << " " <<
541 var("DESTDIR_TARGET") << endl << endl;
542 t << var("DESTDIR_TARGET") << ": " << var("PRE_TARGETDEPS")
543 << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS) $(OBJCOMP) " << target_deps
544 << " " << var("POST_TARGETDEPS");
545 }
546 if(!destdir.isEmpty())
547 t << "\n\t" << "test -d " << destdir << " || mkdir -p " << destdir;
548 if(!project->isEmpty("QMAKE_PRE_LINK"))
549 t << "\n\t" << var("QMAKE_PRE_LINK");
550
551 if(project->isActiveConfig("compile_libtool")) {
552 t << "\n\t"
553 << var("QMAKE_LINK_SHLIB_CMD");
554 } else if(project->isActiveConfig("plugin")) {
555 t << "\n\t"
556 << "-$(DEL_FILE) $(TARGET)" << "\n\t"
557 << var("QMAKE_LINK_SHLIB_CMD");
558 if(!destdir.isEmpty())
559 t << "\n\t"
560 << "-$(MOVE) $(TARGET) " << var("DESTDIR");
561 if(!project->isEmpty("QMAKE_POST_LINK"))
562 t << "\n\t" << var("QMAKE_POST_LINK") << "\n\t";
563 t << endl << endl;
564 } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) {
565 t << "\n\t"
566 << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t"
567 << var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
568 t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)") << "\n\t"
569 << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t"
570 << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)");
571 if(!destdir.isEmpty())
572 t << "\n\t"
573 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t"
574 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t"
575 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET1)\n\t"
576 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET2)\n\t"
577 << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << var("DESTDIR");
578 if(!project->isEmpty("QMAKE_POST_LINK"))
579 t << "\n\t" << var("QMAKE_POST_LINK");
580 t << endl << endl;
581 } else {
582 t << "\n\t"
583 << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t"
584 << var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
585 t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)");
586 if(!destdir.isEmpty())
587 t << "\n\t"
588 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)\n\t"
589 << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET0)\n\t"
590 << "-$(MOVE) $(TARGET) $(TARGET0) " << var("DESTDIR");
591 if(!project->isEmpty("QMAKE_POST_LINK"))
592 t << "\n\t" << var("QMAKE_POST_LINK");
593 t << endl << endl;
594 }
595 t << endl << endl;
596
597 if (! project->isActiveConfig("plugin")) {
598 t << "staticlib: $(TARGETA)" << endl << endl;
599 t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP)";
600 if(do_incremental)
601 t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
602 t << var("POST_TARGETDEPS") << "\n\t"
603 << "-$(DEL_FILE) $(TARGETA) " << "\n\t"
604 << var("QMAKE_AR_CMD");
605 if(do_incremental)
606 t << " $(INCREMENTAL_OBJECTS) $(INCREMENTAL_OBJMOC)";
607 if(!project->isEmpty("QMAKE_RANLIB"))
608 t << "\n\t" << "$(RANLIB) $(TARGETA)";
609 t << endl << endl;
610 }
611 } else {
612 t << "all: " << deps << " " << varGlue("ALL_DEPS",""," "," ") << var("DESTDIR") << "$(TARGET) "
613 << varGlue("QMAKE_AR_SUBLIBS", var("DESTDIR"), " " + var("DESTDIR"), "") << "\n\n"
614 << "staticlib: " << var("DESTDIR") << "$(TARGET)" << "\n\n";
615 if(project->isEmpty("QMAKE_AR_SUBLIBS")) {
616 t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS")
617 << " $(UICDECLS) $(OBJECTS) $(OBJMOC) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t";
618 if(!project->isEmpty("DESTDIR")) {
619 QString destdir = project->first("DESTDIR");
620 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
621 }
622 t << "-$(DEL_FILE) $(TARGET)" << "\n\t"
623 << var("QMAKE_AR_CMD") << "\n";
624 if(!project->isEmpty("QMAKE_POST_LINK"))
625 t << "\t" << var("QMAKE_POST_LINK") << "\n";
626 if(!project->isEmpty("QMAKE_RANLIB"))
627 t << "\t" << "$(RANLIB) $(TARGET)" << "\n";
628 if(!project->isEmpty("DESTDIR"))
629 t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << "$(TARGET)" << "\n"
630 << "\t" << "-$(MOVE) $(TARGET) " << var("DESTDIR") << "\n";
631 } else {
632 int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt();
633 QStringList objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"] +
634 project->variables()["OBJCOMP"],
635 libs = project->variables()["QMAKE_AR_SUBLIBS"];
636 libs.prepend("$(TARGET)");
637 for(QStringList::Iterator libit = libs.begin(), objit = objs.begin();
638 libit != libs.end(); ++libit) {
639 QStringList build;
640 for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++)
641 build << (*objit);
642 QString ar;
643 if((*libit) == "$(TARGET)") {
644 t << var("DESTDIR") << "$(TARGET): " << var("PRE_TARGETDEPS")
645 << " $(UICDECLS) " << var("POST_TARGETDEPS") << valList(build) << "\n\t";
646 ar = project->variables()["QMAKE_AR_CMD"].first();
647 ar = ar.replace("$(OBJMOC)", "").replace("$(OBJECTS)",
648 build.join(" "));
649 } else {
650 t << (*libit) << ": " << valList(build) << "\n\t";
651 ar = "$(AR) " + (*libit) + " " + build.join(" ");
652 }
653 if(!project->isEmpty("DESTDIR")) {
654 QString destdir = project->first("DESTDIR");
655 t << "test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
656 }
657 t << "-$(DEL_FILE) " << (*libit) << "\n\t"
658 << ar << "\n";
659 if(!project->isEmpty("QMAKE_POST_LINK"))
660 t << "\t" << var("QMAKE_POST_LINK") << "\n";
661 if(!project->isEmpty("QMAKE_RANLIB"))
662 t << "\t" << "$(RANLIB) " << (*libit) << "\n";
663 if(!project->isEmpty("DESTDIR"))
664 t << "\t" << "-$(DEL_FILE) " << var("DESTDIR") << (*libit) << "\n"
665 << "\t" << "-$(MOVE) " << (*libit) << " " << var("DESTDIR") << "\n";
666 }
667 }
668 t << endl << endl;
669 }
670
671 t << "mocables: $(SRCMOC)" << endl
672 << "uicables: $(UICDECLS) $(UICIMPLS)" << endl << endl;
673
674 if(!project->isActiveConfig("no_mocdepend")) {
675 //this is an implicity depend on moc, so it will be built if necesary, however
676 //moc itself shouldn't have this dependency - this is a little kludgy but it is
677 //better than the alternative for now.
678 QString moc = project->first("QMAKE_MOC"), target = project->first("TARGET"),
679 moc_dir = "$(QTDIR)/src/moc";
680 if(!project->isEmpty("QMAKE_MOC_SRC"))
681 moc_dir = project->first("QMAKE_MOC_SRC");
682 fixEnvVariables(target);
683 fixEnvVariables(moc);
684 if(target != moc)
685 t << "$(MOC): \n\t"
686 << "( cd " << moc_dir << " && $(MAKE) )" << endl << endl;
687 }
688
689 writeMakeQmake(t);
690 if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake")) {
691 QString meta_files;
692 if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib" &&
693 !project->isActiveConfig("compile_libtool")) { //libtool
694 if(!meta_files.isEmpty())
695 meta_files += " ";
696 meta_files += libtoolFileName();
697 }
698 if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") { //pkg-config
699 if(!meta_files.isEmpty())
700 meta_files += " ";
701 meta_files += pkgConfigFileName();
702 }
703 if(!meta_files.isEmpty()) {
704 QStringList files = fileFixify(Option::mkfile::project_files);
705 t << meta_files << ": " << "\n\t"
706 << "@$(QMAKE) -prl " << buildArgs() << " " << files.join(" ") << endl;
707 }
708 }
709
710 if(!project->first("QMAKE_PKGINFO").isEmpty()) {
711 QString pkginfo = project->first("QMAKE_PKGINFO");
712 QString destdir = project->first("DESTDIR");
713 t << pkginfo << ": " << "\n\t";
714 if(!destdir.isEmpty())
715 t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
716 t << "@$(DEL_FILE) " << pkginfo << "\n\t"
717 << "@echo \"APPL????\" >" << pkginfo << endl;
718 }
719 if(!project->first("QMAKE_INFO_PLIST").isEmpty()) {
720 QString info_plist = project->first("QMAKE_INFO_PLIST"),
721 info_plist_out = project->first("QMAKE_INFO_PLIST_OUT");
722 QString destdir = project->first("DESTDIR");
723 t << info_plist_out << ": " << "\n\t";
724 if(!destdir.isEmpty())
725 t << "@test -d " << destdir << " || mkdir -p " << destdir << "\n\t";
726 t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
727 << "@sed -e \"s,@ICON@,application.icns,g\" -e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET")
728 << ",g\" \"" << info_plist << "\" >\"" << info_plist_out << "\"" << endl;
729 if(!project->first("RC_FILE").isEmpty()) {
730 QString dir = destdir + "../Resources/";
731 t << dir << "application.icns: " << var("RC_FILE") << "\n\t"
732 << "@test -d " << dir << " || mkdir -p " << dir << "\n\t"
733 << "@$(DEL_FILE) " << dir << "application.icns" << "\n\t"
734 << "@$(COPY_FILE) " << var("RC_FILE") << " " << dir << "application.icns" << endl;
735 }
736 }
737
738 QString ddir = project->isEmpty("QMAKE_DISTDIR") ? project->first("QMAKE_ORIG_TARGET") :
739 project->first("QMAKE_DISTDIR");
740 QString ddir_c = fileFixify((project->isEmpty("OBJECTS_DIR") ? QString(".tmp/") :
741 project->first("OBJECTS_DIR")) + ddir);
742 t << "dist: " << "\n\t"
743 << "@mkdir -p " << ddir_c << " && "
744 << "$(COPY_FILE) --parents $(SOURCES) $(HEADERS) $(FORMS) $(DIST) " << ddir_c << Option::dir_sep << " && ";
745 if(!project->isEmpty("TRANSLATIONS"))
746 t << "$(COPY_FILE) --parents " << var("TRANSLATIONS") << " " << ddir_c << Option::dir_sep << " && ";
747 if(!project->isEmpty("IMAGES"))
748 t << "$(COPY_FILE) --parents " << var("IMAGES") << " " << ddir_c << Option::dir_sep << " && ";
749 if(!project->isEmpty("FORMS")) {
750 QStringList &forms = project->variables()["FORMS"], ui_headers;
751 for(QStringList::Iterator formit = forms.begin(); formit != forms.end(); ++formit) {
752 QString ui_h = fileFixify((*formit) + Option::h_ext.first());
753 if(QFile::exists(ui_h) )
754 ui_headers << ui_h;
755 }
756 if(!ui_headers.isEmpty())
757 t << "$(COPY_FILE) --parents " << val(ui_headers) << " " << ddir_c << Option::dir_sep << " && ";
758 }
759 t << "( cd `dirname " << ddir_c << "` && "
760 << "$(TAR) " << var("QMAKE_ORIG_TARGET") << ".tar " << ddir << " && "
761 << "$(GZIP) " << var("QMAKE_ORIG_TARGET") << ".tar ) && "
762 << "$(MOVE) `dirname " << ddir_c << "`" << Option::dir_sep << var("QMAKE_ORIG_TARGET") << ".tar.gz . && "
763 << "$(DEL_FILE) -r " << ddir_c
764 << endl << endl;
765
766 QString clean_targets;
767 t << "mocclean:" << "\n";
768 if(mocAware()) {
769 if(!objMoc.isEmpty() || !srcMoc.isEmpty() || moc_incremental) {
770 if(!objMoc.isEmpty())
771 t << "\t-$(DEL_FILE) $(OBJMOC)" << '\n';
772 if(!srcMoc.isEmpty())
773 t << "\t-$(DEL_FILE) $(SRCMOC)" << '\n';
774 if(moc_incremental)
775 t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n';
776 clean_targets += " mocclean";
777 }
778 t << endl;
779 }
780 t << "uiclean:" << "\n";
781 if (!var("UICIMPLS").isEmpty() || !var("UICDECLS").isEmpty()) {
782 t << "\t-$(DEL_FILE) $(UICIMPLS) $(UICDECLS)" << "\n";
783 clean_targets += " uiclean";
784 }
785 t << endl;
786
787 t << "yaccclean:" << "\n";
788 if(!var("YACCSOURCES").isEmpty()) {
789 QStringList clean, &l = project->variables()["YACCSOURCES"];
790 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
791 QFileInfo fi((*it));
792 QString dir;
793 if(fi.dirPath() != ".")
794 dir = fi.dirPath() + Option::dir_sep;
795 dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir);
796 if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep)
797 dir += Option::dir_sep;
798 clean << ( dir + fi.baseName(TRUE) + Option::yacc_mod + Option::cpp_ext.first() );
799 clean << ( dir + fi.baseName(TRUE) + Option::yacc_mod + Option::h_ext.first() );
800 }
801 if(!clean.isEmpty()) {
802 t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n";
803 clean_targets += " yaccclean";
804 }
805 }
806
807 t << "lexclean:" << "\n";
808 if(!var("LEXSOURCES").isEmpty()) {
809 QStringList clean, &l = project->variables()["LEXSOURCES"];
810 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
811 QFileInfo fi((*it));
812 QString dir;
813 if(fi.dirPath() != ".")
814 dir = fi.dirPath() + Option::dir_sep;
815 dir = fileFixify(dir, QDir::currentDirPath(), Option::output_dir);
816 if(!dir.isEmpty() && dir.right(Option::dir_sep.length()) != Option::dir_sep)
817 dir += Option::dir_sep;
818 clean << ( dir + fi.baseName(TRUE) + Option::lex_mod + Option::cpp_ext.first() );
819 }
820 if(!clean.isEmpty()) {
821 t << "\t-$(DEL_FILE) " << clean.join(" ") << "\n";
822 clean_targets += " lexclean";
823 }
824 }
825
826 if(do_incremental) {
827 t << "incrclean:" << "\n";
828 if(src_incremental)
829 t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n";
830 if(moc_incremental)
831 t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJMOC)" << '\n';
832 t << endl;
833 }
834
835 t << "clean:" << clean_targets << "\n\t";
836 if(!project->isEmpty("OBJECTS")) {
837 if(project->isActiveConfig("compile_libtool"))
838 t << "-$(LIBTOOL) --mode=clean $(DEL_FILE) $(OBJECTS)" << "\n\t";
839 else
840 t << "-$(DEL_FILE) $(OBJECTS)" << "\n\t";
841 }
842 if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
843 QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX");
844 QString precomph_out_dir = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep;
845 t << "-$(DEL_FILE) " << precomph_out_dir << header_prefix + "c "
846 << precomph_out_dir << header_prefix << "c++" << "\n\t";
847 }
848 if(!project->isEmpty("IMAGES"))
849 t << varGlue("QMAKE_IMAGE_COLLECTION", "\t-$(DEL_FILE) ", " ", "") << "\n\t";
850 if(src_incremental)
851 t << "-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n\t";
852 t << varGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t")
853 << "-$(DEL_FILE) *~ core *.core" << "\n"
854 << varGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl;
855 t << "####### Sub-libraries" << endl << endl;
856 if ( !project->variables()["SUBLIBS"].isEmpty() ) {
857 QString libdir = "tmp/";
858 if(!project->isEmpty("SUBLIBS_DIR"))
859 libdir = project->first("SUBLIBS_DIR");
860 QStringList &l = project->variables()["SUBLIBS"];
861 for(it = l.begin(); it != l.end(); ++it)
862 t << libdir << "lib" << (*it) << ".a" << ":\n\t"
863 << var(QString("MAKELIB") + (*it)) << endl << endl;
864 }
865
866 QString destdir = project->first("DESTDIR");
867 if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep)
868 destdir += Option::dir_sep;
869 t << "distclean: " << "clean\n";
870 if(project->first("TEMPLATE") == "app" &&
871 project->isActiveConfig("resource_fork") && !project->isActiveConfig("console"))
872 t << "\t-$(DEL_FILE) -r " << destdir.section(Option::dir_sep, 0, -4) << "\n";
873 else if(project->isActiveConfig("compile_libtool"))
874 t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) " << "$(TARGET)" << "\n";
875 else
876 t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << "$(TARGET)" << "\n";
877 if(!project->isActiveConfig("staticlib") && project->variables()["QMAKE_APP_FLAG"].isEmpty() &&
878 !project->isActiveConfig("plugin") && !project->isActiveConfig("compile_libtool"))
879 t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) "
880 << destdir << "$(TARGET2) $(TARGETA)" << "\n";
881 t << endl << endl;
882
883 if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER") ) {
884 QString precomph = fileFixify(project->first("PRECOMPILED_HEADER"));
885 t << "###### Prefix headers" << endl;
886 QString comps[] = { "C", "CXX", QString::null };
887 for(int i = 0; !comps[i].isNull(); i++) {
888 QString flags = var("QMAKE_" + comps[i] + "FLAGS_PRECOMPILE");
889 flags += " $(" + comps[i] + "FLAGS)";
890
891 QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX");
892 QString outdir = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep, outfile = outdir;
893 QString compiler;
894 if(comps[i] == "C") {
895 outfile += header_prefix + "c";
896 compiler = "$(CC) ";
897 } else {
898 outfile += header_prefix + "c++";
899 compiler = "$(CXX) ";
900 }
901 t << outfile << ": " << precomph << " " << findDependencies(precomph).join(" \\\n\t\t")
902 << "\n\t" << "test -d " << outdir << " || mkdir -p " << outdir
903 << "\n\t" << compiler << flags << " $(INCPATH) " << precomph << " -o " << outfile << endl << endl;
904 }
905 }
906 if(!project->isEmpty("ALLMOC_HEADER")) {
907 QString outdir = project->first("MOC_DIR");
908 QString precomph = fileFixify(project->first("ALLMOC_HEADER"));
909 t << "###### Combined headers" << endl << endl
910 << outdir << "allmoc.cpp: " << precomph << " "
911 << varList("HEADERS_ORIG") << "\n\t"
912 << "echo '#include \"" << precomph << "\"' >" << outdir << "allmoc.cpp" << "\n\t"
913 << "$(CXX) -E -DQT_MOC_CPP -DQT_NO_STL $(CXXFLAGS) $(INCPATH) >" << outdir << "allmoc.h "
914 << outdir << "allmoc.cpp" << "\n\t"
915 << "$(MOC) -o " << outdir << "allmoc.cpp " << outdir << "allmoc.h" << "\n\t"
916 << "perl -pi -e 's{#include \"allmoc.h\"}{#define QT_H_CPP\\n#include \""
917 << precomph << "\"}' " << outdir << "allmoc.cpp" << "\n\t"
918 << "$(DEL_FILE) " << outdir << "allmoc.h" << endl << endl;
919 }
920
921 // user defined targets
922 QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
923 for(it = qut.begin(); it != qut.end(); ++it) {
924 QString targ = var((*it) + ".target"),
925 cmd = var((*it) + ".commands"), deps;
926 if(targ.isEmpty())
927 targ = (*it);
928 QStringList &deplist = project->variables()[(*it) + ".depends"];
929 for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
930 QString dep = var((*dep_it) + ".target");
931 if(dep.isEmpty())
932 dep = (*dep_it);
933 deps += " " + dep;
934 }
935 if(project->variables()[(*it) + ".CONFIG"].findIndex("phony") != -1)
936 deps += QString(" ") + "FORCE";
937 t << targ << ":" << deps << "\n\t"
938 << cmd << endl << endl;
939 }
940 // user defined compilers
941 QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"];
942 for(it = quc.begin(); it != quc.end(); ++it) {
943 QString tmp_out = project->variables()[(*it) + ".output"].first();
944 QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" ");
945 QString tmp_dep = project->variables()[(*it) + ".depends"].join(" ");
946 QStringList &vars = project->variables()[(*it) + ".variables"];
947 if(tmp_out.isEmpty() || tmp_cmd.isEmpty())
948 continue;
949 QStringList &tmp = project->variables()[(*it) + ".input"];
950 for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) {
951 QStringList &inputs = project->variables()[(*it2)];
952 for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) {
953 QFileInfo fi(Option::fixPathToLocalOS((*input)));
954 QString in = Option::fixPathToTargetOS((*input), FALSE),
955 out = tmp_out, cmd = tmp_cmd, deps;
956 out.replace("${QMAKE_FILE_BASE}", fi.baseName());
957 out.replace("${QMAKE_FILE_NAME}", fi.fileName());
958 cmd.replace("${QMAKE_FILE_BASE}", fi.baseName());
959 cmd.replace("${QMAKE_FILE_OUT}", out);
960 cmd.replace("${QMAKE_FILE_NAME}", fi.fileName());
961 for(QStringList::Iterator it3 = vars.begin(); it3 != vars.end(); ++it3)
962 cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")");
963 if(!tmp_dep.isEmpty()) {
964 char buff[256];
965 QString dep_cmd = tmp_dep;
966 dep_cmd.replace("${QMAKE_FILE_NAME}", fi.fileName());
967 if(FILE *proc = QT_POPEN(dep_cmd.latin1(), "r")) {
968 while(!feof(proc)) {
969 int read_in = fread(buff, 1, 255, proc);
970 if(!read_in)
971 break;
972 int l = 0;
973 for(int i = 0; i < read_in; i++) {
974 if(buff[i] == '\n' || buff[i] == ' ') {
975 deps += " " + QCString(buff+l, (i - l) + 1);
976 l = i;
977 }
978 }
979 }
980 fclose(proc);
981 }
982 }
983 t << out << ": " << in << deps << "\n\t"
984 << cmd << endl << endl;
985 }
986 }
987 }
988 t <<"FORCE:" << endl << endl;
989}
990
991struct SubDir
992{
993 QString directory, profile, target, makefile;
994};
995
996void
997UnixMakefileGenerator::writeSubdirs(QTextStream &t, bool direct)
998{
999 // blasted includes
1000 QStringList &qeui = project->variables()["QMAKE_EXTRA_UNIX_INCLUDES"];
1001 for(QStringList::Iterator qeui_it = qeui.begin(); qeui_it != qeui.end(); ++qeui_it)
1002 t << "include " << (*qeui_it) << endl;
1003 writeExtraVariables(t);
1004
1005 QPtrList<SubDir> subdirs;
1006 {
1007 QStringList subdirs_in = project->variables()["SUBDIRS"];
1008 for(QStringList::Iterator it = subdirs_in.begin(); it != subdirs_in.end(); ++it) {
1009 QString file = (*it);
1010 fileFixify(file);
1011 SubDir *sd = new SubDir;
1012 subdirs.append(sd);
1013 sd->makefile = "$(MAKEFILE)";
1014 if((*it).right(4) == ".pro") {
1015 int slsh = file.findRev(Option::dir_sep);
1016 if(slsh != -1) {
1017 sd->directory = file.left(slsh+1);
1018 sd->profile = file.mid(slsh+1);
1019 } else {
1020 sd->profile = file;
1021 }
1022 } else {
1023 if(!file.isEmpty())
1024 sd->profile = file.section(Option::dir_sep, -1) + ".pro";
1025 sd->directory = file;
1026 }
1027 while(sd->directory.right(1) == Option::dir_sep)
1028 sd->directory = sd->directory.left(sd->directory.length() - 1);
1029 if(!sd->profile.isEmpty()) {
1030 QString basename = sd->directory;
1031 int new_slsh = basename.findRev(Option::dir_sep);
1032 if(new_slsh != -1)
1033 basename = basename.mid(new_slsh+1);
1034 if(sd->profile != basename + ".pro")
1035 sd->makefile += "." + sd->profile.left(sd->profile.length() - 4); //no need for the .pro
1036 }
1037 sd->target = "sub-" + (*it);
1038 sd->target.replace('/', '-');
1039 sd->target.replace('.', '_');
1040 }
1041 }
1042 QPtrListIterator<SubDir> it(subdirs);
1043
1044 QString ofile = Option::output.name();
1045 if(ofile.findRev(Option::dir_sep) != -1)
1046 ofile = ofile.right(ofile.length() - ofile.findRev(Option::dir_sep) -1);
1047 t << "MAKEFILE = " << var("MAKEFILE") << endl;
1048 t << "QMAKE = " << var("QMAKE") << endl;
1049 t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl;
1050 t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl;
1051 t << "MKDIR = " << var("QMAKE_MKDIR") << endl;
1052 t << "SUBTARGETS = "; // subdirectory targets are sub-directory
1053 for( it.toFirst(); it.current(); ++it)
1054 t << " \\\n\t\t" << it.current()->target;
1055 t << endl << endl;
1056 t << "first: all\n\nall: " << ofile << " $(SUBTARGETS)" << endl << endl;
1057
1058 // generate target rules
1059 for( it.toFirst(); it.current(); ++it) {
1060 bool have_dir = !(*it)->directory.isEmpty();
1061 QString mkfile = (*it)->makefile, out;
1062 if(have_dir)
1063 mkfile.prepend((*it)->directory + Option::dir_sep);
1064 if(direct || (*it)->makefile != "$(MAKEFILE)")
1065 out = " -o " + (*it)->makefile;
1066 //qmake it
1067 t << mkfile << ": " << "\n\t";
1068 if(have_dir)
1069 t << mkdir_p_asstring((*it)->directory) << "\n\t"
1070 << "cd " << (*it)->directory << " && ";
1071 QString profile = fileFixify((*it)->profile, (*it)->directory, (*it)->directory);
1072 t << "$(QMAKE) " << profile << buildArgs() << out << endl;
1073 //actually compile
1074 t << (*it)->target << ": " << mkfile << " FORCE" << "\n\t";
1075 if(have_dir)
1076 t << "cd " << (*it)->directory << " && ";
1077 t << "$(MAKE) -f " << (*it)->makefile << endl << endl;
1078 }
1079
1080 if (project->isActiveConfig("ordered")) { // generate dependencies
1081 for( it.toFirst(); it.current(); ) {
1082 QString tar = it.current()->target;
1083 ++it;
1084 if (it.current())
1085 t << it.current()->target << ": " << tar << endl;
1086 }
1087 t << endl;
1088 }
1089
1090 writeMakeQmake(t);
1091
1092 if(project->isEmpty("SUBDIRS")) {
1093 t << "all qmake_all distclean uicables mocables install_subdirs uninstall_subdirs"
1094 << " uiclean mocclean lexclean yaccclean clean " << var("SUBDIR_TARGETS") << ": FORCE" << endl;
1095 } else {
1096 t << "all: $(SUBTARGETS)" << endl;
1097 t << "qmake_all:";
1098 for( it.toFirst(); it.current(); ++it) {
1099 t << " ";
1100 if(!(*it)->directory.isEmpty())
1101 t << (*it)->directory << Option::dir_sep;
1102 t << (*it)->makefile;
1103 }
1104 for( it.toFirst(); it.current(); ++it) {
1105 t << "\n\t ( ";
1106 if(!(*it)->directory.isEmpty())
1107 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
1108 t << "grep \"^qmake_all:\" " << (*it)->makefile
1109 << " && $(MAKE) -f " << (*it)->makefile << " qmake_all" << "; ) || true";
1110 }
1111 t << endl;
1112 t << "clean uicables mocables uiclean mocclean lexclean yaccclean "
1113 << var("SUBDIR_TARGETS") << ": qmake_all FORCE";
1114 for( it.toFirst(); it.current(); ++it) {
1115 t << "\n\t ( ";
1116 if(!(*it)->directory.isEmpty())
1117 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
1118 t << "$(MAKE) -f " << (*it)->makefile << " $@" << "; ) || true";
1119 }
1120 t << endl;
1121 t << "uninstall_subdirs: qmake_all FORCE";
1122 for( it.toFirst(); it.current(); ++it) {
1123 t << "\n\t ( ";
1124 if(!(*it)->directory.isEmpty())
1125 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
1126 t << "$(MAKE) -f " << (*it)->makefile << " uninstall" << "; ) || true";
1127 }
1128 t << endl;
1129 t << "install_subdirs: qmake_all FORCE";
1130 for( it.toFirst(); it.current(); ++it) {
1131 t << "\n\t ( ";
1132 if(!(*it)->directory.isEmpty())
1133 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
1134 t << "$(MAKE) -f " << (*it)->makefile << " install" << "; ) || true";
1135 }
1136 t << endl;
1137 t << "distclean: qmake_all FORCE";
1138 for( it.toFirst(); it.current(); ++it) {
1139 t << "\n\t ( ";
1140 if(!(*it)->directory.isEmpty())
1141 t << "[ -d " << (*it)->directory << " ] && cd " << (*it)->directory << " ; ";
1142 t << "$(MAKE) -f " << (*it)->makefile << " $@; $(DEL_FILE) " << (*it)->makefile << "; ) || true";
1143 }
1144 t << endl << endl;
1145 }
1146
1147 //installations
1148 project->variables()["INSTALLDEPS"] += "install_subdirs";
1149 project->variables()["UNINSTALLDEPS"] += "uninstall_subdirs";
1150 writeInstalls(t, "INSTALLS");
1151
1152 // user defined targets
1153 QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
1154 for(QStringList::Iterator qut_it = qut.begin(); qut_it != qut.end(); ++qut_it) {
1155 QString targ = var((*qut_it) + ".target"),
1156 cmd = var((*qut_it) + ".commands"), deps;
1157 if(targ.isEmpty())
1158 targ = (*qut_it);
1159 QStringList &deplist = project->variables()[(*qut_it) + ".depends"];
1160 for(QStringList::Iterator dep_it = deplist.begin(); dep_it != deplist.end(); ++dep_it) {
1161 QString dep = var((*dep_it) + ".target");
1162 if(dep.isEmpty())
1163 dep = (*dep_it);
1164 deps += " " + dep;
1165 }
1166 if(project->variables()[(*qut_it) + ".CONFIG"].findIndex("phony") != -1)
1167 deps += QString(" ") + "FORCE";
1168 t << targ << ":" << deps << "\n\t"
1169 << cmd << endl << endl;
1170 }
1171 t <<"FORCE:" << endl << endl;
1172}
1173
1174void UnixMakefileGenerator::init2()
1175{
1176 //version handling
1177 if(project->variables()["VERSION"].isEmpty())
1178 project->variables()["VERSION"].append("1.0." +
1179 (project->isEmpty("VER_PAT") ? QString("0") :
1180 project->first("VER_PAT")) );
1181 QStringList l = QStringList::split('.', project->first("VERSION"));
1182 l << "0" << "0"; //make sure there are three
1183 project->variables()["VER_MAJ"].append(l[0]);
1184 project->variables()["VER_MIN"].append(l[1]);
1185 project->variables()["VER_PAT"].append(l[2]);
1186
1187 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
1188#if 0
1189 if ( project->isActiveConfig("dll") ) {
1190 project->variables()["TARGET"] += project->variables()["TARGET.so"];
1191 if(project->variables()["QMAKE_LFLAGS_SHAPP"].isEmpty())
1192 project->variables()["QMAKE_LFLAGS_SHAPP"] += project->variables()["QMAKE_LFLAGS_SHLIB"];
1193 if(!project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty())
1194 project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET");
1195 }
1196#endif
1197 project->variables()["TARGET"].first().prepend(project->first("DESTDIR"));
1198 if ( !project->variables()["QMAKE_CYGWIN_EXE"].isEmpty() )
1199 project->variables()["TARGET_EXT"].append(".exe");
1200 } else if ( project->isActiveConfig("staticlib") ) {
1201 project->variables()["TARGET"].first().prepend("lib");
1202 project->variables()["TARGET"].first() += ".a";
1203 if(project->variables()["QMAKE_AR_CMD"].isEmpty())
1204 project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGET) $(OBJECTS) $(OBJMOC)");
1205 } else {
1206 project->variables()["TARGETA"].append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a");
1207 if( project->isActiveConfig("compile_libtool") )
1208 project->variables()["TARGET_la"] = project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext;
1209
1210 if ( !project->variables()["QMAKE_AR_CMD"].isEmpty() )
1211 project->variables()["QMAKE_AR_CMD"].first().replace("(TARGET)","(TARGETA)");
1212 else
1213 project->variables()["QMAKE_AR_CMD"].append("$(AR) $(TARGETA) $(OBJECTS) $(OBJMOC)");
1214 if( project->isActiveConfig("compile_libtool") ) {
1215 project->variables()["TARGET"] = project->variables()["TARGET_la"];
1216 } else if( project->isActiveConfig("plugin") ) {
1217 project->variables()["TARGET_x.y.z"].append("lib" +
1218 project->first("TARGET") + "." +
1219 project->first("QMAKE_EXTENSION_PLUGIN"));
1220 if(project->isActiveConfig("lib_version_first"))
1221 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
1222 project->first("VER_MAJ") + "." +
1223 project->first("QMAKE_EXTENSION_PLUGIN"));
1224 else
1225 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
1226 project->first("QMAKE_EXTENSION_PLUGIN") +
1227 "." + project->first("VER_MAJ"));
1228
1229 project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
1230 if(project->isActiveConfig("qt"))
1231 project->variables()["DEFINES"].append("QT_PLUGIN");
1232 } else if ( !project->isEmpty("QMAKE_HPUX_SHLIB") ) {
1233 project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".sl");
1234 if(project->isActiveConfig("lib_version_first"))
1235 project->variables()["TARGET_x"].append("lib" + project->first("VER_MAJ") + "." +
1236 project->first("TARGET"));
1237 else
1238 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
1239 project->first("VER_MAJ"));
1240 project->variables()["TARGET"] = project->variables()["TARGET_x"];
1241 } else if ( !project->isEmpty("QMAKE_AIX_SHLIB") ) {
1242 project->variables()["TARGET_"].append("lib" + project->first("TARGET") + ".a");
1243 if(project->isActiveConfig("lib_version_first")) {
1244 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
1245 project->first("VER_MAJ") + "." +
1246 project->first("QMAKE_EXTENSION_SHLIB"));
1247 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
1248 project->first("VER_MAJ") +
1249 "." + project->first("VER_MIN") + "." +
1250 project->first("QMAKE_EXTENSION_SHLIB"));
1251 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
1252 project->first("VER_MAJ") + "." +
1253 project->first("VER_MIN") + "." +
1254 project->first("VER_PAT") + "." +
1255 project->first("QMAKE_EXTENSION_SHLIB"));
1256 } else {
1257 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
1258 project->first("QMAKE_EXTENSION_SHLIB") +
1259 "." + project->first("VER_MAJ"));
1260 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
1261 project->first("QMAKE_EXTENSION_SHLIB") +
1262 "." + project->first("VER_MAJ") +
1263 "." + project->first("VER_MIN"));
1264 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
1265 project->first("QMAKE_EXTENSION_SHLIB") + "." +
1266 project->first("VER_MAJ") + "." +
1267 project->first("VER_MIN") + "." +
1268 project->first("VER_PAT"));
1269 }
1270 project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
1271 } else {
1272 project->variables()["TARGET_"].append("lib" + project->first("TARGET") + "." +
1273 project->first("QMAKE_EXTENSION_SHLIB"));
1274 if(project->isActiveConfig("lib_version_first")) {
1275 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
1276 project->first("VER_MAJ") + "." +
1277 project->first("QMAKE_EXTENSION_SHLIB"));
1278 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
1279 project->first("VER_MAJ") +
1280 "." + project->first("VER_MIN") + "." +
1281 project->first("QMAKE_EXTENSION_SHLIB"));
1282 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") + "." +
1283 project->first("VER_MAJ") + "." +
1284 project->first("VER_MIN") + "." +
1285 project->first("VER_PAT") + "." +
1286 project->variables()["QMAKE_EXTENSION_SHLIB"].first());
1287 } else {
1288 project->variables()["TARGET_x"].append("lib" + project->first("TARGET") + "." +
1289 project->first("QMAKE_EXTENSION_SHLIB") +
1290 "." + project->first("VER_MAJ"));
1291 project->variables()["TARGET_x.y"].append("lib" + project->first("TARGET") + "." +
1292 project->first("QMAKE_EXTENSION_SHLIB")
1293 + "." + project->first("VER_MAJ") +
1294 "." + project->first("VER_MIN"));
1295 project->variables()["TARGET_x.y.z"].append("lib" + project->first("TARGET") +
1296 "." +
1297 project->variables()[
1298 "QMAKE_EXTENSION_SHLIB"].first() + "." +
1299 project->first("VER_MAJ") + "." +
1300 project->first("VER_MIN") + "." +
1301 project->first("VER_PAT"));
1302 }
1303 project->variables()["TARGET"] = project->variables()["TARGET_x.y.z"];
1304 }
1305 if(project->isEmpty("QMAKE_LN_SHLIB"))
1306 project->variables()["QMAKE_LN_SHLIB"].append("ln -s");
1307 project->variables()["DESTDIR_TARGET"].append("$(TARGET)");
1308 if ( !project->variables()["DESTDIR"].isEmpty() )
1309 project->variables()["DESTDIR_TARGET"].first().prepend(project->first("DESTDIR"));
1310 if ( !project->variables()["QMAKE_LFLAGS_SONAME"].isEmpty()) {
1311 if(project->isActiveConfig("plugin")) {
1312 if(!project->variables()["TARGET"].isEmpty() )
1313 project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET");
1314 } else {
1315 if(!project->variables()["TARGET_x"].isEmpty() )
1316 project->variables()["QMAKE_LFLAGS_SONAME"].first() += project->first("TARGET_x");
1317 }
1318 }
1319 if ( project->variables()["QMAKE_LINK_SHLIB_CMD"].isEmpty() )
1320 project->variables()["QMAKE_LINK_SHLIB_CMD"].append(
1321 "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS) $(OBJCOMP)");
1322 }
1323 if(project->isEmpty("QMAKE_SYMBOLIC_LINK"))
1324 project->variables()["QMAKE_SYMBOLIC_LINK"].append("ln -sf");
1325 if ( !project->variables()["QMAKE_APP_FLAG"].isEmpty() ) {
1326 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_APP"];
1327 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_APP"];
1328 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_APP"];
1329 } else if ( project->isActiveConfig("dll") ) {
1330 if( !project->isActiveConfig("plugin") || !project->isActiveConfig("plugin_no_share_shlib_cflags")) {
1331 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_SHLIB"];
1332 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_SHLIB"];
1333 }
1334 if ( project->isActiveConfig("plugin") ) {
1335 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_PLUGIN"];
1336 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_PLUGIN"];
1337 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PLUGIN"];
1338 if( project->isActiveConfig("plugin_with_soname") && !project->isActiveConfig("compile_libtool"))
1339 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"];
1340 } else {
1341 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SHLIB"];
1342 if(!project->isEmpty("QMAKE_LFLAGS_COMPAT_VERSION")) {
1343 if(project->isEmpty("COMPAT_VERSION"))
1344 project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") +
1345 project->first("VER_MAJ") + "." +
1346 project->first("VER_MIN"));
1347 else
1348 project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") +
1349 project->first("COMPATIBILITY_VERSION"));
1350 }
1351 if(!project->isEmpty("QMAKE_LFLAGS_VERSION")) {
1352 project->variables()["QMAKE_LFLAGS"] += QString(project->first("QMAKE_LFLAGS_VERSION") +
1353 project->first("VER_MAJ") + "." +
1354 project->first("VER_MIN") + "." +
1355 project->first("VER_PAT"));
1356 }
1357 if(!project->isActiveConfig("compile_libtool"))
1358 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_SONAME"];
1359 }
1360 QString destdir = project->first("DESTDIR");
1361 if ( !destdir.isEmpty() && !project->variables()["QMAKE_RPATH"].isEmpty() ) {
1362 QString rpath_destdir = destdir;
1363 if(QDir::isRelativePath(rpath_destdir)) {
1364 QFileInfo fi(Option::fixPathToLocalOS(rpath_destdir));
1365 if(fi.convertToAbs()) //strange, shouldn't really happen
1366 rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE);
1367 else
1368 rpath_destdir = fi.filePath();
1369 } else {
1370 rpath_destdir = Option::fixPathToTargetOS(rpath_destdir, FALSE);
1371 }
1372 project->variables()["QMAKE_LFLAGS"] += project->first("QMAKE_RPATH") + rpath_destdir;
1373 }
1374 }
1375 QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"];
1376 for(QStringList::Iterator it = quc.begin(); it != quc.end(); ++it) {
1377 QString tmp_out = project->variables()[(*it) + ".output"].first();
1378 if(tmp_out.isEmpty())
1379 continue;
1380 QStringList &tmp = project->variables()[(*it) + ".input"];
1381 for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) {
1382 QStringList &inputs = project->variables()[(*it2)];
1383 for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) {
1384 QFileInfo fi(Option::fixPathToLocalOS((*input)));
1385 QString in = Option::fixPathToTargetOS((*input), FALSE),
1386 out = tmp_out;
1387 out.replace("${QMAKE_FILE_BASE}", fi.baseName());
1388 out.replace("${QMAKE_FILE_NAME}", fi.fileName());
1389 if(project->variables()[(*it) + ".CONFIG"].findIndex("no_link") == -1)
1390 project->variables()["OBJCOMP"] += out;
1391 }
1392 }
1393 }
1394}
1395
1396QString
1397UnixMakefileGenerator::libtoolFileName()
1398{
1399 QString ret = var("TARGET");
1400 int slsh = ret.findRev(Option::dir_sep);
1401 if(slsh != -1)
1402 ret = ret.right(ret.length() - slsh);
1403 int dot = ret.find('.');
1404 if(dot != -1)
1405 ret = ret.left(dot);
1406 ret += Option::libtool_ext;
1407 if(!project->isEmpty("DESTDIR"))
1408 ret.prepend(var("DESTDIR"));
1409 return ret;
1410}
1411
1412void
1413UnixMakefileGenerator::writeLibtoolFile()
1414{
1415 QString fname = libtoolFileName(), lname = fname;
1416 int slsh = lname.findRev(Option::dir_sep);
1417 if(slsh != -1)
1418 lname = lname.right(lname.length() - slsh - 1);
1419 QFile ft(fname);
1420 if(!ft.open(IO_WriteOnly))
1421 return;
1422 project->variables()["ALL_DEPS"].append(fname);
1423
1424 QTextStream t(&ft);
1425 t << "# " << lname << " - a libtool library file\n";
1426 time_t now = time(NULL);
1427 t << "# Generated by qmake/libtool (" << qmake_version() << ") (Qt "
1428 << QT_VERSION_STR << ") on: " << ctime(&now) << "\n";
1429
1430 t << "# The name that we can dlopen(3).\n"
1431 << "dlname='" << var(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x")
1432 << "'\n\n";
1433
1434 t << "# Names of this library.\n";
1435 t << "library_names='";
1436 if(project->isActiveConfig("plugin")) {
1437 t << var("TARGET");
1438 } else {
1439 if (project->isEmpty("QMAKE_HPUX_SHLIB"))
1440 t << var("TARGET_x.y.z") << " ";
1441 t << var("TARGET_x") << " " << var("TARGET_");
1442 }
1443 t << "'\n\n";
1444
1445 t << "# The name of the static archive.\n"
1446 << "old_library='" << lname.left(lname.length()-Option::libtool_ext.length()) << ".a'\n\n";
1447
1448 t << "# Libraries that this one depends upon.\n";
1449 QStringList libs;
1450 if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
1451 libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"];
1452 else
1453 libs << "QMAKE_LIBS"; //obvious one
1454 t << "dependency_libs='";
1455 for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it)
1456 t << project->variables()[(*it)].join(" ") << " ";
1457 t << "'\n\n";
1458
1459 t << "# Version information for " << lname << "\n";
1460 int maj = project->first("VER_MAJ").toInt();
1461 int min = project->first("VER_MIN").toInt();
1462 int pat = project->first("VER_PAT").toInt();
1463 t << "current=" << (10*maj + min) << "\n" // best I can think of
1464 << "age=0\n"
1465 << "revision=" << pat << "\n\n";
1466
1467 t << "# Is this an already installed library.\n"
1468 "installed=yes\n\n"; // ###
1469
1470 t << "# Files to dlopen/dlpreopen.\n"
1471 "dlopen=''\n"
1472 "dlpreopen=''\n\n";
1473
1474 QString install_dir = project->first("target.path");
1475 if(install_dir.isEmpty())
1476 install_dir = project->first("DESTDIR");
1477 t << "# Directory that this library needs to be installed in:\n"
1478 "libdir='" << Option::fixPathToTargetOS(install_dir, FALSE) << "'\n";
1479}
1480
1481QString
1482UnixMakefileGenerator::pkgConfigFileName()
1483{
1484 QString ret = var("TARGET");
1485 int slsh = ret.findRev(Option::dir_sep);
1486 if(slsh != -1)
1487 ret = ret.right(ret.length() - slsh);
1488 if(ret.startsWith("lib"))
1489 ret = ret.mid(3);
1490 int dot = ret.find('.');
1491 if(dot != -1)
1492 ret = ret.left(dot);
1493 ret += Option::pkgcfg_ext;
1494 if(!project->isEmpty("DESTDIR")) {
1495 ret.prepend(var("DESTDIR"));
1496 ret = Option::fixPathToLocalOS(fileFixify(ret,QDir::currentDirPath(), Option::output_dir));
1497 }
1498 return ret;
1499}
1500
1501QString
1502UnixMakefileGenerator::pkgConfigPrefix() const
1503{
1504 if(!project->isEmpty("QMAKE_PKGCONFIG_PREFIX"))
1505 return project->first("QMAKE_PKGCONFIG_PREFIX");
1506 return qInstallPath();
1507}
1508
1509QString
1510UnixMakefileGenerator::pkgConfigFixPath(QString path) const
1511{
1512 QString prefix = pkgConfigPrefix();
1513 if(path.startsWith(prefix))
1514 path = path.replace(prefix, "${prefix}");
1515 return path;
1516}
1517
1518void
1519UnixMakefileGenerator::writePkgConfigFile() // ### does make sense only for libqt so far
1520{
1521 QString fname = pkgConfigFileName(), lname = fname;
1522 int slsh = lname.findRev(Option::dir_sep);
1523 if(slsh != -1)
1524 lname = lname.right(lname.length() - slsh - 1);
1525 QFile ft(fname);
1526 if(!ft.open(IO_WriteOnly))
1527 return;
1528 project->variables()["ALL_DEPS"].append(fname);
1529 QTextStream t(&ft);
1530
1531 QString prefix = pkgConfigPrefix();
1532 QString libDir = project->first("QMAKE_PKGCONFIG_LIBDIR");
1533 if(libDir.isEmpty())
1534 libDir = prefix + "/lib";
1535 QString includeDir = project->first("QMAKE_PKGCONFIG_INCDIR");
1536 if(includeDir.isEmpty())
1537 includeDir = prefix + "/include";
1538
1539 t << "prefix=" << prefix << endl;
1540 t << "exec_prefix=${prefix}\n"
1541 << "libdir=" << pkgConfigFixPath(libDir) << "\n"
1542 << "includedir=" << pkgConfigFixPath(includeDir) << endl;
1543 // non-standard entry. Provides useful info normally only
1544 // contained in the internal .qmake.cache file
1545 t << varGlue("CONFIG", "qt_config=", " ", "") << endl << endl;
1546
1547 t << "Name: Qt" << endl;
1548 QString desc = project->first("QMAKE_PKGCONFIG_DESCRIPTION");
1549 if(desc.isEmpty()) {
1550 desc = project->first("TARGET").lower();
1551 desc.replace(0, 1, desc[0].upper());
1552 if(project->first("TEMPLATE") == "lib") {
1553 if(project->isActiveConfig("plugin"))
1554 desc += " Plugin";
1555 else
1556 desc += " Library";
1557 } else if(project->first("TEMPLATE") == "app") {
1558 desc += " Application";
1559 }
1560 }
1561 t << "Description: " << desc << endl;
1562 t << "Version: " << project->first("VERSION") << endl;
1563
1564 // libs
1565 QStringList libs;
1566 if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
1567 libs = project->variables()["QMAKE_INTERNAL_PRL_LIBS"];
1568 else
1569 libs << "QMAKE_LIBS"; //obvious one
1570 if(project->isActiveConfig("thread"))
1571 libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread?
1572 t << "Libs: -L${libdir} -l" << lname.left(lname.length()-Option::libtool_ext.length()) << " ";
1573 for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it)
1574 t << project->variables()[(*it)].join(" ") << " ";
1575 t << endl;
1576
1577 // flags
1578 // ### too many
1579 t << "Cflags: "
1580 // << var("QMAKE_CXXFLAGS") << " "
1581 << varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ")
1582 << project->variables()["PRL_EXPORT_CXXFLAGS"].join(" ")
1583 // << varGlue("DEFINES","-D"," -D"," ")
1584 << " -I${includedir}";
1585}
Note: See TracBrowser for help on using the repository browser.