1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the qmake application of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 or version 3 as published by the Free
20 ** Software Foundation and appearing in the file LICENSE.LGPLv21 and
21 ** LICENSE.LGPLv3 included in the packaging of this file. Please review the
22 ** following information to ensure the GNU Lesser General Public License
23 ** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
24 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
25 **
26 ** As a special exception, The Qt Company gives you certain additional
27 ** rights. These rights are described in The Qt Company LGPL Exception
28 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 **
30 ** GNU General Public License Usage
31 ** Alternatively, this file may be used under the terms of the GNU
32 ** General Public License version 3.0 as published by the Free Software
33 ** Foundation and appearing in the file LICENSE.GPL included in the
34 ** packaging of this file.  Please review the following information to
35 ** ensure the GNU General Public License version 3.0 requirements will be
36 ** met: http://www.gnu.org/copyleft/gpl.html.
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "unixmake.h"
43 #include "option.h"
44 #include "meta.h"
45 #include <qregexp.h>
46 #include <qbytearray.h>
47 #include <qfile.h>
48 #include <qdir.h>
49 #include <qdatetime.h>
50 #include <qdebug.h>
51 #include <time.h>
52 
53 QT_BEGIN_NAMESPACE
54 
UnixMakefileGenerator()55 UnixMakefileGenerator::UnixMakefileGenerator() : MakefileGenerator(), init_flag(false), include_deps(false)
56 {
57 
58 }
59 
60 void
writePrlFile(QTextStream & t)61 UnixMakefileGenerator::writePrlFile(QTextStream &t)
62 {
63     MakefileGenerator::writePrlFile(t);
64     // libtool support
65 
66     if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib") { //write .la
67         if(project->isActiveConfig("compile_libtool"))
68             warn_msg(WarnLogic, "create_libtool specified with compile_libtool can lead to conflicting .la\n"
69                      "formats, create_libtool has been disabled\n");
70         else
71             writeLibtoolFile();
72     }
73     // pkg-config support
74     if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib")
75         writePkgConfigFile();
76 }
77 
78 bool
writeMakefile(QTextStream & t)79 UnixMakefileGenerator::writeMakefile(QTextStream &t)
80 {
81 
82     writeHeader(t);
83     if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) {
84         t << "QMAKE    = " << var("QMAKE_QMAKE") << endl;
85         QStringList &qut = project->values("QMAKE_EXTRA_TARGETS");
86         for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it)
87             t << *it << " ";
88         t << "first all clean install distclean uninstall qmake_all:" << "\n\t"
89           << "@echo \"Some of the required modules ("
90           << var("QMAKE_FAILED_REQUIREMENTS") << ") are not available.\"" << "\n\t"
91           << "@echo \"Skipped.\"" << endl << endl;
92         writeMakeQmake(t);
93         if(project->isEmpty("QMAKE_NOFORCE"))
94             t << "FORCE:" << endl << endl;
95         return true;
96     }
97 
98     if (project->values("TEMPLATE").first() == "app" ||
99         project->values("TEMPLATE").first() == "lib" ||
100         project->values("TEMPLATE").first() == "aux") {
101         if(Option::mkfile::do_stub_makefile && MakefileGenerator::writeStubMakefile(t))
102             return true;
103         writeMakeParts(t);
104         return MakefileGenerator::writeMakefile(t);
105     } else if(project->values("TEMPLATE").first() == "subdirs") {
106         MakefileGenerator::writeSubDirs(t);
107         return true;
108     }
109     return false;
110 }
111 
112 void
writeMakeParts(QTextStream & t)113 UnixMakefileGenerator::writeMakeParts(QTextStream &t)
114 {
115     QString deps = fileFixify(Option::output.fileName()), target_deps, prl;
116     bool do_incremental = (project->isActiveConfig("incremental") &&
117                            !project->values("QMAKE_INCREMENTAL").isEmpty() &&
118                            (!project->values("QMAKE_APP_FLAG").isEmpty() ||
119                             (!project->isActiveConfig("staticlib")))),
120          src_incremental=false;
121 
122     t << "####### Compiler, tools and options" << endl << endl;
123     t << "CC            = " << var("QMAKE_CC") << endl;
124     t << "CXX           = " << var("QMAKE_CXX") << endl;
125     t << "DEFINES       = "
126       << varGlue("PRL_EXPORT_DEFINES","-D"," -D"," ")
127       << varGlue("DEFINES","-D"," -D","") << endl;
128     t << "CFLAGS        = " << var("QMAKE_CFLAGS") << " $(DEFINES)" << endl;
129     t << "CXXFLAGS      = " << var("QMAKE_CXXFLAGS") << " $(DEFINES)" << endl;
130     t << "INCPATH       = " << "-I" << specdir();
131     if(!project->isActiveConfig("no_include_pwd")) {
132         QString pwd = escapeFilePath(fileFixify(qmake_getpwd()));
133         if(pwd.isEmpty())
134             pwd = ".";
135         t << " -I" << pwd;
136     }
137     {
138         const QStringList &incs = project->values("INCLUDEPATH");
139         for(int i = 0; i < incs.size(); ++i) {
140             QString inc = escapeFilePath(incs.at(i));
141             if(!inc.isEmpty())
142                 t << " " << "-I" << inc;
143         }
144     }
145     if(!project->isEmpty("QMAKE_FRAMEWORKPATH_FLAGS"))
146        t << " " << var("QMAKE_FRAMEWORKPATH_FLAGS");
147     t << endl;
148 
149     if(!project->isActiveConfig("staticlib")) {
150         t << "LINK          = " << var("QMAKE_LINK") << endl;
151         t << "LFLAGS        = " << var("QMAKE_LFLAGS") << endl;
152         t << "LIBS          = " << "$(SUBLIBS) " << var("QMAKE_FRAMEWORKPATH_FLAGS") << " "
153           << var("QMAKE_LIBDIR_FLAGS") << " " << var("QMAKE_LIBS") << " " << var("QMAKE_LIBS_PRIVATE") << endl;
154     }
155 
156     t << "AR            = " << var("QMAKE_AR") << endl;
157     t << "RANLIB        = " << var("QMAKE_RANLIB") << endl;
158     t << "QMAKE         = " << var("QMAKE_QMAKE") << endl;
159     t << "TAR           = " << var("QMAKE_TAR") << endl;
160     t << "COMPRESS      = " << var("QMAKE_GZIP") << endl;
161     if(project->isActiveConfig("compile_libtool"))
162         t << "LIBTOOL       = " << var("QMAKE_LIBTOOL") << endl;
163     t << "COPY          = " << var("QMAKE_COPY") << endl;
164     t << "SED           = " << var("QMAKE_STREAM_EDITOR") << endl;
165     t << "COPY_FILE     = " << var("QMAKE_COPY_FILE") << endl;
166     t << "COPY_DIR      = " << var("QMAKE_COPY_DIR") << endl;
167     t << "STRIP         = " << var("QMAKE_STRIP") << endl;
168     t << "INSTALL_FILE  = " << var("QMAKE_INSTALL_FILE") << endl;
169     t << "INSTALL_DIR   = " << var("QMAKE_INSTALL_DIR") << endl;
170     t << "INSTALL_PROGRAM = " << var("QMAKE_INSTALL_PROGRAM") << endl;
171 
172     t << "DEL_FILE      = " << var("QMAKE_DEL_FILE") << endl;
173     t << "SYMLINK       = " << var("QMAKE_SYMBOLIC_LINK") << endl;
174     t << "DEL_DIR       = " << var("QMAKE_DEL_DIR") << endl;
175     t << "MOVE          = " << var("QMAKE_MOVE") << endl;
176     t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl;
177     t << "MKDIR         = " << var("QMAKE_MKDIR") << endl;
178     if(!project->isEmpty("QMAKE_MACOSX_DEPLOYMENT_TARGET"))
179         t << "export MACOSX_DEPLOYMENT_TARGET = " //exported to children processes
180           << project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET") << endl;
181 
182     if(!project->isEmpty("QMAKE_IPHONEOS_DEPLOYMENT_TARGET"))
183         t << "export IPHONEOS_DEPLOYMENT_TARGET = " //exported to children processes
184 		<< project->first("QMAKE_IPHONEOS_DEPLOYMENT_TARGET") << endl;
185 
186     if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) {
187         t << "vpath %.dso " << project->values("QMAKE_LIBDIR").join(":") << endl;
188         t << "vpath %.lib " << project->values("QMAKE_LIBDIR").join(":") << endl;
189     }
190 
191     t << endl;
192 
193     t << "####### Output directory" << endl << endl;
194     if (! project->values("OBJECTS_DIR").isEmpty())
195         t << "OBJECTS_DIR   = " << var("OBJECTS_DIR") << endl;
196     else
197         t << "OBJECTS_DIR   = ./" << endl;
198     t << endl;
199 
200     /* files */
201     t << "####### Files" << endl << endl;
202     t << "SOURCES       = " << valList(escapeFilePaths(project->values("SOURCES"))) << " "
203       << valList(escapeFilePaths(project->values("GENERATED_SOURCES"))) << endl;
204     if(do_incremental) {
205         QStringList &objs = project->values("OBJECTS"), &incrs = project->values("QMAKE_INCREMENTAL"), incrs_out;
206         t << "OBJECTS       = ";
207         for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
208             bool increment = false;
209             for(QStringList::Iterator incrit = incrs.begin(); incrit != incrs.end(); ++incrit) {
210                 if((*objit).indexOf(QRegExp((*incrit), Qt::CaseSensitive,
211                                     QRegExp::Wildcard)) != -1) {
212                     increment = true;
213                     incrs_out.append((*objit));
214                     break;
215                 }
216             }
217             if(!increment)
218                 t << "\\\n\t\t" << (*objit);
219         }
220         if(incrs_out.count() == objs.count()) { //we just switched places, no real incrementals to be done!
221             t << escapeFilePaths(incrs_out).join(" \\\n\t\t") << endl;
222         } else if(!incrs_out.count()) {
223             t << endl;
224         } else {
225             src_incremental = true;
226             t << endl;
227             t << "INCREMENTAL_OBJECTS = " << escapeFilePaths(incrs_out).join(" \\\n\t\t") << endl;
228         }
229     } else {
230         t << "OBJECTS       = " << valList(escapeFilePaths(project->values("OBJECTS"))) << endl;
231     }
232     if(do_incremental && !src_incremental)
233         do_incremental = false;
234     t << "DIST          = " << valList(fileFixify(project->values("DISTFILES"))) << endl;
235     t << "QMAKE_TARGET  = " << var("QMAKE_ORIG_TARGET") << endl;
236     t << "DESTDIR       = " << var("DESTDIR") << endl;
237     if(project->isActiveConfig("compile_libtool"))
238         t << "TARGETL       = " << var("TARGET_la") << endl;
239     t << "TARGET        = " << escapeFilePath(var("TARGET")) << endl;
240     if(project->isActiveConfig("plugin")) {
241         t << "TARGETD       = " << escapeFilePath(var("TARGET")) << endl;
242     } else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty()) {
243         t << "TARGETA       = " << escapeFilePath(var("TARGETA")) << endl;
244         if(!project->isEmpty("QMAKE_BUNDLE")) {
245             t << "TARGETD       = " << escapeFilePath(var("TARGET_x.y")) << endl;
246             t << "TARGET0       = " << escapeFilePath(var("TARGET_")) << endl;
247         } else if(!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) {
248             t << "TARGETD       = " << escapeFilePath(var("TARGET")) << endl;
249         } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) {
250             t << "TARGETD       = " << escapeFilePath(var("TARGET_x.y.z")) << endl;
251             t << "TARGET0       = " << escapeFilePath(var("TARGET_")) << endl;
252             t << "TARGET1       = " << escapeFilePath(var("TARGET_x")) << endl;
253             t << "TARGET2       = " << escapeFilePath(var("TARGET_x.y")) << endl;
254         } else {
255             t << "TARGETD       = " << escapeFilePath(var("TARGET_x")) << endl;
256             t << "TARGET0       = " << escapeFilePath(var("TARGET_")) << endl;
257         }
258     }
259     writeExtraCompilerVariables(t);
260     writeExtraVariables(t);
261     t << endl;
262 
263     // blasted includes
264     QStringList &qeui = project->values("QMAKE_EXTRA_INCLUDES");
265     QStringList::Iterator it;
266     for(it = qeui.begin(); it != qeui.end(); ++it)
267         t << "include " << (*it) << endl;
268 
269     /* rules */
270     t << "first: all" << endl;
271     t << "####### Implicit rules" << endl << endl;
272     t << ".SUFFIXES: " << Option::obj_ext;
273     for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit)
274         t << " " << (*cit);
275     for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit)
276         t << " " << (*cppit);
277     t << endl << endl;
278     for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit)
279         t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl;
280     for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit)
281         t << (*cit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl;
282 
283     if(include_deps) {
284         QString cmd=var("QMAKE_CFLAGS_DEPS") + " ";
285         cmd += varGlue("DEFINES","-D"," -D","") + varGlue("PRL_EXPORT_DEFINES"," -D"," -D","");
286         if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH"))
287             cmd += " -I" + project->first("QMAKE_ABSOLUTE_SOURCE_PATH") + " ";
288         cmd += " $(INCPATH) " + varGlue("DEPENDPATH", "-I", " -I", "");
289         QString odir;
290         if(!project->values("OBJECTS_DIR").isEmpty())
291             odir = project->first("OBJECTS_DIR");
292         t << "###### Dependencies" << endl << endl;
293         t << odir << ".deps/%.d: %.cpp\n\t";
294         if(project->isActiveConfig("echo_depend_creation"))
295             t << "@echo Creating depend for $<" << "\n\t";
296         t << mkdir_p_asstring("$(@D)") << "\n\t"
297           << "@$(CXX) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl;
298 
299         t << odir << ".deps/%.d: %.c\n\t";
300         if(project->isActiveConfig("echo_depend_creation"))
301             t << "@echo Creating depend for $<" << "\n\t";
302         t << mkdir_p_asstring("$(@D)") << "\n\t"
303           << "@$(CC) " << cmd << " $< | sed \"s,^\\($(*F).o\\):," << odir << "\\1:,g\" >$@" << endl << endl;
304 
305         QString src[] = { "SOURCES", "GENERATED_SOURCES", QString() };
306         for(int x = 0; !src[x].isNull(); x++) {
307             QStringList &l = project->values(src[x]);
308             for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
309                 if(!(*it).isEmpty()) {
310                     QString d_file;
311                     for(QStringList::Iterator cit = Option::c_ext.begin();
312                         cit != Option::c_ext.end(); ++cit) {
313                         if((*it).endsWith((*cit))) {
314                             d_file = (*it).left((*it).length() - (*cit).length());
315                             break;
316                         }
317                     }
318                     if(d_file.isEmpty()) {
319                         for(QStringList::Iterator cppit = Option::cpp_ext.begin();
320                             cppit != Option::cpp_ext.end(); ++cppit) {
321                             if((*it).endsWith((*cppit))) {
322                                 d_file = (*it).left((*it).length() - (*cppit).length());
323                                 break;
324                             }
325                         }
326                     }
327                     if(!d_file.isEmpty()) {
328                         d_file = odir + ".deps/" + d_file + ".d";
329                         QStringList deps = findDependencies((*it)).filter(QRegExp(Option::cpp_moc_ext + "$"));
330                         if(!deps.isEmpty())
331                             t << d_file << ": " << deps.join(" ") << endl;
332                         t << "-include " << d_file << endl;
333                         project->values("QMAKE_DISTCLEAN") += d_file;
334                     }
335                 }
336             }
337         }
338     }
339 
340     t << "####### Build rules" << endl << endl;
341     if(!project->values("SUBLIBS").isEmpty()) {
342         QString libdir = "tmp/";
343         if(!project->isEmpty("SUBLIBS_DIR"))
344             libdir = project->first("SUBLIBS_DIR");
345         t << "SUBLIBS       = ";
346         QStringList &l = project->values("SUBLIBS");
347         for(QStringList::Iterator it = l.begin(); it != l.end(); ++it)
348             t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "."
349               << project->first("QMAKE_EXTENSION_STATICLIB") << " ";
350         t << endl << endl;
351     }
352     if(project->isActiveConfig("depend_prl") && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) {
353         QStringList &l = project->values("QMAKE_PRL_INTERNAL_FILES");
354         QStringList::Iterator it;
355         for(it = l.begin(); it != l.end(); ++it) {
356             QMakeMetaInfo libinfo;
357             if(libinfo.readLib((*it)) && !libinfo.isEmpty("QMAKE_PRL_BUILD_DIR")) {
358                 QString dir;
359                 int slsh = (*it).lastIndexOf(Option::dir_sep);
360                 if(slsh != -1)
361                     dir = (*it).left(slsh + 1);
362                 QString targ = dir + libinfo.first("QMAKE_PRL_TARGET");
363                 target_deps += " " + targ;
364                 t << targ << ":" << "\n\t"
365                   << "@echo \"Creating '" << targ << "'\"" << "\n\t"
366                   << "(cd " << libinfo.first("QMAKE_PRL_BUILD_DIR") << ";"
367                   << "$(MAKE))" << endl;
368             }
369         }
370     }
371     if(!project->values("QMAKE_APP_FLAG").isEmpty()) {
372         QString destdir = project->first("DESTDIR");
373         if(!project->isEmpty("QMAKE_BUNDLE")) {
374             QString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION");
375             if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/"))
376                 bundle_loc.prepend("/");
377             if(!bundle_loc.endsWith("/"))
378                 bundle_loc += "/";
379             destdir += project->first("QMAKE_BUNDLE") + bundle_loc;
380         }
381         if(do_incremental) {
382             //incremental target
383             QString incr_target = var("TARGET") + "_incremental";
384             if(incr_target.indexOf(Option::dir_sep) != -1)
385                 incr_target = incr_target.right(incr_target.length() -
386                                                 (incr_target.lastIndexOf(Option::dir_sep) + 1));
387             QString incr_deps, incr_objs;
388             if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
389                 QString incr_target_dir = var("OBJECTS_DIR") + incr_target + Option::obj_ext;
390                 //actual target
391                 t << incr_target_dir << ": $(OBJECTS)" << "\n\t"
392                   << "ld -r  -o "<< incr_target_dir << " $(OBJECTS)" << endl;
393                 //communicated below
394                 deps.prepend(incr_target_dir + " ");
395                 incr_deps = "$(INCREMENTAL_OBJECTS)";
396                 if(!incr_objs.isEmpty())
397                     incr_objs += " ";
398                 incr_objs += incr_target_dir;
399             } else {
400                 //actual target
401                 QString incr_target_dir = var("DESTDIR") + "lib" + incr_target + "." +
402                                           project->values("QMAKE_EXTENSION_SHLIB").first();
403                 QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
404                 if(project->isActiveConfig("debug"))
405                     incr_lflags += var("QMAKE_LFLAGS_DEBUG");
406                 else
407                     incr_lflags += var("QMAKE_LFLAGS_RELEASE");
408                 t << incr_target_dir << ": $(INCREMENTAL_OBJECTS)" << "\n\t";
409                 if(!destdir.isEmpty())
410                     t << "\n\t" << mkdir_p_asstring(destdir) << "\n\t";
411                 t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir <<
412                     " $(INCREMENTAL_OBJECTS)" << endl;
413                 //communicated below
414                 if(!destdir.isEmpty()) {
415                     if(!incr_objs.isEmpty())
416                         incr_objs += " ";
417                     incr_objs += "-L" + destdir;
418                 } else {
419                     if(!incr_objs.isEmpty())
420                         incr_objs += " ";
421                     incr_objs += "-L" + qmake_getpwd();
422                 }
423                 if(!incr_objs.isEmpty())
424                     incr_objs += " ";
425                 incr_objs += " -l" + incr_target;
426                 deps.prepend(incr_target_dir + " ");
427                 incr_deps = "$(OBJECTS)";
428             }
429             t << "all: " << escapeDependencyPath(deps) <<  " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ") <<  "$(TARGET)"
430               << endl << endl;
431 
432             //real target
433             t << var("TARGET") << ": " << var("PRE_TARGETDEPS") << " " << incr_deps << " " << target_deps
434               << " " << var("POST_TARGETDEPS") << "\n\t";
435             if(!destdir.isEmpty())
436                 t << "\n\t" << mkdir_p_asstring(destdir) << "\n\t";
437             if(!project->isEmpty("QMAKE_PRE_LINK"))
438                 t << var("QMAKE_PRE_LINK") << "\n\t";
439             t << "$(LINK) $(LFLAGS) -o $(TARGET) " << incr_deps << " " << incr_objs << " $(OBJCOMP) $(LIBS)";
440             if(!project->isEmpty("QMAKE_POST_LINK"))
441                 t << "\n\t" << var("QMAKE_POST_LINK");
442             t << endl << endl;
443         } else {
444             t << "all: " << escapeDependencyPath(deps) <<  " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ") <<  "$(TARGET)"
445               << endl << endl;
446 
447             t << "$(TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) "
448               << target_deps << " " << var("POST_TARGETDEPS") << "\n\t";
449             if(!destdir.isEmpty())
450                 t << mkdir_p_asstring(destdir) << "\n\t";
451             if(!project->isEmpty("QMAKE_PRE_LINK"))
452                 t << var("QMAKE_PRE_LINK") << "\n\t";
453             t << "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(OBJCOMP) $(LIBS)";
454             if(!project->isEmpty("QMAKE_POST_LINK"))
455                 t << "\n\t" << var("QMAKE_POST_LINK");
456             t << endl << endl;
457         }
458     } else if(!project->isActiveConfig("staticlib")) {
459         QString destdir = unescapeFilePath(project->first("DESTDIR")), incr_deps;
460         if(!project->isEmpty("QMAKE_BUNDLE")) {
461             QString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION");
462             if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/"))
463                 bundle_loc.prepend("/");
464             if(!bundle_loc.endsWith("/"))
465                 bundle_loc += "/";
466             destdir += project->first("QMAKE_BUNDLE") + bundle_loc;
467         }
468         destdir = escapeFilePath(destdir);
469 
470         if(do_incremental) {
471             QString s_ext = project->values("QMAKE_EXTENSION_SHLIB").first();
472             QString incr_target = var("QMAKE_ORIG_TARGET").replace(
473                 QRegExp("\\." + s_ext), "").replace(QRegExp("^lib"), "") + "_incremental";
474             if(incr_target.indexOf(Option::dir_sep) != -1)
475                 incr_target = incr_target.right(incr_target.length() -
476                                                 (incr_target.lastIndexOf(Option::dir_sep) + 1));
477             incr_target = escapeFilePath(incr_target);
478 
479             if(project->first("QMAKE_INCREMENTAL_STYLE") == "ld") {
480                 QString incr_target_dir = escapeFilePath(var("OBJECTS_DIR") + incr_target + Option::obj_ext);
481                 //actual target
482                 const QString link_deps = "$(OBJECTS) ";
483                 t << incr_target_dir << ": " << link_deps << "\n\t"
484                   << "ld -r  -o " << incr_target_dir << " " << link_deps << endl;
485                 //communicated below
486                 QStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD");
487                 cmd.first().replace("$(OBJECTS) ", "$(INCREMENTAL_OBJECTS)"); //ick
488                 cmd.append(incr_target_dir);
489                 deps.prepend(incr_target_dir + " ");
490                 incr_deps = "$(INCREMENTAL_OBJECTS)";
491             } else {
492                 //actual target
493                 QString incr_target_dir = escapeFilePath(destdir + "lib" + incr_target + "." + s_ext);
494                 QString incr_lflags = var("QMAKE_LFLAGS_SHLIB") + " ";
495                 if(!project->isEmpty("QMAKE_LFLAGS_INCREMENTAL"))
496                     incr_lflags += var("QMAKE_LFLAGS_INCREMENTAL") + " ";
497                 if(project->isActiveConfig("debug"))
498                     incr_lflags += var("QMAKE_LFLAGS_DEBUG");
499                 else
500                     incr_lflags += var("QMAKE_LFLAGS_RELEASE");
501                 t << incr_target_dir << ": $(INCREMENTAL_OBJECTS)" << "\n\t";
502                 if(!destdir.isEmpty())
503                     t << mkdir_p_asstring(destdir) << "\n\t";
504                 t << "$(LINK) " << incr_lflags << " -o "<< incr_target_dir <<
505                     " $(INCREMENTAL_OBJECTS)" << endl;
506                 //communicated below
507                 QStringList &cmd = project->values("QMAKE_LINK_SHLIB_CMD");
508                 if(!destdir.isEmpty())
509                     cmd.append(" -L" + destdir);
510                 cmd.append(" -l" + incr_target);
511                 deps.prepend(incr_target_dir + " ");
512                 incr_deps = "$(OBJECTS)";
513             }
514 
515             t << "all: " << " " << escapeDependencyPath(deps) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ")
516               << " " << destdir << "$(TARGET)" << endl << endl;
517 
518             //real target
519             t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS") << " "
520               << incr_deps << " $(SUBLIBS) " << target_deps << " " << var("POST_TARGETDEPS");
521         } else {
522             t << "all: " << escapeDependencyPath(deps) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ") << " " <<
523                 destdir << "$(TARGET)" << endl << endl;
524             t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS")
525               << " $(OBJECTS) $(SUBLIBS) $(OBJCOMP) " << target_deps
526               << " " << var("POST_TARGETDEPS");
527         }
528         if(!destdir.isEmpty())
529             t << "\n\t" << mkdir_p_asstring(destdir);
530         if(!project->isEmpty("QMAKE_PRE_LINK"))
531             t << "\n\t" << var("QMAKE_PRE_LINK");
532 
533         if(project->isActiveConfig("compile_libtool")) {
534             t << "\n\t"
535               << var("QMAKE_LINK_SHLIB_CMD");
536         } else if(project->isActiveConfig("plugin")) {
537             t << "\n\t"
538               << "-$(DEL_FILE) $(TARGET)" << "\n\t"
539               << var("QMAKE_LINK_SHLIB_CMD");
540             if(!destdir.isEmpty())
541                 t << "\n\t"
542                   << "-$(MOVE) $(TARGET) " << destdir;
543             if(!project->isEmpty("QMAKE_POST_LINK"))
544                 t << "\n\t" << var("QMAKE_POST_LINK");
545             t << endl << endl;
546         } else if(!project->isEmpty("QMAKE_BUNDLE")) {
547             t << "\n\t"
548               << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(DESTDIR)$(TARGET0)" << "\n\t"
549               << var("QMAKE_LINK_SHLIB_CMD") << "\n\t"
550               << mkdir_p_asstring("\"`dirname $(DESTDIR)$(TARGETD)`\"", false) << "\n\t"
551               << "-$(MOVE) $(TARGET) $(DESTDIR)$(TARGETD)" << "\n\t"
552               << mkdir_p_asstring("\"`dirname $(DESTDIR)$(TARGET0)`\"", false) << "\n\t"
553               << varGlue("QMAKE_LN_SHLIB","-"," "," Versions/" +
554                          project->first("QMAKE_FRAMEWORK_VERSION") +
555                          "/$(TARGET) $(DESTDIR)$(TARGET0)") << "\n\t"
556               << "-$(DEL_FILE) " << destdir << "Versions/Current" << "\n\t"
557               << varGlue("QMAKE_LN_SHLIB","-"," ", " " + project->first("QMAKE_FRAMEWORK_VERSION") +
558                          " " + destdir + "Versions/Current") << "\n\t";
559             if(!project->isEmpty("QMAKE_POST_LINK"))
560                 t << "\n\t" << var("QMAKE_POST_LINK");
561             t << endl << endl;
562         } else if(!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) {
563             t << "\n\t"
564               << "-$(DEL_FILE) $(TARGET)" << "\n\t"
565               << var("QMAKE_LINK_SHLIB_CMD");
566             if(!destdir.isEmpty())
567                 t << "\n\t"
568                   << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
569                   << "-$(MOVE) $(TARGET) " << destdir;
570             if(!project->isEmpty("QMAKE_POST_LINK"))
571                 t << "\n\t" << var("QMAKE_POST_LINK");
572             t << endl << endl;
573         } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) {
574             t << "\n\t"
575               << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t"
576               << var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
577             t << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET0)")  << "\n\t"
578               << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET1)") << "\n\t"
579               << varGlue("QMAKE_LN_SHLIB","-"," "," $(TARGET) $(TARGET2)");
580             if(!destdir.isEmpty())
581                 t << "\n\t"
582                   << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
583                   << "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t"
584                   << "-$(DEL_FILE) " << destdir << "$(TARGET1)\n\t"
585                   << "-$(DEL_FILE) " << destdir << "$(TARGET2)\n\t"
586                   << "-$(MOVE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2) " << destdir;
587             if(!project->isEmpty("QMAKE_POST_LINK"))
588                 t << "\n\t" << var("QMAKE_POST_LINK");
589             t << endl << endl;
590         } else {
591             t << "\n\t"
592               << "-$(DEL_FILE) $(TARGET) $(TARGET0)" << "\n\t"
593               << var("QMAKE_LINK_SHLIB_CMD") << "\n\t";
594             t << varGlue("QMAKE_LN_SHLIB",""," "," $(TARGET) $(TARGET0)");
595             if(!destdir.isEmpty())
596                 t  << "\n\t"
597                    << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t"
598                    << "-$(DEL_FILE) " << destdir << "$(TARGET0)\n\t"
599                    << "-$(MOVE) $(TARGET) $(TARGET0) " << destdir;
600             if(!project->isEmpty("QMAKE_POST_LINK"))
601                 t << "\n\t" << var("QMAKE_POST_LINK");
602             t << endl << endl;
603         }
604         t << endl << endl;
605 
606         if (! project->isActiveConfig("plugin")) {
607             t << "staticlib: $(TARGETA)" << endl << endl;
608             t << "$(TARGETA): " << var("PRE_TARGETDEPS") << " $(OBJECTS) $(OBJCOMP)";
609             if(do_incremental)
610                 t << " $(INCREMENTAL_OBJECTS)";
611             t << " " << var("POST_TARGETDEPS") << "\n\t"
612               << "-$(DEL_FILE) $(TARGETA) " << "\n\t"
613               << var("QMAKE_AR_CMD");
614             if(do_incremental)
615                 t << " $(INCREMENTAL_OBJECTS)";
616             if(!project->isEmpty("QMAKE_RANLIB"))
617                 t << "\n\t" << "$(RANLIB) $(TARGETA)";
618             t << endl << endl;
619         }
620     } else {
621         QString destdir = project->first("DESTDIR");
622         t << "all: " << escapeDependencyPath(deps) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS")),""," "," ") << destdir << "$(TARGET) "
623           << varGlue("QMAKE_AR_SUBLIBS", destdir, " " + destdir, "") << "\n\n"
624           << "staticlib: " << destdir << "$(TARGET)" << "\n\n";
625         if(project->isEmpty("QMAKE_AR_SUBLIBS")) {
626             t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS")
627               << " $(OBJECTS) $(OBJCOMP) " << var("POST_TARGETDEPS") << "\n\t";
628             if(!destdir.isEmpty())
629                 t << mkdir_p_asstring(destdir) << "\n\t";
630             t << "-$(DEL_FILE) $(TARGET)" << "\n\t"
631               << var("QMAKE_AR_CMD") << "\n";
632             if(!project->isEmpty("QMAKE_POST_LINK"))
633                 t << "\t" << var("QMAKE_POST_LINK") << "\n";
634             if(!project->isEmpty("QMAKE_RANLIB"))
635                 t << "\t" << "$(RANLIB) $(TARGET)" << "\n";
636             if(!destdir.isEmpty())
637                 t << "\t" << "-$(DEL_FILE) " << destdir << "$(TARGET)" << "\n"
638                   << "\t" << "-$(MOVE) $(TARGET) " << destdir << "\n";
639         } else {
640             int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt();
641             QStringList objs = project->values("OBJECTS") + project->values("OBJCOMP"),
642                         libs = project->values("QMAKE_AR_SUBLIBS");
643             libs.prepend("$(TARGET)");
644             for(QStringList::Iterator libit = libs.begin(), objit = objs.begin();
645                 libit != libs.end(); ++libit) {
646                 QStringList build;
647                 for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++)
648                     build << (*objit);
649                 QString ar;
650                 if((*libit) == "$(TARGET)") {
651                     t << destdir << "$(TARGET): " << var("PRE_TARGETDEPS")
652                       << " " << var("POST_TARGETDEPS") << valList(build) << "\n\t";
653                     ar = project->values("QMAKE_AR_CMD").first();
654                     ar = ar.replace("$(OBJECTS)", build.join(" "));
655                 } else {
656                     t << (*libit) << ": " << valList(build) << "\n\t";
657                     ar = "$(AR) " + (*libit) + " " + build.join(" ");
658                 }
659                 if(!destdir.isEmpty())
660                     t << mkdir_p_asstring(destdir) << "\n\t";
661                 t << "-$(DEL_FILE) " << (*libit) << "\n\t"
662                   << ar << "\n";
663                 if(!project->isEmpty("QMAKE_POST_LINK"))
664                     t << "\t" << var("QMAKE_POST_LINK") << "\n";
665                 if(!project->isEmpty("QMAKE_RANLIB"))
666                     t << "\t" << "$(RANLIB) " << (*libit) << "\n";
667                 if(!destdir.isEmpty())
668                     t << "\t" << "-$(DEL_FILE) " << destdir << (*libit) << "\n"
669                       << "\t" << "-$(MOVE) " << (*libit) << " " << destdir << "\n";
670             }
671         }
672         t << endl << endl;
673     }
674 
675     writeMakeQmake(t);
676     if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake")) {
677         QString meta_files;
678         if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib" &&
679            !project->isActiveConfig("compile_libtool")) { //libtool
680             if(!meta_files.isEmpty())
681                 meta_files += " ";
682             meta_files += libtoolFileName();
683         }
684         if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") { //pkg-config
685             if(!meta_files.isEmpty())
686                 meta_files += " ";
687             meta_files += pkgConfigFileName();
688         }
689         if(!meta_files.isEmpty())
690             t << escapeDependencyPath(meta_files) << ": " << "\n\t"
691               << "@$(QMAKE) -prl " << buildArgs() << " " << project->projectFile() << endl;
692     }
693 
694     if(!project->first("QMAKE_PKGINFO").isEmpty()) {
695         QString pkginfo = escapeFilePath(project->first("QMAKE_PKGINFO"));
696         QString destdir = escapeFilePath(project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents");
697         t << pkginfo << ": " << "\n\t";
698         if(!destdir.isEmpty())
699             t << mkdir_p_asstring(destdir) << "\n\t";
700         t << "@$(DEL_FILE) " << pkginfo << "\n\t"
701           << "@echo \"APPL"
702           << (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4))
703           << "\" >" << pkginfo << endl;
704     }
705     if(!project->first("QMAKE_BUNDLE_RESOURCE_FILE").isEmpty()) {
706         QString resources = escapeFilePath(project->first("QMAKE_BUNDLE_RESOURCE_FILE"));
707         QString destdir = escapeFilePath(project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents/Resources");
708         t << resources << ": " << "\n\t";
709         t << mkdir_p_asstring(destdir) << "\n\t";
710         t << "@touch " << resources << "\n\t" << endl;
711     }
712     if(!project->isEmpty("QMAKE_BUNDLE")) {
713         //copy the plist
714         QString info_plist = escapeFilePath(fileFixify(project->first("QMAKE_INFO_PLIST"))),
715             info_plist_out = escapeFilePath(project->first("QMAKE_INFO_PLIST_OUT"));
716         QString destdir = info_plist_out.section(Option::dir_sep, 0, -2);
717         t << info_plist_out << ": " << "\n\t";
718         if(!destdir.isEmpty())
719             t << mkdir_p_asstring(destdir) << "\n\t";
720         QStringList commonSedArgs;
721         if (!project->values("VERSION").isEmpty())
722             commonSedArgs << "-e \"s,@SHORT_VERSION@," << project->first("VER_MAJ") << "." << project->first("VER_MIN") << ",g\" ";
723         commonSedArgs << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
724                    QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" ";
725         if(project->first("TEMPLATE") == "app") {
726             QString icon = fileFixify(var("ICON"));
727             t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
728               << "@sed ";
729             foreach (const QString &arg, commonSedArgs)
730                 t << arg;
731             t << "-e \"s,@ICON@," << icon.section(Option::dir_sep, -1) << ",g\" "
732               << "-e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") << ",g\" "
733               << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
734                          QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "
735               << "" << info_plist << " >" << info_plist_out << endl;
736             //copy the icon
737             if(!project->isEmpty("ICON")) {
738                 QString dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/Contents/Resources/";
739                 const QString icon_path = escapeFilePath(dir + icon.section(Option::dir_sep, -1));
740                 t << icon_path << ": " << icon << "\n\t"
741                   << mkdir_p_asstring(dir) << "\n\t"
742                   << "@$(DEL_FILE) " << icon_path << "\n\t"
743                   << "@$(COPY_FILE) " << escapeFilePath(icon) << " " << icon_path << endl;
744             }
745         } else {
746             t << "@$(DEL_FILE) " << info_plist_out << "\n\t"
747               << "@sed ";
748             foreach (const QString &arg, commonSedArgs)
749                 t << arg;
750             t << "-e \"s,@LIBRARY@," << var("QMAKE_ORIG_TARGET") << ",g\" "
751               << "-e \"s,@TYPEINFO@,"
752               << (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ?
753                   QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" "
754               << "" << info_plist << " >" << info_plist_out << endl;
755         }
756         //copy other data
757         if(!project->isEmpty("QMAKE_BUNDLE_DATA")) {
758             QString bundle_dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/";
759             const QStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA");
760             for(int i = 0; i < bundle_data.count(); i++) {
761                 const QStringList &files = project->values(bundle_data[i] + ".files");
762                 QString path = bundle_dir;
763                 if(!project->isEmpty(bundle_data[i] + ".version")) {
764                     QString version = project->first(bundle_data[i] + ".version") + "/" +
765                                       project->first("QMAKE_FRAMEWORK_VERSION") + "/";
766                     t << Option::fixPathToLocalOS(path + project->first(bundle_data[i] + ".path")) << ": " << "\n\t"
767                       << mkdir_p_asstring(path) << "\n\t"
768                       << "@$(SYMLINK) " << version << project->first(bundle_data[i] + ".path") << " " << path << endl;
769                     path += version;
770                 }
771                 path += project->first(bundle_data[i] + ".path");
772                 path = Option::fixPathToLocalOS(path);
773                 for(int file = 0; file < files.count(); file++) {
774                     QString src = fileFixify(files[file], FileFixifyAbsolute);
775                     if (!QFile::exists(src))
776                         src = files[file];
777                     src = escapeFilePath(src);
778                     const QString dst = escapeFilePath(path + Option::dir_sep + fileInfo(files[file]).fileName());
779                     t << dst << ": " << src << "\n\t"
780                       << mkdir_p_asstring(path) << "\n\t";
781                     QFileInfo fi(fileInfo(files[file]));
782                     if(fi.isDir())
783                         t << "@$(DEL_FILE) -r " << dst << "\n\t"
784                           << "@$(COPY_DIR) " << src << " " << dst << endl;
785                     else
786                         t << "@$(DEL_FILE) " << dst << "\n\t"
787                           << "@$(COPY_FILE) " << src << " " << dst << endl;
788                 }
789             }
790         }
791     }
792 
793     QString ddir;
794     QString packageName(project->first("QMAKE_ORIG_TARGET"));
795     if(!project->isActiveConfig("no_dist_version"))
796         packageName += var("VERSION");
797     if (project->isEmpty("QMAKE_DISTDIR"))
798         ddir = packageName;
799     else
800         ddir = project->first("QMAKE_DISTDIR");
801 
802     QString ddir_c = escapeFilePath(fileFixify((project->isEmpty("OBJECTS_DIR") ? QString(".tmp/") :
803                                                 project->first("OBJECTS_DIR")) + ddir,
804                                                Option::output_dir, Option::output_dir));
805     t << "dist: " << "\n\t"
806       << mkdir_p_asstring(ddir_c) << "\n\t"
807       << "$(COPY_FILE) --parents $(SOURCES) $(DIST) " << ddir_c << Option::dir_sep << " && ";
808     if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) {
809         const QStringList &quc = project->values("QMAKE_EXTRA_COMPILERS");
810         for(QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) {
811             const QStringList &var = project->values((*it)+".input");
812             for(QStringList::ConstIterator var_it = var.begin(); var_it != var.end(); ++var_it) {
813                 const QStringList &val = project->values((*var_it));
814                 if(val.isEmpty())
815                     continue;
816                 t << "$(COPY_FILE) --parents " << val.join(" ") << " " << ddir_c << Option::dir_sep << " && ";
817             }
818         }
819     }
820     if(!project->isEmpty("TRANSLATIONS"))
821         t << "$(COPY_FILE) --parents " << var("TRANSLATIONS") << " " << ddir_c << Option::dir_sep << " && ";
822     t << "(cd `dirname " << ddir_c << "` && "
823       << "$(TAR) " << packageName << ".tar " << ddir << " && "
824       << "$(COMPRESS) " << packageName << ".tar) && "
825       << "$(MOVE) `dirname " << ddir_c << "`" << Option::dir_sep << packageName << ".tar.gz . && "
826       << "$(DEL_FILE) -r " << ddir_c
827       << endl << endl;
828 
829     t << endl;
830 
831     QString clean_targets = "compiler_clean " + var("CLEAN_DEPS");
832     if(do_incremental) {
833         t << "incrclean:" << "\n";
834         if(src_incremental)
835             t << "\t-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n";
836         t << endl;
837     }
838 
839     t << "clean:" << clean_targets << "\n\t";
840     if(!project->isEmpty("OBJECTS")) {
841         if(project->isActiveConfig("compile_libtool"))
842             t << "-$(LIBTOOL) --mode=clean $(DEL_FILE) $(OBJECTS)" << "\n\t";
843         else
844             t << "-$(DEL_FILE) $(OBJECTS)" << "\n\t";
845     }
846     if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
847         QStringList precomp_files;
848         QString precomph_out_dir;
849 
850         if(!project->isEmpty("PRECOMPILED_DIR"))
851             precomph_out_dir = project->first("PRECOMPILED_DIR");
852         precomph_out_dir += project->first("QMAKE_ORIG_TARGET");
853         if (!project->isActiveConfig("clang_pch_style"))
854             precomph_out_dir += project->first("QMAKE_PCH_OUTPUT_EXT");
855 
856         if (project->isActiveConfig("icc_pch_style")) {
857             // icc style
858             QString pchBaseName = project->first("QMAKE_ORIG_TARGET");
859             QString pchOutput;
860             if(!project->isEmpty("PRECOMPILED_DIR"))
861                 pchOutput = project->first("PRECOMPILED_DIR");
862             pchOutput += pchBaseName + project->first("QMAKE_PCH_OUTPUT_EXT");
863             QString sourceFile = pchOutput + Option::cpp_ext.first();
864             QString objectFile = createObjectList(QStringList(sourceFile)).first();
865 
866             precomp_files << precomph_out_dir << sourceFile << objectFile;
867         } else {
868             // gcc style (including clang_pch_style)
869             precomph_out_dir += Option::dir_sep;
870 
871             QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX");
872             QString header_suffix = project->isActiveConfig("clang_pch_style")
873                                ? project->first("QMAKE_PCH_OUTPUT_EXT") : "";
874 
875             if(!project->isEmpty("QMAKE_CFLAGS_PRECOMPILE"))
876                 precomp_files += precomph_out_dir + header_prefix + "c" + header_suffix;
877             if(!project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE"))
878                 precomp_files += precomph_out_dir + header_prefix + "c++" + header_suffix;
879             if(project->isActiveConfig("objective_c")) {
880                 if(!project->isEmpty("QMAKE_OBJCFLAGS_PRECOMPILE"))
881                     precomp_files += precomph_out_dir + header_prefix + "objective-c" + header_suffix;
882                 if(!project->isEmpty("QMAKE_OBJCXXFLAGS_PRECOMPILE"))
883                     precomp_files += precomph_out_dir + header_prefix + "objective-c++" + header_suffix;
884             }
885         }
886         t << "-$(DEL_FILE) " << precomp_files.join(" ") << "\n\t";
887     }
888     if(!project->isEmpty("IMAGES"))
889         t << varGlue("QMAKE_IMAGE_COLLECTION", "\t-$(DEL_FILE) ", " ", "") << "\n\t";
890     if(src_incremental)
891         t << "-$(DEL_FILE) $(INCREMENTAL_OBJECTS)" << "\n\t";
892     t << varGlue("QMAKE_CLEAN","-$(DEL_FILE) "," ","\n\t")
893       << "-$(DEL_FILE) *~ core *.core" << "\n"
894       << varGlue("CLEAN_FILES","\t-$(DEL_FILE) "," ","") << endl << endl;
895     t << "####### Sub-libraries" << endl << endl;
896     if (!project->values("SUBLIBS").isEmpty()) {
897         QString libdir = "tmp/";
898         if(!project->isEmpty("SUBLIBS_DIR"))
899             libdir = project->first("SUBLIBS_DIR");
900         QStringList &l = project->values("SUBLIBS");
901         for(it = l.begin(); it != l.end(); ++it)
902             t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "."
903               << project->first("QMAKE_EXTENSION_STATICLIB") << ":\n\t"
904               << var(QString("MAKELIB") + (*it)) << endl << endl;
905     }
906 
907     QString destdir = project->first("DESTDIR");
908     if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep)
909         destdir += Option::dir_sep;
910     t << "distclean: " << "clean\n";
911     if(!project->isEmpty("QMAKE_BUNDLE")) {
912         QString bundlePath = escapeFilePath(destdir + project->first("QMAKE_BUNDLE"));
913         t << "\t-$(DEL_FILE) -r " << bundlePath << endl;
914     } else if(project->isActiveConfig("compile_libtool")) {
915         t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) " << "$(TARGET)" << endl;
916     } else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty() &&
917        !project->isActiveConfig("plugin")) {
918         t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << endl;
919         if (project->values("QMAKE_SYMBIAN_SHLIB").isEmpty())
920             t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) "
921               << destdir << "$(TARGET2) $(TARGETA)" << endl;
922     } else {
923         t << "\t-$(DEL_FILE) " << "$(TARGET)" << " " << endl;
924     }
925     t << varGlue("QMAKE_DISTCLEAN","\t-$(DEL_FILE) "," ","\n");
926     {
927         QString ofile = Option::fixPathToTargetOS(fileFixify(Option::output.fileName()));
928         if(!ofile.isEmpty())
929             t << "\t-$(DEL_FILE) " << ofile << endl;
930     }
931     t << endl << endl;
932 
933     if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
934         QString pchInput = project->first("PRECOMPILED_HEADER");
935         t << "###### Prefix headers" << endl;
936         QString comps[] = { "C", "CXX", "OBJC", "OBJCXX", QString() };
937         for(int i = 0; !comps[i].isNull(); i++) {
938             QString pchFlags = var("QMAKE_" + comps[i] + "FLAGS_PRECOMPILE");
939             if(pchFlags.isEmpty())
940                 continue;
941 
942             QString cflags;
943             if(comps[i] == "OBJC" || comps[i] == "OBJCXX")
944                 cflags += " $(CFLAGS)";
945             else
946                 cflags += " $(" + comps[i] + "FLAGS)";
947 
948             QString pchBaseName = project->first("QMAKE_ORIG_TARGET");
949             QString pchOutput;
950             if(!project->isEmpty("PRECOMPILED_DIR"))
951                 pchOutput = project->first("PRECOMPILED_DIR");
952             pchOutput += pchBaseName;
953             if (!project->isActiveConfig("clang_pch_style"))
954                 pchOutput += project->first("QMAKE_PCH_OUTPUT_EXT");
955 
956             if (project->isActiveConfig("icc_pch_style")) {
957                 // icc style
958                 QString sourceFile = pchOutput + Option::cpp_ext.first();
959                 QString objectFile = createObjectList(QStringList(sourceFile)).first();
960                 t << pchOutput << ": " << pchInput << " " << findDependencies(pchInput).join(" \\\n\t\t")
961                   << "\n\techo \"// Automatically generated, do not modify\" > " << sourceFile
962                   << "\n\trm -f " << pchOutput;
963 
964                 pchFlags = pchFlags.replace("${QMAKE_PCH_TEMP_SOURCE}", sourceFile)
965                            .replace("${QMAKE_PCH_TEMP_OBJECT}", objectFile);
966             } else {
967                 // gcc style (including clang_pch_style)
968                 QString header_prefix = project->first("QMAKE_PRECOMP_PREFIX");
969                 QString header_suffix = project->isActiveConfig("clang_pch_style")
970                                   ? project->first("QMAKE_PCH_OUTPUT_EXT") : "";
971                 pchOutput += Option::dir_sep;
972                 QString pchOutputDir = pchOutput, pchOutputFile;
973 
974                 if(comps[i] == "C") {
975                     pchOutputFile = "c";
976                 } else if(comps[i] == "CXX") {
977                     pchOutputFile = "c++";
978                 } else if(project->isActiveConfig("objective_c")) {
979                     if(comps[i] == "OBJC")
980                         pchOutputFile = "objective-c";
981                     else if(comps[i] == "OBJCXX")
982                         pchOutputFile = "objective-c++";
983                 }
984                 if(pchOutputFile.isEmpty())
985                     continue;
986                 pchOutput += header_prefix + pchOutputFile + header_suffix;
987 
988                 t << pchOutput << ": " << pchInput << " " << findDependencies(pchInput).join(" \\\n\t\t")
989                   << "\n\t" << mkdir_p_asstring(pchOutputDir);
990             }
991             pchFlags = pchFlags.replace("${QMAKE_PCH_INPUT}", pchInput)
992                        .replace("${QMAKE_PCH_OUTPUT_BASE}", pchBaseName)
993                        .replace("${QMAKE_PCH_OUTPUT}", pchOutput);
994 
995             QString compiler;
996             if(comps[i] == "C" || comps[i] == "OBJC" || comps[i] == "OBJCXX")
997                 compiler = "$(CC)";
998             else
999                 compiler = "$(CXX)";
1000 
1001             // compile command
1002             t << "\n\t" << compiler << cflags << " $(INCPATH) " << pchFlags << endl << endl;
1003         }
1004     }
1005 
1006     writeExtraTargets(t);
1007     writeExtraCompilerTargets(t);
1008 }
1009 
init2()1010 void UnixMakefileGenerator::init2()
1011 {
1012     //version handling
1013     if(project->isEmpty("VERSION"))
1014         project->values("VERSION").append("1.0." +
1015                                                (project->isEmpty("VER_PAT") ? QString("0") :
1016                                                 project->first("VER_PAT")));
1017     QStringList l = project->first("VERSION").split('.');
1018     l << "0" << "0"; //make sure there are three
1019     project->values("VER_MAJ").append(l[0]);
1020     project->values("VER_MIN").append(l[1]);
1021     project->values("VER_PAT").append(l[2]);
1022     if(project->isEmpty("QMAKE_FRAMEWORK_VERSION"))
1023         project->values("QMAKE_FRAMEWORK_VERSION").append(project->values("VER_MAJ").first());
1024 
1025     if (project->values("TEMPLATE").first() == "aux")
1026         return;
1027 
1028     if (!project->values("QMAKE_APP_FLAG").isEmpty()) {
1029         if(!project->isEmpty("QMAKE_BUNDLE")) {
1030             QString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION");
1031             if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/"))
1032                 bundle_loc.prepend("/");
1033             if(!bundle_loc.endsWith("/"))
1034                 bundle_loc += "/";
1035             project->values("TARGET").first().prepend(project->first("QMAKE_BUNDLE") + bundle_loc);
1036         }
1037         if(!project->isEmpty("TARGET"))
1038             project->values("TARGET").first().prepend(project->first("DESTDIR"));
1039        if (!project->values("QMAKE_CYGWIN_EXE").isEmpty())
1040             project->values("TARGET_EXT").append(".exe");
1041     } else if (project->isActiveConfig("staticlib")) {
1042         project->values("TARGET").first().prepend(project->first("QMAKE_PREFIX_STATICLIB"));
1043         project->values("TARGET").first() += "." + project->first("QMAKE_EXTENSION_STATICLIB");
1044         if(project->values("QMAKE_AR_CMD").isEmpty())
1045             project->values("QMAKE_AR_CMD").append("$(AR) $(TARGET) $(OBJECTS)");
1046     } else {
1047         project->values("TARGETA").append(project->first("DESTDIR") + project->first("QMAKE_PREFIX_STATICLIB")
1048                 + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_STATICLIB"));
1049         if(project->isActiveConfig("compile_libtool"))
1050             project->values("TARGET_la") = QStringList(project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext);
1051 
1052         if (!project->values("QMAKE_AR_CMD").isEmpty())
1053             project->values("QMAKE_AR_CMD").first().replace("(TARGET)","(TARGETA)");
1054         else
1055             project->values("QMAKE_AR_CMD").append("$(AR) $(TARGETA) $(OBJECTS)");
1056         if(project->isActiveConfig("compile_libtool")) {
1057             project->values("TARGET") = project->values("TARGET_la");
1058         } else if(!project->isEmpty("QMAKE_BUNDLE")) {
1059             QString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION");
1060             if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/"))
1061                 bundle_loc.prepend("/");
1062             if(!bundle_loc.endsWith("/"))
1063                 bundle_loc += "/";
1064             project->values("TARGET_").append(project->first("QMAKE_BUNDLE") +
1065                                                    bundle_loc + unescapeFilePath(project->first("TARGET")));
1066             project->values("TARGET_x.y").append(project->first("QMAKE_BUNDLE") +
1067                                                       "/Versions/" +
1068                                                       project->first("QMAKE_FRAMEWORK_VERSION") +
1069                                                       bundle_loc + unescapeFilePath(project->first("TARGET")));
1070         } else if(project->isActiveConfig("plugin")) {
1071             QString prefix;
1072             if(!project->isActiveConfig("no_plugin_name_prefix"))
1073                 prefix = "lib";
1074             project->values("TARGET_x.y.z").append(prefix +
1075                                                         project->first("TARGET") + "." +
1076                                                         project->first("QMAKE_EXTENSION_PLUGIN"));
1077             if(project->isActiveConfig("lib_version_first"))
1078                 project->values("TARGET_x").append(prefix + project->first("TARGET") + "." +
1079                                                         project->first("VER_MAJ") + "." +
1080                                                         project->first("QMAKE_EXTENSION_PLUGIN"));
1081             else
1082                 project->values("TARGET_x").append(prefix + project->first("TARGET") + "." +
1083                                                         project->first("QMAKE_EXTENSION_PLUGIN") +
1084                                                         "." + project->first("VER_MAJ"));
1085             project->values("TARGET") = project->values("TARGET_x.y.z");
1086         } else if (!project->isEmpty("QMAKE_HPUX_SHLIB")) {
1087             project->values("TARGET_").append("lib" + project->first("TARGET") + ".sl");
1088             if(project->isActiveConfig("lib_version_first"))
1089                 project->values("TARGET_x").append("lib" + project->first("VER_MAJ") + "." +
1090                                                         project->first("TARGET"));
1091             else
1092                 project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
1093                                                         project->first("VER_MAJ"));
1094             project->values("TARGET") = project->values("TARGET_x");
1095         } else if (!project->isEmpty("QMAKE_AIX_SHLIB")) {
1096             project->values("TARGET_").append(project->first("QMAKE_PREFIX_STATICLIB") + project->first("TARGET")
1097                     + "." + project->first("QMAKE_EXTENSION_STATICLIB"));
1098             if(project->isActiveConfig("lib_version_first")) {
1099                 project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
1100                                                         project->first("VER_MAJ") + "." +
1101                                                         project->first("QMAKE_EXTENSION_SHLIB"));
1102                 project->values("TARGET_x.y").append("lib" + project->first("TARGET") + "." +
1103                                                           project->first("VER_MAJ") +
1104                                                           "." + project->first("VER_MIN") + "." +
1105                                                           project->first("QMAKE_EXTENSION_SHLIB"));
1106                 project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") + "." +
1107                                                             project->first("VER_MAJ") + "." +
1108                                                             project->first("VER_MIN") + "." +
1109                                                             project->first("VER_PAT") + "." +
1110                                                             project->first("QMAKE_EXTENSION_SHLIB"));
1111             } else {
1112                 project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
1113                                                         project->first("QMAKE_EXTENSION_SHLIB") +
1114                                                         "." + project->first("VER_MAJ"));
1115                 project->values("TARGET_x.y").append("lib" + project->first("TARGET") + "." +
1116                                                           project->first("QMAKE_EXTENSION_SHLIB") +
1117                                                           "." + project->first("VER_MAJ") +
1118                                                           "." + project->first("VER_MIN"));
1119                 project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") + "." +
1120                                                             project->first("QMAKE_EXTENSION_SHLIB") + "." +
1121                                                             project->first("VER_MAJ") + "." +
1122                                                             project->first("VER_MIN") + "." +
1123                                                             project->first("VER_PAT"));
1124             }
1125             project->values("TARGET") = project->values("TARGET_x.y.z");
1126         } else if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) {
1127             project->values("TARGET_").append(project->first("TARGET") + "." +
1128                                                    project->first("QMAKE_EXTENSION_SHLIB"));
1129             project->values("TARGET") = project->values("TARGET_");
1130         } else {
1131             project->values("TARGET_").append("lib" + project->first("TARGET") + "." +
1132                                                    project->first("QMAKE_EXTENSION_SHLIB"));
1133             if(project->isActiveConfig("lib_version_first")) {
1134                 project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
1135                                                         project->first("VER_MAJ") + "." +
1136                                                         project->first("QMAKE_EXTENSION_SHLIB"));
1137                 project->values("TARGET_x.y").append("lib" + project->first("TARGET") + "." +
1138                                                           project->first("VER_MAJ") +
1139                                                           "." + project->first("VER_MIN") + "." +
1140                                                           project->first("QMAKE_EXTENSION_SHLIB"));
1141                 project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") + "." +
1142                                                             project->first("VER_MAJ") + "." +
1143                                                             project->first("VER_MIN") +  "." +
1144                                                             project->first("VER_PAT") + "." +
1145                                                             project->values("QMAKE_EXTENSION_SHLIB").first());
1146             } else {
1147                 project->values("TARGET_x").append("lib" + project->first("TARGET") + "." +
1148                                                         project->first("QMAKE_EXTENSION_SHLIB") +
1149                                                         "." + project->first("VER_MAJ"));
1150                 project->values("TARGET_x.y").append("lib" + project->first("TARGET") + "." +
1151                                                       project->first("QMAKE_EXTENSION_SHLIB")
1152                                                       + "." + project->first("VER_MAJ") +
1153                                                       "." + project->first("VER_MIN"));
1154                 project->values("TARGET_x.y.z").append("lib" + project->first("TARGET") +
1155                                                             "." +
1156                                                             project->values(
1157                                                                 "QMAKE_EXTENSION_SHLIB").first() + "." +
1158                                                             project->first("VER_MAJ") + "." +
1159                                                             project->first("VER_MIN") +  "." +
1160                                                             project->first("VER_PAT"));
1161             }
1162             project->values("TARGET") = project->values("TARGET_x.y.z");
1163         }
1164         if(project->isEmpty("QMAKE_LN_SHLIB"))
1165             project->values("QMAKE_LN_SHLIB").append("ln -s");
1166         if (!project->values("QMAKE_LFLAGS_SONAME").isEmpty()) {
1167             QString soname;
1168             if(project->isActiveConfig("plugin")) {
1169                 if(!project->values("TARGET").isEmpty())
1170                     soname += project->first("TARGET");
1171             } else if(!project->isEmpty("QMAKE_BUNDLE")) {
1172                 soname += project->first("TARGET_x.y");
1173             } else if(!project->values("TARGET_x").isEmpty()) {
1174                 soname += project->first("TARGET_x");
1175             }
1176             if(!soname.isEmpty()) {
1177                 if(project->isActiveConfig("absolute_library_soname") &&
1178                    project->values("INSTALLS").indexOf("target") != -1 &&
1179                    !project->isEmpty("target.path")) {
1180                     QString instpath = Option::fixPathToTargetOS(project->first("target.path"));
1181                     if(!instpath.endsWith(Option::dir_sep))
1182                         instpath += Option::dir_sep;
1183                     soname.prepend(instpath);
1184                 }
1185                 project->values("QMAKE_LFLAGS_SONAME").first() += escapeFilePath(soname);
1186             }
1187         }
1188         if (project->values("QMAKE_LINK_SHLIB_CMD").isEmpty())
1189             project->values("QMAKE_LINK_SHLIB_CMD").append(
1190                 "$(LINK) $(LFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS) $(OBJCOMP)");
1191     }
1192     if (!project->values("QMAKE_APP_FLAG").isEmpty()) {
1193         project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_APP");
1194         project->values("QMAKE_CXXFLAGS") += project->values("QMAKE_CXXFLAGS_APP");
1195         project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_APP");
1196     } else if (project->isActiveConfig("dll")) {
1197         if(!project->isActiveConfig("plugin") || !project->isActiveConfig("plugin_no_share_shlib_cflags")) {
1198             project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_SHLIB");
1199             project->values("QMAKE_CXXFLAGS") += project->values("QMAKE_CXXFLAGS_SHLIB");
1200         }
1201         if (project->isActiveConfig("plugin")) {
1202             project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_PLUGIN");
1203             project->values("QMAKE_CXXFLAGS") += project->values("QMAKE_CXXFLAGS_PLUGIN");
1204             project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_PLUGIN");
1205             if(project->isActiveConfig("plugin_with_soname") && !project->isActiveConfig("compile_libtool"))
1206                 project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SONAME");
1207         } else {
1208             project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SHLIB");
1209             if(!project->isEmpty("QMAKE_LFLAGS_COMPAT_VERSION")) {
1210                 if(project->isEmpty("COMPAT_VERSION"))
1211                     project->values("QMAKE_LFLAGS") += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") +
1212                                                                     project->first("VER_MAJ") + "." +
1213                                                                     project->first("VER_MIN"));
1214                 else
1215                     project->values("QMAKE_LFLAGS") += QString(project->first("QMAKE_LFLAGS_COMPAT_VERSION") +
1216                                                                     project->first("COMPATIBILITY_VERSION"));
1217             }
1218             if(!project->isEmpty("QMAKE_LFLAGS_VERSION")) {
1219                 project->values("QMAKE_LFLAGS") += QString(project->first("QMAKE_LFLAGS_VERSION") +
1220                                                                 project->first("VER_MAJ") + "." +
1221                                                                 project->first("VER_MIN") + "." +
1222                                                                 project->first("VER_PAT"));
1223             }
1224             if(!project->isActiveConfig("compile_libtool"))
1225                 project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SONAME");
1226         }
1227     }
1228 
1229     if(!project->isEmpty("QMAKE_BUNDLE")) {
1230         QString plist = fileFixify(project->first("QMAKE_INFO_PLIST"));
1231         if(plist.isEmpty())
1232             plist = specdir() + QDir::separator() + "Info.plist." + project->first("TEMPLATE");
1233         if(exists(Option::fixPathToLocalOS(plist))) {
1234             if(project->isEmpty("QMAKE_INFO_PLIST"))
1235                 project->values("QMAKE_INFO_PLIST").append(plist);
1236             project->values("QMAKE_INFO_PLIST_OUT").append(project->first("DESTDIR") +
1237                                                                 project->first("QMAKE_BUNDLE") +
1238                                                                 "/Contents/Info.plist");
1239             project->values("ALL_DEPS") += project->first("QMAKE_INFO_PLIST_OUT");
1240             if(!project->isEmpty("ICON") && project->first("TEMPLATE") == "app")
1241                 project->values("ALL_DEPS") += project->first("DESTDIR") +
1242                                                     project->first("QMAKE_BUNDLE") +
1243                                                     "/Contents/Resources/" + project->first("ICON").section('/', -1);
1244             if(!project->isEmpty("QMAKE_BUNDLE_DATA")) {
1245                 QString bundle_dir = project->first("DESTDIR") + project->first("QMAKE_BUNDLE") + "/";
1246                 QStringList &alldeps = project->values("ALL_DEPS");
1247                 const QStringList &bundle_data = project->values("QMAKE_BUNDLE_DATA");
1248                 for(int i = 0; i < bundle_data.count(); i++) {
1249                     const QStringList &files = project->values(bundle_data[i] + ".files");
1250                     QString path = bundle_dir;
1251                     if(!project->isEmpty(bundle_data[i] + ".version")) {
1252                         alldeps += Option::fixPathToLocalOS(path + Option::dir_sep +
1253                                                             project->first(bundle_data[i] + ".path"));
1254                         path += project->first(bundle_data[i] + ".version") + "/" +
1255                                 project->first("QMAKE_FRAMEWORK_VERSION") + "/";
1256                     }
1257                     path += project->first(bundle_data[i] + ".path");
1258                     path = Option::fixPathToLocalOS(path);
1259                     for(int file = 0; file < files.count(); file++)
1260                         alldeps += path + Option::dir_sep + fileInfo(files[file]).fileName();
1261                 }
1262             }
1263         }
1264     }
1265 }
1266 
1267 QString
libtoolFileName(bool fixify)1268 UnixMakefileGenerator::libtoolFileName(bool fixify)
1269 {
1270     QString ret = var("TARGET");
1271     int slsh = ret.lastIndexOf(Option::dir_sep);
1272     if(slsh != -1)
1273         ret = ret.right(ret.length() - slsh - 1);
1274     int dot = ret.indexOf('.');
1275     if(dot != -1)
1276         ret = ret.left(dot);
1277     ret += Option::libtool_ext;
1278     if(!project->isEmpty("QMAKE_LIBTOOL_DESTDIR"))
1279         ret.prepend(project->first("QMAKE_LIBTOOL_DESTDIR") + Option::dir_sep);
1280     if(fixify) {
1281         if(QDir::isRelativePath(ret) && !project->isEmpty("DESTDIR"))
1282             ret.prepend(project->first("DESTDIR"));
1283         ret = Option::fixPathToLocalOS(fileFixify(ret, qmake_getpwd(), Option::output_dir));
1284     }
1285     return ret;
1286 }
1287 
1288 void
writeLibtoolFile()1289 UnixMakefileGenerator::writeLibtoolFile()
1290 {
1291     QString fname = libtoolFileName(), lname = fname;
1292     mkdir(fileInfo(fname).path());
1293     int slsh = lname.lastIndexOf(Option::dir_sep);
1294     if(slsh != -1)
1295         lname = lname.right(lname.length() - slsh - 1);
1296     QFile ft(fname);
1297     if(!ft.open(QIODevice::WriteOnly))
1298         return;
1299     project->values("ALL_DEPS").append(fileFixify(fname));
1300 
1301     QTextStream t(&ft);
1302     t << "# " << lname << " - a libtool library file\n";
1303     t << "# Generated by qmake/libtool (" << qmake_version() << ") (Qt "
1304       << QT_VERSION_STR << ") on: " << QDateTime::currentDateTime().toString();
1305 	t << "\n";
1306 
1307     t << "# The name that we can dlopen(3).\n"
1308       << "dlname='" << var(project->isActiveConfig("plugin") ? "TARGET" : "TARGET_x")
1309       << "'\n\n";
1310 
1311     t << "# Names of this library.\n";
1312     t << "library_names='";
1313     if(project->isActiveConfig("plugin")) {
1314         t << var("TARGET");
1315     } else {
1316         if (project->isEmpty("QMAKE_HPUX_SHLIB"))
1317             t << var("TARGET_x.y.z") << " ";
1318         t << var("TARGET_x") << " " << var("TARGET_");
1319     }
1320     t << "'\n\n";
1321 
1322     t << "# The name of the static archive.\n"
1323       << "old_library='" << lname.left(lname.length()-Option::libtool_ext.length()) << ".a'\n\n";
1324 
1325     t << "# Libraries that this one depends upon.\n";
1326     QStringList libs;
1327     if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
1328         libs = project->values("QMAKE_INTERNAL_PRL_LIBS");
1329     else
1330         libs << "QMAKE_LIBS"; //obvious one
1331     t << "dependency_libs='";
1332     for(QStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it)
1333         t << project->values((*it)).join(" ") << " ";
1334     t << "'\n\n";
1335 
1336     t << "# Version information for " << lname << "\n";
1337     int maj = project->first("VER_MAJ").toInt();
1338     int min = project->first("VER_MIN").toInt();
1339     int pat = project->first("VER_PAT").toInt();
1340     t << "current=" << (10*maj + min) << "\n" // best I can think of
1341       << "age=0\n"
1342       << "revision=" << pat << "\n\n";
1343 
1344     t << "# Is this an already installed library.\n"
1345         "installed=yes\n\n"; // ###
1346 
1347     t << "# Files to dlopen/dlpreopen.\n"
1348         "dlopen=''\n"
1349         "dlpreopen=''\n\n";
1350 
1351     QString install_dir = project->first("QMAKE_LIBTOOL_LIBDIR");
1352     if(install_dir.isEmpty())
1353         install_dir = project->first("target.path");
1354     if(install_dir.isEmpty())
1355         install_dir = project->first("DESTDIR");
1356     t << "# Directory that this library needs to be installed in:\n"
1357         "libdir='" << Option::fixPathToTargetOS(install_dir, false) << "'\n";
1358 }
1359 
1360 QT_END_NAMESPACE
1361