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