38 ** $QT_END_LICENSE$ |
38 ** $QT_END_LICENSE$ |
39 ** |
39 ** |
40 ****************************************************************************/ |
40 ****************************************************************************/ |
41 |
41 |
42 #include "symmake.h" |
42 #include "symmake.h" |
43 #include "initprojectdeploy_symbian.h" |
|
44 |
43 |
45 #include <qstring.h> |
44 #include <qstring.h> |
46 #include <qhash.h> |
45 #include <qhash.h> |
47 #include <qstringlist.h> |
46 #include <qstringlist.h> |
48 #include <qdir.h> |
47 #include <qdir.h> |
49 #include <qdatetime.h> |
48 #include <qdatetime.h> |
50 #include <stdlib.h> |
49 #include <stdlib.h> |
51 #include <qdebug.h> |
50 #include <qdebug.h> |
52 #include <qxmlstream.h> |
51 #include <qxmlstream.h> |
53 #include <qsettings> |
52 #include <QSettings> |
|
53 |
|
54 // Included from tools/shared |
|
55 #include <symbian/epocroot.h> |
54 |
56 |
55 #define RESOURCE_DIRECTORY_MMP "/resource/apps" |
57 #define RESOURCE_DIRECTORY_MMP "/resource/apps" |
56 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" |
58 #define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" |
57 #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps" |
59 #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps" |
58 #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def" |
60 #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def" |
59 #define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonU.def" |
61 #define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonU.def" |
60 #define BLD_INF_FILENAME_LEN (sizeof(BLD_INF_FILENAME) - 1) |
|
61 |
62 |
62 #define BLD_INF_RULES_BASE "BLD_INF_RULES." |
63 #define BLD_INF_RULES_BASE "BLD_INF_RULES." |
63 #define BLD_INF_TAG_PLATFORMS "prj_platforms" |
64 #define BLD_INF_TAG_PLATFORMS "prj_platforms" |
64 #define BLD_INF_TAG_MMPFILES "prj_mmpfiles" |
65 #define BLD_INF_TAG_MMPFILES "prj_mmpfiles" |
65 #define BLD_INF_TAG_TESTMMPFILES "prj_testmmpfiles" |
66 #define BLD_INF_TAG_TESTMMPFILES "prj_testmmpfiles" |
66 #define BLD_INF_TAG_EXTENSIONS "prj_extensions" |
67 #define BLD_INF_TAG_EXTENSIONS "prj_extensions" |
|
68 #define BLD_INF_TAG_EXPORTS "prj_exports" |
67 |
69 |
68 #define RSS_RULES "RSS_RULES" |
70 #define RSS_RULES "RSS_RULES" |
69 #define RSS_RULES_BASE "RSS_RULES." |
71 #define RSS_RULES_BASE "RSS_RULES." |
70 #define RSS_TAG_NBROFICONS "number_of_icons" |
72 #define RSS_TAG_NBROFICONS "number_of_icons" |
71 #define RSS_TAG_ICONFILE "icon_file" |
73 #define RSS_TAG_ICONFILE "icon_file" |
88 #define MMP_VERSION "VERSION" |
90 #define MMP_VERSION "VERSION" |
89 #define MMP_START_RESOURCE "START RESOURCE" |
91 #define MMP_START_RESOURCE "START RESOURCE" |
90 #define MMP_END_RESOURCE "END" |
92 #define MMP_END_RESOURCE "END" |
91 |
93 |
92 #define SIS_TARGET "sis" |
94 #define SIS_TARGET "sis" |
|
95 #define INSTALLER_SIS_TARGET "installer_sis" |
|
96 #define ROM_STUB_SIS_TARGET "stub_sis" |
93 #define OK_SIS_TARGET "ok_sis" |
97 #define OK_SIS_TARGET "ok_sis" |
|
98 #define OK_INSTALLER_SIS_TARGET "ok_installer_sis" |
|
99 #define OK_ROM_STUB_SIS_TARGET "ok_stub_sis" |
94 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg" |
100 #define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg" |
95 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache" |
101 #define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache" |
96 #define RESTORE_BUILD_TARGET "restore_build" |
|
97 |
102 |
98 #define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename)); |
103 #define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename)); |
|
104 |
|
105 #define MANUFACTURER_NOTE_FILE "manufacturer_note.txt" |
|
106 #define DEFAULT_MANUFACTURER_NOTE \ |
|
107 "The package is not supported for devices from this manufacturer. Please try the selfsigned " \ |
|
108 "version of the package instead." |
99 |
109 |
100 QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir) |
110 QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir) |
101 { |
111 { |
102 static QString epocRootStr; |
112 static QString epocRootStr; |
103 if (epocRootStr.isEmpty()) { |
113 if (epocRootStr.isEmpty()) { |
104 QFileInfo efi(epocRoot()); |
114 epocRootStr = epocRoot(); |
105 epocRootStr = efi.canonicalFilePath(); |
115 QFileInfo efi(epocRootStr); |
106 if (epocRootStr.isEmpty()) { |
116 if (!efi.exists() || epocRootStr.isEmpty()) { |
107 fprintf(stderr, "Unable to resolve epocRoot '%s' to real dir on current drive, defaulting to '/' for mmp paths\n", qPrintable(epocRoot())); |
117 fprintf(stderr, "Unable to resolve epocRoot '%s' to real dir on current drive, defaulting to '/' for mmp paths\n", qPrintable(epocRoot())); |
108 epocRootStr = "/"; |
118 epocRootStr = "/"; |
|
119 } else { |
|
120 epocRootStr = efi.absoluteFilePath(); |
109 } |
121 } |
110 if (!epocRootStr.endsWith("/")) |
122 if (!epocRootStr.endsWith("/")) |
111 epocRootStr += "/"; |
123 epocRootStr += "/"; |
112 |
124 |
113 epocRootStr += "epoc32/"; |
125 epocRootStr += "epoc32/"; |
127 resultPath = "."; |
139 resultPath = "."; |
128 |
140 |
129 return resultPath; |
141 return resultPath; |
130 } |
142 } |
131 |
143 |
132 QString SymbianMakefileGenerator::canonizePath(const QString& origPath) |
144 QString SymbianMakefileGenerator::absolutizePath(const QString& origPath) |
133 { |
145 { |
134 // Since current path gets appended almost always anyway, use it as default |
|
135 // for nonexisting paths. |
|
136 static QString defaultPath; |
|
137 if (defaultPath.isEmpty()) { |
|
138 QFileInfo fi("."); |
|
139 defaultPath = fi.canonicalFilePath(); |
|
140 } |
|
141 |
|
142 // Prepend epocroot to any paths beginning with "/epoc32/" |
146 // Prepend epocroot to any paths beginning with "/epoc32/" |
143 QString resultPath = QDir::fromNativeSeparators(origPath); |
147 QString resultPath = QDir::fromNativeSeparators(origPath); |
144 QString tempPath(resultPath); |
148 if (resultPath.startsWith("/epoc32/", Qt::CaseInsensitive)) |
145 bool isEpoc = false; |
|
146 if (resultPath.startsWith("/epoc32/", Qt::CaseInsensitive)) { |
|
147 isEpoc = true; |
|
148 resultPath = QDir::fromNativeSeparators(epocRoot()) + resultPath.mid(1); |
149 resultPath = QDir::fromNativeSeparators(epocRoot()) + resultPath.mid(1); |
149 } |
|
150 |
150 |
151 QFileInfo fi(fileInfo(resultPath)); |
151 QFileInfo fi(fileInfo(resultPath)); |
152 if(fi.isDir()) { |
152 |
153 if (isEpoc) |
153 // Since origPath can be something given in HEADERS, we need to check if we are dealing |
154 resultPath = fi.absoluteFilePath();//canonicalFilePath(); |
154 // with a file or a directory. In case the origPath doesn't yet exist, isFile() returns |
155 else |
155 // false and we default to assuming it is a dir. |
156 resultPath = fi.canonicalFilePath(); |
156 if (fi.isFile()) { |
|
157 resultPath = fi.absolutePath(); |
157 } else { |
158 } else { |
158 if (isEpoc) |
159 resultPath = fi.absoluteFilePath(); |
159 resultPath = fi.absolutePath();//canonicalPath(); |
|
160 else |
|
161 resultPath = fi.canonicalPath(); |
|
162 } |
|
163 //some fix for the not existed EPOC32\include folder |
|
164 if (isEpoc) { |
|
165 int index = resultPath.lastIndexOf("/epoc32/"); |
|
166 QString tmpRes = resultPath.mid(index); |
|
167 if (tmpRes != tempPath) { |
|
168 //we have the problems for not existed include directory |
|
169 //change the path |
|
170 resultPath.replace(tmpRes, tempPath); |
|
171 } |
|
172 } |
160 } |
173 |
161 |
174 resultPath = QDir::cleanPath(resultPath); |
162 resultPath = QDir::cleanPath(resultPath); |
175 |
|
176 if (resultPath.isEmpty()) |
|
177 resultPath = defaultPath; |
|
178 |
163 |
179 return resultPath; |
164 return resultPath; |
180 } |
165 } |
181 |
166 |
182 SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { } |
167 SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { } |
235 } |
222 } |
236 } |
223 } |
237 } |
224 } |
238 |
225 |
239 if (generatePkg) { |
226 if (generatePkg) { |
240 generatePkgFile(iconFile); |
227 generatePkgFile(iconFile, depList); |
241 } |
228 } |
242 |
229 |
243 writeBldInfContent(t, generatePkg, iconFile); |
230 writeBldInfContent(t, generatePkg, iconFile, depList); |
244 |
231 |
245 // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile, |
232 // Generate empty wrapper makefile here, because wrapper makefile must exist before writeMkFile, |
246 // but all required data is not yet available. |
233 // but all required data is not yet available. |
247 bool isPrimaryMakefile = true; |
234 bool isPrimaryMakefile = true; |
248 QString wrapperFileName("Makefile"); |
235 QString wrapperFileName("Makefile"); |
249 QString outputFileName = fileInfo(Option::output.fileName()).fileName(); |
236 QString outputFileName = fileInfo(Option::output.fileName()).fileName(); |
250 if (outputFileName != BLD_INF_FILENAME) { |
237 if (outputFileName != BLD_INF_FILENAME) { |
251 wrapperFileName.append(".").append((outputFileName.size() > BLD_INF_FILENAME_LEN && outputFileName.left(BLD_INF_FILENAME_LEN) == BLD_INF_FILENAME) ? outputFileName.mid(8) : outputFileName); |
238 wrapperFileName.append(".").append(outputFileName.startsWith(BLD_INF_FILENAME) |
|
239 ? outputFileName.mid(sizeof(BLD_INF_FILENAME)) |
|
240 : outputFileName); |
252 isPrimaryMakefile = false; |
241 isPrimaryMakefile = false; |
253 } |
242 } |
254 |
243 |
255 QFile wrapperMakefile(wrapperFileName); |
244 QFile wrapperMakefile(wrapperFileName); |
256 if (wrapperMakefile.open(QIODevice::WriteOnly)) { |
245 if (wrapperMakefile.open(QIODevice::WriteOnly)) { |
284 mmpFilename.append(uid3); |
273 mmpFilename.append(uid3); |
285 mmpFilename.append(Option::mmp_ext); |
274 mmpFilename.append(Option::mmp_ext); |
286 writeMmpFile(mmpFilename, symbianLangCodes); |
275 writeMmpFile(mmpFilename, symbianLangCodes); |
287 |
276 |
288 if (targetType == TypeExe) { |
277 if (targetType == TypeExe) { |
289 if (!project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) { |
278 if (!project->isActiveConfig("no_icon")) { |
290 writeRegRssFile(userRssRules); |
279 writeRegRssFile(userRssRules); |
291 writeRssFile(numberOfIcons, iconFile); |
280 writeRssFile(numberOfIcons, iconFile); |
292 writeLocFile(symbianLangCodes); |
281 writeLocFile(symbianLangCodes); |
293 if (!project->values("SYMBIANTRANSLATIONS").isEmpty()) |
282 if (!project->values("SYMBIANTRANSLATIONS").isEmpty()) |
294 writeSymbianLocFile(symbianLangCodes); |
283 writeSymbianLocFile(symbianLangCodes); |
313 } |
302 } |
314 if (Option::mkfile::listgen) { |
303 if (Option::mkfile::listgen) { |
315 generatePrint(fileInfo(pkgFile.fileName()).absoluteFilePath()); |
304 generatePrint(fileInfo(pkgFile.fileName()).absoluteFilePath()); |
316 } |
305 } |
317 generatedFiles << pkgFile.fileName(); |
306 generatedFiles << pkgFile.fileName(); |
|
307 QTextStream t(&pkgFile); |
|
308 |
|
309 QString installerSisHeader = project->values("DEPLOYMENT.installer_header").join("\n"); |
|
310 if (installerSisHeader.isEmpty()) |
|
311 installerSisHeader = "0xA000D7CE"; // Use default self-signable UID if not defined |
|
312 |
|
313 QString wrapperStreamBuffer; |
|
314 QTextStream tw(&wrapperStreamBuffer); |
|
315 |
|
316 QString dateStr = QDateTime::currentDateTime().toString(Qt::ISODate); |
318 |
317 |
319 // Header info |
318 // Header info |
320 QTextStream t(&pkgFile); |
319 QString wrapperPkgFilename = QString("%1_installer.%2") |
321 t << QString("; %1 generated by qmake at %2").arg(pkgFilename).arg(QDateTime::currentDateTime().toString(Qt::ISODate)) << endl; |
320 .arg(fixedTarget) |
322 t << "; This file is generated by qmake and should not be modified by the user" << endl; |
321 .arg("pkg"); |
323 t << ";" << endl << endl; |
322 QString headerComment = "; %1 generated by qmake at %2\n" |
|
323 "; This file is generated by qmake and should not be modified by the user\n" |
|
324 ";\n\n"; |
|
325 t << headerComment.arg(pkgFilename).arg(dateStr); |
|
326 tw << headerComment.arg(wrapperPkgFilename).arg(dateStr); |
324 |
327 |
325 // Construct QStringList from pkg_prerules since we need search it before printed to file |
328 // Construct QStringList from pkg_prerules since we need search it before printed to file |
326 QStringList rawPkgPreRules; |
329 QStringList rawPkgPreRules; |
327 foreach(QString deploymentItem, project->values("DEPLOYMENT")) { |
330 foreach(QString deploymentItem, project->values("DEPLOYMENT")) { |
328 foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) { |
331 foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) { |
341 |
344 |
342 // Apply some defaults if specific data does not exist in PKG pre-rules |
345 // Apply some defaults if specific data does not exist in PKG pre-rules |
343 |
346 |
344 if (!containsStartWithItem('&', rawPkgPreRules)) { |
347 if (!containsStartWithItem('&', rawPkgPreRules)) { |
345 // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS) |
348 // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS) |
346 t << "; Language" << endl; |
349 QString languageCode = "; Language\n&EN\n\n"; |
347 t << "&EN" << endl << endl; |
350 t << languageCode; |
|
351 tw << languageCode; |
348 } else { |
352 } else { |
349 // In case user defines langs, he must take care also about SIS header |
353 // In case user defines langs, he must take care also about SIS header |
350 if (!containsStartWithItem('#', rawPkgPreRules)) |
354 if (!containsStartWithItem('#', rawPkgPreRules)) |
351 fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n"); |
355 fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n"); |
352 } |
356 } |
353 |
357 |
354 // name of application, UID and version |
358 // name of application, UID and version |
355 QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ','); |
359 QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ','); |
|
360 QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n"; |
|
361 QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET"))); |
|
362 visualTarget = removePathSeparators(visualTarget); |
|
363 QString wrapperTarget = visualTarget + " installer"; |
|
364 |
|
365 if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) { |
|
366 tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion); |
|
367 } else { |
|
368 tw << installerSisHeader << endl; |
|
369 } |
356 |
370 |
357 if (!containsStartWithItem('#', rawPkgPreRules)) { |
371 if (!containsStartWithItem('#', rawPkgPreRules)) { |
358 QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET"))); |
372 t << sisHeader.arg(visualTarget).arg(uid3).arg(applicationVersion); |
359 visualTarget = removePathSeparators(visualTarget); |
|
360 |
|
361 t << "; SIS header: name, uid, version" << endl; |
|
362 t << QString("#{\"%1\"},(%2),%3").arg(visualTarget).arg(uid3).arg(applicationVersion) << endl << endl; |
|
363 } |
373 } |
364 |
374 |
365 // Localized vendor name |
375 // Localized vendor name |
|
376 QString vendorName; |
366 if (!containsStartWithItem('%', rawPkgPreRules)) { |
377 if (!containsStartWithItem('%', rawPkgPreRules)) { |
367 t << "; Localised Vendor name" << endl; |
378 vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n"; |
368 t << "%{\"Vendor\"}" << endl << endl; |
|
369 } |
379 } |
370 |
380 |
371 // Unique vendor name |
381 // Unique vendor name |
372 if (!containsStartWithItem(':', rawPkgPreRules)) { |
382 if (!containsStartWithItem(':', rawPkgPreRules)) { |
373 t << "; Unique Vendor name" << endl; |
383 vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n"; |
374 t << ":\"Vendor\"" << endl << endl; |
384 } |
375 } |
385 |
|
386 t << vendorName; |
|
387 tw << vendorName; |
376 |
388 |
377 // PKG pre-rules - these are added before actual file installations i.e. SIS package body |
389 // PKG pre-rules - these are added before actual file installations i.e. SIS package body |
378 if (rawPkgPreRules.size()) { |
390 if (rawPkgPreRules.size()) { |
379 t << "; Manual PKG pre-rules from PRO files" << endl; |
391 QString comment = "\n; Manual PKG pre-rules from PRO files\n"; |
|
392 t << comment; |
|
393 tw << comment; |
|
394 |
380 foreach(QString item, rawPkgPreRules) { |
395 foreach(QString item, rawPkgPreRules) { |
|
396 // Only regular pkg file should have package dependencies or pkg header if that is |
|
397 // defined using prerules. |
|
398 if (!item.startsWith("(") && !item.startsWith("#")) { |
|
399 tw << item << endl; |
|
400 } |
381 t << item << endl; |
401 t << item << endl; |
382 } |
402 } |
383 t << endl; |
403 t << endl; |
|
404 tw << endl; |
|
405 } |
|
406 |
|
407 // Begin Manufacturer block |
|
408 if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { |
|
409 QString manufacturerStr("IF "); |
|
410 foreach(QString manufacturer, project->values("DEPLOYMENT.manufacturers")) { |
|
411 manufacturerStr.append(QString("(MANUFACTURER)=(%1) OR \n ").arg(manufacturer)); |
|
412 } |
|
413 // Remove the final OR |
|
414 manufacturerStr.chop(8); |
|
415 t << manufacturerStr << endl; |
384 } |
416 } |
385 |
417 |
386 // Install paths on the phone *** should be dynamic at some point |
418 // Install paths on the phone *** should be dynamic at some point |
387 QString installPathBin = "!:\\sys\\bin"; |
419 QString installPathBin = "!:\\sys\\bin"; |
388 QString installPathResource = "!:\\resource\\apps"; |
420 QString installPathResource = "!:\\resource\\apps"; |
389 QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps"; |
421 QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps"; |
390 |
422 |
391 // Find location of builds |
423 // Find location of builds |
392 QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)") |
424 QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)") |
393 .arg(epocRoot()); |
425 .arg(epocRoot()); |
394 |
|
395 |
426 |
396 if (targetType == TypeExe) { |
427 if (targetType == TypeExe) { |
397 // deploy .exe file |
428 // deploy .exe file |
398 t << "; Executable and default resource files" << endl; |
429 t << "; Executable and default resource files" << endl; |
399 QString exeFile = fixedTarget + ".exe"; |
430 QString exeFile = fixedTarget + ".exe"; |
456 } |
486 } |
457 } |
487 } |
458 t << endl; |
488 t << endl; |
459 } |
489 } |
460 } |
490 } |
|
491 |
|
492 // Close Manufacturer block |
|
493 if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { |
|
494 QString manufacturerFailNoteFile; |
|
495 if (project->values("DEPLOYMENT.manufacturers.fail_note").isEmpty()) { |
|
496 manufacturerFailNoteFile = QString("%1_" MANUFACTURER_NOTE_FILE).arg(uid3); |
|
497 QFile ft(manufacturerFailNoteFile); |
|
498 if (ft.open(QIODevice::WriteOnly)) { |
|
499 generatedFiles << ft.fileName(); |
|
500 QTextStream t2(&ft); |
|
501 |
|
502 t2 << QString(DEFAULT_MANUFACTURER_NOTE) << endl; |
|
503 } else { |
|
504 PRINT_FILE_CREATE_ERROR(manufacturerFailNoteFile) |
|
505 } |
|
506 } else { |
|
507 manufacturerFailNoteFile = project->values("DEPLOYMENT.manufacturers.fail_note").join(""); |
|
508 } |
|
509 |
|
510 t << "ELSEIF NOT(0) ; MANUFACTURER" << endl |
|
511 << "\"" << fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\"" |
|
512 << " - \"\", FILETEXT, TEXTEXIT" << endl |
|
513 << "ENDIF ; MANUFACTURER" << endl; |
|
514 } |
|
515 |
|
516 // Write wrapper pkg |
|
517 if (!installerSisHeader.isEmpty()) { |
|
518 QFile wrapperPkgFile(wrapperPkgFilename); |
|
519 if (!wrapperPkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { |
|
520 PRINT_FILE_CREATE_ERROR(wrapperPkgFilename); |
|
521 return; |
|
522 } |
|
523 |
|
524 generatedFiles << wrapperPkgFile.fileName(); |
|
525 QTextStream twf(&wrapperPkgFile); |
|
526 |
|
527 twf << wrapperStreamBuffer << endl; |
|
528 |
|
529 // Wrapped files deployment |
|
530 QString currentPath = qmake_getpwd(); |
|
531 QString sisName = QString("%1.sis").arg(fixedTarget); |
|
532 twf << "\"" << currentPath << "/" << sisName << "\" - \"c:\\adm\\" << sisName << "\"" << endl; |
|
533 |
|
534 QString bootStrapPath = QLibraryInfo::location(QLibraryInfo::PrefixPath); |
|
535 bootStrapPath.append("/smartinstaller.sis"); |
|
536 QFileInfo fi(fileInfo(bootStrapPath)); |
|
537 twf << "@\"" << fi.absoluteFilePath() << "\",(0x2002CCCD)" << endl; |
|
538 } |
461 } |
539 } |
462 |
540 |
463 bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src) |
541 bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src) |
464 { |
542 { |
465 bool result = false; |
543 bool result = false; |
513 { |
591 { |
514 MakefileGenerator::init(); |
592 MakefileGenerator::init(); |
515 fixedTarget = escapeFilePath(fileFixify(project->first("TARGET"))); |
593 fixedTarget = escapeFilePath(fileFixify(project->first("TARGET"))); |
516 fixedTarget = removePathSeparators(fixedTarget); |
594 fixedTarget = removePathSeparators(fixedTarget); |
517 removeSpecialCharacters(fixedTarget); |
595 removeSpecialCharacters(fixedTarget); |
|
596 |
|
597 translationFileName = escapeFilePath(fileFixify(project->first("TRANSLATIONS"))); |
|
598 if (!translationFileName.isEmpty()){ |
|
599 translationFileName.chop(3); |
|
600 translationFileName = removePathSeparators(translationFileName); |
|
601 removeSpecialCharacters(translationFileName); |
|
602 } |
|
603 else |
|
604 translationFileName = fixedTarget; |
518 |
605 |
519 if (0 != project->values("QMAKE_PLATFORM").size()) |
606 if (0 != project->values("QMAKE_PLATFORM").size()) |
520 platform = varGlue("QMAKE_PLATFORM", "", " ", ""); |
607 platform = varGlue("QMAKE_PLATFORM", "", " ", ""); |
521 |
608 |
522 if (0 == project->values("QMAKESPEC").size()) |
609 if (0 == project->values("QMAKESPEC").size()) |
540 |
627 |
541 if ((project->values("TEMPLATE")).contains("app")) |
628 if ((project->values("TEMPLATE")).contains("app")) |
542 targetType = TypeExe; |
629 targetType = TypeExe; |
543 else if ((project->values("TEMPLATE")).contains("lib")) { |
630 else if ((project->values("TEMPLATE")).contains("lib")) { |
544 // Check CONFIG to see if we are to build staticlib or dll |
631 // Check CONFIG to see if we are to build staticlib or dll |
545 if (project->values("CONFIG").contains("staticlib") || project->values("CONFIG").contains("static")) |
632 if (project->isActiveConfig("staticlib") || project->isActiveConfig("static")) |
546 targetType = TypeLib; |
633 targetType = TypeLib; |
547 else if (project->values("CONFIG").contains("plugin")) |
634 else if (project->isActiveConfig("plugin")) |
548 targetType = TypePlugin; |
635 targetType = TypePlugin; |
549 else |
636 else |
550 targetType = TypeDll; |
637 targetType = TypeDll; |
551 } else { |
638 } else { |
552 targetType = TypeSubdirs; |
639 targetType = TypeSubdirs; |
553 } |
640 } |
554 |
641 |
555 if (0 != project->values("TARGET.UID2").size()) { |
642 if (0 != project->values("TARGET.UID2").size()) { |
556 uid2 = project->first("TARGET.UID2"); |
643 uid2 = project->first("TARGET.UID2"); |
557 } else if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) { |
644 } else if (project->isActiveConfig("stdbinary")) { |
558 uid2 = "0x20004C45"; |
645 uid2 = "0x20004C45"; |
559 } else { |
646 } else { |
560 if (targetType == TypeExe) { |
647 if (targetType == TypeExe) { |
561 if (project->values("QT").contains("gui", Qt::CaseInsensitive)) { |
648 if (project->values("QT").contains("gui", Qt::CaseInsensitive)) { |
562 // exe and gui -> uid2 needed |
649 // exe and gui -> uid2 needed |
623 srcpaths << project->values("SOURCES") << project->values("GENERATED_SOURCES"); |
710 srcpaths << project->values("SOURCES") << project->values("GENERATED_SOURCES"); |
624 srcpaths << project->values("UNUSED_SOURCES") << project->values("UI_SOURCES_DIR"); |
711 srcpaths << project->values("UNUSED_SOURCES") << project->values("UI_SOURCES_DIR"); |
625 srcpaths << project->values("UI_DIR"); |
712 srcpaths << project->values("UI_DIR"); |
626 |
713 |
627 QDir current = QDir::current(); |
714 QDir current = QDir::current(); |
628 QString canonizedCurrent = canonizePath("."); |
715 QString absolutizedCurrent = absolutizePath("."); |
629 |
716 |
630 for (int j = 0; j < srcpaths.size(); ++j) { |
717 for (int j = 0; j < srcpaths.size(); ++j) { |
631 QFileInfo fi(fileInfo(srcpaths.at(j))); |
718 QFileInfo fi(fileInfo(srcpaths.at(j))); |
632 // Sometimes sources have other than *.c* files (e.g. *.moc); prune them. |
719 // Sometimes sources have other than *.c* files (e.g. *.moc); prune them. |
633 if (fi.suffix().startsWith("c")) { |
720 if (fi.suffix().startsWith("c")) { |
634 if (fi.filePath().length() > fi.fileName().length()) { |
721 if (fi.filePath().length() > fi.fileName().length()) { |
635 appendIfnotExist(srcincpaths, fi.path()); |
722 appendIfnotExist(srcincpaths, fi.path()); |
636 sources[canonizePath(fi.path())] += fi.fileName(); |
723 sources[absolutizePath(fi.path())] += fi.fileName(); |
637 } else { |
724 } else { |
638 sources[canonizedCurrent] += fi.fileName(); |
725 sources[absolutizedCurrent] += fi.fileName(); |
639 appendIfnotExist(srcincpaths, canonizedCurrent); |
726 appendIfnotExist(srcincpaths, absolutizedCurrent); |
640 } |
727 } |
641 } |
728 } |
642 } |
729 } |
643 |
730 |
644 QStringList incpaths; |
731 QStringList incpaths; |
876 bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE); |
963 bool skipTargetType = overriddenMmpKeywords.contains(MMP_TARGETTYPE); |
877 |
964 |
878 if (targetType == TypeExe) { |
965 if (targetType == TypeExe) { |
879 t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl; |
966 t << MMP_TARGET "\t\t" << fixedTarget << ".exe" << endl; |
880 if (!skipTargetType) { |
967 if (!skipTargetType) { |
881 if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) |
968 if (project->isActiveConfig("stdbinary")) |
882 t << MMP_TARGETTYPE "\t\tSTDEXE" << endl; |
969 t << MMP_TARGETTYPE "\t\tSTDEXE" << endl; |
883 else |
970 else |
884 t << MMP_TARGETTYPE "\t\tEXE" << endl; |
971 t << MMP_TARGETTYPE "\t\tEXE" << endl; |
885 } |
972 } |
886 } else if (targetType == TypeDll || targetType == TypePlugin) { |
973 } else if (targetType == TypeDll || targetType == TypePlugin) { |
887 t << MMP_TARGET "\t\t" << fixedTarget << ".dll" << endl; |
974 t << MMP_TARGET "\t\t" << fixedTarget << ".dll" << endl; |
888 if (!skipTargetType) { |
975 if (!skipTargetType) { |
889 if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) |
976 if (project->isActiveConfig("stdbinary")) |
890 t << MMP_TARGETTYPE "\t\tSTDDLL" << endl; |
977 t << MMP_TARGETTYPE "\t\tSTDDLL" << endl; |
891 else |
978 else |
892 t << MMP_TARGETTYPE "\t\tDLL" << endl; |
979 t << MMP_TARGETTYPE "\t\tDLL" << endl; |
893 } |
980 } |
894 } else if (targetType == TypeLib) { |
981 } else if (targetType == TypeLib) { |
895 t << MMP_TARGET "\t\t" << fixedTarget << ".lib" << endl; |
982 t << MMP_TARGET "\t\t" << fixedTarget << ".lib" << endl; |
896 if (!skipTargetType) { |
983 if (!skipTargetType) { |
897 if (project->values("CONFIG").contains("stdbinary", Qt::CaseInsensitive)) |
984 if (project->isActiveConfig("stdbinary")) |
898 t << MMP_TARGETTYPE "\t\tSTDLIB" << endl; |
985 t << MMP_TARGETTYPE "\t\tSTDLIB" << endl; |
899 else |
986 else |
900 t << MMP_TARGETTYPE "\t\tLIB" << endl; |
987 t << MMP_TARGETTYPE "\t\tLIB" << endl; |
901 } |
988 } |
902 } else { |
989 } else { |
1574 } |
1658 } |
1575 } |
1659 } |
1576 |
1660 |
1577 void SymbianMakefileGenerator::writeSymbianLocFile(QStringList &symbianLangCodes) |
1661 void SymbianMakefileGenerator::writeSymbianLocFile(QStringList &symbianLangCodes) |
1578 { |
1662 { |
1579 QString filename(fixedTarget); |
1663 QString filename(translationFileName); |
1580 foreach(QString lang, symbianLangCodes) { |
1664 foreach(QString lang, symbianLangCodes) { |
1581 |
1665 |
1582 QString tsFilename(filename); |
1666 QString tsFilename(filename); |
1583 QString language = qt2S60LangMapTable.key(lang, QString("en")); |
1667 QString language = qt2S60LangMapTable.key(lang, QString("en")); |
1584 tsFilename.append("_"+language+".ts"); |
1668 tsFilename.append("_"+language+".ts"); |
1585 tsFilename.insert(0,project->first("SYMBIANTRANSLATIONDIR")); |
1669 |
|
1670 tsFilename.insert(0,project->first("SYMBIANTRANSLATIONSRCDIR")); |
1586 |
1671 |
1587 QString locFilename(filename); |
1672 QString locFilename(filename); |
1588 locFilename.append("_"+lang+".loc"); |
1673 locFilename.append("_"+lang+".loc"); |
1589 if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) { |
1674 if (!project->first("SYMBIANLOCFILESDIR").isEmpty()) { |
1590 locFilename.insert(0,lang+"/"); |
1675 locFilename.insert(0,lang+"/"); |
1591 locFilename.insert(0,project->first("SYMBIANLOCFILESDIR")); |
1676 locFilename.insert(0,project->first("SYMBIANLOCFILESDIR")); |
1592 } else { |
1677 } else { |
1593 locFilename.insert(0,"/epoc32/include/platform/app/loc/"+lang+"/"); |
1678 locFilename.insert(0,"/epoc32/include/platform/mw/loc/"+lang+"/"); |
1594 } |
1679 } |
1595 |
1680 |
1596 QString shortCaption; |
1681 QString shortCaption; |
1597 QString longCaption; |
1682 QString longCaption; |
1598 |
1683 |
1631 } |
1716 } |
1632 } |
1717 } |
1633 } |
1718 } |
1634 } |
1719 } |
1635 } |
1720 } |
1636 if (shortCaption.isEmpty()) |
1721 if (shortCaption.isEmpty()){ |
1637 fprintf(stderr, "Warning: STRING_r_short_caption not generated from file '%s'.\n", qPrintable(tsFilename)); |
1722 fprintf(stderr, "Warning: STRING_r_short_caption not generated from file '%s'.\n", qPrintable(tsFilename)); |
1638 if (longCaption.isEmpty()) |
1723 fprintf(stderr, " : short caption generated from target name '#%s'.\n", qPrintable(fixedTarget)); |
|
1724 } |
|
1725 if (longCaption.isEmpty()){ |
1639 fprintf(stderr, "Warning: STRING_r_caption not generated from file '%s'.\n", qPrintable(tsFilename)); |
1726 fprintf(stderr, "Warning: STRING_r_caption not generated from file '%s'.\n", qPrintable(tsFilename)); |
|
1727 fprintf(stderr, " : caption generated from target name '#%s'.\n", qPrintable(fixedTarget)); |
|
1728 } |
1640 if (xml.hasError()) |
1729 if (xml.hasError()) |
1641 fprintf(stderr, "ERROR: \"%s\" when parsing ts file\n", qPrintable(xml.errorString())); |
1730 fprintf(stderr, "ERROR: \"%s\" when parsing ts file\n", qPrintable(xml.errorString())); |
1642 } else { |
1731 } else { |
1643 fprintf(stderr, "Could not open ts file (%s)\n", qPrintable(tsFilename)); |
1732 fprintf(stderr, "Could not open ts file (%s)\n", qPrintable(tsFilename)); |
1644 } |
1733 } |
1645 } else { |
1734 } else { |
1646 fprintf(stderr, "ts file does not exist: (%s)\n", qPrintable(tsFilename)); |
1735 fprintf(stderr, "Warning: ts file does not exist: (%s)\n", qPrintable(tsFilename)); |
|
1736 fprintf(stderr, " : short and long caption generated from target name '#%s'.\n", qPrintable(fixedTarget)); |
1647 } |
1737 } |
1648 |
1738 |
1649 // generate language specific caption loc file |
1739 // generate language specific caption loc file |
1650 QFile ft(locFilename); |
1740 QFile ft(locFilename); |
1651 if (ft.open(QIODevice::WriteOnly)) { |
1741 if (ft.open(QIODevice::WriteOnly)) { |
2039 str.replace(QString(" "), QString("_")); |
2129 str.replace(QString(" "), QString("_")); |
2040 } |
2130 } |
2041 |
2131 |
2042 void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) |
2132 void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) |
2043 { |
2133 { |
2044 t << SIS_TARGET ": " RESTORE_BUILD_TARGET << endl; |
2134 t << "-include " MAKE_CACHE_NAME << endl; |
2045 QString siscommand = QString("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ |
2135 t << endl; |
2046 "$(MAKE) -s -f $(MAKEFILE) %4,$(MAKE) -s -f $(MAKEFILE) %5)," \ |
2136 |
|
2137 t << SIS_TARGET ":" << endl; |
|
2138 QString siscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ |
|
2139 "$(MAKE) -s -f $(MAKEFILE) %4," \ |
|
2140 "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \ |
|
2141 "$(MAKE) -s -f $(MAKEFILE) %5))," \ |
2047 "$(MAKE) -s -f $(MAKEFILE) %6)") |
2142 "$(MAKE) -s -f $(MAKEFILE) %6)") |
2048 .arg(fixedTarget) |
2143 .arg(fixedTarget) |
2049 .arg("pkg") |
2144 .arg("pkg") |
2050 .arg(MAKE_CACHE_NAME) |
2145 .arg(MAKE_CACHE_NAME) |
2051 .arg(OK_SIS_TARGET) |
2146 .arg(OK_SIS_TARGET) |
2054 t << siscommand << endl; |
2149 t << siscommand << endl; |
2055 t << endl; |
2150 t << endl; |
2056 |
2151 |
2057 t << OK_SIS_TARGET ":" << endl; |
2152 t << OK_SIS_TARGET ":" << endl; |
2058 |
2153 |
2059 QString pkgcommand = QString("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \ |
2154 QString pkgcommand = QString::fromLatin1("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \ |
2060 "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") |
2155 "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") |
2061 .arg(fixedTarget) |
2156 .arg(fixedTarget) |
2062 .arg("pkg"); |
2157 .arg("pkg"); |
2063 t << pkgcommand << endl; |
2158 t << pkgcommand << endl; |
2064 t << endl; |
2159 t << endl; |
2065 |
2160 |
|
2161 QString sisName = fixedTarget; |
|
2162 sisName += ".sis"; |
|
2163 |
|
2164 t << sisName << ":" << endl; |
|
2165 t << "\t$(MAKE) -s -f $(MAKEFILE) " SIS_TARGET << endl << endl; |
|
2166 |
|
2167 t << ROM_STUB_SIS_TARGET ":" << endl; |
|
2168 QString stubsiscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ |
|
2169 "$(MAKE) -s -f $(MAKEFILE) %4," \ |
|
2170 "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \ |
|
2171 "$(MAKE) -s -f $(MAKEFILE) %5))," \ |
|
2172 "$(MAKE) -s -f $(MAKEFILE) %6)") |
|
2173 .arg(fixedTarget) |
|
2174 .arg("pkg") |
|
2175 .arg(MAKE_CACHE_NAME) |
|
2176 .arg(OK_ROM_STUB_SIS_TARGET) |
|
2177 .arg(FAIL_SIS_NOCACHE_TARGET) |
|
2178 .arg(FAIL_SIS_NOPKG_TARGET); |
|
2179 t << stubsiscommand << endl; |
|
2180 t << endl; |
|
2181 |
|
2182 t << OK_ROM_STUB_SIS_TARGET ":" << endl; |
|
2183 |
|
2184 QString stubpkgcommand = QString::fromLatin1("\tcreatepackage.bat -s $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \ |
|
2185 "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") |
|
2186 .arg(fixedTarget) |
|
2187 .arg("pkg"); |
|
2188 t << stubpkgcommand << endl; |
|
2189 t << endl; |
|
2190 |
|
2191 t << INSTALLER_SIS_TARGET ": " << sisName << endl; |
|
2192 siscommand = QString::fromLatin1("\t$(if $(wildcard %1_installer.%2)," \ |
|
2193 "$(MAKE) -s -f $(MAKEFILE) %3," \ |
|
2194 "$(MAKE) -s -f $(MAKEFILE) %4)") |
|
2195 .arg(fixedTarget) |
|
2196 .arg("pkg") |
|
2197 .arg(OK_INSTALLER_SIS_TARGET) |
|
2198 .arg(FAIL_SIS_NOPKG_TARGET); |
|
2199 t << siscommand << endl; |
|
2200 t << endl; |
|
2201 |
|
2202 t << OK_INSTALLER_SIS_TARGET ": " << endl; |
|
2203 |
|
2204 pkgcommand = QString::fromLatin1("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_installer.%2 - " \ |
|
2205 "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") |
|
2206 .arg(fixedTarget) |
|
2207 .arg("pkg"); |
|
2208 t << pkgcommand << endl; |
|
2209 t << endl; |
|
2210 |
2066 t << FAIL_SIS_NOPKG_TARGET ":" << endl; |
2211 t << FAIL_SIS_NOPKG_TARGET ":" << endl; |
2067 t << "\t$(error PKG file does not exist, 'SIS' target is only supported for executables or projects with DEPLOYMENT statement)" << endl; |
2212 t << "\t$(error PKG file does not exist, '" SIS_TARGET "' and '" INSTALLER_SIS_TARGET "' target are only supported for executables or projects with DEPLOYMENT statement)" << endl; |
2068 t << endl; |
2213 t << endl; |
2069 |
2214 |
2070 t << FAIL_SIS_NOCACHE_TARGET ":" << endl; |
2215 t << FAIL_SIS_NOCACHE_TARGET ":" << endl; |
2071 t << "\t$(error Project has to be build before calling 'SIS' target)" << endl; |
2216 t << "\t$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" << endl; |
2072 t << endl; |
|
2073 |
|
2074 |
|
2075 t << RESTORE_BUILD_TARGET ":" << endl; |
|
2076 t << "-include " MAKE_CACHE_NAME << endl; |
|
2077 t << endl; |
2217 t << endl; |
2078 } |
2218 } |
2079 |
2219 |
2080 void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t) |
2220 void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t) |
2081 { |
2221 { |