1 | /****************************************************************************
|
---|
2 | **
|
---|
3 | ** Copyright (C) 2011 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 | ** Commercial Usage
|
---|
11 | ** Licensees holding valid Qt Commercial licenses may use this file in
|
---|
12 | ** accordance with the Qt Commercial License Agreement provided with the
|
---|
13 | ** Software or, alternatively, in accordance with the terms contained in
|
---|
14 | ** a written agreement between you and Nokia.
|
---|
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 | ** GNU General Public License Usage
|
---|
29 | ** Alternatively, this file may be used under the terms of the GNU
|
---|
30 | ** General Public License version 3.0 as published by the Free Software
|
---|
31 | ** Foundation and appearing in the file LICENSE.GPL included in the
|
---|
32 | ** packaging of this file. Please review the following information to
|
---|
33 | ** ensure the GNU General Public License version 3.0 requirements will be
|
---|
34 | ** met: http://www.gnu.org/copyleft/gpl.html.
|
---|
35 | **
|
---|
36 | ** If you have questions regarding the use of this file, please contact
|
---|
37 | ** Nokia at qt-info@nokia.com.
|
---|
38 | ** $QT_END_LICENSE$
|
---|
39 | **
|
---|
40 | ****************************************************************************/
|
---|
41 |
|
---|
42 | #include "symmake.h"
|
---|
43 |
|
---|
44 | #include <qstring.h>
|
---|
45 | #include <qhash.h>
|
---|
46 | #include <qstringlist.h>
|
---|
47 | #include <qdir.h>
|
---|
48 | #include <qdatetime.h>
|
---|
49 | #include <stdlib.h>
|
---|
50 | #include <qdebug.h>
|
---|
51 |
|
---|
52 | // Included from tools/shared
|
---|
53 | #include <symbian/epocroot_p.h>
|
---|
54 |
|
---|
55 | #define RESOURCE_DIRECTORY_MMP "/resource/apps"
|
---|
56 | #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps"
|
---|
57 | #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def"
|
---|
58 | #define BLD_INF_FILENAME_LEN (sizeof(BLD_INF_FILENAME) - 1)
|
---|
59 |
|
---|
60 | #define BLD_INF_RULES_BASE "BLD_INF_RULES."
|
---|
61 | #define BLD_INF_TAG_PLATFORMS "prj_platforms"
|
---|
62 | #define BLD_INF_TAG_MMPFILES "prj_mmpfiles"
|
---|
63 | #define BLD_INF_TAG_TESTMMPFILES "prj_testmmpfiles"
|
---|
64 | #define BLD_INF_TAG_EXTENSIONS "prj_extensions"
|
---|
65 | #define BLD_INF_TAG_TESTEXTENSIONS "prj_testextensions"
|
---|
66 |
|
---|
67 | #define MMP_TARGET "TARGET"
|
---|
68 | #define MMP_TARGETTYPE "TARGETTYPE"
|
---|
69 | #define MMP_SECUREID "SECUREID"
|
---|
70 | #define MMP_OPTION "OPTION"
|
---|
71 | #define MMP_LINKEROPTION "LINKEROPTION"
|
---|
72 | #define MMP_CAPABILITY "CAPABILITY"
|
---|
73 | #define MMP_EPOCALLOWDLLDATA "EPOCALLOWDLLDATA"
|
---|
74 | #define MMP_EPOCHEAPSIZE "EPOCHEAPSIZE"
|
---|
75 | #define MMP_EPOCSTACKSIZE "EPOCSTACKSIZE"
|
---|
76 | #define MMP_UID "UID"
|
---|
77 | #define MMP_VENDORID "VENDORID"
|
---|
78 | #define MMP_VERSION "VERSION"
|
---|
79 | #define MMP_START_RESOURCE "START RESOURCE"
|
---|
80 | #define MMP_END_RESOURCE "END"
|
---|
81 |
|
---|
82 | #define VAR_CXXFLAGS "QMAKE_CXXFLAGS"
|
---|
83 | #define VAR_CFLAGS "QMAKE_CFLAGS"
|
---|
84 | #define VAR_LFLAGS "QMAKE_LFLAGS"
|
---|
85 |
|
---|
86 | #define DEFINE_REPLACE_REGEXP "[^A-Z0-9_]"
|
---|
87 |
|
---|
88 | QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir)
|
---|
89 | {
|
---|
90 | static QString epocRootStr;
|
---|
91 | if (epocRootStr.isEmpty()) {
|
---|
92 | epocRootStr = qt_epocRoot();
|
---|
93 | QFileInfo efi(epocRootStr);
|
---|
94 | if (!efi.exists() || epocRootStr.isEmpty()) {
|
---|
95 | fprintf(stderr, "Unable to resolve epocRoot '%s' to real dir on current drive, defaulting to '/' for mmp paths\n", qPrintable(qt_epocRoot()));
|
---|
96 | epocRootStr = "/";
|
---|
97 | } else {
|
---|
98 | epocRootStr = efi.absoluteFilePath();
|
---|
99 | }
|
---|
100 | if (!epocRootStr.endsWith("/"))
|
---|
101 | epocRootStr += "/";
|
---|
102 |
|
---|
103 | epocRootStr += "epoc32/";
|
---|
104 | }
|
---|
105 |
|
---|
106 | QString resultPath = origPath;
|
---|
107 |
|
---|
108 | // Make it relative, unless it starts with "%epocroot%/epoc32/"
|
---|
109 | if (resultPath.startsWith(epocRootStr, Qt::CaseInsensitive)) {
|
---|
110 | resultPath.replace(epocRootStr, "/epoc32/", Qt::CaseInsensitive);
|
---|
111 | } else {
|
---|
112 | resultPath = parentDir.relativeFilePath(resultPath);
|
---|
113 | }
|
---|
114 | resultPath = QDir::cleanPath(resultPath);
|
---|
115 |
|
---|
116 | if (resultPath.isEmpty())
|
---|
117 | resultPath = ".";
|
---|
118 |
|
---|
119 | return resultPath;
|
---|
120 | }
|
---|
121 |
|
---|
122 | QString SymbianMakefileGenerator::absolutizePath(const QString& origPath)
|
---|
123 | {
|
---|
124 | // Prepend epocroot to any paths beginning with "/epoc32/"
|
---|
125 | QString resultPath = QDir::fromNativeSeparators(origPath);
|
---|
126 | if (resultPath.startsWith("/epoc32/", Qt::CaseInsensitive))
|
---|
127 | resultPath = QDir::fromNativeSeparators(qt_epocRoot()) + resultPath.mid(1);
|
---|
128 |
|
---|
129 | QFileInfo fi(fileInfo(resultPath));
|
---|
130 |
|
---|
131 | // Since origPath can be something given in HEADERS, we need to check if we are dealing
|
---|
132 | // with a file or a directory. In case the origPath doesn't yet exist, isFile() returns
|
---|
133 | // false and we default to assuming it is a dir.
|
---|
134 | if (fi.isFile()) {
|
---|
135 | resultPath = fi.absolutePath();
|
---|
136 | } else {
|
---|
137 | resultPath = fi.absoluteFilePath();
|
---|
138 | }
|
---|
139 |
|
---|
140 | resultPath = QDir::cleanPath(resultPath);
|
---|
141 |
|
---|
142 | return resultPath;
|
---|
143 | }
|
---|
144 |
|
---|
145 | SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator(), SymbianCommonGenerator(this) { }
|
---|
146 | SymbianMakefileGenerator::~SymbianMakefileGenerator() { }
|
---|
147 |
|
---|
148 | void SymbianMakefileGenerator::writeHeader(QTextStream &t)
|
---|
149 | {
|
---|
150 | t << "// ============================================================================" << endl;
|
---|
151 | t << "// * Makefile for building: " << escapeFilePath(var("TARGET")) << endl;
|
---|
152 | t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
|
---|
153 | t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
|
---|
154 | t << "// * This file is generated by qmake and should not be modified by the" << endl;
|
---|
155 | t << "// * user." << endl;
|
---|
156 | t << "// * Project: " << fileFixify(project->projectFile()) << endl;
|
---|
157 | t << "// * Template: " << var("TEMPLATE") << endl;
|
---|
158 | t << "// ============================================================================" << endl;
|
---|
159 | t << endl;
|
---|
160 |
|
---|
161 | // Defining define for bld.inf
|
---|
162 |
|
---|
163 | QString shortProFilename = project->projectFile();
|
---|
164 | shortProFilename.replace(0, shortProFilename.lastIndexOf("/") + 1, QString(""));
|
---|
165 | shortProFilename.replace(Option::pro_ext, QString(""));
|
---|
166 |
|
---|
167 | QString bldinfDefine = shortProFilename;
|
---|
168 | bldinfDefine.append("_");
|
---|
169 | bldinfDefine.append(generate_uid(project->projectFile()));
|
---|
170 | bldinfDefine = bldinfDefine.toUpper();
|
---|
171 |
|
---|
172 | // replace anything not alphanumeric with underscore
|
---|
173 | QRegExp replacementMask(DEFINE_REPLACE_REGEXP);
|
---|
174 | bldinfDefine.replace(replacementMask, QLatin1String("_"));
|
---|
175 |
|
---|
176 | bldinfDefine.prepend("BLD_INF_");
|
---|
177 |
|
---|
178 | t << "#define " << bldinfDefine << endl << endl;
|
---|
179 | }
|
---|
180 |
|
---|
181 | bool SymbianMakefileGenerator::writeMakefile(QTextStream &t)
|
---|
182 | {
|
---|
183 | if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) {
|
---|
184 | fprintf(stderr, "Project files not generated because all requirements are not met:\n\t%s\n",
|
---|
185 | qPrintable(var("QMAKE_FAILED_REQUIREMENTS")));
|
---|
186 | return false;
|
---|
187 | }
|
---|
188 |
|
---|
189 | writeHeader(t);
|
---|
190 |
|
---|
191 | QString numberOfIcons;
|
---|
192 | QString iconFile;
|
---|
193 | QMap<QString, QStringList> userRssRules;
|
---|
194 | readRssRules(numberOfIcons, iconFile, userRssRules);
|
---|
195 |
|
---|
196 | SymbianLocalizationList symbianLocalizationList;
|
---|
197 | parseTsFiles(&symbianLocalizationList);
|
---|
198 |
|
---|
199 | // Generate pkg files if there are any actual files to deploy
|
---|
200 | bool generatePkg = false;
|
---|
201 |
|
---|
202 | if (targetType == TypeExe) {
|
---|
203 | generatePkg = true;
|
---|
204 | } else {
|
---|
205 | foreach(QString item, project->values("DEPLOYMENT")) {
|
---|
206 | if (!project->values(item + ".sources").isEmpty()) {
|
---|
207 | generatePkg = true;
|
---|
208 | break;
|
---|
209 | }
|
---|
210 | }
|
---|
211 | }
|
---|
212 |
|
---|
213 | if (generatePkg) {
|
---|
214 | generatePkgFile(iconFile, true, symbianLocalizationList);
|
---|
215 | }
|
---|
216 |
|
---|
217 | writeBldInfContent(t, generatePkg, iconFile);
|
---|
218 |
|
---|
219 | // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile,
|
---|
220 | // but all required data is not yet available.
|
---|
221 | bool isPrimaryMakefile = true;
|
---|
222 | QString wrapperFileName = Option::output_dir + QLatin1Char('/') + QLatin1String("Makefile");
|
---|
223 | QString outputFileName = fileInfo(Option::output.fileName()).fileName();
|
---|
224 | if (outputFileName != BLD_INF_FILENAME) {
|
---|
225 | wrapperFileName.append(".").append(outputFileName.startsWith(BLD_INF_FILENAME)
|
---|
226 | ? outputFileName.mid(sizeof(BLD_INF_FILENAME))
|
---|
227 | : outputFileName);
|
---|
228 | isPrimaryMakefile = false;
|
---|
229 | }
|
---|
230 |
|
---|
231 | QFile wrapperMakefile(wrapperFileName);
|
---|
232 | if (wrapperMakefile.open(QIODevice::WriteOnly)) {
|
---|
233 | generatedFiles << wrapperFileName;
|
---|
234 | } else {
|
---|
235 | PRINT_FILE_CREATE_ERROR(wrapperFileName);
|
---|
236 | return false;
|
---|
237 | }
|
---|
238 |
|
---|
239 | if (targetType == TypeSubdirs) {
|
---|
240 | // If we have something to deploy, generate extension makefile for just that, since
|
---|
241 | // normal extension makefile is not getting generated and we need emulator deployment to be done.
|
---|
242 | if (generatePkg)
|
---|
243 | writeMkFile(wrapperFileName, true);
|
---|
244 | writeWrapperMakefile(wrapperMakefile, isPrimaryMakefile);
|
---|
245 | return true;
|
---|
246 | }
|
---|
247 |
|
---|
248 | writeMkFile(wrapperFileName, false);
|
---|
249 |
|
---|
250 | QString absoluteMmpFileName = Option::output_dir + QLatin1Char('/') + mmpFileName;
|
---|
251 | writeMmpFile(absoluteMmpFileName, symbianLocalizationList);
|
---|
252 |
|
---|
253 | if (targetType == TypeExe) {
|
---|
254 | if (!project->isActiveConfig("no_icon")) {
|
---|
255 | writeRegRssFile(userRssRules);
|
---|
256 | writeRssFile(numberOfIcons, iconFile);
|
---|
257 | writeLocFile(symbianLocalizationList);
|
---|
258 | }
|
---|
259 | }
|
---|
260 |
|
---|
261 | writeCustomDefFile();
|
---|
262 | writeWrapperMakefile(wrapperMakefile, isPrimaryMakefile);
|
---|
263 |
|
---|
264 | return true;
|
---|
265 | }
|
---|
266 |
|
---|
267 | void SymbianMakefileGenerator::init()
|
---|
268 | {
|
---|
269 | MakefileGenerator::init();
|
---|
270 | SymbianCommonGenerator::init();
|
---|
271 |
|
---|
272 | if (0 != project->values("QMAKE_PLATFORM").size())
|
---|
273 | platform = varGlue("QMAKE_PLATFORM", "", " ", "");
|
---|
274 |
|
---|
275 | if (0 == project->values("QMAKESPEC").size())
|
---|
276 | project->values("QMAKESPEC").append(qgetenv("QMAKESPEC"));
|
---|
277 |
|
---|
278 | project->values("QMAKE_LIBS") += escapeFilePaths(project->values("LIBS"));
|
---|
279 | project->values("QMAKE_LIBS_PRIVATE") += escapeFilePaths(project->values("LIBS_PRIVATE"));
|
---|
280 |
|
---|
281 | // Disallow renaming of bld.inf.
|
---|
282 | project->values("MAKEFILE").clear();
|
---|
283 | project->values("MAKEFILE") += BLD_INF_FILENAME;
|
---|
284 |
|
---|
285 | // .mmp
|
---|
286 | mmpFileName = fixedTarget;
|
---|
287 | if (targetType == TypeExe)
|
---|
288 | mmpFileName.append("_exe");
|
---|
289 | else if (targetType == TypeDll || targetType == TypePlugin)
|
---|
290 | mmpFileName.append("_dll");
|
---|
291 | else if (targetType == TypeLib)
|
---|
292 | mmpFileName.append("_lib");
|
---|
293 | mmpFileName.append(Option::mmp_ext);
|
---|
294 |
|
---|
295 | initMmpVariables();
|
---|
296 |
|
---|
297 | uid2 = project->first("TARGET.UID2");
|
---|
298 |
|
---|
299 | uid2 = uid2.trimmed();
|
---|
300 | }
|
---|
301 |
|
---|
302 | QString SymbianMakefileGenerator::getTargetExtension()
|
---|
303 | {
|
---|
304 | QString ret;
|
---|
305 | if (targetType == TypeExe) {
|
---|
306 | ret.append("exe");
|
---|
307 | } else if (targetType == TypeLib) {
|
---|
308 | ret.append("lib");
|
---|
309 | } else if (targetType == TypeDll || targetType == TypePlugin) {
|
---|
310 | ret.append("dll");
|
---|
311 | } else if (targetType == TypeSubdirs) {
|
---|
312 | // Not actually usable, so return empty
|
---|
313 | } else {
|
---|
314 | // If nothing else set, default to exe
|
---|
315 | ret.append("exe");
|
---|
316 | }
|
---|
317 |
|
---|
318 | return ret;
|
---|
319 | }
|
---|
320 |
|
---|
321 | QString SymbianMakefileGenerator::generateUID3()
|
---|
322 | {
|
---|
323 | QString target = project->first("TARGET");
|
---|
324 | QString currPath = qmake_getpwd();
|
---|
325 | target.prepend("/").prepend(currPath);
|
---|
326 | return generate_test_uid(target);
|
---|
327 | }
|
---|
328 |
|
---|
329 | void SymbianMakefileGenerator::initMmpVariables()
|
---|
330 | {
|
---|
331 | QStringList sysincspaths;
|
---|
332 | QStringList srcincpaths;
|
---|
333 | QStringList srcpaths;
|
---|
334 |
|
---|
335 | srcpaths << project->values("SOURCES") << project->values("GENERATED_SOURCES");
|
---|
336 | srcpaths << project->values("UNUSED_SOURCES") << project->values("UI_SOURCES_DIR");
|
---|
337 | srcpaths << project->values("UI_DIR");
|
---|
338 |
|
---|
339 | QDir current = QDir::current();
|
---|
340 | QString absolutizedCurrent = absolutizePath(".");
|
---|
341 |
|
---|
342 | for (int j = 0; j < srcpaths.size(); ++j) {
|
---|
343 | QFileInfo fi(fileInfo(srcpaths.at(j)));
|
---|
344 | // Sometimes sources have other than *.c* files (e.g. *.moc); prune them.
|
---|
345 | if (fi.suffix().startsWith("c")) {
|
---|
346 | if (fi.filePath().length() > fi.fileName().length()) {
|
---|
347 | appendIfnotExist(srcincpaths, fi.path());
|
---|
348 | sources[absolutizePath(fi.path())] += fi.fileName();
|
---|
349 | } else {
|
---|
350 | sources[absolutizedCurrent] += fi.fileName();
|
---|
351 | appendIfnotExist(srcincpaths, absolutizedCurrent);
|
---|
352 | }
|
---|
353 | }
|
---|
354 | }
|
---|
355 |
|
---|
356 | QStringList incpaths;
|
---|
357 | incpaths << project->values("INCLUDEPATH");
|
---|
358 | incpaths << QLibraryInfo::location(QLibraryInfo::HeadersPath);
|
---|
359 | incpaths << project->values("HEADERS");
|
---|
360 | incpaths << srcincpaths;
|
---|
361 | incpaths << project->values("UI_HEADERS_DIR");
|
---|
362 | incpaths << project->values("UI_DIR");
|
---|
363 |
|
---|
364 | for (int j = 0; j < incpaths.size(); ++j) {
|
---|
365 | QString includepath = absolutizePath(incpaths.at(j));
|
---|
366 | appendIfnotExist(sysincspaths, includepath);
|
---|
367 | appendAbldTempDirs(sysincspaths, includepath);
|
---|
368 | }
|
---|
369 |
|
---|
370 | // Remove duplicate include path entries
|
---|
371 | QStringList temporary;
|
---|
372 | for (int i = 0; i < sysincspaths.size(); ++i) {
|
---|
373 | QString origPath = sysincspaths.at(i);
|
---|
374 | QFileInfo origPathInfo(fileInfo(origPath));
|
---|
375 | bool bFound = false;
|
---|
376 |
|
---|
377 | for (int j = 0; j < temporary.size(); ++j) {
|
---|
378 | QString tmpPath = temporary.at(j);
|
---|
379 | QFileInfo tmpPathInfo(fileInfo(tmpPath));
|
---|
380 |
|
---|
381 | if (origPathInfo.absoluteFilePath() == tmpPathInfo.absoluteFilePath()) {
|
---|
382 | bFound = true;
|
---|
383 | if (!tmpPathInfo.isRelative() && origPathInfo.isRelative()) {
|
---|
384 | // We keep the relative notation
|
---|
385 | temporary.removeOne(tmpPath);
|
---|
386 | temporary << origPath;
|
---|
387 | }
|
---|
388 | }
|
---|
389 | }
|
---|
390 |
|
---|
391 | if (!bFound)
|
---|
392 | temporary << origPath;
|
---|
393 |
|
---|
394 | }
|
---|
395 |
|
---|
396 | sysincspaths.clear();
|
---|
397 | sysincspaths << temporary;
|
---|
398 |
|
---|
399 | systeminclude.insert("SYSTEMINCLUDE", sysincspaths);
|
---|
400 |
|
---|
401 | // Check MMP_RULES for singleton keywords that are overridden
|
---|
402 | QStringList overridableMmpKeywords;
|
---|
403 | QStringList restrictableMmpKeywords;
|
---|
404 | QStringList restrictedMmpKeywords;
|
---|
405 | bool inResourceBlock = false;
|
---|
406 |
|
---|
407 | overridableMmpKeywords << QLatin1String(MMP_TARGETTYPE) << QLatin1String(MMP_EPOCHEAPSIZE);
|
---|
408 | restrictableMmpKeywords << QLatin1String(MMP_TARGET) << QLatin1String(MMP_SECUREID)
|
---|
409 | << QLatin1String(MMP_OPTION) << QLatin1String(MMP_LINKEROPTION)
|
---|
410 | << QLatin1String(MMP_CAPABILITY) << QLatin1String(MMP_EPOCALLOWDLLDATA)
|
---|
411 | << QLatin1String(MMP_EPOCSTACKSIZE) << QLatin1String(MMP_UID)
|
---|
412 | << QLatin1String(MMP_VENDORID) << QLatin1String(MMP_VERSION);
|
---|
413 |
|
---|
414 | foreach (QString item, project->values("MMP_RULES")) {
|
---|
415 | if (project->values(item).isEmpty()) {
|
---|
416 | handleMmpRulesOverrides(item, inResourceBlock, restrictedMmpKeywords,
|
---|
417 | restrictableMmpKeywords, overridableMmpKeywords);
|
---|
418 | } else {
|
---|
419 | foreach (QString itemRow, project->values(item)) {
|
---|
420 | handleMmpRulesOverrides(itemRow, inResourceBlock, restrictedMmpKeywords,
|
---|
421 | restrictableMmpKeywords, overridableMmpKeywords);
|
---|
422 | }
|
---|
423 | }
|
---|
424 | }
|
---|
425 |
|
---|
426 | if (restrictedMmpKeywords.size()) {
|
---|
427 | fprintf(stderr, "Warning: Restricted statements detected in MMP_RULES:\n"
|
---|
428 | " (%s)\n"
|
---|
429 | " Use corresponding qmake variable(s) instead.\n",
|
---|
430 | qPrintable(restrictedMmpKeywords.join(", ")));
|
---|
431 | }
|
---|
432 | }
|
---|
433 |
|
---|
434 | void SymbianMakefileGenerator::handleMmpRulesOverrides(QString &checkString,
|
---|
435 | bool &inResourceBlock,
|
---|
436 | QStringList &restrictedMmpKeywords,
|
---|
437 | const QStringList &restrictableMmpKeywords,
|
---|
438 | const QStringList &overridableMmpKeywords)
|
---|
439 | {
|
---|
440 | QString simplifiedString = checkString.simplified();
|
---|
441 |
|
---|
442 | if (!inResourceBlock && simplifiedString.startsWith(MMP_START_RESOURCE, Qt::CaseInsensitive))
|
---|
443 | inResourceBlock = true;
|
---|
444 | else if (inResourceBlock && simplifiedString.startsWith(MMP_END_RESOURCE, Qt::CaseInsensitive))
|
---|
445 | inResourceBlock = false;
|
---|
446 |
|
---|
447 | // Allow restricted and overridable items in RESOURCE blocks as those do not actually
|
---|
448 | // override anything.
|
---|
449 | if (!inResourceBlock) {
|
---|
450 | appendKeywordIfMatchFound(overriddenMmpKeywords, overridableMmpKeywords, simplifiedString);
|
---|
451 | appendKeywordIfMatchFound(restrictedMmpKeywords, restrictableMmpKeywords, simplifiedString);
|
---|
452 | }
|
---|
453 | }
|
---|
454 |
|
---|
455 | void SymbianMakefileGenerator::appendKeywordIfMatchFound(QStringList &list,
|
---|
456 | const QStringList &keywordList,
|
---|
457 | QString &checkString)
|
---|
458 | {
|
---|
459 | // Check if checkString starts with any supplied keyword and
|
---|
460 | // add the found keyword to list if it does.
|
---|
461 | foreach (QString item, keywordList) {
|
---|
462 | if (checkString.startsWith(QString(item).append(" "), Qt::CaseInsensitive)
|
---|
463 | || checkString.compare(item, Qt::CaseInsensitive) == 0) {
|
---|
464 | appendIfnotExist(list, item);
|
---|
465 | }
|
---|
466 | }
|
---|
467 | }
|
---|
468 |
|
---|
469 |
|
---|
470 | bool SymbianMakefileGenerator::removeDuplicatedStrings(QStringList &stringList)
|
---|
471 | {
|
---|
472 | QStringList tmpStringList;
|
---|
473 |
|
---|
474 | for (int i = 0; i < stringList.size(); ++i) {
|
---|
475 | QString string = stringList.at(i);
|
---|
476 | if (tmpStringList.contains(string))
|
---|
477 | continue;
|
---|
478 | else
|
---|
479 | tmpStringList.append(string);
|
---|
480 | }
|
---|
481 |
|
---|
482 | stringList.clear();
|
---|
483 | stringList = tmpStringList;
|
---|
484 | return true;
|
---|
485 | }
|
---|
486 |
|
---|
487 | void SymbianMakefileGenerator::writeMmpFileHeader(QTextStream &t)
|
---|
488 | {
|
---|
489 | t << "// ==============================================================================" << endl;
|
---|
490 | t << "// Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: ";
|
---|
491 | t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl;
|
---|
492 | t << "// This file is generated by qmake and should not be modified by the" << endl;
|
---|
493 | t << "// user." << endl;
|
---|
494 | t << "// Name : " << mmpFileName << endl;
|
---|
495 | t << "// ==============================================================================" << endl << endl;
|
---|
496 | }
|
---|
497 |
|
---|
498 | void SymbianMakefileGenerator::writeMmpFile(QString &filename, const SymbianLocalizationList &symbianLocalizationList)
|
---|
499 | {
|
---|
500 | QFile ft(filename);
|
---|
501 | if (ft.open(QIODevice::WriteOnly)) {
|
---|
502 | generatedFiles << ft.fileName();
|
---|
503 |
|
---|
504 | QTextStream t(&ft);
|
---|
505 |
|
---|
506 | writeMmpFileHeader(t);
|
---|
507 |
|
---|
508 | writeMmpFileTargetPart(t);
|
---|
509 |
|
---|
510 | writeMmpFileResourcePart(t, symbianLocalizationList);
|
---|
511 |
|
---|
512 | writeMmpFileMacrosPart(t);
|
---|
513 |
|
---|
514 | writeMmpFileIncludePart(t);
|
---|
515 |
|
---|
516 | QDir current = QDir::current();
|
---|
517 |
|
---|
518 | for (QMap<QString, QStringList>::iterator it = sources.begin(); it != sources.end(); ++it) {
|
---|
519 | QStringList values = it.value();
|
---|
520 | QString currentSourcePath = it.key();
|
---|
521 |
|
---|
522 | if (values.size())
|
---|
523 | t << "SOURCEPATH \t" << fixPathForMmp(currentSourcePath, current) << endl;
|
---|
524 |
|
---|
525 | for (int i = 0; i < values.size(); ++i) {
|
---|
526 | QString sourceFileName = values.at(i);
|
---|
527 | t << "SOURCE\t\t" << sourceFileName << endl;
|
---|
528 | }
|
---|
529 | t << endl;
|
---|
530 | }
|
---|
531 | t << endl;
|
---|
532 |
|
---|
533 | if (!project->isActiveConfig("static") && !project->isActiveConfig("staticlib")) {
|
---|
534 | writeMmpFileLibraryPart(t);
|
---|
535 | }
|
---|
536 |
|
---|
537 | writeMmpFileCapabilityPart(t);
|
---|
538 |
|
---|
539 | writeMmpFileCompilerOptionPart(t);
|
---|
540 |
|
---|
541 | writeMmpFileBinaryVersionPart(t);
|
---|
542 |
|
---|
543 | writeMmpFileRulesPart(t);
|
---|
544 | } else {
|
---|
545 | PRINT_FILE_CREATE_ERROR(filename)
|
---|
546 | }
|
---|
547 | }
|
---|
548 |
|
---|
549 | void SymbianMakefileGenerator::writeMmpFileMacrosPart(QTextStream& t)
|
---|
550 | {
|
---|
551 | t << endl;
|
---|
552 |
|
---|
553 | QStringList &defines = project->values("DEFINES");
|
---|
554 | if (defines.size())
|
---|
555 | t << "// Qt Macros" << endl;
|
---|
556 | for (int i = 0; i < defines.size(); ++i) {
|
---|
557 | QString def = defines.at(i);
|
---|
558 | addMacro(t, def);
|
---|
559 | }
|
---|
560 |
|
---|
561 | // These are required in order that all methods will be correctly exported e.g from qtestlib
|
---|
562 | QStringList &exp_defines = project->values("PRL_EXPORT_DEFINES");
|
---|
563 | if (exp_defines.size())
|
---|
564 | t << endl << "// Qt Export Defines" << endl;
|
---|
565 | for (int i = 0; i < exp_defines.size(); ++i) {
|
---|
566 | QString def = exp_defines.at(i);
|
---|
567 | addMacro(t, def);
|
---|
568 | }
|
---|
569 |
|
---|
570 | t << endl;
|
---|
571 | }
|
---|
572 |
|
---|
573 | void SymbianMakefileGenerator::addMacro(QTextStream& t, const QString& value)
|
---|
574 | {
|
---|
575 | t << "MACRO\t\t" << value << endl;
|
---|
576 | }
|
---|
577 |
|
---|
578 |
|
---|
579 | void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t)
|
---|
580 | {
|
---|
581 | bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE);
|
---|
582 | bool skipEpocHeapSize = overriddenMmpKeywords.contains(MMP_EPOCHEAPSIZE);
|
---|
583 |
|
---|
584 | if (targetType == TypeExe) {
|
---|
585 | t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl;
|
---|
586 | if (!skipTargetType) {
|
---|
587 | if (project->isActiveConfig("stdbinary"))
|
---|
588 | t << MMP_TARGETTYPE "\t\tSTDEXE" << endl;
|
---|
589 | else
|
---|
590 | t << MMP_TARGETTYPE "\t\tEXE" << endl;
|
---|
591 | }
|
---|
592 | } else if (targetType == TypeDll || targetType == TypePlugin) {
|
---|
593 | t << MMP_TARGET "\t\t" << fixedTarget << ".dll" << endl;
|
---|
594 | if (!skipTargetType) {
|
---|
595 | if (project->isActiveConfig("stdbinary"))
|
---|
596 | t << MMP_TARGETTYPE "\t\tSTDDLL" << endl;
|
---|
597 | else
|
---|
598 | t << MMP_TARGETTYPE "\t\tDLL" << endl;
|
---|
599 | }
|
---|
600 | } else if (targetType == TypeLib) {
|
---|
601 | t << MMP_TARGET "\t\t" << fixedTarget << ".lib" << endl;
|
---|
602 | if (!skipTargetType) {
|
---|
603 | if (project->isActiveConfig("stdbinary"))
|
---|
604 | t << MMP_TARGETTYPE "\t\tSTDLIB" << endl;
|
---|
605 | else
|
---|
606 | t << MMP_TARGETTYPE "\t\tLIB" << endl;
|
---|
607 | }
|
---|
608 | } else {
|
---|
609 | fprintf(stderr, "Error: Unexpected targettype (%d) in SymbianMakefileGenerator::writeMmpFileTargetPart\n", targetType);
|
---|
610 | }
|
---|
611 |
|
---|
612 | t << endl;
|
---|
613 |
|
---|
614 | t << MMP_UID "\t\t" << uid2 << " " << uid3 << endl;
|
---|
615 |
|
---|
616 | if (0 != project->values("TARGET.SID").size()) {
|
---|
617 | t << MMP_SECUREID "\t\t" << project->values("TARGET.SID").join(" ") << endl;
|
---|
618 | } else {
|
---|
619 | if (0 == uid3.size())
|
---|
620 | t << MMP_SECUREID "\t\t0" << endl;
|
---|
621 | else
|
---|
622 | t << MMP_SECUREID "\t\t" << uid3 << endl;
|
---|
623 | }
|
---|
624 |
|
---|
625 | // default value used from mkspecs is 0
|
---|
626 | if (0 != project->values("TARGET.VID").size()) {
|
---|
627 | t << MMP_VENDORID "\t\t" << project->values("TARGET.VID").join(" ") << endl;
|
---|
628 | }
|
---|
629 |
|
---|
630 | t << endl;
|
---|
631 |
|
---|
632 | if (0 != project->first("TARGET.EPOCSTACKSIZE").size())
|
---|
633 | t << MMP_EPOCSTACKSIZE "\t\t" << project->first("TARGET.EPOCSTACKSIZE") << endl;
|
---|
634 | if (!skipEpocHeapSize && 0 != project->values("TARGET.EPOCHEAPSIZE").size())
|
---|
635 | t << MMP_EPOCHEAPSIZE "\t\t" << project->values("TARGET.EPOCHEAPSIZE").join(" ") << endl;
|
---|
636 | if (0 != project->values("TARGET.EPOCALLOWDLLDATA").size())
|
---|
637 | t << MMP_EPOCALLOWDLLDATA << endl;
|
---|
638 |
|
---|
639 | if (targetType == TypePlugin && !project->isActiveConfig("stdbinary")) {
|
---|
640 | // Use custom def file for Qt plugins
|
---|
641 | t << "DEFFILE " PLUGIN_COMMON_DEF_FILE_FOR_MMP << endl;
|
---|
642 | }
|
---|
643 |
|
---|
644 | t << endl;
|
---|
645 | }
|
---|
646 |
|
---|
647 |
|
---|
648 | /*
|
---|
649 | Application registration resource files should be installed to the
|
---|
650 | \private\10003a3f\import\apps directory.
|
---|
651 | */
|
---|
652 | void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, const SymbianLocalizationList &symbianLocalizationList)
|
---|
653 | {
|
---|
654 | if ((targetType == TypeExe) &&
|
---|
655 | !project->isActiveConfig("no_icon")) {
|
---|
656 |
|
---|
657 | QString locTarget = fixedTarget;
|
---|
658 | locTarget.append(".rss");
|
---|
659 |
|
---|
660 | t << "SOURCEPATH\t\t\t. " << endl;
|
---|
661 | t << "LANG SC "; // no endl
|
---|
662 | SymbianLocalizationListIterator iter(symbianLocalizationList);
|
---|
663 | while (iter.hasNext()) {
|
---|
664 | const SymbianLocalization &loc = iter.next();
|
---|
665 | t << loc.symbianLanguageCode << " "; // no endl
|
---|
666 | }
|
---|
667 | t << endl;
|
---|
668 | t << MMP_START_RESOURCE "\t\t" << locTarget << endl;
|
---|
669 | t << "HEADER" << endl;
|
---|
670 | t << "TARGETPATH\t\t\t" RESOURCE_DIRECTORY_MMP << endl;
|
---|
671 | t << MMP_END_RESOURCE << endl << endl;
|
---|
672 |
|
---|
673 | QString regTarget = fixedTarget;
|
---|
674 | regTarget.append("_reg.rss");
|
---|
675 |
|
---|
676 | t << "SOURCEPATH\t\t\t." << endl;
|
---|
677 | t << MMP_START_RESOURCE "\t\t" << regTarget << endl;
|
---|
678 | if (isForSymbianSbsv2())
|
---|
679 | t << "DEPENDS " << fixedTarget << ".rsg" << endl;
|
---|
680 | t << "TARGETPATH\t\t" REGISTRATION_RESOURCE_DIRECTORY_HW << endl;
|
---|
681 | t << MMP_END_RESOURCE << endl << endl;
|
---|
682 | }
|
---|
683 | }
|
---|
684 |
|
---|
685 | void SymbianMakefileGenerator::writeMmpFileSystemIncludePart(QTextStream& t)
|
---|
686 | {
|
---|
687 | QDir current = QDir::current();
|
---|
688 |
|
---|
689 | for (QMap<QString, QStringList>::iterator it = systeminclude.begin(); it != systeminclude.end(); ++it) {
|
---|
690 | QStringList values = it.value();
|
---|
691 | for (int i = 0; i < values.size(); ++i) {
|
---|
692 | QString handledPath = values.at(i);
|
---|
693 | t << "SYSTEMINCLUDE\t\t" << fixPathForMmp(handledPath, current) << endl;
|
---|
694 | }
|
---|
695 | }
|
---|
696 |
|
---|
697 | t << endl;
|
---|
698 | }
|
---|
699 |
|
---|
700 | void SymbianMakefileGenerator::writeMmpFileIncludePart(QTextStream& t)
|
---|
701 | {
|
---|
702 | writeMmpFileSystemIncludePart(t);
|
---|
703 | }
|
---|
704 |
|
---|
705 | void SymbianMakefileGenerator::writeMmpFileLibraryPart(QTextStream& t)
|
---|
706 | {
|
---|
707 | QStringList &libs = project->values("LIBS");
|
---|
708 | libs << project->values("QMAKE_LIBS") << project->values("QMAKE_LIBS_PRIVATE");
|
---|
709 |
|
---|
710 | removeDuplicatedStrings(libs);
|
---|
711 |
|
---|
712 | for (int i = 0; i < libs.size(); ++i) {
|
---|
713 | QString lib = libs.at(i);
|
---|
714 | // The -L flag is uninteresting, since all symbian libraries exist in the same directory.
|
---|
715 | if (lib.startsWith("-l")) {
|
---|
716 | lib.remove(0, 2);
|
---|
717 | QString mmpStatement;
|
---|
718 | if (lib.endsWith(".dll")) {
|
---|
719 | lib.chop(4);
|
---|
720 | mmpStatement = "LIBRARY\t\t";
|
---|
721 | } else if (lib.endsWith(".lib")) {
|
---|
722 | lib.chop(4);
|
---|
723 | mmpStatement = "STATICLIBRARY\t";
|
---|
724 | } else {
|
---|
725 | // Hacky way to find out what kind of library it is. Check the
|
---|
726 | // ARMV5 build directory for library type. We default to shared
|
---|
727 | // library, since that is more common.
|
---|
728 | QString udebStaticLibLocation(qt_epocRoot());
|
---|
729 | QString urelStaticLibLocation(udebStaticLibLocation);
|
---|
730 | udebStaticLibLocation += QString("epoc32/release/armv5/udeb/%1.lib").arg(lib);
|
---|
731 | urelStaticLibLocation += QString("epoc32/release/armv5/urel/%1.lib").arg(lib);
|
---|
732 | if (QFile::exists(udebStaticLibLocation) || QFile::exists(urelStaticLibLocation)) {
|
---|
733 | mmpStatement = "STATICLIBRARY\t";
|
---|
734 | } else {
|
---|
735 | mmpStatement = "LIBRARY\t\t";
|
---|
736 | }
|
---|
737 | }
|
---|
738 | t << mmpStatement << lib << ".lib" << endl;
|
---|
739 | }
|
---|
740 | }
|
---|
741 |
|
---|
742 | t << endl;
|
---|
743 | }
|
---|
744 |
|
---|
745 | void SymbianMakefileGenerator::writeMmpFileCapabilityPart(QTextStream& t)
|
---|
746 | {
|
---|
747 | if (0 != project->first("TARGET.CAPABILITY").size()) {
|
---|
748 | QStringList &capabilities = project->values("TARGET.CAPABILITY");
|
---|
749 | t << MMP_CAPABILITY "\t\t";
|
---|
750 |
|
---|
751 | for (int i = 0; i < capabilities.size(); ++i) {
|
---|
752 | QString cap = capabilities.at(i);
|
---|
753 | t << cap << " ";
|
---|
754 | }
|
---|
755 | } else {
|
---|
756 | t << MMP_CAPABILITY "\t\tNone";
|
---|
757 | }
|
---|
758 | t << endl << endl;
|
---|
759 | }
|
---|
760 |
|
---|
761 | void SymbianMakefileGenerator::writeMmpFileConditionalOptions(QTextStream& t,
|
---|
762 | const QString &optionType,
|
---|
763 | const QString &optionTag,
|
---|
764 | const QString &variableBase)
|
---|
765 | {
|
---|
766 | foreach(QString compilerVersion, project->values("VERSION_FLAGS." + optionTag)) {
|
---|
767 | QStringList currentValues = project->values(variableBase + "." + compilerVersion);
|
---|
768 | if (currentValues.size()) {
|
---|
769 | t << "#if defined(" << compilerVersion << ")" << endl;
|
---|
770 | t << optionType << " " << optionTag << " " << currentValues.join(" ") << endl;
|
---|
771 | t << "#endif" << endl;
|
---|
772 | }
|
---|
773 | }
|
---|
774 | }
|
---|
775 |
|
---|
776 | void SymbianMakefileGenerator::writeMmpFileSimpleOption(QTextStream& t,
|
---|
777 | const QString &optionType,
|
---|
778 | const QString &optionTag,
|
---|
779 | const QString &options)
|
---|
780 | {
|
---|
781 | QString trimmedOptions = options.trimmed();
|
---|
782 | if (!trimmedOptions.isEmpty())
|
---|
783 | t << optionType << " " << optionTag << " " << trimmedOptions << endl;
|
---|
784 | }
|
---|
785 |
|
---|
786 | void SymbianMakefileGenerator::appendMmpFileOptions(QString &options, const QStringList &list)
|
---|
787 | {
|
---|
788 | if (list.size()) {
|
---|
789 | options.append(list.join(" "));
|
---|
790 | options.append(" ");
|
---|
791 | }
|
---|
792 | }
|
---|
793 |
|
---|
794 | void SymbianMakefileGenerator::writeMmpFileCompilerOptionPart(QTextStream& t)
|
---|
795 | {
|
---|
796 | QStringList keywords = project->values("MMP_OPTION_KEYWORDS");
|
---|
797 | QStringList commonCxxFlags = project->values(VAR_CXXFLAGS);
|
---|
798 | QStringList commonCFlags = project->values(VAR_CFLAGS);
|
---|
799 | QStringList commonLFlags = project->values(VAR_LFLAGS);
|
---|
800 |
|
---|
801 | foreach(QString item, keywords) {
|
---|
802 | QString compilerOption;
|
---|
803 | QString linkerOption;
|
---|
804 |
|
---|
805 | appendMmpFileOptions(compilerOption, project->values(VAR_CXXFLAGS "." + item));
|
---|
806 | appendMmpFileOptions(compilerOption, project->values(VAR_CFLAGS "." + item));
|
---|
807 | appendMmpFileOptions(compilerOption, commonCxxFlags);
|
---|
808 | appendMmpFileOptions(compilerOption, commonCFlags);
|
---|
809 |
|
---|
810 | appendMmpFileOptions(linkerOption, project->values(VAR_LFLAGS "." + item));
|
---|
811 | appendMmpFileOptions(linkerOption, commonLFlags);
|
---|
812 |
|
---|
813 | writeMmpFileSimpleOption(t, MMP_OPTION, item, compilerOption);
|
---|
814 | writeMmpFileSimpleOption(t, MMP_LINKEROPTION, item, linkerOption);
|
---|
815 |
|
---|
816 | writeMmpFileConditionalOptions(t, MMP_OPTION, item, VAR_CXXFLAGS);
|
---|
817 | writeMmpFileConditionalOptions(t, MMP_LINKEROPTION, item, VAR_LFLAGS);
|
---|
818 | }
|
---|
819 |
|
---|
820 | t << endl;
|
---|
821 | }
|
---|
822 |
|
---|
823 | void SymbianMakefileGenerator::writeMmpFileBinaryVersionPart(QTextStream& t)
|
---|
824 | {
|
---|
825 | QString applicationVersion = project->first("VERSION");
|
---|
826 | QStringList verNumList = applicationVersion.split('.');
|
---|
827 | uint major = 0;
|
---|
828 | uint minor = 0;
|
---|
829 | uint patch = 0;
|
---|
830 | bool success = false;
|
---|
831 |
|
---|
832 | if (verNumList.size() > 0) {
|
---|
833 | major = verNumList[0].toUInt(&success);
|
---|
834 | if (success && verNumList.size() > 1) {
|
---|
835 | minor = verNumList[1].toUInt(&success);
|
---|
836 | if (success && verNumList.size() > 2) {
|
---|
837 | patch = verNumList[2].toUInt(&success);
|
---|
838 | }
|
---|
839 | }
|
---|
840 | }
|
---|
841 |
|
---|
842 | QString mmpVersion;
|
---|
843 | if (success && major <= 0xFFFF && minor <= 0xFF && patch <= 0xFF) {
|
---|
844 | // Symbian binary version only has major and minor components, so compress
|
---|
845 | // Qt's minor and patch values into the minor component. Since Symbian's minor
|
---|
846 | // component is a 16 bit value, only allow 8 bits for each to avoid overflow.
|
---|
847 | mmpVersion.append(QString::number(major))
|
---|
848 | .append('.')
|
---|
849 | .append(QString::number((minor << 8) + patch));
|
---|
850 | } else {
|
---|
851 | if (!applicationVersion.isEmpty())
|
---|
852 | fprintf(stderr, "Invalid VERSION string: %s\n", qPrintable(applicationVersion));
|
---|
853 | mmpVersion = "10.0"; // Default binary version for symbian is 10.0
|
---|
854 | }
|
---|
855 |
|
---|
856 | t << MMP_VERSION " " << mmpVersion << endl;
|
---|
857 | }
|
---|
858 |
|
---|
859 | void SymbianMakefileGenerator::writeMmpFileRulesPart(QTextStream& t)
|
---|
860 | {
|
---|
861 | foreach(QString item, project->values("MMP_RULES")) {
|
---|
862 | t << endl;
|
---|
863 | // If there is no stringlist defined for a rule, use rule name directly
|
---|
864 | // This is convenience for defining single line mmp statements
|
---|
865 | if (project->values(item).isEmpty()) {
|
---|
866 | t << item << endl;
|
---|
867 | } else {
|
---|
868 | foreach(QString itemRow, project->values(item)) {
|
---|
869 | t << itemRow << endl;
|
---|
870 | }
|
---|
871 | }
|
---|
872 | }
|
---|
873 | }
|
---|
874 |
|
---|
875 | void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploymentExtension, const QString &iconFile)
|
---|
876 | {
|
---|
877 | // Read user defined bld inf rules
|
---|
878 |
|
---|
879 | QMap<QString, QStringList> userBldInfRules;
|
---|
880 | for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) {
|
---|
881 | if (it.key().startsWith(BLD_INF_RULES_BASE)) {
|
---|
882 | QString newKey = it.key().mid(sizeof(BLD_INF_RULES_BASE) - 1);
|
---|
883 | if (newKey.isEmpty()) {
|
---|
884 | fprintf(stderr, "Warning: Empty BLD_INF_RULES key encountered\n");
|
---|
885 | continue;
|
---|
886 | }
|
---|
887 | QStringList newValues;
|
---|
888 | QStringList values = it.value();
|
---|
889 | foreach(QString item, values) {
|
---|
890 | // If there is no stringlist defined for a rule, use rule name directly
|
---|
891 | // This is convenience for defining single line statements
|
---|
892 | if (project->values(item).isEmpty()) {
|
---|
893 | newValues << item;
|
---|
894 | } else {
|
---|
895 | foreach(QString itemRow, project->values(item)) {
|
---|
896 | newValues << itemRow;
|
---|
897 | }
|
---|
898 | }
|
---|
899 | }
|
---|
900 | userBldInfRules.insert(newKey, newValues);
|
---|
901 | }
|
---|
902 | }
|
---|
903 |
|
---|
904 | // Add includes of subdirs bld.inf files
|
---|
905 |
|
---|
906 | QString currentPath = qmake_getpwd();
|
---|
907 | QDir directory(currentPath);
|
---|
908 |
|
---|
909 | const QStringList &subdirs = project->values("SUBDIRS");
|
---|
910 | foreach(QString item, subdirs) {
|
---|
911 | bool fromFile = false;
|
---|
912 | QString fixedItem;
|
---|
913 | if (!project->isEmpty(item + ".file")) {
|
---|
914 | fixedItem = project->first(item + ".file");
|
---|
915 | fromFile = true;
|
---|
916 | } else if (!project->isEmpty(item + ".subdir")) {
|
---|
917 | fixedItem = project->first(item + ".subdir");
|
---|
918 | fromFile = false;
|
---|
919 | } else {
|
---|
920 | fixedItem = item;
|
---|
921 | fromFile = item.endsWith(Option::pro_ext);
|
---|
922 | }
|
---|
923 |
|
---|
924 | QString condition;
|
---|
925 | if (!project->isEmpty(item + ".condition"))
|
---|
926 | condition = project->first(item + ".condition");
|
---|
927 |
|
---|
928 | QFileInfo subdir(fileInfo(fixedItem));
|
---|
929 | QString relativePath = directory.relativeFilePath(fixedItem);
|
---|
930 | QString fullProName = subdir.absoluteFilePath();
|
---|
931 | QString bldinfFilename;
|
---|
932 | QString subdirFileName;
|
---|
933 |
|
---|
934 | if (fromFile) {
|
---|
935 | subdirFileName = subdir.completeBaseName();
|
---|
936 | } else {
|
---|
937 | subdirFileName = subdir.fileName();
|
---|
938 | }
|
---|
939 |
|
---|
940 | if (subdir.isDir()) {
|
---|
941 | // Subdir is a regular project
|
---|
942 | bldinfFilename = relativePath + QString("/") + QString(BLD_INF_FILENAME);
|
---|
943 | fullProName += QString("/") + subdirFileName + Option::pro_ext;
|
---|
944 | } else {
|
---|
945 | // Subdir is actually a .pro file
|
---|
946 | if (relativePath.contains("/")) {
|
---|
947 | // .pro not in same directory as parent .pro
|
---|
948 | relativePath.remove(relativePath.lastIndexOf("/") + 1, relativePath.length());
|
---|
949 | bldinfFilename = relativePath;
|
---|
950 | } else {
|
---|
951 | // .pro and parent .pro in same directory
|
---|
952 | bldinfFilename = QString("./");
|
---|
953 | }
|
---|
954 | bldinfFilename += QString(BLD_INF_FILENAME ".") + subdirFileName;
|
---|
955 | }
|
---|
956 |
|
---|
957 | QString uid = generate_uid(fullProName);
|
---|
958 | QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid;
|
---|
959 | bldinfDefine = bldinfDefine.toUpper();
|
---|
960 |
|
---|
961 | // replace anything not alphanumeric with underscore
|
---|
962 | QRegExp replacementMask(DEFINE_REPLACE_REGEXP);
|
---|
963 | bldinfDefine.replace(replacementMask, QLatin1String("_"));
|
---|
964 |
|
---|
965 | if (!condition.isEmpty())
|
---|
966 | t << "#if defined(" << condition << ")" << endl;
|
---|
967 |
|
---|
968 | t << "#ifndef " << bldinfDefine << endl;
|
---|
969 | t << "\t#include \"" << bldinfFilename << "\"" << endl;
|
---|
970 | t << "#endif" << endl;
|
---|
971 |
|
---|
972 | if (!condition.isEmpty())
|
---|
973 | t << "#endif" << endl;
|
---|
974 |
|
---|
975 | }
|
---|
976 |
|
---|
977 | // Add supported project platforms
|
---|
978 |
|
---|
979 | t << endl << BLD_INF_TAG_PLATFORMS << endl << endl;
|
---|
980 | if (0 != project->values("SYMBIAN_PLATFORMS").size())
|
---|
981 | t << project->values("SYMBIAN_PLATFORMS").join(" ") << endl;
|
---|
982 |
|
---|
983 | QStringList userItems = userBldInfRules.value(BLD_INF_TAG_PLATFORMS);
|
---|
984 | foreach(QString item, userItems)
|
---|
985 | t << item << endl;
|
---|
986 | userBldInfRules.remove(BLD_INF_TAG_PLATFORMS);
|
---|
987 | t << endl;
|
---|
988 |
|
---|
989 | // Add project mmps and old style extension makefiles
|
---|
990 |
|
---|
991 | QString mmpTag;
|
---|
992 | if (project->isActiveConfig(SYMBIAN_TEST_CONFIG))
|
---|
993 | mmpTag = QLatin1String(BLD_INF_TAG_TESTMMPFILES);
|
---|
994 | else
|
---|
995 | mmpTag = QLatin1String(BLD_INF_TAG_MMPFILES);
|
---|
996 |
|
---|
997 | t << endl << mmpTag << endl << endl;
|
---|
998 |
|
---|
999 | writeBldInfMkFilePart(t, addDeploymentExtension);
|
---|
1000 | if (targetType != TypeSubdirs)
|
---|
1001 | t << mmpFileName << endl;
|
---|
1002 |
|
---|
1003 | userItems = userBldInfRules.value(mmpTag);
|
---|
1004 | foreach(QString item, userItems)
|
---|
1005 | t << item << endl;
|
---|
1006 | userBldInfRules.remove(mmpTag);
|
---|
1007 |
|
---|
1008 | QString extensionTag;
|
---|
1009 | if (project->isActiveConfig(SYMBIAN_TEST_CONFIG))
|
---|
1010 | extensionTag = QLatin1String(BLD_INF_TAG_TESTEXTENSIONS);
|
---|
1011 | else
|
---|
1012 | extensionTag = QLatin1String(BLD_INF_TAG_EXTENSIONS);
|
---|
1013 |
|
---|
1014 | t << endl << extensionTag << endl << endl;
|
---|
1015 |
|
---|
1016 | // Generate extension rules
|
---|
1017 |
|
---|
1018 | writeBldInfExtensionRulesPart(t, iconFile);
|
---|
1019 |
|
---|
1020 | userItems = userBldInfRules.value(extensionTag);
|
---|
1021 | foreach(QString item, userItems)
|
---|
1022 | t << item << endl;
|
---|
1023 | userBldInfRules.remove(extensionTag);
|
---|
1024 |
|
---|
1025 | // Add rest of the user defined content
|
---|
1026 |
|
---|
1027 | for (QMap<QString, QStringList>::iterator it = userBldInfRules.begin(); it != userBldInfRules.end(); ++it) {
|
---|
1028 | t << endl << endl << it.key() << endl << endl;
|
---|
1029 | userItems = it.value();
|
---|
1030 | foreach(QString item, userItems)
|
---|
1031 | t << item << endl;
|
---|
1032 | }
|
---|
1033 | }
|
---|
1034 |
|
---|
1035 | void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QString value)
|
---|
1036 | {
|
---|
1037 | if (!list.contains(value))
|
---|
1038 | list += value;
|
---|
1039 | }
|
---|
1040 |
|
---|
1041 | void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QStringList values)
|
---|
1042 | {
|
---|
1043 | foreach(QString item, values)
|
---|
1044 | appendIfnotExist(list, item);
|
---|
1045 | }
|
---|
1046 |
|
---|
1047 |
|
---|
1048 | QString SymbianMakefileGenerator::removeTrailingPathSeparators(QString &file)
|
---|
1049 | {
|
---|
1050 | QString ret = file;
|
---|
1051 | if (ret.endsWith(QDir::separator())) {
|
---|
1052 | ret.remove(ret.length() - 1, 1);
|
---|
1053 | }
|
---|
1054 |
|
---|
1055 | return ret;
|
---|
1056 | }
|
---|
1057 |
|
---|
1058 | void SymbianMakefileGenerator::generateCleanCommands(QTextStream& t,
|
---|
1059 | const QStringList& toClean,
|
---|
1060 | const QString& cmd,
|
---|
1061 | const QString& cmdOptions,
|
---|
1062 | const QString& itemPrefix,
|
---|
1063 | const QString& itemSuffix)
|
---|
1064 | {
|
---|
1065 | for (int i = 0; i < toClean.size(); ++i) {
|
---|
1066 | QString item = toClean.at(i);
|
---|
1067 | item.prepend(itemPrefix).append(itemSuffix);
|
---|
1068 | #if defined(Q_OS_WIN)
|
---|
1069 | t << "\t-@ if EXIST \"" << QDir::toNativeSeparators(item) << "\" ";
|
---|
1070 | t << cmd << " " << cmdOptions << " \"" << QDir::toNativeSeparators(item) << "\"" << endl;
|
---|
1071 | #else
|
---|
1072 | t << "\t-if test -e " << QDir::toNativeSeparators(item) << "; then ";
|
---|
1073 | t << cmd << " " << cmdOptions << " " << QDir::toNativeSeparators(item) << "; fi" << endl;
|
---|
1074 | #endif
|
---|
1075 | }
|
---|
1076 | }
|
---|
1077 |
|
---|
1078 | void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t)
|
---|
1079 | {
|
---|
1080 | t << "dodistclean:" << endl;
|
---|
1081 | const QStringList &subdirs = project->values("SUBDIRS");
|
---|
1082 | foreach(QString item, subdirs) {
|
---|
1083 | bool fromFile = false;
|
---|
1084 | QString fixedItem;
|
---|
1085 | if (!project->isEmpty(item + ".file")) {
|
---|
1086 | fixedItem = project->first(item + ".file");
|
---|
1087 | fromFile = true;
|
---|
1088 | } else if (!project->isEmpty(item + ".subdir")) {
|
---|
1089 | fixedItem = project->first(item + ".subdir");
|
---|
1090 | fromFile = false;
|
---|
1091 | } else {
|
---|
1092 | fromFile = item.endsWith(Option::pro_ext);
|
---|
1093 | fixedItem = item;
|
---|
1094 | }
|
---|
1095 | QFileInfo fi(fileInfo(fixedItem));
|
---|
1096 | if (!fromFile) {
|
---|
1097 | t << "\t-$(MAKE) -f \"" << Option::fixPathToTargetOS(fi.absoluteFilePath() + "/Makefile") << "\" dodistclean" << endl;
|
---|
1098 | } else {
|
---|
1099 | QString itemName = fi.fileName();
|
---|
1100 | int extIndex = itemName.lastIndexOf(Option::pro_ext);
|
---|
1101 | if (extIndex)
|
---|
1102 | fixedItem = fi.absolutePath() + "/" + QString("Makefile.") + itemName.mid(0, extIndex);
|
---|
1103 | t << "\t-$(MAKE) -f \"" << Option::fixPathToTargetOS(fixedItem) << "\" dodistclean" << endl;
|
---|
1104 | }
|
---|
1105 |
|
---|
1106 | }
|
---|
1107 |
|
---|
1108 | generatedFiles << Option::fixPathToTargetOS(fileInfo(Option::output.fileName()).absoluteFilePath()); // bld.inf
|
---|
1109 | generatedFiles << project->values("QMAKE_INTERNAL_PRL_FILE"); // Add generated prl files for cleanup
|
---|
1110 | generatedFiles << project->values("QMAKE_DISTCLEAN"); // Add any additional files marked for distclean
|
---|
1111 | QStringList fixedFiles;
|
---|
1112 | QStringList fixedDirs;
|
---|
1113 | foreach(QString item, generatedFiles) {
|
---|
1114 | QString fixedItem = Option::fixPathToTargetOS(fileInfo(item).absoluteFilePath());
|
---|
1115 | if (!fixedFiles.contains(fixedItem)) {
|
---|
1116 | fixedFiles << fixedItem;
|
---|
1117 | }
|
---|
1118 | }
|
---|
1119 | foreach(QString item, generatedDirs) {
|
---|
1120 | QString fixedItem = Option::fixPathToTargetOS(fileInfo(item).absoluteFilePath());
|
---|
1121 | if (!fixedDirs.contains(fixedItem)) {
|
---|
1122 | fixedDirs << fixedItem;
|
---|
1123 | }
|
---|
1124 | }
|
---|
1125 | generateCleanCommands(t, fixedFiles, "$(DEL_FILE)", "", "", "");
|
---|
1126 | generateCleanCommands(t, fixedDirs, "$(DEL_DIR)", "", "", "");
|
---|
1127 | t << endl;
|
---|
1128 |
|
---|
1129 | t << "distclean: clean dodistclean" << endl;
|
---|
1130 | t << endl;
|
---|
1131 | }
|
---|
1132 |
|
---|
1133 | // Returns a string that can be used as a dependency to loc file on other targets
|
---|
1134 | QString SymbianMakefileGenerator::generateLocFileTarget(QTextStream& t, const QString& locCmd)
|
---|
1135 | {
|
---|
1136 | QString locFile;
|
---|
1137 | if (targetType == TypeExe && !project->isActiveConfig("no_icon")) {
|
---|
1138 | locFile = Option::fixPathToLocalOS(generateLocFileName());
|
---|
1139 | t << locFile << QLatin1String(": ") << project->values("SYMBIAN_MATCHED_TRANSLATIONS").join(" ") << endl;
|
---|
1140 | t << locCmd << endl;
|
---|
1141 | t << endl;
|
---|
1142 | locFile += QLatin1Char(' ');
|
---|
1143 | }
|
---|
1144 |
|
---|
1145 | return locFile;
|
---|
1146 | }
|
---|