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

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

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

  • Property svn:keywords set to Id
File size: 34.6 KB
Line 
1/****************************************************************************
2** $Id: unixmake.cpp 8 2005-11-16 19:36:46Z 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 <qregexp.h>
39#include <qfile.h>
40#include <qdict.h>
41#include <qdir.h>
42#include <time.h>
43
44
45void
46UnixMakefileGenerator::init()
47{
48 if(init_flag)
49 return;
50 init_flag = TRUE;
51
52 if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */
53 return;
54
55 QStringList &configs = project->variables()["CONFIG"];
56 /* this should probably not be here, but I'm using it to wrap the .t files */
57 if(project->first("TEMPLATE") == "app")
58 project->variables()["QMAKE_APP_FLAG"].append("1");
59 else if(project->first("TEMPLATE") == "lib")
60 project->variables()["QMAKE_LIB_FLAG"].append("1");
61 else if(project->first("TEMPLATE") == "subdirs") {
62 MakefileGenerator::init();
63 if(project->isEmpty("MAKEFILE"))
64 project->variables()["MAKEFILE"].append("Makefile");
65 if(project->isEmpty("QMAKE"))
66 project->variables()["QMAKE"].append("qmake");
67 if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].findIndex("qmake_all") == -1)
68 project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all");
69 return; /* subdirs is done */
70 }
71
72 if( project->isEmpty("QMAKE_EXTENSION_SHLIB") ) {
73 if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) {
74 project->variables()["QMAKE_EXTENSION_SHLIB"].append( "so" );
75 } else {
76 project->variables()["QMAKE_EXTENSION_SHLIB"].append( "dll" );
77 }
78 }
79 if( project->isEmpty("QMAKE_CFLAGS_PRECOMPILE"))
80 project->variables()["QMAKE_CFLAGS_PRECOMPILE"].append("-x c-header -c");
81 if( project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE"))
82 project->variables()["QMAKE_CXXFLAGS_PRECOMPILE"].append("-x c++-header -c");
83 if( project->isEmpty("QMAKE_CFLAGS_USE_PRECOMPILE"))
84 project->variables()["QMAKE_CFLAGS_USE_PRECOMPILE"].append("-include");
85 if( project->isEmpty("QMAKE_EXTENSION_PLUGIN") )
86 project->variables()["QMAKE_EXTENSION_PLUGIN"].append(project->first("QMAKE_EXTENSION_SHLIB"));
87 if( project->isEmpty("QMAKE_COPY_FILE") )
88 project->variables()["QMAKE_COPY_FILE"].append( "$(COPY)" );
89 if( project->isEmpty("QMAKE_COPY_DIR") )
90 project->variables()["QMAKE_COPY_DIR"].append( "$(COPY) -R" );
91 if( project->isEmpty("QMAKE_INSTALL_FILE") )
92 project->variables()["QMAKE_INSTALL_FILE"].append( "$(COPY_FILE)" );
93 if( project->isEmpty("QMAKE_INSTALL_DIR") )
94 project->variables()["QMAKE_INSTALL_DIR"].append( "$(COPY_DIR)" );
95 if( project->isEmpty("QMAKE_LIBTOOL") )
96 project->variables()["QMAKE_LIBTOOL"].append( "libtool --silent" );
97 //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET
98 if(!project->isEmpty("TARGET")) {
99 QString targ = project->first("TARGET");
100 int slsh = QMAX(targ.findRev('/'), targ.findRev(Option::dir_sep));
101 if(slsh != -1) {
102 if(project->isEmpty("DESTDIR"))
103 project->values("DESTDIR").append("");
104 else if(project->first("DESTDIR").right(1) != Option::dir_sep)
105 project->variables()["DESTDIR"] = project->first("DESTDIR") + Option::dir_sep;
106 project->variables()["DESTDIR"] = project->first("DESTDIR") + targ.left(slsh+1);
107 project->variables()["TARGET"] = targ.mid(slsh+1);
108 }
109 }
110
111 project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
112
113 bool is_qt = (project->first("TARGET") == "qt" || project->first("TARGET") == "qte" ||
114 project->first("TARGET") == "qt-mt" || project->first("TARGET") == "qte-mt");
115 bool extern_libs = !project->isEmpty("QMAKE_APP_FLAG") ||
116 (!project->isEmpty("QMAKE_LIB_FLAG") &&
117 project->isActiveConfig("dll")) || is_qt;
118 project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
119 if ( (!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib") ) ||
120 (project->isActiveConfig("qt") && project->isActiveConfig( "plugin" ) )) {
121 if(configs.findIndex("dll") == -1) configs.append("dll");
122 } else if ( !project->isEmpty("QMAKE_APP_FLAG") || project->isActiveConfig("dll") ) {
123 configs.remove("staticlib");
124 }
125 if ( project->isActiveConfig("warn_off") ) {
126 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_OFF"];
127 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_OFF"];
128 } else if ( project->isActiveConfig("warn_on") ) {
129 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_WARN_ON"];
130 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_WARN_ON"];
131 }
132 if ( project->isActiveConfig("debug") ) {
133 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_DEBUG"];
134 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_DEBUG"];
135 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_DEBUG"];
136 } else {
137 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_RELEASE"];
138 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_RELEASE"];
139 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_RELEASE"];
140 }
141 if(!project->isEmpty("QMAKE_INCREMENTAL"))
142 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_INCREMENTAL"];
143 else if(!project->isEmpty("QMAKE_LFLAGS_PREBIND") &&
144 !project->variables()["QMAKE_LIB_FLAG"].isEmpty() &&
145 project->isActiveConfig("dll"))
146 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PREBIND"];
147 if(!project->isEmpty("QMAKE_INCDIR"))
148 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
149 if(!project->isEmpty("QMAKE_LIBDIR")) {
150 if ( !project->isEmpty("QMAKE_RPATH") )
151 project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_LIBDIR", " " + var("QMAKE_RPATH"),
152 " " + var("QMAKE_RPATH"), "");
153 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue( "QMAKE_LIBDIR", "-L", " -L", "" );
154 }
155 if ( project->isActiveConfig("qtopia") ) {
156 if(configs.findIndex("qtopialib") == -1)
157 configs.append("qtopialib");
158 if(configs.findIndex("qtopiainc") == -1)
159 configs.append("qtopiainc");
160 }
161 if ( project->isActiveConfig("qtopiainc") )
162 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QTOPIA"];
163 if ( project->isActiveConfig("qtopialib") ) {
164 if(!project->isEmpty("QMAKE_LIBDIR_QTOPIA"))
165 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QTOPIA", "-L", " -L", "");
166 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QTOPIA"];
167 }
168 if ( project->isActiveConfig("qt") ) {
169 if ( project->isActiveConfig("accessibility" ) )
170 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_ACCESSIBILITY_SUPPORT");
171 if ( project->isActiveConfig("tablet") )
172 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_TABLET_SUPPORT");
173 if(configs.findIndex("moc")) configs.append("moc");
174 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_QT"];
175 if ( !project->isActiveConfig("debug") )
176 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_NO_DEBUG");
177 if ( !is_qt ) {
178 if ( !project->isEmpty("QMAKE_RPATH") ) {
179 if ( !project->isEmpty("QMAKE_RTLDIR_QT") )
180 project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_RTLDIR_QT", " " + var("QMAKE_RPATH"),
181 " " + var("QMAKE_RPATH"), "");
182 else if ( !project->isEmpty("QMAKE_LIBDIR_QT") )
183 project->variables()["QMAKE_LFLAGS"] += varGlue("QMAKE_LIBDIR_QT", " " + var("QMAKE_RPATH"),
184 " " + var("QMAKE_RPATH"), "");
185 }
186 if ( !project->isEmpty("QMAKE_LIBDIR_QT") )
187 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_QT", "-L", " -L", "");
188 if ( project->isActiveConfig("thread") && !project->isEmpty("QMAKE_LIBS_QT_THREAD") )
189 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT_THREAD"];
190 else
191 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_QT"];
192 }
193 }
194 if ( project->isActiveConfig("opengl") && !project->isActiveConfig("dlopen_opengl")) {
195 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_OPENGL"];
196 if(!project->isEmpty("QMAKE_LIBDIR_OPENGL"))
197 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_OPENGL", "-L", " -L", "");
198 if ( is_qt )
199 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL_QT"];
200 else
201 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_OPENGL"];
202 }
203 if ( extern_libs && (project->isActiveConfig("qt") || project->isActiveConfig("opengl")) ) {
204 if(configs.findIndex("x11lib") == -1)
205 configs.append("x11lib");
206 if ( project->isActiveConfig("opengl") && configs.findIndex("x11inc") == -1 )
207 configs.append("x11inc");
208 }
209 if ( project->isActiveConfig("x11") ) {
210 if(configs.findIndex("x11lib") == -1)
211 configs.append("x11lib");
212 if(configs.findIndex("x11inc") == -1)
213 configs.append("x11inc");
214 }
215 if ( project->isActiveConfig("x11inc") )
216 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_X11"];
217 if ( project->isActiveConfig("x11lib") ) {
218 if(!project->isEmpty("QMAKE_LIBDIR_X11"))
219 project->variables()["QMAKE_LIBDIR_FLAGS"] += varGlue("QMAKE_LIBDIR_X11", "-L", " -L", "");
220 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11"];
221 }
222 if ( project->isActiveConfig("x11sm") )
223 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_X11SM"];
224 if ( project->isActiveConfig("dylib") )
225 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_DYNLOAD"];
226 if ( project->isActiveConfig("thread") ) {
227 if(project->isActiveConfig("qt"))
228 project->variables()[is_qt ? "PRL_EXPORT_DEFINES" : "DEFINES"].append("QT_THREAD_SUPPORT");
229 if ( !project->isEmpty("QMAKE_CFLAGS_THREAD")) {
230 project->variables()["QMAKE_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"];
231 project->variables()["PRL_EXPORT_CFLAGS"] += project->variables()["QMAKE_CFLAGS_THREAD"];
232 }
233 if( !project->isEmpty("QMAKE_CXXFLAGS_THREAD")) {
234 project->variables()["QMAKE_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"];
235 project->variables()["PRL_EXPORT_CXXFLAGS"] += project->variables()["QMAKE_CXXFLAGS_THREAD"];
236 }
237 project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR_THREAD"];
238 project->variables()["QMAKE_LIBS"] += project->variables()["QMAKE_LIBS_THREAD"];
239 if(!project->isEmpty("QMAKE_LFLAGS_THREAD"))
240 project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_THREAD"];
241 }
242 if ( project->isActiveConfig("moc") )
243 setMocAware(TRUE);
244 QString compile_flag = var("QMAKE_COMPILE_FLAG");
245 if(compile_flag.isEmpty())
246 compile_flag = "-c";
247 if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
248 QString prefix_flags = project->first("QMAKE_CFLAGS_PREFIX_INCLUDE");
249 if(prefix_flags.isEmpty())
250 prefix_flags = "-include";
251 compile_flag += " " + prefix_flags + " " + project->first("QMAKE_ORIG_TARGET");
252 }
253 if(!project->isEmpty("ALLMOC_HEADER")) {
254 initOutPaths(); // Need to fix outdirs since we do this before init() (because we could add to SOURCES et al)
255 QString allmoc = fileFixify(project->first("MOC_DIR") + "/allmoc.cpp", QDir::currentDirPath(), Option::output_dir);
256 project->variables()["SOURCES"].prepend(allmoc);
257 project->variables()["HEADERS_ORIG"] = project->variables()["HEADERS"];
258 project->variables()["HEADERS"].clear();
259 }
260 if ( project->isEmpty("QMAKE_RUN_CC") )
261 project->variables()["QMAKE_RUN_CC"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $obj $src");
262 if ( project->isEmpty("QMAKE_RUN_CC_IMP") )
263 project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $@ $<");
264 if ( project->isEmpty("QMAKE_RUN_CXX") )
265 project->variables()["QMAKE_RUN_CXX"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $obj $src");
266 if ( project->isEmpty("QMAKE_RUN_CXX_IMP") )
267 project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $@ $<");
268 project->variables()["QMAKE_FILETAGS"] += QStringList::split("HEADERS SOURCES TARGET DESTDIR", " ");
269 if( project->isActiveConfig("GNUmake") && !project->isEmpty("QMAKE_CFLAGS_DEPS"))
270 include_deps = TRUE; //do not generate deps
271 if(project->isActiveConfig("compile_libtool"))
272 Option::obj_ext = ".lo"; //override the .o
273
274 MakefileGenerator::init();
275 if ( project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
276 if(!project->isEmpty("QMAKE_APP_FLAG")) {
277 if(project->isEmpty("DESTDIR"))
278 project->values("DESTDIR").append("");
279 project->variables()["DESTDIR"].first() += project->variables()["TARGET"].first() +
280 ".app/Contents/MacOS/";
281 project->variables()["QMAKE_PKGINFO"].append(project->first("DESTDIR") + "../PkgInfo");
282 project->variables()["ALL_DEPS"] += project->first("QMAKE_PKGINFO");
283
284 QString plist = fileFixify(project->first("QMAKE_INFO_PLIST"));
285 if(plist.isEmpty())
286 plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE");
287 if(QFile::exists(Option::fixPathToLocalOS(plist))) {
288 if(project->isEmpty("QMAKE_INFO_PLIST"))
289 project->variables()["QMAKE_INFO_PLIST"].append(plist);
290 project->variables()["QMAKE_INFO_PLIST_OUT"].append(project->first("DESTDIR") +
291 "../Info.plist");
292 project->variables()["ALL_DEPS"] += project->first("QMAKE_INFO_PLIST_OUT");
293 if(!project->isEmpty("RC_FILE"))
294 project->variables()["ALL_DEPS"] += project->first("DESTDIR") +
295 "../Resources/application.icns";
296 }
297 }
298 }
299
300 if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES"))
301 project->variables()["DISTFILES"] += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"];
302 project->variables()["DISTFILES"] += Option::mkfile::project_files;
303
304 init2();
305 project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_LIBDIR_FLAGS" << "QMAKE_LIBS";
306 if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) {
307 bool ok;
308 int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(&ok);
309 QStringList ar_sublibs, objs = project->variables()["OBJECTS"] + project->variables()["OBJMOC"];
310 if(ok && max_files > 5 && max_files < (int)objs.count()) {
311 int obj_cnt = 0, lib_cnt = 0;
312 QString lib;
313 for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
314 if((++obj_cnt) >= max_files) {
315 if(lib_cnt) {
316 lib.sprintf("lib%s-tmp%d.a", project->first("QMAKE_ORIG_TARGET").latin1(), lib_cnt);
317 ar_sublibs << lib;
318 obj_cnt = 0;
319 }
320 lib_cnt++;
321 }
322 }
323 }
324 if(!ar_sublibs.isEmpty()) {
325 project->variables()["QMAKE_AR_SUBLIBS"] = ar_sublibs;
326 project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_AR_SUBLIBS";
327 }
328 }
329
330 if(project->isActiveConfig("compile_libtool")) {
331 const QString libtoolify[] = { "QMAKE_RUN_CC", "QMAKE_RUN_CC_IMP",
332 "QMAKE_RUN_CXX", "QMAKE_RUN_CXX_IMP",
333 "QMAKE_LINK_THREAD", "QMAKE_LINK", "QMAKE_AR_CMD", "QMAKE_LINK_SHLIB_CMD",
334 QString::null };
335 for(int i = 0; !libtoolify[i].isNull(); i++) {
336 QStringList &l = project->variables()[libtoolify[i]];
337 if(!l.isEmpty()) {
338 QString libtool_flags, comp_flags;
339 if(libtoolify[i].startsWith("QMAKE_LINK") || libtoolify[i] == "QMAKE_AR_CMD") {
340 libtool_flags += " --mode=link";
341 if(project->isActiveConfig("staticlib")) {
342 libtool_flags += " -static";
343 } else {
344 if(!project->isEmpty("QMAKE_LIB_FLAG")) {
345 int maj = project->first("VER_MAJ").toInt();
346 int min = project->first("VER_MIN").toInt();
347 int pat = project->first("VER_PAT").toInt();
348 comp_flags += " -version-info " + QString::number(10*maj + min) +
349 ":" + QString::number(pat) + ":0";
350 if(libtoolify[i] != "QMAKE_AR_CMD") {
351 QString rpath = Option::output_dir;
352 if(!project->isEmpty("DESTDIR")) {
353 rpath = project->first("DESTDIR");
354 if(QDir::isRelativePath(rpath))
355 rpath.prepend(Option::output_dir + Option::dir_sep);
356 }
357 comp_flags += " -rpath " + Option::fixPathToTargetOS(rpath, FALSE);
358 }
359 }
360 }
361 if(project->isActiveConfig("plugin"))
362 libtool_flags += " -module";
363 } else {
364 libtool_flags += " --mode=compile";
365 }
366 l.first().prepend("$(LIBTOOL)" + libtool_flags + " ");
367 if(!comp_flags.isEmpty())
368 l.first() += comp_flags;
369 }
370 }
371 }
372}
373
374QStringList
375UnixMakefileGenerator::combineSetLFlags(const QStringList &list1, const QStringList &list2)
376{
377 if(project->isActiveConfig("no_smart_library_merge"))
378 return list1 + list2;
379
380 QStringList ret;
381 for(int i = 0; i < 2; i++) {
382 const QStringList *lst = i ? &list2 : &list1;
383 for(QStringList::ConstIterator it = lst->begin(); it != lst->end(); ++it) {
384 if((*it).startsWith("-")) {
385 if((*it).startsWith("-L")) {
386 if(ret.findIndex((*it)) == -1)
387 ret.append((*it));
388 } else if((*it).startsWith("-l")) {
389 while(1) {
390 QStringList::Iterator idx = ret.find((*it));
391 if(idx == ret.end())
392 break;
393 ret.remove(idx);
394 }
395 ret.append((*it));
396 } else if(project->isActiveConfig("macx") && (*it).startsWith("-framework")) {
397 int as_one = TRUE;
398 QString framework_in;
399 if((*it).length() > 11) {
400 framework_in = (*it).mid(11);
401 } else {
402 if(it != lst->end()) {
403 ++it;
404 as_one = FALSE;
405 framework_in = (*it);
406 }
407 }
408 if(!framework_in.isEmpty()) {
409 for(QStringList::Iterator outit = ret.begin(); outit != ret.end(); ++outit) {
410 if((*outit).startsWith("-framework")) {
411 int found = 0;
412 if((*outit).length() > 11) {
413 if(framework_in == (*outit).mid(11))
414 found = 1;
415 } else {
416 if(it != lst->end()) {
417 ++outit;
418 if(framework_in == (*outit)) {
419 --outit;
420 found = 2;
421 }
422 }
423 }
424 for(int i = 0; i < found; i++)
425 outit = ret.remove(outit);
426 }
427 }
428 if(as_one) {
429 ret.append("-framework " + framework_in);
430 } else {
431 ret.append("-framework");
432 ret.append(framework_in);
433 }
434 }
435 } else {
436#if 1
437 while(1) {
438 QStringList::Iterator idx = ret.find((*it));
439 if(idx == ret.end())
440 break;
441 ret.remove(idx);
442 }
443#endif
444 ret.append((*it));
445 }
446 } else /*if(QFile::exists((*it)))*/ {
447 while(1) {
448 QStringList::Iterator idx = ret.find((*it));
449 if(idx == ret.end())
450 break;
451 ret.remove(idx);
452 }
453 ret.append((*it));
454 }
455 }
456 }
457 return ret;
458}
459
460void
461UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
462{
463 if(var == "QMAKE_PRL_LIBS")
464 project->variables()["QMAKE_CURRENT_PRL_LIBS"] = combineSetLFlags(project->variables()["QMAKE_CURRENT_PRL_LIBS"] +
465 project->variables()["QMAKE_LIBS"], l);
466 else
467 MakefileGenerator::processPrlVariable(var, l);
468}
469
470QString
471UnixMakefileGenerator::findDependency(const QString &dep)
472{
473 QStringList::Iterator it;
474 {
475 QStringList &qut = project->variables()["QMAKE_EXTRA_UNIX_TARGETS"];
476 for(it = qut.begin(); it != qut.end(); ++it) {
477 QString targ = var((*it) + ".target");
478 if(targ.isEmpty())
479 targ = (*it);
480 if(targ.endsWith(dep))
481 return targ;
482 }
483 }
484 {
485 QStringList &quc = project->variables()["QMAKE_EXTRA_UNIX_COMPILERS"];
486 for(it = quc.begin(); it != quc.end(); ++it) {
487 QString tmp_out = project->variables()[(*it) + ".output"].first();
488 QString tmp_cmd = project->variables()[(*it) + ".commands"].join(" ");
489 if(tmp_out.isEmpty() || tmp_cmd.isEmpty())
490 continue;
491 QStringList &tmp = project->variables()[(*it) + ".input"];
492 for(QStringList::Iterator it2 = tmp.begin(); it2 != tmp.end(); ++it2) {
493 QStringList &inputs = project->variables()[(*it2)];
494 for(QStringList::Iterator input = inputs.begin(); input != inputs.end(); ++input) {
495 QString out = tmp_out;
496 QFileInfo fi(Option::fixPathToLocalOS((*input)));
497 out.replace("${QMAKE_FILE_BASE}", fi.baseName());
498 out.replace("${QMAKE_FILE_NAME}", fi.fileName());
499 if(out.endsWith(dep))
500 return out;
501 }
502 }
503 }
504 }
505 return MakefileGenerator::findDependency(dep);
506}
507
508QStringList
509&UnixMakefileGenerator::findDependencies(const QString &file)
510{
511 QStringList &ret = MakefileGenerator::findDependencies(file);
512 // Note: The QMAKE_IMAGE_COLLECTION file have all images
513 // as dependency, so don't add precompiled header then
514 if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")
515 && file != project->first("QMAKE_IMAGE_COLLECTION")) {
516 QString header_prefix = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep;
517 header_prefix += project->first("QMAKE_PRECOMP_PREFIX");
518 if(file.endsWith(".c")) {
519 QString precomp_h = header_prefix + "c";
520 if(!ret.contains(precomp_h))
521 ret += precomp_h;
522 } else {
523 for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) {
524 if(file.endsWith(*it)) {
525 QString precomp_h = header_prefix + "c++";
526 if(!ret.contains(precomp_h))
527 ret += precomp_h;
528 break;
529 }
530 }
531 }
532 }
533 return ret;
534}
535
536bool
537UnixMakefileGenerator::findLibraries()
538{
539 QPtrList<MakefileDependDir> libdirs;
540 libdirs.setAutoDelete(TRUE);
541 const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null };
542 for(int i = 0; !lflags[i].isNull(); i++) {
543 QStringList &l = project->variables()[lflags[i]];
544 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
545 QString stub, dir, extn, opt = (*it).stripWhiteSpace();
546 if(opt.startsWith("-")) {
547 if(opt.startsWith("-L")) {
548 QString r = opt.right(opt.length() - 2), l = r;
549 fixEnvVariables(l);
550 libdirs.append(new MakefileDependDir(r.replace("\"",""),
551 l.replace("\"","")));
552 } else if(opt.startsWith("-l")) {
553 stub = opt.mid(2);
554 } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) {
555 if(opt.length() > 11) {
556 opt = opt.mid(11);
557 } else {
558 ++it;
559 opt = (*it);
560 }
561 extn = "";
562 dir = "/System/Library/Frameworks/" + opt + ".framework/";
563 stub = opt;
564 }
565 } else {
566 extn = dir = "";
567 stub = opt;
568 int slsh = opt.findRev(Option::dir_sep);
569 if(slsh != -1) {
570 dir = opt.left(slsh);
571 stub = opt.mid(slsh+1);
572 }
573 QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$");
574 if(stub_reg.exactMatch(stub)) {
575 stub = stub_reg.cap(1);
576 extn = stub_reg.cap(2);
577 }
578 }
579 if(!stub.isEmpty()) {
580 const QString modifs[] = { "", "-mt", QString::null };
581 for(int modif = 0; !modifs[modif].isNull(); modif++) {
582 bool found = FALSE;
583 QStringList extens;
584 if(!extn.isNull())
585 extens << extn;
586 else
587 extens << project->variables()["QMAKE_EXTENSION_SHLIB"].first() << "a";
588 for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) {
589 if(dir.isNull()) {
590 QString lib_stub;
591 for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
592 if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub +
593 modifs[modif] + "." + (*extit))) {
594 lib_stub = stub + modifs[modif];
595 break;
596 }
597 }
598 if(!lib_stub.isNull()) {
599 (*it) = "-l" + lib_stub;
600 found = TRUE;
601 break;
602 }
603 } else {
604 if(QFile::exists("lib" + stub + modifs[modif] + "." + (*extit))) {
605 (*it) = "lib" + stub + modifs[modif] + "." + (*extit);
606 found = TRUE;
607 break;
608 }
609 }
610 }
611 if(!found && project->isActiveConfig("compile_libtool")) {
612 for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
613 if(QFile::exists(mdd->local_dir + Option::dir_sep + "lib" + stub + modifs[modif] + Option::libtool_ext)) {
614 (*it) = mdd->real_dir + Option::dir_sep + "lib" + stub + modifs[modif] + Option::libtool_ext;
615 found = TRUE;
616 break;
617 }
618 }
619 }
620 if(found)
621 break;
622
623 }
624 }
625 }
626 }
627 return FALSE;
628}
629
630QString linkLib(const QString &file, const QString &libName) {
631 QString ret;
632 QRegExp reg("^.*lib(" + libName + "[^./=]*).*$");
633 if(reg.exactMatch(file))
634 ret = "-l" + reg.cap(1);
635 return ret;
636}
637
638void
639UnixMakefileGenerator::processPrlFiles()
640{
641 QDict<void> processed;
642 QPtrList<MakefileDependDir> libdirs;
643 libdirs.setAutoDelete(TRUE);
644 const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString::null };
645 for(int i = 0; !lflags[i].isNull(); i++) {
646 for(bool ret = FALSE; TRUE; ret = FALSE) {
647 QStringList l_out;
648 QStringList &l = project->variables()[lflags[i]];
649 for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
650 project->variables()["QMAKE_CURRENT_PRL_LIBS"].clear();
651 QString opt = (*it).stripWhiteSpace();
652 if(opt.startsWith("-")) {
653 if(opt.startsWith("-L")) {
654 QString r = opt.right(opt.length() - 2), l = r;
655 fixEnvVariables(l);
656 libdirs.append(new MakefileDependDir(r.replace("\"",""),
657 l.replace("\"","")));
658 } else if(opt.startsWith("-l") && !processed[opt]) {
659 QString lib = opt.right(opt.length() - 2);
660 for(MakefileDependDir *mdd = libdirs.first(); mdd; mdd = libdirs.next() ) {
661 if(!project->isActiveConfig("compile_libtool")) { //give them the .libs..
662 QString la = mdd->local_dir + Option::dir_sep + "lib" + lib + Option::libtool_ext;
663 if(QFile::exists(la) && QFile::exists(mdd->local_dir + Option::dir_sep + ".libs")) {
664 l_out.append("-L" + mdd->real_dir + Option::dir_sep + ".libs");
665 libdirs.append(new MakefileDependDir(mdd->real_dir + Option::dir_sep + ".libs",
666 mdd->local_dir + Option::dir_sep + ".libs"));
667 }
668 }
669
670 QString prl = mdd->local_dir + Option::dir_sep + "lib" + lib;
671 if(processPrlFile(prl)) {
672 if(prl.startsWith(mdd->local_dir))
673 prl.replace(0, mdd->local_dir.length(), mdd->real_dir);
674 opt = linkLib(prl, lib);
675 processed.insert(opt, (void*)1);
676 ret = TRUE;
677 break;
678 }
679 }
680 } else if(project->isActiveConfig("macx") && opt.startsWith("-framework")) {
681 if(opt.length() > 11) {
682 opt = opt.mid(11);
683 } else {
684 ++it;
685 opt = (*it);
686 }
687 QString prl = "/System/Library/Frameworks/" + opt +
688 ".framework/" + opt;
689 if(processPrlFile(prl))
690 ret = TRUE;
691 l_out.append("-framework");
692 }
693 if(!opt.isEmpty())
694 l_out.append(opt);
695 l_out = combineSetLFlags(l_out, project->variables()["QMAKE_CURRENT_PRL_LIBS"]);
696 } else {
697 QString lib = opt;
698 if(!processed[lib] && processPrlFile(lib)) {
699 processed.insert(lib, (void*)1);
700 ret = TRUE;
701 }
702#if 0
703 if(ret)
704 opt = linkLib(lib, "");
705#endif
706 if(!opt.isEmpty())
707 l_out.append(opt);
708 l_out = combineSetLFlags(l_out, project->variables()["QMAKE_CURRENT_PRL_LIBS"]);
709 }
710 }
711 if(ret && l != l_out)
712 l = l_out;
713 else
714 break;
715 }
716 }
717}
718
719QString
720UnixMakefileGenerator::defaultInstall(const QString &t)
721{
722 if(t != "target" || project->first("TEMPLATE") == "subdirs")
723 return QString();
724
725 bool resource = FALSE;
726 const QString root = "$(INSTALL_ROOT)";
727 QStringList &uninst = project->variables()[t + ".uninstall"];
728 QString ret, destdir=project->first("DESTDIR");
729 QString targetdir = Option::fixPathToTargetOS(project->first("target.path"), FALSE);
730 if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep)
731 destdir += Option::dir_sep;
732 targetdir = fileFixify(targetdir);
733 if(targetdir.right(1) != Option::dir_sep)
734 targetdir += Option::dir_sep;
735
736 QStringList links;
737 QString target="$(TARGET)";
738 if(project->first("TEMPLATE") == "app") {
739 target = "$(QMAKE_TARGET)";
740 if(project->isActiveConfig("resource_fork") && !project->isActiveConfig("console")) {
741 destdir += "../../../";
742 target += ".app";
743 resource = TRUE;
744 }
745 } else if(project->first("TEMPLATE") == "lib") {
746 if(project->isActiveConfig("create_prl") && !project->isActiveConfig("no_install_prl") &&
747 !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) {
748 QString dst_prl = project->first("QMAKE_INTERNAL_PRL_FILE");
749 int slsh = dst_prl.findRev('/');
750 if(slsh != -1)
751 dst_prl = dst_prl.right(dst_prl.length() - slsh - 1);
752 dst_prl = root + targetdir + dst_prl;
753 ret += "-$(INSTALL_FILE) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\"";
754 if(!uninst.isEmpty())
755 uninst.append("\n\t");
756 uninst.append("-$(DEL_FILE) \"" + dst_prl + "\"");
757 }
758 if(project->isActiveConfig("create_libtool") && !project->isActiveConfig("compile_libtool")) {
759 QString src_lt = var("QMAKE_ORIG_TARGET");
760 int slsh = src_lt.findRev(Option::dir_sep);
761 if(slsh != -1)
762 src_lt = src_lt.right(src_lt.length() - slsh);
763 int dot = src_lt.find('.');
764 if(dot != -1)
765 src_lt = src_lt.left(dot);
766 src_lt += Option::libtool_ext;
767 src_lt.prepend("lib");
768 QString dst_lt = root + targetdir + src_lt;
769 if(!project->isEmpty("DESTDIR")) {
770 src_lt.prepend(var("DESTDIR"));
771 src_lt = Option::fixPathToLocalOS(fileFixify(src_lt,
772 QDir::currentDirPath(), Option::output_dir));
773 }
774 if(!ret.isEmpty())
775 ret += "\n\t";
776 ret += "-$(INSTALL_FILE) \"" + src_lt + "\" \"" + dst_lt + "\"";
777 if(!uninst.isEmpty())
778 uninst.append("\n\t");
779 uninst.append("-$(DEL_FILE) \"" + dst_lt + "\"");
780 }
781 if(project->isActiveConfig("create_pc")) {
782 QString src_pc = var("QMAKE_ORIG_TARGET");
783 int slsh = src_pc.findRev(Option::dir_sep);
784 if(slsh != -1)
785 src_pc = src_pc.right(src_pc.length() - slsh);
786 int dot = src_pc.find('.');
787 if(dot != -1)
788 src_pc = src_pc.left(dot);
789 src_pc += ".pc";
790 QString d = root + targetdir + "pkgconfig" + Option::dir_sep;
791 QString dst_pc = d + src_pc;
792 if(!project->isEmpty("DESTDIR")) {
793 src_pc.prepend(var("DESTDIR"));
794 src_pc = Option::fixPathToLocalOS(fileFixify(src_pc,
795 QDir::currentDirPath(), Option::output_dir));
796 }
797 if(!ret.isEmpty())
798 ret += "\n\t";
799 ret += mkdir_p_asstring(d) + "\n\t";
800 ret += "-$(INSTALL_FILE) \"" + src_pc + "\" \"" + dst_pc + "\"";
801 if(!uninst.isEmpty())
802 uninst.append("\n\t");
803 uninst.append("-$(DEL_FILE) \"" + dst_pc + "\"");
804 }
805 if ( project->isEmpty("QMAKE_CYGWIN_SHLIB") ) {
806 if ( !project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") ) {
807 if ( project->isEmpty("QMAKE_HPUX_SHLIB") ) {
808 links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)";
809 } else {
810 links << "$(TARGET0)";
811 }
812 }
813 }
814 }
815
816 if(!resource && project->isActiveConfig("compile_libtool")) {
817 QString src_targ = target;
818 if(src_targ == "$(TARGET)")
819 src_targ = "$(TARGETL)";
820 QString dst_dir = fileFixify(targetdir);
821 if(QDir::isRelativePath(dst_dir))
822 dst_dir = Option::fixPathToTargetOS(Option::output_dir + Option::dir_sep + dst_dir);
823 ret = "-$(LIBTOOL) --mode=install cp \"" + src_targ + "\" \"" + root + dst_dir + "\"";
824 uninst.append("-$(LIBTOOL) --mode=uninstall \"" + src_targ + "\"");
825 } else {
826 QString src_targ = target;
827 if(!destdir.isEmpty())
828 src_targ = Option::fixPathToTargetOS(destdir + target, FALSE);
829 QString dst_targ = root + fileFixify(targetdir + target);
830 if(!ret.isEmpty())
831 ret += "\n\t";
832 if(resource)
833 ret += "$(DEL_FILE) -r \"" + dst_targ + "\"" + "\n\t";
834 if(!ret.isEmpty())
835 ret += "\n\t";
836 ret += QString(resource ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" +
837 src_targ + "\" \"" + dst_targ + "\"";
838 if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP") &&
839 (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("staticlib"))) {
840 ret += "\n\t-" + var("QMAKE_STRIP");
841 if(project->first("TEMPLATE") == "lib" && !project->isEmpty("QMAKE_STRIPFLAGS_LIB"))
842 ret += " " + var("QMAKE_STRIPFLAGS_LIB");
843 else if(project->first("TEMPLATE") == "app" && !project->isEmpty("QMAKE_STRIPFLAGS_APP"))
844 ret += " " + var("QMAKE_STRIPFLAGS_APP");
845 if(resource)
846 ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\"";
847 else
848 ret += " \"" + dst_targ + "\"";
849 }
850 if(!uninst.isEmpty())
851 uninst.append("\n\t");
852 if(resource)
853 uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\"");
854 else
855 uninst.append("-$(DEL_FILE) \"" + dst_targ + "\"");
856 if(!links.isEmpty()) {
857 for(QStringList::Iterator it = links.begin(); it != links.end(); it++) {
858 if(Option::target_mode == Option::TARG_WIN_MODE ||
859 Option::target_mode == Option::TARG_OS2_MODE ||
860 Option::target_mode == Option::TARG_MAC9_MODE) {
861 } else if(Option::target_mode == Option::TARG_UNIX_MODE ||
862 Option::target_mode == Option::TARG_MACX_MODE) {
863 QString link = Option::fixPathToTargetOS(destdir + (*it), FALSE);
864 int lslash = link.findRev(Option::dir_sep);
865 if(lslash != -1)
866 link = link.right(link.length() - (lslash + 1));
867 QString dst_link = root + fileFixify(targetdir + link);
868 ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\"";
869 if(!uninst.isEmpty())
870 uninst.append("\n\t");
871 uninst.append("-$(DEL_FILE) \"" + dst_link + "\"");
872 }
873 }
874 }
875 }
876 return ret;
877}
Note: See TracBrowser for help on using the repository browser.