diff options
author | David Boddie <dboddie@trolltech.com> | 2010-03-30 14:56:41 (GMT) |
---|---|---|
committer | David Boddie <dboddie@trolltech.com> | 2010-03-30 14:56:41 (GMT) |
commit | 87f66d52e362de003a9f2cdaafbfbe3ba4e5fbc3 (patch) | |
tree | f8b8c24056d54e19937dea1b0301af558597726a /qmake | |
parent | 09ce407aaa4a00013a606bf0011faf6cbc654c72 (diff) | |
parent | 00f7426f3906361fb5addb36e428648eee5e2983 (diff) | |
download | Qt-87f66d52e362de003a9f2cdaafbfbe3ba4e5fbc3.zip Qt-87f66d52e362de003a9f2cdaafbfbe3ba4e5fbc3.tar.gz Qt-87f66d52e362de003a9f2cdaafbfbe3ba4e5fbc3.tar.bz2 |
Merge branch '4.7' of git@scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7
Conflicts:
doc/src/modules.qdoc
mkspecs/common/symbian/symbian.conf
src/gui/graphicsview/qgraphicswidget.h
src/s60installs/bwins/QtGuiu.def
src/s60installs/eabi/QtGuiu.def
Diffstat (limited to 'qmake')
39 files changed, 1533 insertions, 2634 deletions
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index d4f5849..875b9d1 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -9,10 +9,9 @@ LFLAGS = @QMAKE_LFLAGS@ OBJS=project.o property.o main.o makefile.o unixmake2.o unixmake.o \ mingw_make.o option.o winmakefile.o projectgenerator.o \ meta.o makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ - borland_bmake.o msvc_dsp.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ + borland_bmake.o msvc_vcproj.o msvc_nmake.o msvc_objectmodel.o \ symmake.o initprojectdeploy_symbian.o symmake_abld.o symmake_sbsv2.o \ - registry.o \ - epocroot.o + symbiancommon.o registry.o epocroot.o #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qtextstream.o qiodevice.o qmalloc.o qglobal.o \ @@ -37,6 +36,7 @@ DEPEND_SRC=project.cpp property.cpp meta.cpp main.cpp generators/makefile.cpp ge $(SOURCE_PATH)/tools/shared/windows/registry.cpp \ $(SOURCE_PATH)/tools/shared/symbian/epocroot.cpp \ generators/symbian/symmake_abld.cpp generators/symbian/symmake_sbsv2.cpp \ + generaters/symbian/symbiancommon.cpp \ $(SOURCE_PATH)/src/corelib/codecs/qtextcodec.cpp $(SOURCE_PATH)/src/corelib/codecs/qutfcodec.cpp \ $(SOURCE_PATH)/src/corelib/tools/qstring.cpp $(SOURCE_PATH)/src/corelib/io/qfile.cpp \ $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \ @@ -235,7 +235,7 @@ option.o: option.cpp option.h $(BUILD_PATH)/src/corelib/global/qconfig.cpp qcryptographichash.o: $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qcryptographichash.cpp -metamakefile.o: generators/metamakefile.cpp +metamakefile.o: generators/metamakefile.cpp generators/symbian/symbian_makefile.h $(CXX) -c -o $@ $(CXXFLAGS) generators/metamakefile.cpp xmloutput.o: generators/xmloutput.cpp @@ -271,9 +271,6 @@ msvc_nmake.o: generators/win32/msvc_nmake.cpp pbuilder_pbx.o: generators/mac/pbuilder_pbx.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/mac/pbuilder_pbx.cpp -msvc_dsp.o: generators/win32/msvc_dsp.cpp - $(CXX) -c -o $@ $(CXXFLAGS) generators/win32/msvc_dsp.cpp - symmake.o: generators/symbian/symmake.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/symmake.cpp @@ -283,6 +280,9 @@ symmake_abld.o: generators/symbian/symmake_abld.cpp symmake_sbsv2.o: generators/symbian/symmake_sbsv2.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/symmake_sbsv2.cpp +symbiancommon.o: generators/symbian/symbiancommon.cpp + $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/symbiancommon.cpp + initprojectdeploy_symbian.o: generators/symbian/initprojectdeploy_symbian.cpp $(CXX) -c -o $@ $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 48d84b7..63156b3 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -75,11 +75,9 @@ ADDCLEAN = qmake.tds OBJS = project.obj main.obj makefile.obj unixmake.obj unixmake2.obj mingw_make.obj \ option.obj winmakefile.obj projectgenerator.obj property.obj meta.obj \ makefiledeps.obj metamakefile.obj xmloutput.obj pbuilder_pbx.obj \ - borland_bmake.obj msvc_nmake.obj msvc_dsp.obj msvc_vcproj.obj \ + borland_bmake.obj msvc_nmake.obj msvc_vcproj.obj \ msvc_objectmodel.obj symmake.obj initprojectdeploy_symbian.obj \ - registry.obj \ - epocroot.obj \ - symmake_abld.obj symmake_sbsv2.obj + symmake_abld.obj symmake_sbsv2.obj symbiancommon.obj registry.obj epocroot.obj !IFDEF QMAKE_OPENSOURCE_EDITION CFLAGS = $(CFLAGS) -DQMAKE_OPENSOURCE_EDITION @@ -195,12 +193,12 @@ clean:: -del xmloutput.obj -del borland_bmake.obj -del msvc_nmake.obj - -del msvc_dsp.obj -del msvc_vcproj.obj -del msvc_objectmodel.obj -del symmake.obj -del symmake_abld.obj -del symmake_sbsv2.obj + -del symbiancommon.obj -del initprojectdeploy_symbian.obj -del registry.obj -del epocroot.obj @@ -382,9 +380,6 @@ mingw_make.obj: $(SOURCE_PATH)/qmake/generators/win32/mingw_make.cpp msvc_nmake.obj: $(SOURCE_PATH)/qmake/generators/win32/msvc_nmake.cpp $(CXX) $(CXXFLAGS) generators/win32/msvc_nmake.cpp -msvc_dsp.obj: $(SOURCE_PATH)/qmake/generators/win32/msvc_dsp.cpp - $(CXX) $(CXXFLAGS) generators/win32/msvc_dsp.cpp - msvc_vcproj.obj: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcproj.cpp $(CXX) $(CXXFLAGS) generators/win32/msvc_vcproj.cpp @@ -400,6 +395,9 @@ symmake_abld.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_abld.cpp symmake_sbsv2.obj: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp $(CXX) $(CXXFLAGS) generators/symbian/symmake_sbsv2.cpp +symbiancommon.obj: $(SOURCE_PATH)/qmake/generators/symbian/symbiancommon.cpp + $(CXX) $(CXXFLAGS) generators/symbian/symbiancommon.cpp + initprojectdeploy_symbian.obj: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp @@ -436,7 +434,7 @@ pbuilder_pbx.obj: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp makefiledeps.obj: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp -metamakefile.obj: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp +metamakefile.obj: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp $(SOURCE_PATH)/qmake/generators/symbian/symbiancommon.obj $(CXX) $(CXXFLAGS) generators/metamakefile.cpp xmloutput.obj: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp diff --git a/qmake/Makefile.win32-g++ b/qmake/Makefile.win32-g++ index 169de3c..ab7d558 100644 --- a/qmake/Makefile.win32-g++ +++ b/qmake/Makefile.win32-g++ @@ -27,7 +27,7 @@ CFLAGS = -c -o$@ -O \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ -DQT_BOOTSTRAPPED CXXFLAGS = $(CFLAGS) -LFLAGS = +LFLAGS = -static-libgcc -s LIBS = -lole32 -luuid LINKQMAKE = g++ $(LFLAGS) -o qmake.exe $(OBJS) $(QTOBJS) $(LIBS) ADDCLEAN = @@ -37,11 +37,9 @@ ADDCLEAN = OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ option.o winmakefile.o projectgenerator.o property.o meta.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ - borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ + borland_bmake.o msvc_nmake.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ - registry.o \ - epocroot.o \ - symmake_abld.o symmake_sbsv2.o + symmake_abld.o symmake_sbsv2.o symbiancommon.o registry.o epocroot.o ifdef QMAKE_OPENSOURCE_EDITION CFLAGS += -DQMAKE_OPENSOURCE_EDITION @@ -260,9 +258,6 @@ mingw_make.o: $(SOURCE_PATH)/qmake/generators/win32/mingw_make.cpp msvc_nmake.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_nmake.cpp $(CXX) $(CXXFLAGS) generators/win32/msvc_nmake.cpp -msvc_dsp.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_dsp.cpp - $(CXX) $(CXXFLAGS) generators/win32/msvc_dsp.cpp - msvc_vcproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcproj.cpp $(CXX) $(CXXFLAGS) generators/win32/msvc_vcproj.cpp @@ -278,6 +273,9 @@ symmake_abld.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_abld.cpp symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp $(CXX) $(CXXFLAGS) generators/symbian/symmake_sbsv2.cpp +symbiancommon.o: $(SOURCE_PATH)/qmake/generators/symbian/symbiancommon.cpp + $(CXX) $(CXXFLAGS) generators/symbian/symbiancommon.cpp + initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp @@ -311,7 +309,7 @@ pbuilder_pbx.o: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp makefiledeps.o: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp -metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp +metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp $(SOURCE_PATH)/qmake/generators/symbian/symbian_makefile.h $(CXX) $(CXXFLAGS) generators/metamakefile.cpp xmloutput.o: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp diff --git a/qmake/Makefile.win32-g++-sh b/qmake/Makefile.win32-g++-sh index 98237e7..755d046 100644 --- a/qmake/Makefile.win32-g++-sh +++ b/qmake/Makefile.win32-g++-sh @@ -27,7 +27,7 @@ CFLAGS = -c -o$@ -O \ -DQT_BUILD_QMAKE -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ -DQT_BOOTSTRAPPED CXXFLAGS = $(CFLAGS) -LFLAGS = +LFLAGS = -static-libgcc -s LIBS = -lole32 -luuid LINKQMAKE = g++ $(LFLAGS) -o qmake.exe $(OBJS) $(QTOBJS) $(LIBS) ADDCLEAN = @@ -37,11 +37,9 @@ ADDCLEAN = OBJS = project.o main.o makefile.o unixmake.o unixmake2.o mingw_make.o \ option.o winmakefile.o projectgenerator.o property.o meta.o \ makefiledeps.o metamakefile.o xmloutput.o pbuilder_pbx.o \ - borland_bmake.o msvc_nmake.o msvc_dsp.o msvc_vcproj.o \ + borland_bmake.o msvc_nmake.o msvc_vcproj.o \ msvc_objectmodel.o symmake.o initprojectdeploy_symbian.o \ - registry.o \ - epocroot.o \ - symmake_abld.o symmake_sbsv2.o + symmake_abld.o symmake_sbsv2.o symbiancommon.o registry.o epocroot.o ifdef QMAKE_OPENSOURCE_EDITION CFLAGS += -DQMAKE_OPENSOURCE_EDITION @@ -259,9 +257,6 @@ mingw_make.o: $(SOURCE_PATH)/qmake/generators/win32/mingw_make.cpp msvc_nmake.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_nmake.cpp $(CXX) $(CXXFLAGS) generators/win32/msvc_nmake.cpp -msvc_dsp.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_dsp.cpp - $(CXX) $(CXXFLAGS) generators/win32/msvc_dsp.cpp - msvc_vcproj.o: $(SOURCE_PATH)/qmake/generators/win32/msvc_vcproj.cpp $(CXX) $(CXXFLAGS) generators/win32/msvc_vcproj.cpp @@ -277,6 +272,9 @@ symmake_abld.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_abld.cpp symmake_sbsv2.o: $(SOURCE_PATH)/qmake/generators/symbian/symmake_sbsv2.cpp $(CXX) $(CXXFLAGS) generators/symbian/symmake_sbsv2.cpp +symbiancommon.o: $(SOURCE_PATH)/qmake/generators/symbian/symbiancommon.cpp + $(CXX) $(CXXFLAGS) generators/symbian/symbiancommon.cpp + initprojectdeploy_symbian.o: $(SOURCE_PATH)/qmake/generators/symbian/initprojectdeploy_symbian.cpp $(CXX) $(CXXFLAGS) generators/symbian/initprojectdeploy_symbian.cpp @@ -310,7 +308,7 @@ pbuilder_pbx.o: $(SOURCE_PATH)/qmake/generators/mac/pbuilder_pbx.cpp makefiledeps.o: $(SOURCE_PATH)/qmake/generators/makefiledeps.cpp $(CXX) $(CXXFLAGS) generators/makefiledeps.cpp -metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp +metamakefile.o: $(SOURCE_PATH)/qmake/generators/metamakefile.cpp $(SOURCE_PATH)/qmake/generators/symbian/symbian_makefile.h $(CXX) $(CXXFLAGS) generators/metamakefile.cpp xmloutput.o: $(SOURCE_PATH)/qmake/generators/xmloutput.cpp diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index ac9fa99..1a7391b 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -523,9 +523,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) debug_msg(1, "pbuilder: Creating file: %s", mkfile.toLatin1().constData()); QTextStream mkt(&mkf); writeHeader(mkt); - mkt << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? - QString((QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmake")) : - var("QMAKE_QMAKE")) << endl; + mkt << "QMAKE = " << var("QMAKE_QMAKE") << endl; writeMakeQmake(mkt); mkt.flush(); mkf.close(); diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index db2737b..29a2422 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -806,9 +806,8 @@ MakefileGenerator::init() } // escape qmake command - if (!project->isEmpty("QMAKE_QMAKE")) { - project->values("QMAKE_QMAKE") = escapeFilePaths(project->values("QMAKE_QMAKE")); - } + QStringList &qmk = project->values("QMAKE_QMAKE"); + qmk = escapeFilePaths(qmk); } bool @@ -1246,7 +1245,8 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs, bool n } if(!dirstr.endsWith(Option::dir_sep)) dirstr += Option::dir_sep; - if(exists(wild)) { //real file + bool is_target = (wild == fileFixify(var("TARGET"), FileFixifyAbsolute)); + if(is_target || exists(wild)) { //real file or target QString file = wild; QFileInfo fi(fileInfo(wild)); if(!target.isEmpty()) @@ -1260,7 +1260,7 @@ MakefileGenerator::writeInstalls(QTextStream &t, const QString &installs, bool n QString cmd; if (fi.isDir()) cmd = "-$(INSTALL_DIR)"; - else if (fi.isExecutable()) + else if (is_target || fi.isExecutable()) cmd = "-$(INSTALL_PROGRAM)"; else cmd = "-$(INSTALL_FILE)"; @@ -1808,8 +1808,6 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) tmp_clean = tmp_out; if(tmp_clean.indexOf("${QMAKE_") == -1) { t << "\n\t" << "-$(DEL_FILE) " << tmp_clean; - if (isForSymbian()) - t << " 2> NUL"; // Eliminate unnecessary warnings wrote_clean = true; } if(!wrote_clean_cmds || !wrote_clean) { @@ -1837,12 +1835,8 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) cleans.append(files); } } - if(!cleans.isEmpty()) { - if (isForSymbian()) - t << valGlue(cleans, "\n\t" + del_statement, " 2> NUL\n\t" + del_statement, " 2> NUL"); - else - t << valGlue(cleans, "\n\t" + del_statement, "\n\t" + del_statement, ""); - } + if(!cleans.isEmpty()) + t << valGlue(cleans, "\n\t" + del_statement, "\n\t" + del_statement, ""); if(!wrote_clean_cmds) { for(QStringList::ConstIterator input = tmp_inputs.begin(); input != tmp_inputs.end(); ++input) { t << "\n\t" << replaceExtraCompilerVariables(tmp_clean_cmds, (*input), @@ -2103,7 +2097,7 @@ MakefileGenerator::writeExtraVariables(QTextStream &t) bool MakefileGenerator::writeStubMakefile(QTextStream &t) { - t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; + t << "QMAKE = " << var("QMAKE_QMAKE") << endl; QStringList &qut = project->values("QMAKE_EXTRA_TARGETS"); for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) t << *it << " "; @@ -2158,14 +2152,14 @@ QString MakefileGenerator::buildArgs(const QString &outdir) ret += " -nodependheuristics"; if(!Option::mkfile::qmakespec_commandline.isEmpty()) ret += " -spec " + specdir(outdir); - if(Option::target_mode == Option::TARG_MAC9_MODE) - ret += " -mac9"; - else if(Option::target_mode == Option::TARG_MACX_MODE) - ret += " -macx"; - else if(Option::target_mode == Option::TARG_UNIX_MODE) - ret += " -unix"; - else if(Option::target_mode == Option::TARG_WIN_MODE) - ret += " -win32"; + if (Option::target_mode_overridden) { + if (Option::target_mode == Option::TARG_MACX_MODE) + ret += " -macx"; + else if (Option::target_mode == Option::TARG_UNIX_MODE) + ret += " -unix"; + else if (Option::target_mode == Option::TARG_WIN_MODE) + ret += " -win32"; + } //configs for(QStringList::Iterator it = Option::user_configs.begin(); @@ -2218,8 +2212,7 @@ MakefileGenerator::writeHeader(QTextStream &t) t << "# Project: " << fileFixify(project->projectFile()) << endl; t << "# Template: " << var("TEMPLATE") << endl; if(!project->isActiveConfig("build_pass")) - t << "# Command: " << build_args().replace("$(QMAKE)", - (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE"))) << endl; + t << "# Command: " << build_args().replace("$(QMAKE)", var("QMAKE_QMAKE")) << endl; t << "#############################################################################" << endl; t << endl; } @@ -2352,7 +2345,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT t << "MAKEFILE = " << ofile << endl; /* Calling Option::fixPathToTargetOS() is necessary for MinGW/MSYS, which requires * back-slashes to be turned into slashes. */ - t << "QMAKE = " << Option::fixPathToTargetOS(var("QMAKE_QMAKE")) << endl; + t << "QMAKE = " << var("QMAKE_QMAKE") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "CHK_DIR_EXISTS= " << var("QMAKE_CHK_DIR_EXISTS") << endl; t << "MKDIR = " << var("QMAKE_MKDIR") << endl; @@ -2675,8 +2668,6 @@ MakefileGenerator::writeMakeQmake(QTextStream &t) if(!specdir().isEmpty()) { if(exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"qmake.conf"))) t << escapeDependencyPath(specdir() + Option::dir_sep + "qmake.conf") << " "; - else if(exists(Option::fixPathToLocalOS(specdir()+QDir::separator()+"tmake.conf"))) - t << escapeDependencyPath(specdir() + Option::dir_sep + "tmake.conf") << " "; } const QStringList &included = project->values("QMAKE_INTERNAL_INCLUDED_FILES"); t << escapeDependencyPaths(included).join(" \\\n\t\t") << "\n\t" diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index d89c3b1..4c3be3d 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -247,7 +247,41 @@ public: virtual bool supportsMergedBuilds() { return false; } virtual bool mergeBuildProject(MakefileGenerator * /*other*/) { return false; } virtual bool openOutput(QFile &, const QString &build) const; - virtual bool isWindowsShell() const { return Option::target_mode == Option::TARG_WIN_MODE; } + virtual bool isWindowsShell() const { return Option::host_mode == Option::HOST_WIN_MODE; } + virtual bool isForSymbianSbsv2() const { return false; } // FIXME: killme - i'm ugly! + + /* The next one is to avoid having SymbianCommonGenerator as a virtually + inherited class of this class. Instead it is without a base class + (avoiding the virtual inheritance problem), and is allowed to use + functions defined in here. + + To illustrate: + +-------------------+ + | MakefileGenerator | + +-------------------+ + ^ ^ + | | + | X <-- Avoid this inheritance + | | + +------------------------+ +------------------------+ + | UnixMakefileGenerator | | SymbianCommonGenerator | + | or | | | + | NmakeMakefileGenerator | | | + +------------------------+ +------------------------+ + ^ ^ + | | + | | + | | + +-----------------------------+ + | SymbianMakefileTemplate<> | + +-----------------------------+ + + We want to avoid the famous diamond problem, because if we have that, we need + virtual inheritance, which not all compilers like. Therefore, we break the + link as illustrated. Instead, we have a pointer to MakefileGenerator inside + SymbianCommonGenerator, and allows full access by making it a friend here. + */ + friend class SymbianCommonGenerator; }; inline void MakefileGenerator::setNoIO(bool o) diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 4151193..e76e596 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -293,7 +293,15 @@ SubdirsMetaMakefileGenerator::init() init_flag = true; bool hasError = false; - if(Option::recursive) { + // It might make sense to bequeath the CONFIG option to the recursed + // projects. OTOH, one would most likely have it in all projects anyway - + // either through a qmakespec, a .qmake.cache or explicitly - as otherwise + // running qmake in a subdirectory would have a different auto-recurse + // setting than in parent directories. + bool recurse = Option::recursive == Option::QMAKE_RECURSIVE_YES + || (Option::recursive == Option::QMAKE_RECURSIVE_DEFAULT + && project->isRecursive()); + if(recurse) { QString old_output_dir = Option::output_dir; QString old_output = Option::output.fileName(); QString oldpwd = qmake_getpwd(); @@ -375,7 +383,7 @@ SubdirsMetaMakefileGenerator::init() Subdir *self = new Subdir; self->input_dir = qmake_getpwd(); self->output_dir = Option::output_dir; - if(!Option::recursive || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir())) + if(!recurse || (!Option::output.fileName().endsWith(Option::dir_sep) && !QFileInfo(Option::output).isDir())) self->output_file = Option::output.fileName(); self->makefile = new BuildsMetaMakefileGenerator(project, name, false); self->makefile->init(); @@ -432,10 +440,10 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "pbuilder_pbx.h" #include "msvc_nmake.h" #include "borland_bmake.h" -#include "msvc_dsp.h" #include "msvc_vcproj.h" #include "symmake_abld.h" #include "symmake_sbsv2.h" +#include "symbian_makefile.h" QT_END_INCLUDE_NAMESPACE MakefileGenerator * @@ -458,15 +466,8 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) mkfile = new MingwMakefileGenerator; } else if(gen == "PROJECTBUILDER" || gen == "XCODE") { mkfile = new ProjectBuilderMakefileGenerator; - } else if(gen == "MSVC") { - // Visual Studio =< v6.0 - if(proj->first("TEMPLATE").indexOf(QRegExp("^vc.*")) != -1) - mkfile = new DspMakefileGenerator; - else - mkfile = new NmakeMakefileGenerator; } else if(gen == "MSVC.NET") { - // Visual Studio >= v7.0 - if(proj->first("TEMPLATE").indexOf(QRegExp("^vc.*")) != -1 || proj->first("TEMPLATE").indexOf(QRegExp("^ce.*")) != -1) + if (proj->first("TEMPLATE").startsWith("vc")) mkfile = new VcprojGenerator; else mkfile = new NmakeMakefileGenerator; @@ -476,6 +477,8 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) mkfile = new SymbianAbldMakefileGenerator; } else if(gen == "SYMBIAN_SBSV2") { mkfile = new SymbianSbsv2MakefileGenerator; + } else if(gen == "SYMBIAN_UNIX") { + mkfile = new SymbianMakefileTemplate<UnixMakefileGenerator>; } else { fprintf(stderr, "Unknown generator specified: %s\n", gen.toLatin1().constData()); } @@ -486,6 +489,40 @@ MetaMakefileGenerator::createMakefileGenerator(QMakeProject *proj, bool noIO) return mkfile; } +bool +MetaMakefileGenerator::modesForGenerator(const QString &gen, + Option::HOST_MODE *host_mode, Option::TARG_MODE *target_mode) +{ + if (gen == "UNIX") { +#ifdef Q_OS_MAC + *host_mode = Option::HOST_MACX_MODE; + *target_mode = Option::TARG_MACX_MODE; +#else + *host_mode = Option::HOST_UNIX_MODE; + *target_mode = Option::TARG_UNIX_MODE; +#endif + } else if (gen == "MSVC.NET" || gen == "MINGW" || gen == "BMAKE") { + *host_mode = Option::HOST_WIN_MODE; + *target_mode = Option::TARG_WIN_MODE; + } else if (gen == "PROJECTBUILDER" || gen == "XCODE") { + *host_mode = Option::HOST_MACX_MODE; + *target_mode = Option::TARG_MACX_MODE; + } else if (gen == "SYMBIAN_ABLD" || gen == "SYMBIAN_SBSV2" || gen == "SYMBIAN_UNIX") { +#if defined(Q_OS_MAC) + *host_mode = Option::HOST_MACX_MODE; +#elif defined(Q_OS_UNIX) + *host_mode = Option::HOST_UNIX_MODE; +#else + *host_mode = Option::HOST_WIN_MODE; +#endif + *target_mode = Option::TARG_SYMBIAN_MODE; + } else { + fprintf(stderr, "Unknown generator specified: %s\n", gen.toLatin1().constData()); + return false; + } + return true; +} + MetaMakefileGenerator * MetaMakefileGenerator::createMetaGenerator(QMakeProject *proj, const QString &name, bool op, bool *success) { diff --git a/qmake/generators/metamakefile.h b/qmake/generators/metamakefile.h index 8675115..e559c8e 100644 --- a/qmake/generators/metamakefile.h +++ b/qmake/generators/metamakefile.h @@ -42,6 +42,8 @@ #ifndef METAMAKEFILE_H #define METAMAKEFILE_H +#include <option.h> + #include <qlist.h> #include <qstring.h> @@ -65,6 +67,9 @@ public: static MetaMakefileGenerator *createMetaGenerator(QMakeProject *proj, const QString &name, bool op=true, bool *success = 0); static MakefileGenerator *createMakefileGenerator(QMakeProject *proj, bool noIO = false); + static bool modesForGenerator(const QString &generator, + Option::HOST_MODE *host_mode, Option::TARG_MODE *target_mode); + inline QMakeProject *projectFile() const { return project; } virtual bool init() = 0; diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 8622cd9..d225635 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -111,7 +111,7 @@ ProjectGenerator::init() add_depend = true; if(dir.right(1) != Option::dir_sep) dir += Option::dir_sep; - if(Option::recursive) { + if(Option::recursive == Option::QMAKE_RECURSIVE_YES) { QStringList files = QDir(dir).entryList(QDir::Files); for(int i = 0; i < (int)files.count(); i++) { if(files[i] != "." && files[i] != "..") @@ -138,7 +138,7 @@ ProjectGenerator::init() dir = regex.left(s+1); regex = regex.right(regex.length() - (s+1)); } - if(Option::recursive) { + if(Option::recursive == Option::QMAKE_RECURSIVE_YES) { QStringList entries = QDir(dir).entryList(QDir::Dirs); for(int i = 0; i < (int)entries.count(); i++) { if(entries[i] != "." && entries[i] != "..") { @@ -193,7 +193,7 @@ ProjectGenerator::init() subdirs.append(nd); } } - if(Option::recursive) { + if(Option::recursive == Option::QMAKE_RECURSIVE_YES) { QStringList dirs = QDir(newdir).entryList(QDir::Dirs); for(int i = 0; i < (int)dirs.count(); i++) { QString nd = fileFixify(newdir + QDir::separator() + dirs[i]); @@ -230,7 +230,8 @@ ProjectGenerator::init() } } } - if(Option::recursive && !knownDirs.contains(newdir, Qt::CaseInsensitive)) + if(Option::recursive == Option::QMAKE_RECURSIVE_YES + && !knownDirs.contains(newdir, Qt::CaseInsensitive)) knownDirs.append(newdir); } } diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.cpp b/qmake/generators/symbian/initprojectdeploy_symbian.cpp index 81c9408..6407412 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.cpp +++ b/qmake/generators/symbian/initprojectdeploy_symbian.cpp @@ -155,6 +155,7 @@ void initProjectDeploySymbian(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath, bool deployBinaries, + bool epocBuild, const QString &platform, const QString &build, QStringList& generatedDirs, @@ -264,7 +265,11 @@ void initProjectDeploySymbian(QMakeProject* project, if (isBinary(info)) { if (deployBinaries) { // Executables and libraries are deployed to \sys\bin - QFileInfo targetPath(epocRoot() + "epoc32/release/" + platform + "/" + build + "/"); + QFileInfo targetPath; + if (epocBuild) + targetPath.setFile(epocRoot() + "epoc32/release/" + platform + "/" + build + "/"); + else + targetPath.setFile(info.path() + QDir::separator()); if(devicePathHasDriveLetter) { deploymentList.append(CopyItem( Option::fixPathToLocalOS(targetPath.absolutePath() + "/" + info.fileName(), diff --git a/qmake/generators/symbian/initprojectdeploy_symbian.h b/qmake/generators/symbian/initprojectdeploy_symbian.h index c621915..2653d2a 100644 --- a/qmake/generators/symbian/initprojectdeploy_symbian.h +++ b/qmake/generators/symbian/initprojectdeploy_symbian.h @@ -69,6 +69,7 @@ extern void initProjectDeploySymbian(QMakeProject* project, DeploymentList &deploymentList, const QString &testPath, bool deployBinaries, + bool epocBuild, const QString &platform, const QString &build, QStringList& generatedDirs, diff --git a/qmake/generators/symbian/symbian_makefile.h b/qmake/generators/symbian/symbian_makefile.h new file mode 100644 index 0000000..f9d3c24 --- /dev/null +++ b/qmake/generators/symbian/symbian_makefile.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIAN_MAKEFILE_H +#define SYMBIAN_MAKEFILE_H + +#include "symbiancommon.h" + +// This allows us to reuse the code for both win32 and unix makefile generators. +template <class T> +class SymbianMakefileTemplate : public T, public SymbianCommonGenerator +{ +public: + SymbianMakefileTemplate() : SymbianCommonGenerator(this) {} + + void init() + { + T::init(); + SymbianCommonGenerator::init(); + } + + bool writeMakefile(QTextStream &t) + { + QString numberOfIcons; + QString iconFile; + QMap<QString, QStringList> userRssRules; + readRssRules(numberOfIcons, iconFile, userRssRules); + + // Generate pkg files if there are any actual files to deploy + bool generatePkg = false; + DeploymentList depList; + + if (targetType == TypeExe) { + generatePkg = true; + } else { + foreach(QString item, this->project->values("DEPLOYMENT")) { + if (!this->project->values(item + ".sources").isEmpty()) { + generatePkg = true; + break; + } + } + } + + if (generatePkg) { + generatePkgFile(iconFile, depList, false); + } + + // Get the application translations and convert to symbian OS lang code, i.e. decical number + QStringList symbianLangCodes = symbianLangCodesFromTsFiles(); + + if (targetType == TypeExe) { + if (!this->project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) { + writeRegRssFile(userRssRules); + writeRssFile(numberOfIcons, iconFile); + writeLocFile(symbianLangCodes); + } + } + + return T::writeMakefile(t); + } +}; + +#endif // SYMBIAN_MAKEFILE_H diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp new file mode 100644 index 0000000..1de4b65 --- /dev/null +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -0,0 +1,872 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "symbiancommon.h" +#include <qdebug.h> + +// Included from tools/shared +#include <symbian/epocroot.h> + +#define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" + +#define RSS_RULES "RSS_RULES" +#define RSS_RULES_BASE "RSS_RULES." +#define RSS_TAG_NBROFICONS "number_of_icons" +#define RSS_TAG_ICONFILE "icon_file" +#define RSS_TAG_HEADER "header" +#define RSS_TAG_SERVICE_LIST "service_list" +#define RSS_TAG_FILE_OWNERSHIP_LIST "file_ownership_list" +#define RSS_TAG_DATATYPE_LIST "datatype_list" +#define RSS_TAG_FOOTER "footer" +#define RSS_TAG_DEFAULT "default_rules" // Same as just giving rules without tag + +#define MANUFACTURER_NOTE_FILE "manufacturer_note.txt" +#define DEFAULT_MANUFACTURER_NOTE \ + "The package is not supported for devices from this manufacturer. Please try the selfsigned " \ + "version of the package instead." + +SymbianCommonGenerator::SymbianCommonGenerator(MakefileGenerator *generator) + : generator(generator) +{ +} + +void SymbianCommonGenerator::init() +{ + QMakeProject *project = generator->project; + fixedTarget = project->first("QMAKE_ORIG_TARGET"); + if (fixedTarget.isEmpty()) + fixedTarget = project->first("TARGET"); + fixedTarget = generator->unescapeFilePath(fixedTarget); + fixedTarget = removePathSeparators(fixedTarget); + if (project->first("MAKEFILE_GENERATOR") == "SYMBIAN_ABLD" + || project->first("MAKEFILE_GENERATOR") == "SYMBIAN_SBSV2") + removeEpocSpecialCharacters(fixedTarget); + else + removeSpecialCharacters(fixedTarget); + + // This should not be empty since the mkspecs are supposed to set it if missing. + uid3 = project->first("TARGET.UID3").trimmed(); + + if ((project->values("TEMPLATE")).contains("app")) + targetType = TypeExe; + else if ((project->values("TEMPLATE")).contains("lib")) { + // Check CONFIG to see if we are to build staticlib or dll + if (project->isActiveConfig("staticlib") || project->isActiveConfig("static")) + targetType = TypeLib; + else if (project->isActiveConfig("plugin")) + targetType = TypePlugin; + else + targetType = TypeDll; + } else { + targetType = TypeSubdirs; + } + + // UID is valid as either hex or decimal, so just convert it to number and back to hex + // to get proper string for private dir + bool conversionOk = false; + uint uidNum = uid3.toUInt(&conversionOk, 0); + + if (!conversionOk) { + fprintf(stderr, "Error: Invalid UID \"%s\".\n", uid3.toUtf8().constData()); + } else { + privateDirUid.setNum(uidNum, 16); + while (privateDirUid.length() < 8) + privateDirUid.insert(0, QLatin1Char('0')); + } +} + +bool SymbianCommonGenerator::containsStartWithItem(const QChar &c, const QStringList& src) +{ + bool result = false; + foreach(QString str, src) { + if (str.startsWith(c)) { + result = true; + break; + } + } + return result; +} + +void SymbianCommonGenerator::removeSpecialCharacters(QString& str) +{ + // When modifying this method check also application_icon.prf + str.replace(QString("/"), QString("_")); + str.replace(QString("\\"), QString("_")); + str.replace(QString(" "), QString("_")); +} + +void SymbianCommonGenerator::removeEpocSpecialCharacters(QString& str) +{ + // When modifying this method check also application_icon.prf + str.replace(QString("-"), QString("_")); + str.replace(QString(":"), QString("_")); + str.replace(QString("."), QString("_")); + removeSpecialCharacters(str); +} + +void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, DeploymentList &depList, bool epocBuild) +{ + QMakeProject *project = generator->project; + QString pkgTarget = project->first("QMAKE_ORIG_TARGET"); + if (pkgTarget.isEmpty()) + pkgTarget = project->first("TARGET"); + pkgTarget = generator->unescapeFilePath(pkgTarget); + pkgTarget = removePathSeparators(pkgTarget); + QString pkgFilename = QString("%1_template.%2").arg(pkgTarget).arg("pkg"); + if (!Option::output_dir.isEmpty()) + pkgFilename = Option::output_dir + '/' + pkgFilename; + + QFile pkgFile(pkgFilename); + if (!pkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + PRINT_FILE_CREATE_ERROR(pkgFilename); + return; + } + + generatedFiles << pkgFile.fileName(); + QTextStream t(&pkgFile); + + QString installerSisHeader = project->values("DEPLOYMENT.installer_header").join("\n"); + QString wrapperStreamBuffer; + QTextStream tw(&wrapperStreamBuffer); + + QString dateStr = QDateTime::currentDateTime().toString(Qt::ISODate); + + // Header info + QString wrapperPkgFilename = QString("%1_installer.%2") + .arg(pkgTarget) + .arg("pkg"); + QString headerComment = "; %1 generated by qmake at %2\n" + "; This file is generated by qmake and should not be modified by the user\n" + ";\n\n"; + t << headerComment.arg(pkgFilename).arg(dateStr); + tw << headerComment.arg(wrapperPkgFilename).arg(dateStr); + + // Construct QStringList from pkg_prerules since we need search it before printed to file + QStringList rawPkgPreRules; + foreach(QString deploymentItem, project->values("DEPLOYMENT")) { + foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) { + QStringList pkgrulesValue = project->values(pkgrulesItem); + // If there is no stringlist defined for a rule, use rule name directly + // This is convenience for defining single line mmp statements + if (pkgrulesValue.isEmpty()) { + rawPkgPreRules << pkgrulesItem; + } else { + foreach(QString pkgrule, pkgrulesValue) { + rawPkgPreRules << pkgrule; + } + } + } + } + + // Apply some defaults if specific data does not exist in PKG pre-rules + + if (!containsStartWithItem('&', rawPkgPreRules)) { + // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS) + QString languageCode = "; Language\n&EN\n\n"; + t << languageCode; + tw << languageCode; + } else { + // In case user defines langs, he must take care also about SIS header + if (!containsStartWithItem('#', rawPkgPreRules)) + fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n"); + } + + // name of application, UID and version + QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ','); + QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n"; + QString visualTarget = generator->escapeFilePath(project->first("TARGET")); + + visualTarget = removePathSeparators(visualTarget); + QString wrapperTarget = visualTarget + " installer"; + + if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) { + tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion); + } else { + tw << installerSisHeader << endl; + } + if (!containsStartWithItem('#', rawPkgPreRules)) { + t << sisHeader.arg(visualTarget).arg(uid3).arg(applicationVersion); + } + + // Localized vendor name + QString vendorName; + if (!containsStartWithItem('%', rawPkgPreRules)) { + vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n"; + } + + // Unique vendor name + if (!containsStartWithItem(':', rawPkgPreRules)) { + vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n"; + } + + t << vendorName; + tw << vendorName; + + // PKG pre-rules - these are added before actual file installations i.e. SIS package body + if (rawPkgPreRules.size()) { + QString comment = "\n; Manual PKG pre-rules from PRO files\n"; + t << comment; + tw << comment; + + foreach(QString item, rawPkgPreRules) { + // Only regular pkg file should have package dependencies or pkg header if that is + // defined using prerules. + if (!item.startsWith("(") && !item.startsWith("#")) { + tw << item << endl; + } + t << item << endl; + } + t << endl; + tw << endl; + } + + // Begin Manufacturer block + if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { + QString manufacturerStr("IF "); + foreach(QString manufacturer, project->values("DEPLOYMENT.manufacturers")) { + manufacturerStr.append(QString("(MANUFACTURER)=(%1) OR \n ").arg(manufacturer)); + } + // Remove the final OR + manufacturerStr.chop(8); + t << manufacturerStr << endl; + } + + // Install paths on the phone *** should be dynamic at some point + QString installPathBin = "!:\\sys\\bin"; + QString installPathResource = "!:\\resource\\apps"; + QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps"; + + // Find location of builds + QString destDirBin; + QString destDirResource; + QString destDirRegResource; + if (epocBuild) { + destDirBin = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)").arg(epocRoot()); + destDirResource = QString("%1epoc32/data/z/resource/apps").arg(epocRoot()); + destDirRegResource = QString("%1epoc32/data/z/private/10003a3f/import/apps").arg(epocRoot()); + } else { + destDirBin = project->first("DESTDIR"); + if (destDirBin.isEmpty()) + destDirBin = "."; + else if (destDirBin.endsWith('/') || destDirBin.endsWith('\\')) + destDirBin.chop(1); + destDirResource = destDirBin; + destDirRegResource = destDirBin; + } + + if (targetType == TypeExe) { + // deploy .exe file + t << "; Executable and default resource files" << endl; + QString exeFile = fixedTarget + ".exe"; + t << QString("\"%1/%2\" - \"%3\\%4\"") + .arg(destDirBin) + .arg(exeFile) + .arg(installPathBin) + .arg(exeFile) << endl; + + // deploy rsc & reg_rsc file + if (!project->isActiveConfig("no_icon")) { + t << QString("\"%1/%2\" - \"%3\\%4\"") + .arg(destDirResource) + .arg(fixedTarget + ".rsc") + .arg(installPathResource) + .arg(fixedTarget + ".rsc") << endl; + + t << QString("\"%1/%2\" - \"%3\\%4\"") + .arg(destDirRegResource) + .arg(fixedTarget + "_reg.rsc") + .arg(installPathRegResource) + .arg(fixedTarget + "_reg.rsc") << endl; + + if (!iconFile.isEmpty()) { + if (epocBuild) { + t << QString("\"%1epoc32/data/z%2\" - \"!:%3\"") + .arg(epocRoot()) + .arg(iconFile) + .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; + } else { + QDir mifIconDir(project->first("DESTDIR")); + QFileInfo mifIcon(mifIconDir.relativeFilePath(project->first("TARGET"))); + QString mifIconFileName = mifIcon.fileName(); + mifIconFileName.append(".mif"); + t << QString("\"%1/%2\" - \"!:%3\"") + .arg(mifIcon.path()) + .arg(mifIconFileName) + .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; + } + } + } + } + + // deploy any additional DEPLOYMENT files + QString remoteTestPath; + remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid); + + initProjectDeploySymbian(project, depList, remoteTestPath, true, epocBuild, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles); + if (depList.size()) + t << "; DEPLOYMENT" << endl; + for (int i = 0; i < depList.size(); ++i) { + t << QString("\"%1\" - \"%2\"") + .arg(depList.at(i).from) + .arg(depList.at(i).to) << endl; + } + t << endl; + + // PKG post-rules - these are added after actual file installations i.e. SIS package body + t << "; Manual PKG post-rules from PRO files" << endl; + foreach(QString deploymentItem, project->values("DEPLOYMENT")) { + foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_postrules")) { + QStringList pkgrulesValue = project->values(pkgrulesItem); + // If there is no stringlist defined for a rule, use rule name directly + // This is convenience for defining single line statements + if (pkgrulesValue.isEmpty()) { + t << pkgrulesItem << endl; + } else { + foreach(QString pkgrule, pkgrulesValue) { + t << pkgrule << endl; + } + } + t << endl; + } + } + + // Close Manufacturer block + if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { + QString manufacturerFailNoteFile; + if (project->values("DEPLOYMENT.manufacturers.fail_note").isEmpty()) { + manufacturerFailNoteFile = QString("%1_" MANUFACTURER_NOTE_FILE).arg(uid3); + QFile ft(manufacturerFailNoteFile); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t2(&ft); + + t2 << QString(DEFAULT_MANUFACTURER_NOTE) << endl; + } else { + PRINT_FILE_CREATE_ERROR(manufacturerFailNoteFile) + } + } else { + manufacturerFailNoteFile = project->values("DEPLOYMENT.manufacturers.fail_note").join(""); + } + + t << "ELSEIF NOT(0) ; MANUFACTURER" << endl + << "\"" << generator->fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\"" + << " - \"\", FILETEXT, TEXTEXIT" << endl + << "ENDIF ; MANUFACTURER" << endl; + } + + // Write wrapper pkg + if (!installerSisHeader.isEmpty()) { + QFile wrapperPkgFile(wrapperPkgFilename); + if (!wrapperPkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { + PRINT_FILE_CREATE_ERROR(wrapperPkgFilename); + return; + } + + generatedFiles << wrapperPkgFile.fileName(); + QTextStream twf(&wrapperPkgFile); + + twf << wrapperStreamBuffer << endl; + + // Wrapped files deployment + QString currentPath = qmake_getpwd(); + QString sisName = QString("%1.sis").arg(pkgTarget); + twf << "\"" << currentPath << "/" << sisName << "\" - \"c:\\adm\\" << sisName << "\"" << endl; + + QString bootStrapPath = QLibraryInfo::location(QLibraryInfo::PrefixPath); + bootStrapPath.append("/bootstrap.sis"); + QFileInfo fi(generator->fileInfo(bootStrapPath)); + twf << "@\"" << fi.absoluteFilePath() << "\",(0x2002CCCD)" << endl; + } +} + +QString SymbianCommonGenerator::removePathSeparators(QString &file) +{ + QString ret = file; + while (ret.indexOf(QDir::separator()) > 0) { + ret.remove(0, ret.indexOf(QDir::separator()) + 1); + } + + return ret; +} + +void SymbianCommonGenerator::writeRegRssFile(QMap<QString, QStringList> &userItems) +{ + QString filename(fixedTarget); + filename.append("_reg.rss"); + if (!Option::output_dir.isEmpty()) + filename = Option::output_dir + '/' + filename; + QFile ft(filename); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t(&ft); + t << "// ============================================================================" << endl; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; + t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; + t << "// * This file is generated by qmake and should not be modified by the" << endl; + t << "// * user." << endl; + t << "// ============================================================================" << endl; + t << endl; + t << "#include <" << fixedTarget << ".rsg>" << endl; + t << "#include <appinfo.rh>" << endl; + foreach(QString item, userItems[RSS_TAG_HEADER]) + t << item << endl; + t << endl; + t << "UID2 KUidAppRegistrationResourceFile" << endl; + t << "UID3 " << uid3 << endl << endl; + t << "RESOURCE APP_REGISTRATION_INFO" << endl; + t << "\t{" << endl; + t << "\tapp_file=\"" << fixedTarget << "\";" << endl; + t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl; + + writeRegRssList(t, userItems[RSS_TAG_SERVICE_LIST], + QLatin1String(RSS_TAG_SERVICE_LIST), + QLatin1String("SERVICE_INFO")); + writeRegRssList(t, userItems[RSS_TAG_FILE_OWNERSHIP_LIST], + QLatin1String(RSS_TAG_FILE_OWNERSHIP_LIST), + QLatin1String("FILE_OWNERSHIP_INFO")); + writeRegRssList(t, userItems[RSS_TAG_DATATYPE_LIST], + QLatin1String(RSS_TAG_DATATYPE_LIST), + QLatin1String("DATATYPE")); + t << endl; + + foreach(QString item, userItems[RSS_TAG_DEFAULT]) + t << "\t" << item.replace("\n","\n\t") << endl; + t << "\t}" << endl; + + foreach(QString item, userItems[RSS_TAG_FOOTER]) + t << item << endl; + } else { + PRINT_FILE_CREATE_ERROR(filename) + } +} + +void SymbianCommonGenerator::writeRegRssList(QTextStream &t, + QStringList &userList, + const QString &listTag, + const QString &listItem) +{ + int itemCount = userList.count(); + if (itemCount) { + t << "\t" << listTag << " ="<< endl; + t << "\t\t{" << endl; + foreach(QString item, userList) { + t << "\t\t" << listItem << endl; + t << "\t\t\t{" << endl; + t << "\t\t\t" << item.replace("\n","\n\t\t\t") << endl; + t << "\t\t\t}"; + if (--itemCount) + t << ","; + t << endl; + } + t << "\t\t}; "<< endl; + } +} + +void SymbianCommonGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile) +{ + QString filename(fixedTarget); + if (!Option::output_dir.isEmpty()) + filename = Option::output_dir + '/' + filename; + filename.append(".rss"); + QFile ft(filename); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t(&ft); + t << "// ============================================================================" << endl; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; + t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; + t << "// * This file is generated by qmake and should not be modified by the" << endl; + t << "// * user." << endl; + t << "// ============================================================================" << endl; + t << endl; + t << "#include <appinfo.rh>" << endl; + t << "#include \"" << fixedTarget << ".loc\"" << endl; + t << endl; + t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl; + t << "\t{" << endl; + t << "\tshort_caption = STRING_r_short_caption;" << endl; + t << "\tcaption_and_icon =" << endl; + t << "\tCAPTION_AND_ICON_INFO" << endl; + t << "\t\t{" << endl; + t << "\t\tcaption = STRING_r_caption;" << endl; + + QString rssIconFile = iconFile; + rssIconFile = rssIconFile.replace("/", "\\\\"); + + if (numberOfIcons.isEmpty() || rssIconFile.isEmpty()) { + // There can be maximum one item in this tag, validated when parsed + t << "\t\tnumber_of_icons = 0;" << endl; + t << "\t\ticon_file = \"\";" << endl; + } else { + // There can be maximum one item in this tag, validated when parsed + t << "\t\tnumber_of_icons = " << numberOfIcons << ";" << endl; + t << "\t\ticon_file = \"" << rssIconFile << "\";" << endl; + } + t << "\t\t};" << endl; + t << "\t}" << endl; + t << endl; + } else { + PRINT_FILE_CREATE_ERROR(filename); + } +} + +void SymbianCommonGenerator::writeLocFile(QStringList &symbianLangCodes) +{ + QString filename(fixedTarget); + if (!Option::output_dir.isEmpty()) + filename = Option::output_dir + '/' + filename; + filename.append(".loc"); + QFile ft(filename); + if (ft.open(QIODevice::WriteOnly)) { + generatedFiles << ft.fileName(); + QTextStream t(&ft); + t << "// ============================================================================" << endl; + t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; + t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; + t << "// * This file is generated by qmake and should not be modified by the" << endl; + t << "// * user." << endl; + t << "// ============================================================================" << endl; + t << endl; + t << "#ifdef LANGUAGE_SC" << endl; + t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + foreach(QString lang, symbianLangCodes) { + t << "#elif defined LANGUAGE_" << lang << endl; + t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + } + t << "#else" << endl; + t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; + t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; + t << "#endif" << endl; + } else { + PRINT_FILE_CREATE_ERROR(filename); + } +} + +void SymbianCommonGenerator::readRssRules(QString &numberOfIcons, + QString &iconFile, QMap<QString, + QStringList> &userRssRules) +{ + QMakeProject *project = generator->project; + for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) { + if (it.key().startsWith(RSS_RULES_BASE)) { + QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1); + if (newKey.isEmpty()) { + fprintf(stderr, "Warning: Empty RSS_RULES_BASE key encountered\n"); + continue; + } + QStringList newValues; + QStringList values = it.value(); + foreach(QString item, values) { + // If there is no stringlist defined for a rule, use rule value directly + // This is convenience for defining single line statements + if (project->values(item).isEmpty()) { + newValues << item; + } else { + QStringList itemList; + foreach(QString itemRow, project->values(item)) { + itemList << itemRow; + } + newValues << itemList.join("\n"); + } + } + // Verify thet there is exactly one value in RSS_TAG_NBROFICONS + if (newKey == RSS_TAG_NBROFICONS) { + if (newValues.count() == 1) { + numberOfIcons = newValues[0]; + } else { + fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n", + RSS_RULES_BASE, RSS_TAG_NBROFICONS); + continue; + } + // Verify thet there is exactly one value in RSS_TAG_ICONFILE + } else if (newKey == RSS_TAG_ICONFILE) { + if (newValues.count() == 1) { + iconFile = newValues[0]; + } else { + fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n", + RSS_RULES_BASE, RSS_TAG_ICONFILE); + continue; + } + } else if (newKey == RSS_TAG_HEADER + || newKey == RSS_TAG_SERVICE_LIST + || newKey == RSS_TAG_FILE_OWNERSHIP_LIST + || newKey == RSS_TAG_DATATYPE_LIST + || newKey == RSS_TAG_FOOTER + || newKey == RSS_TAG_DEFAULT) { + userRssRules[newKey] = newValues; + continue; + } else { + fprintf(stderr, "Warning: Unsupported key:'%s%s'\n", + RSS_RULES_BASE, newKey.toLatin1().constData()); + continue; + } + } + } + + QStringList newValues; + foreach(QString item, project->values(RSS_RULES)) { + // If there is no stringlist defined for a rule, use rule value directly + // This is convenience for defining single line statements + if (project->values(item).isEmpty()) { + newValues << item; + } else { + newValues << project->values(item); + } + } + userRssRules[RSS_TAG_DEFAULT] << newValues; + + // Validate that either both RSS_TAG_NBROFICONS and RSS_TAG_ICONFILE keys exist + // or neither of them exist + if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) || + (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) { + numberOfIcons.clear(); + iconFile.clear(); + fprintf(stderr, "Warning: Both or neither of '%s%s' and '%s%s' keys must exist.\n", + RSS_RULES_BASE, RSS_TAG_NBROFICONS, RSS_RULES_BASE, RSS_TAG_ICONFILE); + } + + // Validate that RSS_TAG_NBROFICONS contains only numbers + if (!numberOfIcons.isEmpty()) { + bool ok; + numberOfIcons = numberOfIcons.simplified(); + numberOfIcons.toInt(&ok); + if (!ok) { + numberOfIcons.clear(); + iconFile.clear(); + fprintf(stderr, "Warning: '%s%s' must be integer in decimal format.\n", + RSS_RULES_BASE, RSS_TAG_NBROFICONS); + } + } +} + +QStringList SymbianCommonGenerator::symbianLangCodesFromTsFiles() +{ + QStringList tsfiles; + QStringList symbianLangCodes; + tsfiles << generator->project->values("TRANSLATIONS"); + + fillQt2S60LangMapTable(); + + foreach(QString file, tsfiles) { + int extIndex = file.lastIndexOf("."); + int langIndex = file.lastIndexOf("_", (extIndex - file.length())); + langIndex += 1; + QString qtlang = file.mid(langIndex, extIndex - langIndex); + QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC")); + + if (!symbianLangCodes.contains(s60lang) && s60lang != "SC") + symbianLangCodes += s60lang; + } + + return symbianLangCodes; +} + +void SymbianCommonGenerator::fillQt2S60LangMapTable() +{ + qt2S60LangMapTable.reserve(170); // 165 items at time of writing. + qt2S60LangMapTable.insert("ab", "SC"); //Abkhazian // + qt2S60LangMapTable.insert("om", "SC"); //Afan // + qt2S60LangMapTable.insert("aa", "SC"); //Afar // + qt2S60LangMapTable.insert("af", "34"); //Afrikaans //Afrikaans + qt2S60LangMapTable.insert("sq", "35"); //Albanian //Albanian + qt2S60LangMapTable.insert("am", "36"); //Amharic //Amharic + qt2S60LangMapTable.insert("ar", "37"); //Arabic //Arabic + qt2S60LangMapTable.insert("hy", "38"); //Armenian //Armenian + qt2S60LangMapTable.insert("as", "SC"); //Assamese // + qt2S60LangMapTable.insert("ay", "SC"); //Aymara // + qt2S60LangMapTable.insert("az", "SC"); //Azerbaijani // + qt2S60LangMapTable.insert("ba", "SC"); //Bashkir // + qt2S60LangMapTable.insert("eu", "SC"); //Basque // + qt2S60LangMapTable.insert("bn", "41"); //Bengali //Bengali + qt2S60LangMapTable.insert("dz", "SC"); //Bhutani // + qt2S60LangMapTable.insert("bh", "SC"); //Bihari // + qt2S60LangMapTable.insert("bi", "SC"); //Bislama // + qt2S60LangMapTable.insert("br", "SC"); //Breton // + qt2S60LangMapTable.insert("bg", "42"); //Bulgarian //Bulgarian + qt2S60LangMapTable.insert("my", "43"); //Burmese //Burmese + qt2S60LangMapTable.insert("be", "40"); //Byelorussian //Belarussian + qt2S60LangMapTable.insert("km", "SC"); //Cambodian // + qt2S60LangMapTable.insert("ca", "44"); //Catalan //Catalan + qt2S60LangMapTable.insert("zh", "SC"); //Chinese // + qt2S60LangMapTable.insert("co", "SC"); //Corsican // + qt2S60LangMapTable.insert("hr", "45"); //Croatian //Croatian + qt2S60LangMapTable.insert("cs", "25"); //Czech //Czech + qt2S60LangMapTable.insert("da", "07"); //Danish //Danish + qt2S60LangMapTable.insert("nl", "18"); //Dutch //Dutch + qt2S60LangMapTable.insert("en", "01"); //English //English(UK) + qt2S60LangMapTable.insert("eo", "SC"); //Esperanto // + qt2S60LangMapTable.insert("et", "49"); //Estonian //Estonian + qt2S60LangMapTable.insert("fo", "SC"); //Faroese // + qt2S60LangMapTable.insert("fj", "SC"); //Fiji // + qt2S60LangMapTable.insert("fi", "09"); //Finnish //Finnish + qt2S60LangMapTable.insert("fr", "02"); //French //French + qt2S60LangMapTable.insert("fy", "SC"); //Frisian // + qt2S60LangMapTable.insert("gd", "52"); //Gaelic //Gaelic + qt2S60LangMapTable.insert("gl", "SC"); //Galician // + qt2S60LangMapTable.insert("ka", "53"); //Georgian //Georgian + qt2S60LangMapTable.insert("de", "03"); //German //German + qt2S60LangMapTable.insert("el", "54"); //Greek //Greek + qt2S60LangMapTable.insert("kl", "SC"); //Greenlandic // + qt2S60LangMapTable.insert("gn", "SC"); //Guarani // + qt2S60LangMapTable.insert("gu", "56"); //Gujarati //Gujarati + qt2S60LangMapTable.insert("ha", "SC"); //Hausa // + qt2S60LangMapTable.insert("he", "57"); //Hebrew //Hebrew + qt2S60LangMapTable.insert("hi", "58"); //Hindi //Hindi + qt2S60LangMapTable.insert("hu", "17"); //Hungarian //Hungarian + qt2S60LangMapTable.insert("is", "15"); //Icelandic //Icelandic + qt2S60LangMapTable.insert("id", "59"); //Indonesian //Indonesian + qt2S60LangMapTable.insert("ia", "SC"); //Interlingua // + qt2S60LangMapTable.insert("ie", "SC"); //Interlingue // + qt2S60LangMapTable.insert("iu", "SC"); //Inuktitut // + qt2S60LangMapTable.insert("ik", "SC"); //Inupiak // + qt2S60LangMapTable.insert("ga", "60"); //Irish //Irish + qt2S60LangMapTable.insert("it", "05"); //Italian //Italian + qt2S60LangMapTable.insert("ja", "32"); //Japanese //Japanese + qt2S60LangMapTable.insert("jv", "SC"); //Javanese // + qt2S60LangMapTable.insert("kn", "62"); //Kannada //Kannada + qt2S60LangMapTable.insert("ks", "SC"); //Kashmiri // + qt2S60LangMapTable.insert("kk", "63"); //Kazakh //Kazakh + qt2S60LangMapTable.insert("rw", "SC"); //Kinyarwanda // + qt2S60LangMapTable.insert("ky", "SC"); //Kirghiz // + qt2S60LangMapTable.insert("ko", "65"); //Korean //Korean + qt2S60LangMapTable.insert("ku", "SC"); //Kurdish // + qt2S60LangMapTable.insert("rn", "SC"); //Kurundi // + qt2S60LangMapTable.insert("lo", "66"); //Laothian //Laothian + qt2S60LangMapTable.insert("la", "SC"); //Latin // + qt2S60LangMapTable.insert("lv", "67"); //Latvian //Latvian + qt2S60LangMapTable.insert("ln", "SC"); //Lingala // + qt2S60LangMapTable.insert("lt", "68"); //Lithuanian //Lithuanian + qt2S60LangMapTable.insert("mk", "69"); //Macedonian //Macedonian + qt2S60LangMapTable.insert("mg", "SC"); //Malagasy // + qt2S60LangMapTable.insert("ms", "70"); //Malay //Malay + qt2S60LangMapTable.insert("ml", "71"); //Malayalam //Malayalam + qt2S60LangMapTable.insert("mt", "SC"); //Maltese // + qt2S60LangMapTable.insert("mi", "SC"); //Maori // + qt2S60LangMapTable.insert("mr", "72"); //Marathi //Marathi + qt2S60LangMapTable.insert("mo", "73"); //Moldavian //Moldovian + qt2S60LangMapTable.insert("mn", "74"); //Mongolian //Mongolian + qt2S60LangMapTable.insert("na", "SC"); //Nauru // + qt2S60LangMapTable.insert("ne", "SC"); //Nepali // + qt2S60LangMapTable.insert("nb", "08"); //Norwegian //Norwegian + qt2S60LangMapTable.insert("oc", "SC"); //Occitan // + qt2S60LangMapTable.insert("or", "SC"); //Oriya // + qt2S60LangMapTable.insert("ps", "SC"); //Pashto // + qt2S60LangMapTable.insert("fa", "SC"); //Persian // + qt2S60LangMapTable.insert("pl", "27"); //Polish //Polish + qt2S60LangMapTable.insert("pt", "13"); //Portuguese //Portuguese + qt2S60LangMapTable.insert("pa", "77"); //Punjabi //Punjabi + qt2S60LangMapTable.insert("qu", "SC"); //Quechua // + qt2S60LangMapTable.insert("rm", "SC"); //RhaetoRomance // + qt2S60LangMapTable.insert("ro", "78"); //Romanian //Romanian + qt2S60LangMapTable.insert("ru", "16"); //Russian //Russian + qt2S60LangMapTable.insert("sm", "SC"); //Samoan // + qt2S60LangMapTable.insert("sg", "SC"); //Sangho // + qt2S60LangMapTable.insert("sa", "SC"); //Sanskrit // + qt2S60LangMapTable.insert("sr", "79"); //Serbian //Serbian + qt2S60LangMapTable.insert("sh", "SC"); //SerboCroatian // + qt2S60LangMapTable.insert("st", "SC"); //Sesotho // + qt2S60LangMapTable.insert("tn", "SC"); //Setswana // + qt2S60LangMapTable.insert("sn", "SC"); //Shona // + qt2S60LangMapTable.insert("sd", "SC"); //Sindhi // + qt2S60LangMapTable.insert("si", "80"); //Singhalese //Sinhalese + qt2S60LangMapTable.insert("ss", "SC"); //Siswati // + qt2S60LangMapTable.insert("sk", "26"); //Slovak //Slovak + qt2S60LangMapTable.insert("sl", "28"); //Slovenian //Slovenian + qt2S60LangMapTable.insert("so", "81"); //Somali //Somali + qt2S60LangMapTable.insert("es", "04"); //Spanish //Spanish + qt2S60LangMapTable.insert("su", "SC"); //Sundanese // + qt2S60LangMapTable.insert("sw", "84"); //Swahili //Swahili + qt2S60LangMapTable.insert("sv", "06"); //Swedish //Swedish + qt2S60LangMapTable.insert("tl", "39"); //Tagalog //Tagalog + qt2S60LangMapTable.insert("tg", "SC"); //Tajik // + qt2S60LangMapTable.insert("ta", "87"); //Tamil //Tamil + qt2S60LangMapTable.insert("tt", "SC"); //Tatar // + qt2S60LangMapTable.insert("te", "88"); //Telugu //Telugu + qt2S60LangMapTable.insert("th", "33"); //Thai //Thai + qt2S60LangMapTable.insert("bo", "89"); //Tibetan //Tibetan + qt2S60LangMapTable.insert("ti", "90"); //Tigrinya //Tigrinya + qt2S60LangMapTable.insert("to", "SC"); //Tonga // + qt2S60LangMapTable.insert("ts", "SC"); //Tsonga // + qt2S60LangMapTable.insert("tr", "14"); //Turkish //Turkish + qt2S60LangMapTable.insert("tk", "92"); //Turkmen //Turkmen + qt2S60LangMapTable.insert("tw", "SC"); //Twi // + qt2S60LangMapTable.insert("ug", "SC"); //Uigur // + qt2S60LangMapTable.insert("uk", "93"); //Ukrainian //Ukrainian + qt2S60LangMapTable.insert("ur", "94"); //Urdu //Urdu + qt2S60LangMapTable.insert("uz", "SC"); //Uzbek // + qt2S60LangMapTable.insert("vi", "96"); //Vietnamese //Vietnamese + qt2S60LangMapTable.insert("vo", "SC"); //Volapuk // + qt2S60LangMapTable.insert("cy", "97"); //Welsh //Welsh + qt2S60LangMapTable.insert("wo", "SC"); //Wolof // + qt2S60LangMapTable.insert("xh", "SC"); //Xhosa // + qt2S60LangMapTable.insert("yi", "SC"); //Yiddish // + qt2S60LangMapTable.insert("yo", "SC"); //Yoruba // + qt2S60LangMapTable.insert("za", "SC"); //Zhuang // + qt2S60LangMapTable.insert("zu", "98"); //Zulu //Zulu + qt2S60LangMapTable.insert("nn", "75"); //Nynorsk //NorwegianNynorsk + qt2S60LangMapTable.insert("bs", "SC"); //Bosnian // + qt2S60LangMapTable.insert("dv", "SC"); //Divehi // + qt2S60LangMapTable.insert("gv", "SC"); //Manx // + qt2S60LangMapTable.insert("kw", "SC"); //Cornish // + qt2S60LangMapTable.insert("ak", "SC"); //Akan // + qt2S60LangMapTable.insert("kok", "SC"); //Konkani // + qt2S60LangMapTable.insert("gaa", "SC"); //Ga // + qt2S60LangMapTable.insert("ig", "SC"); //Igbo // + qt2S60LangMapTable.insert("kam", "SC"); //Kamba // + qt2S60LangMapTable.insert("syr", "SC"); //Syriac // + qt2S60LangMapTable.insert("byn", "SC"); //Blin // + qt2S60LangMapTable.insert("gez", "SC"); //Geez // + qt2S60LangMapTable.insert("kfo", "SC"); //Koro // + qt2S60LangMapTable.insert("sid", "SC"); //Sidamo // + qt2S60LangMapTable.insert("cch", "SC"); //Atsam // + qt2S60LangMapTable.insert("tig", "SC"); //Tigre // + qt2S60LangMapTable.insert("kaj", "SC"); //Jju // + qt2S60LangMapTable.insert("fur", "SC"); //Friulian // + qt2S60LangMapTable.insert("ve", "SC"); //Venda // + qt2S60LangMapTable.insert("ee", "SC"); //Ewe // + qt2S60LangMapTable.insert("wa", "SC"); //Walamo // + qt2S60LangMapTable.insert("haw", "SC"); //Hawaiian // + qt2S60LangMapTable.insert("kcg", "SC"); //Tyap // + qt2S60LangMapTable.insert("ny", "SC"); //Chewa // +} + diff --git a/qmake/generators/symbian/symbiancommon.h b/qmake/generators/symbian/symbiancommon.h new file mode 100644 index 0000000..e2b1173 --- /dev/null +++ b/qmake/generators/symbian/symbiancommon.h @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake application of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef SYMBIANCOMMON_H +#define SYMBIANCOMMON_H + +#include <project.h> +#include <makefile.h> +#include "initprojectdeploy_symbian.h" + +#define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename)); + +class SymbianCommonGenerator +{ +public: + enum TargetType { + TypeExe, + TypeDll, + TypeLib, + TypePlugin, + TypeSubdirs + }; + + SymbianCommonGenerator(MakefileGenerator *generator); + + virtual void init(); + +protected: + + QString removePathSeparators(QString &file); + void removeSpecialCharacters(QString& str); + void removeEpocSpecialCharacters(QString& str); + void generatePkgFile(const QString &iconFile, DeploymentList &depList, bool epocBuild); + bool containsStartWithItem(const QChar &c, const QStringList& src); + + void writeRegRssFile(QMap<QString, QStringList> &useritems); + void writeRegRssList(QTextStream &t, QStringList &userList, + const QString &listTag, + const QString &listItem); + void writeRssFile(QString &numberOfIcons, QString &iconfile); + void writeLocFile(QStringList &symbianLangCodes); + void readRssRules(QString &numberOfIcons, + QString &iconFile, + QMap<QString, QStringList> &userRssRules); + + QStringList symbianLangCodesFromTsFiles(); + void fillQt2S60LangMapTable(); + +protected: + MakefileGenerator *generator; + + QStringList generatedFiles; + QStringList generatedDirs; + QString fixedTarget; + QString privateDirUid; + QString uid3; + TargetType targetType; + + QHash<QString, QString> qt2S60LangMapTable; +}; + +#endif // SYMBIANCOMMON_H diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index e1256d8..0fcd26d 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -53,10 +53,10 @@ #include <symbian/epocroot.h> #define RESOURCE_DIRECTORY_MMP "/resource/apps" -#define RESOURCE_DIRECTORY_RESOURCE "\\\\resource\\\\apps\\\\" #define REGISTRATION_RESOURCE_DIRECTORY_HW "/private/10003a3f/import/apps" #define PLUGIN_COMMON_DEF_FILE_FOR_MMP "./plugin_common.def" -#define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonU.def" +#define PLUGIN_COMMON_DEF_FILE_ACTUAL "plugin_commonu.def" +#define BLD_INF_FILENAME_LEN (sizeof(BLD_INF_FILENAME) - 1) #define BLD_INF_RULES_BASE "BLD_INF_RULES." #define BLD_INF_TAG_PLATFORMS "prj_platforms" @@ -65,17 +65,6 @@ #define BLD_INF_TAG_EXTENSIONS "prj_extensions" #define BLD_INF_TAG_TESTEXTENSIONS "prj_testextensions" -#define RSS_RULES "RSS_RULES" -#define RSS_RULES_BASE "RSS_RULES." -#define RSS_TAG_NBROFICONS "number_of_icons" -#define RSS_TAG_ICONFILE "icon_file" -#define RSS_TAG_HEADER "header" -#define RSS_TAG_SERVICE_LIST "service_list" -#define RSS_TAG_FILE_OWNERSHIP_LIST "file_ownership_list" -#define RSS_TAG_DATATYPE_LIST "datatype_list" -#define RSS_TAG_FOOTER "footer" -#define RSS_TAG_DEFAULT "default_rules" // Same as just giving rules without tag - #define MMP_TARGET "TARGET" #define MMP_TARGETTYPE "TARGETTYPE" #define MMP_SECUREID "SECUREID" @@ -95,22 +84,6 @@ #define MMP_START_RESOURCE "START RESOURCE" #define MMP_END_RESOURCE "END" -#define SIS_TARGET "sis" -#define INSTALLER_SIS_TARGET "installer_sis" -#define ROM_STUB_SIS_TARGET "stub_sis" -#define OK_SIS_TARGET "ok_sis" -#define OK_INSTALLER_SIS_TARGET "ok_installer_sis" -#define OK_ROM_STUB_SIS_TARGET "ok_stub_sis" -#define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg" -#define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache" - -#define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename)); - -#define MANUFACTURER_NOTE_FILE "manufacturer_note.txt" -#define DEFAULT_MANUFACTURER_NOTE \ - "The package is not supported for devices from this manufacturer. Please try the selfsigned " \ - "version of the package instead." - QString SymbianMakefileGenerator::fixPathForMmp(const QString& origPath, const QDir& parentDir) { static QString epocRootStr; @@ -168,7 +141,7 @@ QString SymbianMakefileGenerator::absolutizePath(const QString& origPath) return resultPath; } -SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator() { } +SymbianMakefileGenerator::SymbianMakefileGenerator() : MakefileGenerator(), SymbianCommonGenerator(this) { } SymbianMakefileGenerator::~SymbianMakefileGenerator() { } void SymbianMakefileGenerator::writeHeader(QTextStream &t) @@ -195,7 +168,7 @@ void SymbianMakefileGenerator::writeHeader(QTextStream &t) bldinfDefine.append(generate_uid(project->projectFile())); bldinfDefine.prepend("BLD_INF_"); - removeSpecialCharacters(bldinfDefine); + removeEpocSpecialCharacters(bldinfDefine); t << "#define " << bldinfDefine.toUpper() << endl << endl; } @@ -228,7 +201,7 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) } if (generatePkg) { - generatePkgFile(iconFile, depList); + generatePkgFile(iconFile, depList, true); } writeBldInfContent(t, generatePkg, iconFile, depList); @@ -288,299 +261,6 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) return true; } -void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile, DeploymentList &depList) -{ - QString pkgFilename = QString("%1_template.%2") - .arg(fixedTarget) - .arg("pkg"); - QFile pkgFile(pkgFilename); - if (!pkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - PRINT_FILE_CREATE_ERROR(pkgFilename); - return; - } - - generatedFiles << pkgFile.fileName(); - QTextStream t(&pkgFile); - - QString installerSisHeader = project->values("DEPLOYMENT.installer_header").join("\n"); - if (installerSisHeader.isEmpty()) - installerSisHeader = "0xA000D7CE"; // Use default self-signable UID if not defined - - QString wrapperStreamBuffer; - QTextStream tw(&wrapperStreamBuffer); - - QString dateStr = QDateTime::currentDateTime().toString(Qt::ISODate); - - // Header info - QString wrapperPkgFilename = QString("%1_installer.%2") - .arg(fixedTarget) - .arg("pkg"); - QString headerComment = "; %1 generated by qmake at %2\n" - "; This file is generated by qmake and should not be modified by the user\n" - ";\n\n"; - t << headerComment.arg(pkgFilename).arg(dateStr); - tw << headerComment.arg(wrapperPkgFilename).arg(dateStr); - - // Construct QStringList from pkg_prerules since we need search it before printed to file - // Note: Though there can't be more than one language or header line, use stringlists - // in case user wants comments to go with the rules. - QStringList rawPkgPreRules; - QStringList languageRules; - QStringList headerRules; - foreach(QString deploymentItem, project->values("DEPLOYMENT")) { - foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_prerules")) { - QStringList pkgrulesValue = project->values(pkgrulesItem); - // If there is no stringlist defined for a rule, use rule name directly - // This is convenience for defining single line mmp statements - if (pkgrulesValue.isEmpty()) { - if (pkgrulesItem.startsWith("&")) - languageRules << pkgrulesItem; - else if (pkgrulesItem.startsWith("#")) - headerRules << pkgrulesItem; - else - rawPkgPreRules << pkgrulesItem; - } else { - if (containsStartWithItem('&', pkgrulesValue)) { - foreach(QString pkgrule, pkgrulesValue) { - languageRules << pkgrule; - } - } else if (containsStartWithItem('#', pkgrulesValue)) { - foreach(QString pkgrule, pkgrulesValue) { - headerRules << pkgrule; - } - } else { - foreach(QString pkgrule, pkgrulesValue) { - rawPkgPreRules << pkgrule; - } - } - } - } - } - - // Apply some defaults if specific data does not exist in PKG pre-rules - - if (languageRules.isEmpty()) { - // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS) - languageRules << "; Language\n&EN\n\n"; - } else if (headerRules.isEmpty()) { - // In case user defines langs, he must take care also about SIS header - fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n"); - } - - t << languageRules.join("\n") << endl; - tw << languageRules.join("\n") << endl; - - // name of application, UID and version - QString applicationVersion = project->first("VERSION").isEmpty() ? "1,0,0" : project->first("VERSION").replace('.', ','); - QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n"; - QString visualTarget = escapeFilePath(fileFixify(project->first("TARGET"))); - visualTarget = removePathSeparators(visualTarget); - QString wrapperTarget = visualTarget + " installer"; - - if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) { - tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion); - } else { - tw << installerSisHeader << endl; - } - - if (headerRules.isEmpty()) - t << sisHeader.arg(visualTarget).arg(uid3).arg(applicationVersion); - else - t << headerRules.join("\n") << endl; - - // Localized vendor name - QString vendorName; - if (!containsStartWithItem('%', rawPkgPreRules)) { - vendorName += "; Localised Vendor name\n%{\"Vendor\"}\n\n"; - } - - // Unique vendor name - if (!containsStartWithItem(':', rawPkgPreRules)) { - vendorName += "; Unique Vendor name\n:\"Vendor\"\n\n"; - } - - t << vendorName; - tw << vendorName; - - // PKG pre-rules - these are added before actual file installations i.e. SIS package body - if (rawPkgPreRules.size()) { - QString comment = "\n; Manual PKG pre-rules from PRO files\n"; - t << comment; - tw << comment; - - foreach(QString item, rawPkgPreRules) { - // Only regular pkg file should have package dependencies or pkg header if that is - // defined using prerules. - if (!item.startsWith("(") && !item.startsWith("#")) { - tw << item << endl; - } - t << item << endl; - } - t << endl; - tw << endl; - } - - // Begin Manufacturer block - if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { - QString manufacturerStr("IF "); - foreach(QString manufacturer, project->values("DEPLOYMENT.manufacturers")) { - manufacturerStr.append(QString("(MANUFACTURER)=(%1) OR \n ").arg(manufacturer)); - } - // Remove the final OR - manufacturerStr.chop(8); - t << manufacturerStr << endl; - } - - // Install paths on the phone *** should be dynamic at some point - QString installPathBin = "!:\\sys\\bin"; - QString installPathResource = "!:\\resource\\apps"; - QString installPathRegResource = "!:\\private\\10003a3f\\import\\apps"; - - // Find location of builds - QString epocReleasePath = QString("%1epoc32/release/$(PLATFORM)/$(TARGET)") - .arg(epocRoot()); - - if (targetType == TypeExe) { - // deploy .exe file - t << "; Executable and default resource files" << endl; - QString exeFile = fixedTarget + ".exe"; - t << QString("\"%1/%2\" - \"%3\\%4\"") - .arg(epocReleasePath) - .arg(exeFile) - .arg(installPathBin) - .arg(exeFile) << endl; - - // deploy rsc & reg_rsc file - if (!project->isActiveConfig("no_icon")) { - t << QString("\"%1epoc32/data/z/resource/apps/%2\" - \"%3\\%4\"") - .arg(epocRoot()) - .arg(fixedTarget + ".rsc") - .arg(installPathResource) - .arg(fixedTarget + ".rsc") << endl; - - t << QString("\"%1epoc32/data/z/private/10003a3f/import/apps/%2\" - \"%3\\%4\"") - .arg(epocRoot()) - .arg(fixedTarget + "_reg.rsc") - .arg(installPathRegResource) - .arg(fixedTarget + "_reg.rsc") << endl; - - if (!iconFile.isEmpty()) { - t << QString("\"%1epoc32/data/z%2\" - \"!:%3\"") - .arg(epocRoot()) - .arg(iconFile) - .arg(QDir::toNativeSeparators(iconFile)) << endl << endl; - } - } - } - - // deploy any additional DEPLOYMENT files - QString remoteTestPath; - remoteTestPath = QString("!:\\private\\%1").arg(privateDirUid); - QString zDir = epocRoot() + QLatin1String("epoc32/data/z"); - - initProjectDeploySymbian(project, depList, remoteTestPath, true, "$(PLATFORM)", "$(TARGET)", generatedDirs, generatedFiles); - if (depList.size()) - t << "; DEPLOYMENT" << endl; - for (int i = 0; i < depList.size(); ++i) { - QString from = depList.at(i).from; - QString to = depList.at(i).to; - - // Deploy anything not already deployed from under epoc32 instead from under - // \epoc32\data\z\ to enable using pkg file without rebuilding - // the project, which can be useful for some binary only distributions. - if (!from.contains(QLatin1String("epoc32"), Qt::CaseInsensitive)) { - from = to; - if (from.size() > 1 && from.at(1) == QLatin1Char(':')) - from = from.mid(2); - from.prepend(zDir); - } else { - if (from.size() > 1 && from.at(1) == QLatin1Char(':')) - from = from.mid(2); - } - - t << QString("\"%1\" - \"%2\"").arg(from.replace('\\','/')).arg(to) << endl; - } - t << endl; - - // PKG post-rules - these are added after actual file installations i.e. SIS package body - t << "; Manual PKG post-rules from PRO files" << endl; - foreach(QString deploymentItem, project->values("DEPLOYMENT")) { - foreach(QString pkgrulesItem, project->values(deploymentItem + ".pkg_postrules")) { - QStringList pkgrulesValue = project->values(pkgrulesItem); - // If there is no stringlist defined for a rule, use rule name directly - // This is convenience for defining single line statements - if (pkgrulesValue.isEmpty()) { - t << pkgrulesItem << endl; - } else { - foreach(QString pkgrule, pkgrulesValue) { - t << pkgrule << endl; - } - } - t << endl; - } - } - - // Close Manufacturer block - if (!project->values("DEPLOYMENT.manufacturers").isEmpty()) { - QString manufacturerFailNoteFile; - if (project->values("DEPLOYMENT.manufacturers.fail_note").isEmpty()) { - manufacturerFailNoteFile = QString("%1_" MANUFACTURER_NOTE_FILE).arg(uid3); - QFile ft(manufacturerFailNoteFile); - if (ft.open(QIODevice::WriteOnly)) { - generatedFiles << ft.fileName(); - QTextStream t2(&ft); - - t2 << QString(DEFAULT_MANUFACTURER_NOTE) << endl; - } else { - PRINT_FILE_CREATE_ERROR(manufacturerFailNoteFile) - } - } else { - manufacturerFailNoteFile = project->values("DEPLOYMENT.manufacturers.fail_note").join(""); - } - - t << "ELSEIF NOT(0) ; MANUFACTURER" << endl - << "\"" << fileInfo(manufacturerFailNoteFile).absoluteFilePath() << "\"" - << " - \"\", FILETEXT, TEXTEXIT" << endl - << "ENDIF ; MANUFACTURER" << endl; - } - - // Write wrapper pkg - if (!installerSisHeader.isEmpty()) { - QFile wrapperPkgFile(wrapperPkgFilename); - if (!wrapperPkgFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - PRINT_FILE_CREATE_ERROR(wrapperPkgFilename); - return; - } - - generatedFiles << wrapperPkgFile.fileName(); - QTextStream twf(&wrapperPkgFile); - - twf << wrapperStreamBuffer << endl; - - // Wrapped files deployment - QString currentPath = qmake_getpwd(); - QString sisName = QString("%1.sis").arg(fixedTarget); - twf << "\"" << currentPath << "/" << sisName << "\" - \"c:\\adm\\" << sisName << "\"" << endl; - - QString bootStrapPath = QLibraryInfo::location(QLibraryInfo::PrefixPath); - bootStrapPath.append("/smartinstaller.sis"); - QFileInfo fi(fileInfo(bootStrapPath)); - twf << "@\"" << fi.absoluteFilePath() << "\",(0x2002CCCD)" << endl; - } -} - -bool SymbianMakefileGenerator::containsStartWithItem(const QChar &c, const QStringList& src) -{ - bool result = false; - foreach(QString str, src) { - if (str.startsWith(c)) { - result = true; - break; - } - } - return result; -} - void SymbianMakefileGenerator::writeCustomDefFile() { if (targetType == TypePlugin && !project->isActiveConfig("stdbinary")) { @@ -618,9 +298,7 @@ void SymbianMakefileGenerator::writeCustomDefFile() void SymbianMakefileGenerator::init() { MakefileGenerator::init(); - fixedTarget = escapeFilePath(fileFixify(project->first("TARGET"))); - fixedTarget = removePathSeparators(fixedTarget); - removeSpecialCharacters(fixedTarget); + SymbianCommonGenerator::init(); if (0 != project->values("QMAKE_PLATFORM").size()) platform = varGlue("QMAKE_PLATFORM", "", " ", ""); @@ -637,60 +315,9 @@ void SymbianMakefileGenerator::init() // .mmp initMmpVariables(); - // Check TARGET.UID3 presence - if (0 != project->values("TARGET.UID3").size()) { - uid3 = project->first("TARGET.UID3"); - } else { - uid3 = generateUID3(); - } - - if ((project->values("TEMPLATE")).contains("app")) - targetType = TypeExe; - else if ((project->values("TEMPLATE")).contains("lib")) { - // Check CONFIG to see if we are to build staticlib or dll - if (project->isActiveConfig("staticlib") || project->isActiveConfig("static")) - targetType = TypeLib; - else if (project->isActiveConfig("plugin")) - targetType = TypePlugin; - else - targetType = TypeDll; - } else { - targetType = TypeSubdirs; - } - - if (0 != project->values("TARGET.UID2").size()) { - uid2 = project->first("TARGET.UID2"); - } else if (project->isActiveConfig("stdbinary")) { - uid2 = "0x20004C45"; - } else { - if (targetType == TypeExe) { - if (project->values("QT").contains("gui", Qt::CaseInsensitive)) { - // exe and gui -> uid2 needed - uid2 = "0x100039CE"; - } else { - // exe but not gui: uid2 is ignored anyway -> set it to 0 - uid2 = "0"; - } - } else if (targetType == TypeDll || targetType == TypeLib || targetType == TypePlugin) { - uid2 = "0x1000008d"; - } - } + uid2 = project->first("TARGET.UID2"); uid2 = uid2.trimmed(); - uid3 = uid3.trimmed(); - - // UID is valid as either hex or decimal, so just convert it to number and back to hex - // to get proper string for private dir - bool conversionOk = false; - uint uidNum = uid3.toUInt(&conversionOk, 0); - - if (!conversionOk) { - fprintf(stderr, "Error: Invalid UID \"%s\".\n", uid3.toUtf8().constData()); - } else { - privateDirUid.setNum(uidNum, 16); - while (privateDirUid.length() < 8) - privateDirUid.insert(0, QLatin1Char('0')); - } } QString SymbianMakefileGenerator::getTargetExtension() @@ -1398,7 +1025,7 @@ void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploy QString uid = generate_uid(fullProName); QString bldinfDefine = QString("BLD_INF_") + subdirFileName + QString("_") + uid; bldinfDefine = bldinfDefine.toUpper(); - removeSpecialCharacters(bldinfDefine); + removeEpocSpecialCharacters(bldinfDefine); if (!condition.isEmpty()) t << "#if defined(" << condition << ")" << endl; @@ -1477,442 +1104,6 @@ void SymbianMakefileGenerator::writeBldInfContent(QTextStream &t, bool addDeploy } } -void SymbianMakefileGenerator::writeRegRssFile(QMap<QString, QStringList> &userItems) -{ - QString filename(fixedTarget); - filename.append("_reg.rss"); - QFile ft(filename); - if (ft.open(QIODevice::WriteOnly)) { - generatedFiles << ft.fileName(); - QTextStream t(&ft); - t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; - t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; - t << "// * This file is generated by qmake and should not be modified by the" << endl; - t << "// * user." << endl; - t << "// ============================================================================" << endl; - t << endl; - t << "#include <" << fixedTarget << ".rsg>" << endl; - t << "#include <appinfo.rh>" << endl; - foreach(QString item, userItems[RSS_TAG_HEADER]) - t << item << endl; - t << endl; - t << "UID2 KUidAppRegistrationResourceFile" << endl; - t << "UID3 " << uid3 << endl << endl; - t << "RESOURCE APP_REGISTRATION_INFO" << endl; - t << "\t{" << endl; - t << "\tapp_file=\"" << fixedTarget << "\";" << endl; - t << "\tlocalisable_resource_file=\"" RESOURCE_DIRECTORY_RESOURCE << fixedTarget << "\";" << endl; - - writeRegRssList(t, userItems[RSS_TAG_SERVICE_LIST], - QLatin1String(RSS_TAG_SERVICE_LIST), - QLatin1String("SERVICE_INFO")); - writeRegRssList(t, userItems[RSS_TAG_FILE_OWNERSHIP_LIST], - QLatin1String(RSS_TAG_FILE_OWNERSHIP_LIST), - QLatin1String("FILE_OWNERSHIP_INFO")); - writeRegRssList(t, userItems[RSS_TAG_DATATYPE_LIST], - QLatin1String(RSS_TAG_DATATYPE_LIST), - QLatin1String("DATATYPE")); - t << endl; - - foreach(QString item, userItems[RSS_TAG_DEFAULT]) - t << "\t" << item.replace("\n","\n\t") << endl; - t << "\t}" << endl; - - foreach(QString item, userItems[RSS_TAG_FOOTER]) - t << item << endl; - } else { - PRINT_FILE_CREATE_ERROR(filename) - } -} - -void SymbianMakefileGenerator::writeRegRssList(QTextStream &t, - QStringList &userList, - const QString &listTag, - const QString &listItem) -{ - int itemCount = userList.count(); - if (itemCount) { - t << "\t" << listTag << " ="<< endl; - t << "\t\t{" << endl; - foreach(QString item, userList) { - t << "\t\t" << listItem << endl; - t << "\t\t\t{" << endl; - t << "\t\t\t" << item.replace("\n","\n\t\t\t") << endl; - t << "\t\t\t}"; - if (--itemCount) - t << ","; - t << endl; - } - t << "\t\t}; "<< endl; - } -} - -void SymbianMakefileGenerator::writeRssFile(QString &numberOfIcons, QString &iconFile) -{ - QString filename(fixedTarget); - filename.append(".rss"); - QFile ft(filename); - if (ft.open(QIODevice::WriteOnly)) { - generatedFiles << ft.fileName(); - QTextStream t(&ft); - t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; - t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; - t << "// * This file is generated by qmake and should not be modified by the" << endl; - t << "// * user." << endl; - t << "// ============================================================================" << endl; - t << endl; - t << "#include <appinfo.rh>" << endl; - t << "#include \"" << fixedTarget << ".loc\"" << endl; - t << endl; - t << "RESOURCE LOCALISABLE_APP_INFO r_localisable_app_info" << endl; - t << "\t{" << endl; - t << "\tshort_caption = STRING_r_short_caption;" << endl; - t << "\tcaption_and_icon =" << endl; - t << "\tCAPTION_AND_ICON_INFO" << endl; - t << "\t\t{" << endl; - t << "\t\tcaption = STRING_r_caption;" << endl; - - QString rssIconFile = iconFile; - rssIconFile = rssIconFile.replace("/", "\\\\"); - - if (numberOfIcons.isEmpty() || rssIconFile.isEmpty()) { - // There can be maximum one item in this tag, validated when parsed - t << "\t\tnumber_of_icons = 0;" << endl; - t << "\t\ticon_file = \"\";" << endl; - } else { - // There can be maximum one item in this tag, validated when parsed - t << "\t\tnumber_of_icons = " << numberOfIcons << ";" << endl; - t << "\t\ticon_file = \"" << rssIconFile << "\";" << endl; - } - t << "\t\t};" << endl; - t << "\t}" << endl; - t << endl; - } else { - PRINT_FILE_CREATE_ERROR(filename); - } -} - -void SymbianMakefileGenerator::writeLocFile(QStringList &symbianLangCodes) -{ - QString filename(fixedTarget); - filename.append(".loc"); - QFile ft(filename); - if (ft.open(QIODevice::WriteOnly)) { - generatedFiles << ft.fileName(); - QTextStream t(&ft); - t << "// ============================================================================" << endl; - t << "// * Generated by qmake (" << qmake_version() << ") (Qt " QT_VERSION_STR ") on: "; - t << QDateTime::currentDateTime().toString(Qt::ISODate) << endl; - t << "// * This file is generated by qmake and should not be modified by the" << endl; - t << "// * user." << endl; - t << "// ============================================================================" << endl; - t << endl; - t << "#ifdef LANGUAGE_SC" << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; - foreach(QString lang, symbianLangCodes) { - t << "#elif defined LANGUAGE_" << lang << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; - } - t << "#else" << endl; - t << "#define STRING_r_short_caption \"" << fixedTarget << "\"" << endl; - t << "#define STRING_r_caption \"" << fixedTarget << "\"" << endl; - t << "#endif" << endl; - } else { - PRINT_FILE_CREATE_ERROR(filename); - } -} - -void SymbianMakefileGenerator::readRssRules(QString &numberOfIcons, - QString &iconFile, QMap<QString, - QStringList> &userRssRules) -{ - for (QMap<QString, QStringList>::iterator it = project->variables().begin(); it != project->variables().end(); ++it) { - if (it.key().startsWith(RSS_RULES_BASE)) { - QString newKey = it.key().mid(sizeof(RSS_RULES_BASE) - 1); - if (newKey.isEmpty()) { - fprintf(stderr, "Warning: Empty RSS_RULES_BASE key encountered\n"); - continue; - } - QStringList newValues; - QStringList values = it.value(); - foreach(QString item, values) { - // If there is no stringlist defined for a rule, use rule value directly - // This is convenience for defining single line statements - if (project->values(item).isEmpty()) { - newValues << item; - } else { - QStringList itemList; - foreach(QString itemRow, project->values(item)) { - itemList << itemRow; - } - newValues << itemList.join("\n"); - } - } - // Verify thet there is exactly one value in RSS_TAG_NBROFICONS - if (newKey == RSS_TAG_NBROFICONS) { - if (newValues.count() == 1) { - numberOfIcons = newValues[0]; - } else { - fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n", - RSS_RULES_BASE, RSS_TAG_NBROFICONS); - continue; - } - // Verify thet there is exactly one value in RSS_TAG_ICONFILE - } else if (newKey == RSS_TAG_ICONFILE) { - if (newValues.count() == 1) { - iconFile = newValues[0]; - } else { - fprintf(stderr, "Warning: There must be exactly one value in '%s%s'\n", - RSS_RULES_BASE, RSS_TAG_ICONFILE); - continue; - } - } else if (newKey == RSS_TAG_HEADER - || newKey == RSS_TAG_SERVICE_LIST - || newKey == RSS_TAG_FILE_OWNERSHIP_LIST - || newKey == RSS_TAG_DATATYPE_LIST - || newKey == RSS_TAG_FOOTER - || newKey == RSS_TAG_DEFAULT) { - userRssRules[newKey] = newValues; - continue; - } else { - fprintf(stderr, "Warning: Unsupported key:'%s%s'\n", - RSS_RULES_BASE, newKey.toLatin1().constData()); - continue; - } - } - } - - QStringList newValues; - foreach(QString item, project->values(RSS_RULES)) { - // If there is no stringlist defined for a rule, use rule value directly - // This is convenience for defining single line statements - if (project->values(item).isEmpty()) { - newValues << item; - } else { - newValues << project->values(item); - } - } - userRssRules[RSS_TAG_DEFAULT] << newValues; - - // Validate that either both RSS_TAG_NBROFICONS and RSS_TAG_ICONFILE keys exist - // or neither of them exist - if (!((numberOfIcons.isEmpty() && iconFile.isEmpty()) || - (!numberOfIcons.isEmpty() && !iconFile.isEmpty()))) { - numberOfIcons.clear(); - iconFile.clear(); - fprintf(stderr, "Warning: Both or neither of '%s%s' and '%s%s' keys must exist.\n", - RSS_RULES_BASE, RSS_TAG_NBROFICONS, RSS_RULES_BASE, RSS_TAG_ICONFILE); - } - - // Validate that RSS_TAG_NBROFICONS contains only numbers - if (!numberOfIcons.isEmpty()) { - bool ok; - numberOfIcons = numberOfIcons.simplified(); - numberOfIcons.toInt(&ok); - if (!ok) { - numberOfIcons.clear(); - iconFile.clear(); - fprintf(stderr, "Warning: '%s%s' must be integer in decimal format.\n", - RSS_RULES_BASE, RSS_TAG_NBROFICONS); - } - } -} - -QStringList SymbianMakefileGenerator::symbianLangCodesFromTsFiles() -{ - QStringList tsfiles; - QStringList symbianLangCodes; - tsfiles << project->values("TRANSLATIONS"); - - fillQt2S60LangMapTable(); - - foreach(QString file, tsfiles) { - int extIndex = file.lastIndexOf("."); - int langIndex = file.lastIndexOf("_", (extIndex - file.length())); - langIndex += 1; - QString qtlang = file.mid(langIndex, extIndex - langIndex); - QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC")); - - if (!symbianLangCodes.contains(s60lang) && s60lang != "SC") - symbianLangCodes += s60lang; - } - - return symbianLangCodes; -} - -void SymbianMakefileGenerator::fillQt2S60LangMapTable() -{ - qt2S60LangMapTable.reserve(170); // 165 items at time of writing. - qt2S60LangMapTable.insert("ab", "SC"); //Abkhazian // - qt2S60LangMapTable.insert("om", "SC"); //Afan // - qt2S60LangMapTable.insert("aa", "SC"); //Afar // - qt2S60LangMapTable.insert("af", "34"); //Afrikaans //Afrikaans - qt2S60LangMapTable.insert("sq", "35"); //Albanian //Albanian - qt2S60LangMapTable.insert("am", "36"); //Amharic //Amharic - qt2S60LangMapTable.insert("ar", "37"); //Arabic //Arabic - qt2S60LangMapTable.insert("hy", "38"); //Armenian //Armenian - qt2S60LangMapTable.insert("as", "SC"); //Assamese // - qt2S60LangMapTable.insert("ay", "SC"); //Aymara // - qt2S60LangMapTable.insert("az", "SC"); //Azerbaijani // - qt2S60LangMapTable.insert("ba", "SC"); //Bashkir // - qt2S60LangMapTable.insert("eu", "SC"); //Basque // - qt2S60LangMapTable.insert("bn", "41"); //Bengali //Bengali - qt2S60LangMapTable.insert("dz", "SC"); //Bhutani // - qt2S60LangMapTable.insert("bh", "SC"); //Bihari // - qt2S60LangMapTable.insert("bi", "SC"); //Bislama // - qt2S60LangMapTable.insert("br", "SC"); //Breton // - qt2S60LangMapTable.insert("bg", "42"); //Bulgarian //Bulgarian - qt2S60LangMapTable.insert("my", "43"); //Burmese //Burmese - qt2S60LangMapTable.insert("be", "40"); //Byelorussian //Belarussian - qt2S60LangMapTable.insert("km", "SC"); //Cambodian // - qt2S60LangMapTable.insert("ca", "44"); //Catalan //Catalan - qt2S60LangMapTable.insert("zh", "SC"); //Chinese // - qt2S60LangMapTable.insert("co", "SC"); //Corsican // - qt2S60LangMapTable.insert("hr", "45"); //Croatian //Croatian - qt2S60LangMapTable.insert("cs", "25"); //Czech //Czech - qt2S60LangMapTable.insert("da", "07"); //Danish //Danish - qt2S60LangMapTable.insert("nl", "18"); //Dutch //Dutch - qt2S60LangMapTable.insert("en", "01"); //English //English(UK) - qt2S60LangMapTable.insert("eo", "SC"); //Esperanto // - qt2S60LangMapTable.insert("et", "49"); //Estonian //Estonian - qt2S60LangMapTable.insert("fo", "SC"); //Faroese // - qt2S60LangMapTable.insert("fj", "SC"); //Fiji // - qt2S60LangMapTable.insert("fi", "09"); //Finnish //Finnish - qt2S60LangMapTable.insert("fr", "02"); //French //French - qt2S60LangMapTable.insert("fy", "SC"); //Frisian // - qt2S60LangMapTable.insert("gd", "52"); //Gaelic //Gaelic - qt2S60LangMapTable.insert("gl", "SC"); //Galician // - qt2S60LangMapTable.insert("ka", "53"); //Georgian //Georgian - qt2S60LangMapTable.insert("de", "03"); //German //German - qt2S60LangMapTable.insert("el", "54"); //Greek //Greek - qt2S60LangMapTable.insert("kl", "SC"); //Greenlandic // - qt2S60LangMapTable.insert("gn", "SC"); //Guarani // - qt2S60LangMapTable.insert("gu", "56"); //Gujarati //Gujarati - qt2S60LangMapTable.insert("ha", "SC"); //Hausa // - qt2S60LangMapTable.insert("he", "57"); //Hebrew //Hebrew - qt2S60LangMapTable.insert("hi", "58"); //Hindi //Hindi - qt2S60LangMapTable.insert("hu", "17"); //Hungarian //Hungarian - qt2S60LangMapTable.insert("is", "15"); //Icelandic //Icelandic - qt2S60LangMapTable.insert("id", "59"); //Indonesian //Indonesian - qt2S60LangMapTable.insert("ia", "SC"); //Interlingua // - qt2S60LangMapTable.insert("ie", "SC"); //Interlingue // - qt2S60LangMapTable.insert("iu", "SC"); //Inuktitut // - qt2S60LangMapTable.insert("ik", "SC"); //Inupiak // - qt2S60LangMapTable.insert("ga", "60"); //Irish //Irish - qt2S60LangMapTable.insert("it", "05"); //Italian //Italian - qt2S60LangMapTable.insert("ja", "32"); //Japanese //Japanese - qt2S60LangMapTable.insert("jv", "SC"); //Javanese // - qt2S60LangMapTable.insert("kn", "62"); //Kannada //Kannada - qt2S60LangMapTable.insert("ks", "SC"); //Kashmiri // - qt2S60LangMapTable.insert("kk", "63"); //Kazakh //Kazakh - qt2S60LangMapTable.insert("rw", "SC"); //Kinyarwanda // - qt2S60LangMapTable.insert("ky", "SC"); //Kirghiz // - qt2S60LangMapTable.insert("ko", "65"); //Korean //Korean - qt2S60LangMapTable.insert("ku", "SC"); //Kurdish // - qt2S60LangMapTable.insert("rn", "SC"); //Kurundi // - qt2S60LangMapTable.insert("lo", "66"); //Laothian //Laothian - qt2S60LangMapTable.insert("la", "SC"); //Latin // - qt2S60LangMapTable.insert("lv", "67"); //Latvian //Latvian - qt2S60LangMapTable.insert("ln", "SC"); //Lingala // - qt2S60LangMapTable.insert("lt", "68"); //Lithuanian //Lithuanian - qt2S60LangMapTable.insert("mk", "69"); //Macedonian //Macedonian - qt2S60LangMapTable.insert("mg", "SC"); //Malagasy // - qt2S60LangMapTable.insert("ms", "70"); //Malay //Malay - qt2S60LangMapTable.insert("ml", "71"); //Malayalam //Malayalam - qt2S60LangMapTable.insert("mt", "SC"); //Maltese // - qt2S60LangMapTable.insert("mi", "SC"); //Maori // - qt2S60LangMapTable.insert("mr", "72"); //Marathi //Marathi - qt2S60LangMapTable.insert("mo", "73"); //Moldavian //Moldovian - qt2S60LangMapTable.insert("mn", "74"); //Mongolian //Mongolian - qt2S60LangMapTable.insert("na", "SC"); //Nauru // - qt2S60LangMapTable.insert("ne", "SC"); //Nepali // - qt2S60LangMapTable.insert("nb", "08"); //Norwegian //Norwegian - qt2S60LangMapTable.insert("oc", "SC"); //Occitan // - qt2S60LangMapTable.insert("or", "SC"); //Oriya // - qt2S60LangMapTable.insert("ps", "SC"); //Pashto // - qt2S60LangMapTable.insert("fa", "SC"); //Persian // - qt2S60LangMapTable.insert("pl", "27"); //Polish //Polish - qt2S60LangMapTable.insert("pt", "13"); //Portuguese //Portuguese - qt2S60LangMapTable.insert("pa", "77"); //Punjabi //Punjabi - qt2S60LangMapTable.insert("qu", "SC"); //Quechua // - qt2S60LangMapTable.insert("rm", "SC"); //RhaetoRomance // - qt2S60LangMapTable.insert("ro", "78"); //Romanian //Romanian - qt2S60LangMapTable.insert("ru", "16"); //Russian //Russian - qt2S60LangMapTable.insert("sm", "SC"); //Samoan // - qt2S60LangMapTable.insert("sg", "SC"); //Sangho // - qt2S60LangMapTable.insert("sa", "SC"); //Sanskrit // - qt2S60LangMapTable.insert("sr", "79"); //Serbian //Serbian - qt2S60LangMapTable.insert("sh", "SC"); //SerboCroatian // - qt2S60LangMapTable.insert("st", "SC"); //Sesotho // - qt2S60LangMapTable.insert("tn", "SC"); //Setswana // - qt2S60LangMapTable.insert("sn", "SC"); //Shona // - qt2S60LangMapTable.insert("sd", "SC"); //Sindhi // - qt2S60LangMapTable.insert("si", "80"); //Singhalese //Sinhalese - qt2S60LangMapTable.insert("ss", "SC"); //Siswati // - qt2S60LangMapTable.insert("sk", "26"); //Slovak //Slovak - qt2S60LangMapTable.insert("sl", "28"); //Slovenian //Slovenian - qt2S60LangMapTable.insert("so", "81"); //Somali //Somali - qt2S60LangMapTable.insert("es", "04"); //Spanish //Spanish - qt2S60LangMapTable.insert("su", "SC"); //Sundanese // - qt2S60LangMapTable.insert("sw", "84"); //Swahili //Swahili - qt2S60LangMapTable.insert("sv", "06"); //Swedish //Swedish - qt2S60LangMapTable.insert("tl", "39"); //Tagalog //Tagalog - qt2S60LangMapTable.insert("tg", "SC"); //Tajik // - qt2S60LangMapTable.insert("ta", "87"); //Tamil //Tamil - qt2S60LangMapTable.insert("tt", "SC"); //Tatar // - qt2S60LangMapTable.insert("te", "88"); //Telugu //Telugu - qt2S60LangMapTable.insert("th", "33"); //Thai //Thai - qt2S60LangMapTable.insert("bo", "89"); //Tibetan //Tibetan - qt2S60LangMapTable.insert("ti", "90"); //Tigrinya //Tigrinya - qt2S60LangMapTable.insert("to", "SC"); //Tonga // - qt2S60LangMapTable.insert("ts", "SC"); //Tsonga // - qt2S60LangMapTable.insert("tr", "14"); //Turkish //Turkish - qt2S60LangMapTable.insert("tk", "92"); //Turkmen //Turkmen - qt2S60LangMapTable.insert("tw", "SC"); //Twi // - qt2S60LangMapTable.insert("ug", "SC"); //Uigur // - qt2S60LangMapTable.insert("uk", "93"); //Ukrainian //Ukrainian - qt2S60LangMapTable.insert("ur", "94"); //Urdu //Urdu - qt2S60LangMapTable.insert("uz", "SC"); //Uzbek // - qt2S60LangMapTable.insert("vi", "96"); //Vietnamese //Vietnamese - qt2S60LangMapTable.insert("vo", "SC"); //Volapuk // - qt2S60LangMapTable.insert("cy", "97"); //Welsh //Welsh - qt2S60LangMapTable.insert("wo", "SC"); //Wolof // - qt2S60LangMapTable.insert("xh", "SC"); //Xhosa // - qt2S60LangMapTable.insert("yi", "SC"); //Yiddish // - qt2S60LangMapTable.insert("yo", "SC"); //Yoruba // - qt2S60LangMapTable.insert("za", "SC"); //Zhuang // - qt2S60LangMapTable.insert("zu", "98"); //Zulu //Zulu - qt2S60LangMapTable.insert("nn", "75"); //Nynorsk //NorwegianNynorsk - qt2S60LangMapTable.insert("bs", "SC"); //Bosnian // - qt2S60LangMapTable.insert("dv", "SC"); //Divehi // - qt2S60LangMapTable.insert("gv", "SC"); //Manx // - qt2S60LangMapTable.insert("kw", "SC"); //Cornish // - qt2S60LangMapTable.insert("ak", "SC"); //Akan // - qt2S60LangMapTable.insert("kok", "SC"); //Konkani // - qt2S60LangMapTable.insert("gaa", "SC"); //Ga // - qt2S60LangMapTable.insert("ig", "SC"); //Igbo // - qt2S60LangMapTable.insert("kam", "SC"); //Kamba // - qt2S60LangMapTable.insert("syr", "SC"); //Syriac // - qt2S60LangMapTable.insert("byn", "SC"); //Blin // - qt2S60LangMapTable.insert("gez", "SC"); //Geez // - qt2S60LangMapTable.insert("kfo", "SC"); //Koro // - qt2S60LangMapTable.insert("sid", "SC"); //Sidamo // - qt2S60LangMapTable.insert("cch", "SC"); //Atsam // - qt2S60LangMapTable.insert("tig", "SC"); //Tigre // - qt2S60LangMapTable.insert("kaj", "SC"); //Jju // - qt2S60LangMapTable.insert("fur", "SC"); //Friulian // - qt2S60LangMapTable.insert("ve", "SC"); //Venda // - qt2S60LangMapTable.insert("ee", "SC"); //Ewe // - qt2S60LangMapTable.insert("wa", "SC"); //Walamo // - qt2S60LangMapTable.insert("haw", "SC"); //Hawaiian // - qt2S60LangMapTable.insert("kcg", "SC"); //Tyap // - qt2S60LangMapTable.insert("ny", "SC"); //Chewa // -} - void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QString value) { if (!list.contains(value)) @@ -1925,16 +1116,6 @@ void SymbianMakefileGenerator::appendIfnotExist(QStringList &list, QStringList v appendIfnotExist(list, item); } -QString SymbianMakefileGenerator::removePathSeparators(QString &file) -{ - QString ret = file; - while (ret.indexOf(QDir::separator()) > 0) { - ret.remove(0, ret.indexOf(QDir::separator()) + 1); - } - - return ret; -} - QString SymbianMakefileGenerator::removeTrailingPathSeparators(QString &file) { @@ -1960,111 +1141,12 @@ void SymbianMakefileGenerator::generateCleanCommands(QTextStream& t, t << "\t-@ if EXIST \"" << QDir::toNativeSeparators(item) << "\" "; t << cmd << " " << cmdOptions << " \"" << QDir::toNativeSeparators(item) << "\"" << endl; #else - t << "\t-if test -f " << QDir::toNativeSeparators(item) << "; then "; + t << "\t-if test -e " << QDir::toNativeSeparators(item) << "; then "; t << cmd << " " << cmdOptions << " " << QDir::toNativeSeparators(item) << "; fi" << endl; #endif } } -void SymbianMakefileGenerator::removeSpecialCharacters(QString& str) -{ - // When modifying this method check also application_icon.prf - str.replace(QString("/"), QString("_")); - str.replace(QString("\\"), QString("_")); - str.replace(QString("-"), QString("_")); - str.replace(QString(":"), QString("_")); - str.replace(QString("."), QString("_")); - str.replace(QString(" "), QString("_")); -} - -void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) -{ - t << "-include " MAKE_CACHE_NAME << endl; - t << endl; - - t << SIS_TARGET ":" << endl; - QString siscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ - "$(MAKE) -s -f $(MAKEFILE) %4," \ - "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \ - "$(MAKE) -s -f $(MAKEFILE) %5))," \ - "$(MAKE) -s -f $(MAKEFILE) %6)") - .arg(fixedTarget) - .arg("pkg") - .arg(MAKE_CACHE_NAME) - .arg(OK_SIS_TARGET) - .arg(FAIL_SIS_NOCACHE_TARGET) - .arg(FAIL_SIS_NOPKG_TARGET); - t << siscommand << endl; - t << endl; - - t << OK_SIS_TARGET ":" << endl; - - QString pkgcommand = QString::fromLatin1("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \ - "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") - .arg(fixedTarget) - .arg("pkg"); - t << pkgcommand << endl; - t << endl; - - QString sisName = fixedTarget; - sisName += ".sis"; - - t << sisName << ":" << endl; - t << "\t$(MAKE) -s -f $(MAKEFILE) " SIS_TARGET << endl << endl; - - t << ROM_STUB_SIS_TARGET ":" << endl; - QString stubsiscommand = QString::fromLatin1("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ - "$(MAKE) -s -f $(MAKEFILE) %4," \ - "$(if $(QT_SIS_TARGET),$(MAKE) -s -f $(MAKEFILE) %4," \ - "$(MAKE) -s -f $(MAKEFILE) %5))," \ - "$(MAKE) -s -f $(MAKEFILE) %6)") - .arg(fixedTarget) - .arg("pkg") - .arg(MAKE_CACHE_NAME) - .arg(OK_ROM_STUB_SIS_TARGET) - .arg(FAIL_SIS_NOCACHE_TARGET) - .arg(FAIL_SIS_NOPKG_TARGET); - t << stubsiscommand << endl; - t << endl; - - t << OK_ROM_STUB_SIS_TARGET ":" << endl; - - QString stubpkgcommand = QString::fromLatin1("\tcreatepackage.bat -s $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \ - "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") - .arg(fixedTarget) - .arg("pkg"); - t << stubpkgcommand << endl; - t << endl; - - t << INSTALLER_SIS_TARGET ": " << sisName << endl; - siscommand = QString::fromLatin1("\t$(if $(wildcard %1_installer.%2)," \ - "$(MAKE) -s -f $(MAKEFILE) %3," \ - "$(MAKE) -s -f $(MAKEFILE) %4)") - .arg(fixedTarget) - .arg("pkg") - .arg(OK_INSTALLER_SIS_TARGET) - .arg(FAIL_SIS_NOPKG_TARGET); - t << siscommand << endl; - t << endl; - - t << OK_INSTALLER_SIS_TARGET ": " << endl; - - pkgcommand = QString::fromLatin1("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_installer.%2 - " \ - "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") - .arg(fixedTarget) - .arg("pkg"); - t << pkgcommand << endl; - t << endl; - - t << FAIL_SIS_NOPKG_TARGET ":" << endl; - 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; - t << endl; - - t << FAIL_SIS_NOCACHE_TARGET ":" << endl; - t << "\t$(error Project has to be built or QT_SIS_TARGET environment variable has to be set before calling 'SIS' target)" << endl; - t << endl; -} - void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t) { t << "dodistclean:" << endl; diff --git a/qmake/generators/symbian/symmake.h b/qmake/generators/symbian/symmake.h index 9de852a..d9ca390 100644 --- a/qmake/generators/symbian/symmake.h +++ b/qmake/generators/symbian/symmake.h @@ -43,6 +43,7 @@ #define SYMMAKEFILE_H #include "initprojectdeploy_symbian.h" +#include "symbiancommon.h" #include <makefile.h> QT_BEGIN_NAMESPACE @@ -53,22 +54,11 @@ QT_BEGIN_NAMESPACE #define MAKE_CACHE_NAME ".make.cache" #define SYMBIAN_TEST_CONFIG "symbian_test" -class SymbianMakefileGenerator : public MakefileGenerator +class SymbianMakefileGenerator : public MakefileGenerator, public SymbianCommonGenerator { protected: - enum TargetType { - TypeExe, - TypeDll, - TypeLib, - TypePlugin, - TypeSubdirs - }; - QString platform; QString uid2; - QString uid3; - QString privateDirUid; - TargetType targetType; QMap<QString, QStringList> sources; QMap<QString, QStringList> systeminclude; QMap<QString, QStringList> library; @@ -76,19 +66,10 @@ protected: QMap<QString, QStringList> makmakeCommands; QStringList overriddenMmpKeywords; - QStringList generatedFiles; - QStringList generatedDirs; - QHash<QString, QString> qt2S60LangMapTable; - - QString fixedTarget; - - void removeSpecialCharacters(QString& str); QString fixPathForMmp(const QString& origPath, const QDir& parentDir); QString absolutizePath(const QString& origPath); virtual bool writeMakefile(QTextStream &t); - void generatePkgFile(const QString &iconFile, DeploymentList &depList); - bool containsStartWithItem(const QChar &c, const QStringList& src); virtual void init(); @@ -130,23 +111,9 @@ protected: void writeCustomDefFile(); - void writeRegRssFile(QMap<QString, QStringList> &useritems); - void writeRegRssList(QTextStream &t, QStringList &userList, - const QString &listTag, - const QString &listItem); - void writeRssFile(QString &numberOfIcons, QString &iconfile); - void writeLocFile(QStringList &symbianLangCodes); - void readRssRules(QString &numberOfIcons, - QString &iconFile, - QMap<QString, QStringList> &userRssRules); - - QStringList symbianLangCodesFromTsFiles(); - void fillQt2S60LangMapTable(); - void appendIfnotExist(QStringList &list, QString value); void appendIfnotExist(QStringList &list, QStringList values); - QString removePathSeparators(QString &file); QString removeTrailingPathSeparators(QString &file); void generateCleanCommands(QTextStream& t, const QStringList& toClean, @@ -155,7 +122,6 @@ protected: const QString& itemPrefix, const QString& itemSuffix); - void writeSisTargets(QTextStream &t); void generateDistcleanTargets(QTextStream& t); void generateExecutionTargets(QTextStream& t, const QStringList& platforms); diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index ad6e743..0ba1a3c 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -71,7 +71,7 @@ SymbianAbldMakefileGenerator::~SymbianAbldMakefileGenerator() { } void SymbianAbldMakefileGenerator::writeMkFile(const QString& wrapperFileName, bool deploymentOnly) { QString gnuMakefileName = QLatin1String("Makefile_") + uid3; - removeSpecialCharacters(gnuMakefileName); + removeEpocSpecialCharacters(gnuMakefileName); gnuMakefileName.append(".mk"); QFile ft(gnuMakefileName); @@ -200,22 +200,27 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool t << endl; t << "MAKEFILE = " << wrapperFile.fileName() << endl; - t << "QMAKE = " << Option::fixPathToTargetOS(var("QMAKE_QMAKE")) << endl; + t << "QMAKE = " << var("QMAKE_QMAKE") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "MOVE = " << var("QMAKE_MOVE") << endl; t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; t << "MKDIR = " << var("QMAKE_MKDIR") << endl; +#ifdef Q_OS_WIN32 t << "XCOPY = xcopy /d /f /h /r /y /i" << endl; t << "ABLD = ABLD.BAT" << endl; +#else + t << "XCOPY = cp -u -v" << endl; + t << "ABLD = abld" << endl; +#endif t << "DEBUG_PLATFORMS = " << debugPlatforms.join(" ") << endl; t << "RELEASE_PLATFORMS = " << releasePlatforms.join(" ") << endl; t << "MAKE = make" << endl; t << endl; t << "ifeq (WINS,$(findstring WINS, $(PLATFORM)))" << endl; - t << "ZDIR=$(EPOCROOT)epoc32\\release\\$(PLATFORM)\\$(CFG)\\Z" << endl; + t << "ZDIR=$(EPOCROOT)" << QDir::toNativeSeparators("epoc32/release/$(PLATFORM)/$(CFG)/z") << endl; t << "else" << endl; - t << "ZDIR=$(EPOCROOT)epoc32\\data\\z" << endl; + t << "ZDIR=$(EPOCROOT)" << QDir::toNativeSeparators("epoc32/data/z") << endl; t << "endif" << endl; t << endl; t << "DEFINES" << '\t' << " = " @@ -309,14 +314,16 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool // generate command lines like this ... // -@ if NOT EXIST ".\somedir" mkdir ".\somedir" QStringList dirsToClean; + QString dirExists = var("QMAKE_CHK_DIR_EXISTS"); + QString mkdir = var("QMAKE_MKDIR"); for (QMap<QString, QStringList>::iterator it = systeminclude.begin(); it != systeminclude.end(); ++it) { QStringList values = it.value(); for (int i = 0; i < values.size(); ++i) { if (values.at(i).endsWith("/" QT_EXTRA_INCLUDE_DIR)) { QString fixedValue(QDir::toNativeSeparators(values.at(i))); dirsToClean << fixedValue; - t << "\t-@ if NOT EXIST \"" << fixedValue << "\" mkdir \"" - << fixedValue << "\"" << endl; + t << "\t-@ " << dirExists << " \"" << fixedValue << "\" " + << mkdir << " \"" << fixedValue << "\"" << endl; } } } @@ -325,7 +332,7 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool // Note: EXTENSION_CLEAN will get called many times when doing reallyclean // This is why the "2> NUL" gets appended to generated clean targets in makefile.cpp. t << EXTENSION_CLEAN ": " COMPILER_CLEAN_TARGET << endl; - generateCleanCommands(t, dirsToClean, var("QMAKE_DEL_DIR"), " /S /Q ", "", ""); + generateCleanCommands(t, dirsToClean, var("QMAKE_DEL_TREE"), "", "", ""); t << endl; t << PRE_TARGETDEPS_TARGET ":" @@ -374,10 +381,6 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool writeDeploymentTargets(t, false); writeDeploymentTargets(t, true); - writeSisTargets(t); - - writeStoreBuildTarget(t); - generateDistcleanTargets(t); t << "clean: $(ABLD)" << endl; @@ -429,7 +432,7 @@ bool SymbianAbldMakefileGenerator::writeDeploymentTargets(QTextStream &t, bool i + privateDirUid; DeploymentList depList; - initProjectDeploySymbian(project, depList, remoteTestPath, false, + initProjectDeploySymbian(project, depList, remoteTestPath, false, true, QLatin1String(isRom ? ROM_DEPLOYMENT_PLATFORM : EMULATOR_DEPLOYMENT_PLATFORM), QString(), generatedDirs, generatedFiles); @@ -465,32 +468,13 @@ bool SymbianAbldMakefileGenerator::writeDeploymentTargets(QTextStream &t, bool i return true; } -void SymbianAbldMakefileGenerator::writeStoreBuildTarget(QTextStream &t) -{ - t << STORE_BUILD_TARGET ":" << endl; - t << "\t@echo # ============================================================================== > " MAKE_CACHE_NAME << endl; - t << "\t@echo # This file is generated by make and should not be modified by the user >> " MAKE_CACHE_NAME << endl; - t << "\t@echo # Name : " << MAKE_CACHE_NAME << " >> " MAKE_CACHE_NAME << endl; - t << "\t@echo # Part of : " << project->values("TARGET").join(" ") << " >> " MAKE_CACHE_NAME << endl; - t << "\t@echo # Description : This file is used to cache last build target for >> " MAKE_CACHE_NAME << endl; - t << "\t@echo # make sis target. >> " MAKE_CACHE_NAME << endl; - t << "\t@echo # Version : >> " MAKE_CACHE_NAME << endl; - t << "\t@echo # >> " MAKE_CACHE_NAME << endl; - t << "\t@echo # ============================================================================== >> " MAKE_CACHE_NAME << endl; - t << "\t@echo. >> " MAKE_CACHE_NAME << endl; - t << "\t@echo QT_SIS_TARGET ?= $(QT_SIS_TARGET) >> " MAKE_CACHE_NAME << endl; - t << endl; - - generatedFiles << MAKE_CACHE_NAME; -} - void SymbianAbldMakefileGenerator::writeBldInfMkFilePart(QTextStream& t, bool addDeploymentExtension) { // Normally emulator deployment gets done via regular makefile, but since subdirs // do not get that, special deployment only makefile is generated for them if needed. if (targetType != TypeSubdirs || addDeploymentExtension) { QString gnuMakefileName = QLatin1String("Makefile_") + uid3; - removeSpecialCharacters(gnuMakefileName); + removeEpocSpecialCharacters(gnuMakefileName); gnuMakefileName.append(".mk"); t << "gnumakefile " << gnuMakefileName << endl; } diff --git a/qmake/generators/symbian/symmake_abld.h b/qmake/generators/symbian/symmake_abld.h index c033284..f998b28 100644 --- a/qmake/generators/symbian/symmake_abld.h +++ b/qmake/generators/symbian/symmake_abld.h @@ -57,7 +57,6 @@ protected: virtual void writeWrapperMakefile(QFile& wrapperFile, bool isPrimaryMakefile); virtual void appendAbldTempDirs(QStringList& sysincspaths, QString includepath); - void writeStoreBuildTarget(QTextStream &t); bool writeDeploymentTargets(QTextStream &t, bool isRom); public: diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index 1014ba2..c817056 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -144,7 +144,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << "# ==============================================================================" << "\n" << endl; t << endl; t << "MAKEFILE = " << wrapperFile.fileName() << endl; - t << "QMAKE = " << Option::fixPathToTargetOS(var("QMAKE_QMAKE")) << endl; + t << "QMAKE = " << var("QMAKE_QMAKE") << endl; t << "DEL_FILE = " << var("QMAKE_DEL_FILE") << endl; t << "DEL_DIR = " << var("QMAKE_DEL_DIR") << endl; t << "CHK_DIR_EXISTS = " << var("QMAKE_CHK_DIR_EXISTS") << endl; @@ -253,8 +253,6 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo qDeleteAll(subtargets); } - writeSisTargets(t); - generateDistcleanTargets(t); t << "clean: " << BLD_INF_FILENAME << endl; @@ -390,7 +388,7 @@ void SymbianSbsv2MakefileGenerator::writeBldInfExtensionRulesPart(QTextStream& t //write emulator deployment t << "#if defined(WINSCW)" << endl; - initProjectDeploySymbian(project, depList, remoteTestPath, false, + initProjectDeploySymbian(project, depList, remoteTestPath, false, true, QLatin1String(EMULATOR_DEPLOYMENT_PLATFORM), QString(), generatedDirs, generatedFiles); writeSbsDeploymentList(depList, t); t << "#endif" << endl; @@ -398,7 +396,7 @@ void SymbianSbsv2MakefileGenerator::writeBldInfExtensionRulesPart(QTextStream& t //write ROM deployment remoteTestPath = epocRoot() + QLatin1String("epoc32/data/z/private/") + privateDirUid; depList.clear(); - initProjectDeploySymbian(project, depList, remoteTestPath, false, + initProjectDeploySymbian(project, depList, remoteTestPath, false, true, QLatin1String(ROM_DEPLOYMENT_PLATFORM), QString(), generatedDirs, generatedFiles); writeSbsDeploymentList(depList, t); t << endl; diff --git a/qmake/generators/symbian/symmake_sbsv2.h b/qmake/generators/symbian/symmake_sbsv2.h index b8ccdbe..286c91c 100644 --- a/qmake/generators/symbian/symmake_sbsv2.h +++ b/qmake/generators/symbian/symmake_sbsv2.h @@ -56,6 +56,7 @@ protected: virtual void writeMkFile(const QString& wrapperFileName, bool deploymentOnly); virtual void writeWrapperMakefile(QFile& wrapperFile, bool isPrimaryMakefile); virtual void appendAbldTempDirs(QStringList& sysincspaths, QString includepath); + virtual bool isForSymbianSbsv2() const { return true; } // FIXME: killme - i'm ugly! public: diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index 670e3a0..db5b957 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -65,6 +65,10 @@ UnixMakefileGenerator::init() } } + if (project->isEmpty("QMAKE_PREFIX_SHLIB")) + // Prevent crash when using the empty variable. + project->values("QMAKE_PREFIX_SHLIB").append(""); + if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */ return; @@ -99,8 +103,6 @@ UnixMakefileGenerator::init() MakefileGenerator::init(); if(project->isEmpty("MAKEFILE")) project->values("MAKEFILE").append("Makefile"); - if(project->isEmpty("QMAKE_QMAKE")) - project->values("QMAKE_QMAKE").append("qmake"); if(project->values("QMAKE_INTERNAL_QMAKE_DEPS").indexOf("qmake_all") == -1) project->values("QMAKE_INTERNAL_QMAKE_DEPS").append("qmake_all"); return; /* subdirs is done */ @@ -451,7 +453,9 @@ UnixMakefileGenerator::findLibraries() if(!libdirs.contains(f)) libdirs.append(f); } else if(opt.startsWith("-l")) { - if (project->isActiveConfig("rvct_linker")) { + if (!project->isEmpty("QMAKE_RVCT_LINKSTYLE")) { + (*it) = opt.mid(2); + } else if (project->isActiveConfig("rvct_linker")) { (*it) = "lib" + opt.mid(2) + ".so"; } else { stub = opt.mid(2); @@ -491,26 +495,29 @@ UnixMakefileGenerator::findLibraries() QStringList extens; if(!extn.isNull()) extens << extn; + else if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) + // In Symbian you link to the stub .lib file, but run with the .dll file. + extens << "lib"; else extens << project->values("QMAKE_EXTENSION_SHLIB").first() << "a"; for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { if(dir.isNull()) { - QString lib_stub; for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) { - if(exists((*dep_it).local() + Option::dir_sep + "lib" + stub + - "." + (*extit))) { - lib_stub = stub; + QString pathToLib = ((*dep_it).local() + Option::dir_sep + + project->values("QMAKE_PREFIX_SHLIB").first() + + stub + "." + (*extit)); + if(exists(pathToLib)) { + if (!project->isEmpty("QMAKE_RVCT_LINKSTYLE")) + (*it) = pathToLib; + else + (*it) = "-l" + stub; + found = true; break; } } - if(!lib_stub.isNull()) { - (*it) = "-l" + lib_stub; - found = true; - break; - } } else { - if(exists("lib" + stub + "." + (*extit))) { - (*it) = "lib" + stub + "." + (*extit); + if(exists(project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit))) { + (*it) = project->values("QMAKE_PREFIX_SHLIB").first() + stub + "." + (*extit); found = true; break; } @@ -518,8 +525,8 @@ UnixMakefileGenerator::findLibraries() } if(!found && project->isActiveConfig("compile_libtool")) { for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { - if(exists(libdirs[dep_i].local() + Option::dir_sep + "lib" + stub + Option::libtool_ext)) { - (*it) = libdirs[dep_i].real() + Option::dir_sep + "lib" + stub + Option::libtool_ext; + if(exists(libdirs[dep_i].local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext)) { + (*it) = libdirs[dep_i].real() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + stub + Option::libtool_ext; found = true; break; } @@ -544,7 +551,6 @@ UnixMakefileGenerator::processPrlFiles() { QList<QMakeLocalFileName> libdirs, frameworkdirs; frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks")); - frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks")); const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS", "QMAKE_LFLAGS", "QMAKE_LIBS", QString() }; for(int i = 0; !lflags[i].isNull(); i++) { QStringList &l = project->values(lflags[i]); @@ -560,7 +566,7 @@ UnixMakefileGenerator::processPrlFiles() for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { const QMakeLocalFileName &lfn = libdirs[dep_i]; if(!project->isActiveConfig("compile_libtool")) { //give them the .libs.. - QString la = lfn.local() + Option::dir_sep + "lib" + lib + Option::libtool_ext; + QString la = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib + Option::libtool_ext; if(exists(la) && QFile::exists(lfn.local() + Option::dir_sep + ".libs")) { QString dot_libs = lfn.real() + Option::dir_sep + ".libs"; l.append("-L" + dot_libs); @@ -568,7 +574,7 @@ UnixMakefileGenerator::processPrlFiles() } } - QString prl = lfn.local() + Option::dir_sep + "lib" + lib; + QString prl = lfn.local() + Option::dir_sep + project->values("QMAKE_PREFIX_SHLIB").first() + lib; if(!project->isEmpty("QMAKE_" + lib.toUpper() + "_SUFFIX")) prl += project->first("QMAKE_" + lib.toUpper() + "_SUFFIX"); if(processPrlFile(prl)) { @@ -779,10 +785,8 @@ UnixMakefileGenerator::defaultInstall(const QString &t) uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); if(!links.isEmpty()) { for(int i = 0; i < links.size(); ++i) { - if(Option::target_mode == Option::TARG_WIN_MODE || - Option::target_mode == Option::TARG_MAC9_MODE) { - } else if(Option::target_mode == Option::TARG_UNIX_MODE || - Option::target_mode == Option::TARG_MACX_MODE) { + if(Option::target_mode == Option::TARG_UNIX_MODE || + Option::target_mode == Option::TARG_MACX_MODE) { QString link = Option::fixPathToTargetOS(destdir + links[i], false); int lslash = link.lastIndexOf(Option::dir_sep); if(lslash != -1) diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index 77bdd01..0ea3350 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -49,7 +49,6 @@ QT_BEGIN_NAMESPACE class UnixMakefileGenerator : public MakefileGenerator { bool init_flag, include_deps; - bool writeMakefile(QTextStream &); QString libtoolFileName(bool fixify=true); void writeLibtoolFile(); // for libtool QString pkgConfigPrefix() const; @@ -75,6 +74,7 @@ protected: virtual void init(); void writeMakeParts(QTextStream &); + bool writeMakefile(QTextStream &); private: void init2(); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 025882e..3e731a1 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -81,7 +81,7 @@ UnixMakefileGenerator::writeMakefile(QTextStream &t) writeHeader(t); if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) { - t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; + t << "QMAKE = " << var("QMAKE_QMAKE") << endl; QStringList &qut = project->values("QMAKE_EXTRA_TARGETS"); for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) t << *it << " "; @@ -154,7 +154,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "AR = " << var("QMAKE_AR") << endl; t << "RANLIB = " << var("QMAKE_RANLIB") << endl; - t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; + t << "QMAKE = " << var("QMAKE_QMAKE") << endl; t << "TAR = " << var("QMAKE_TAR") << endl; t << "COMPRESS = " << var("QMAKE_GZIP") << endl; if(project->isActiveConfig("compile_libtool")) @@ -177,6 +177,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_MACOSX_DEPLOYMENT_TARGET")) t << "export MACOSX_DEPLOYMENT_TARGET = " //exported to children processes << project->first("QMAKE_MACOSX_DEPLOYMENT_TARGET") << endl; + + if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) { + t << "vpath %.dso " << project->values("QMAKE_LIBDIR").join(":") << endl; + t << "vpath %.lib " << project->values("QMAKE_LIBDIR").join(":") << endl; + } + t << endl; t << "####### Output directory" << endl << endl; @@ -233,6 +239,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_BUNDLE")) { t << "TARGETD = " << escapeFilePath(var("TARGET_x.y")) << endl; t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; + } else if(!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) { + t << "TARGETD = " << escapeFilePath(var("TARGET")) << endl; } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "TARGETD = " << escapeFilePath(var("TARGET_x.y.z")) << endl; t << "TARGET0 = " << escapeFilePath(var("TARGET_")) << endl; @@ -332,7 +340,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "SUBLIBS = "; QStringList &l = project->values("SUBLIBS"); for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) - t << libdir << "lib" << (*it) << ".a "; + t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "." + << project->first("QMAKE_EXTENSION_STATICLIB") << " "; t << endl << endl; } if(project->isActiveConfig("depend_prl") && !project->isEmpty("QMAKE_PRL_INTERNAL_FILES")) { @@ -545,6 +554,17 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_POST_LINK")) t << "\n\t" << var("QMAKE_POST_LINK"); t << endl << endl; + } else if(!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) { + t << "\n\t" + << "-$(DEL_FILE) $(TARGET)" << "\n\t" + << var("QMAKE_LINK_SHLIB_CMD"); + if(!destdir.isEmpty()) + t << "\n\t" + << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t" + << "-$(MOVE) $(TARGET) " << destdir; + if(!project->isEmpty("QMAKE_POST_LINK")) + t << "\n\t" << var("QMAKE_POST_LINK"); + t << endl << endl; } else if(project->isEmpty("QMAKE_HPUX_SHLIB")) { t << "\n\t" << "-$(DEL_FILE) $(TARGET) $(TARGET0) $(TARGET1) $(TARGET2)" << "\n\t" @@ -860,7 +880,8 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) libdir = project->first("SUBLIBS_DIR"); QStringList &l = project->values("SUBLIBS"); for(it = l.begin(); it != l.end(); ++it) - t << libdir << "lib" << (*it) << ".a" << ":\n\t" + t << libdir << project->first("QMAKE_PREFIX_STATICLIB") << (*it) << "." + << project->first("QMAKE_EXTENSION_STATICLIB") << ":\n\t" << var(QString("MAKELIB") + (*it)) << endl << endl; } @@ -875,9 +896,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) " << "$(TARGET)" << endl; } else if(!project->isActiveConfig("staticlib") && project->values("QMAKE_APP_FLAG").isEmpty() && !project->isActiveConfig("plugin")) { - t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << endl - << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " - << destdir << "$(TARGET2) $(TARGETA)" << endl; + t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)" << " " << endl; + if (project->values("QMAKE_SYMBIAN_SHLIB").isEmpty()) + t << "\t-$(DEL_FILE) " << destdir << "$(TARGET0) " << destdir << "$(TARGET1) " + << destdir << "$(TARGET2) $(TARGETA)" << endl; } else { t << "\t-$(DEL_FILE) " << "$(TARGET)" << " " << endl; } @@ -992,12 +1014,13 @@ void UnixMakefileGenerator::init2() if (!project->values("QMAKE_CYGWIN_EXE").isEmpty()) project->values("TARGET_EXT").append(".exe"); } else if (project->isActiveConfig("staticlib")) { - project->values("TARGET").first().prepend("lib"); - project->values("TARGET").first() += ".a"; + project->values("TARGET").first().prepend(project->first("QMAKE_PREFIX_STATICLIB")); + project->values("TARGET").first() += "." + project->first("QMAKE_EXTENSION_STATICLIB"); if(project->values("QMAKE_AR_CMD").isEmpty()) project->values("QMAKE_AR_CMD").append("$(AR) $(TARGET) $(OBJECTS)"); } else { - project->values("TARGETA").append(project->first("DESTDIR") + "lib" + project->first("TARGET") + ".a"); + project->values("TARGETA").append(project->first("DESTDIR") + project->first("QMAKE_PREFIX_STATICLIB") + + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_STATICLIB")); if(project->isActiveConfig("compile_libtool")) project->values("TARGET_la") = QStringList(project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext); @@ -1045,7 +1068,8 @@ void UnixMakefileGenerator::init2() project->first("VER_MAJ")); project->values("TARGET") = project->values("TARGET_x"); } else if (!project->isEmpty("QMAKE_AIX_SHLIB")) { - project->values("TARGET_").append("lib" + project->first("TARGET") + ".a"); + project->values("TARGET_").append(project->first("QMAKE_PREFIX_STATICLIB") + project->first("TARGET") + + "." + project->first("QMAKE_EXTENSION_STATICLIB")); if(project->isActiveConfig("lib_version_first")) { project->values("TARGET_x").append("lib" + project->first("TARGET") + "." + project->first("VER_MAJ") + "." + @@ -1074,6 +1098,10 @@ void UnixMakefileGenerator::init2() project->first("VER_PAT")); } project->values("TARGET") = project->values("TARGET_x.y.z"); + } else if (!project->isEmpty("QMAKE_SYMBIAN_SHLIB")) { + project->values("TARGET_").append(project->first("TARGET") + "." + + project->first("QMAKE_EXTENSION_SHLIB")); + project->values("TARGET") = project->values("TARGET_"); } else { project->values("TARGET_").append("lib" + project->first("TARGET") + "." + project->first("QMAKE_EXTENSION_SHLIB")); diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp index 9208e1d..b5c33c4 100644 --- a/qmake/generators/win32/borland_bmake.cpp +++ b/qmake/generators/win32/borland_bmake.cpp @@ -115,8 +115,6 @@ BorlandMakefileGenerator::init() project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); if(project->values("MAKEFILE").isEmpty()) project->values("MAKEFILE").append("Makefile"); - if(project->values("QMAKE_QMAKE").isEmpty()) - project->values("QMAKE_QMAKE").append("qmake"); return; } diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index e1f502f..0936d15 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -143,7 +143,7 @@ bool MingwMakefileGenerator::writeMakefile(QTextStream &t) if(project->first("TEMPLATE") == "app" || project->first("TEMPLATE") == "lib") { if(Option::mkfile::do_stub_makefile) { - t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : var("QMAKE_QMAKE")) << endl; + t << "QMAKE = " << var("QMAKE_QMAKE") << endl; QStringList &qut = project->values("QMAKE_EXTRA_TARGETS"); for(QStringList::ConstIterator it = qut.begin(); it != qut.end(); ++it) t << *it << " "; @@ -248,8 +248,6 @@ void MingwMakefileGenerator::init() project->values("QMAKE_INSTALL_DIR").append("$(COPY_DIR)"); if(project->values("MAKEFILE").isEmpty()) project->values("MAKEFILE").append("Makefile"); - if(project->values("QMAKE_QMAKE").isEmpty()) - project->values("QMAKE_QMAKE").append("qmake"); return; } @@ -417,7 +415,7 @@ void MingwMakefileGenerator::writeRcFilePart(QTextStream &t) if (!rc_file.isEmpty()) { t << escapeDependencyPath(var("RES_FILE")) << ": " << rc_file << "\n\t" << var("QMAKE_RC") << " -i " << rc_file << " -o " << var("RES_FILE") - << " --include-dir=" << incPathStr << endl << endl; + << " --include-dir=" << incPathStr << " $(DEFINES)" << endl << endl; } } diff --git a/qmake/generators/win32/msvc_dsp.cpp b/qmake/generators/win32/msvc_dsp.cpp deleted file mode 100644 index 9c8dd1d..0000000 --- a/qmake/generators/win32/msvc_dsp.cpp +++ /dev/null @@ -1,1207 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "msvc_dsp.h" -#include "option.h" - -#include <qdir.h> -#include <qset.h> - -#include <stdlib.h> - -QT_BEGIN_NAMESPACE - -DspMakefileGenerator::DspMakefileGenerator() : Win32MakefileGenerator(), init_flag(false) -{ -} - -bool DspMakefileGenerator::writeMakefile(QTextStream &t) -{ - if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) { - /* for now just dump, I need to generated an empty dsp or something.. */ - fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", - var("QMAKE_FAILED_REQUIREMENTS").toLatin1().constData()); - return true; - } - - // Generate workspace file - if(project->first("TEMPLATE") == "vcsubdirs") { - if (!project->isActiveConfig("build_pass")) { - debug_msg(1, "Generator: MSVC: Writing workspave file"); - writeSubDirs(t); - } else { - debug_msg(1, "Generator: MSVC: Not writing workspace file for build_pass configs"); - } - return true; - } else if (project->first("TEMPLATE") == "vcapp" || project->first("TEMPLATE") == "vclib") { - if(!project->isActiveConfig("build_pass")) - return writeDspParts(t); - return true; - } - return project->isActiveConfig("build_pass"); -} - -bool DspMakefileGenerator::hasBuiltinCompiler(const QString &filename) const -{ - for (int i = 0; i < Option::cpp_ext.count(); ++i) - if (filename.endsWith(Option::cpp_ext.at(i))) - return true; - for (int i = 0; i < Option::c_ext.count(); ++i) - if (filename.endsWith(Option::c_ext.at(i))) - return true; - return false; -} - -QString DspMakefileGenerator::replaceExtraCompilerVariables(const QString &var, const QStringList &in, const QStringList &out) -{ - QString ret = MakefileGenerator::replaceExtraCompilerVariables(var, in, out); - ret.replace("$(DEFINES)", varGlue("PRL_EXPORT_DEFINES"," -D"," -D","") + - varGlue("DEFINES"," -D"," -D","")); - - QString incpath = this->var("MSVCDSP_INCPATH"); - incpath.replace("/I", "-I"); - ret.replace("$(INCPATH)", incpath); - return ret; -} - - -// if config is part of a multibuild thenthe gule (this) has the correct MSVCDSP_PROJECT -QString DspMakefileGenerator::configName(DspMakefileGenerator * config) -{ - return var("MSVCDSP_PROJECT") + config->var("MSVCDSP_CONFIG_NAME"); -} - -bool DspMakefileGenerator::writeDspHeader(QTextStream &t) -{ - DspMakefileGenerator * config = this; - if (mergedProjects.count()) - config = mergedProjects.at(0); - - t << "# Microsoft Developer Studio Project File - Name=\"" << var("MSVCDSP_PROJECT") << "\" - Package Owner=<4>" << endl; - t << "# Microsoft Developer Studio Generated Build File, Format Version 6.00" << endl; - t << "# ** DO NOT EDIT **" << endl; - t << endl; - t << "# TARGTYPE \"Win32 (x86) " << var("MSVCDSP_TARGETTYPE") << "\" " << var("MSVCDSP_DSPTYPE") << endl; - t << endl; - t << "CFG=\"" << configName(config) << "\"" << endl; - t << "!MESSAGE This is not a valid makefile. To build this project using NMAKE," << endl; - t << "!MESSAGE use the Export Makefile command and run" << endl; - t << "!MESSAGE " << endl; - t << "!MESSAGE NMAKE /f " << escapeFilePath(var("TARGET")) << ".mak." << endl; - t << "!MESSAGE " << endl; - t << "!MESSAGE You can specify a configuration when running NMAKE" << endl; - t << "!MESSAGE by defining the macro CFG on the command line. For example:" << endl; - t << "!MESSAGE " << endl; - t << "!MESSAGE NMAKE /f " << escapeFilePath(var("TARGET")) << ".mak CFG=\"" << configName(config) << "\"" << endl; - t << "!MESSAGE " << endl; - t << "!MESSAGE Possible choices for configuration are:" << endl; - t << "!MESSAGE " << endl; - if (mergedProjects.count()) { - for (int i = 0; i < mergedProjects.count(); ++i) { - DspMakefileGenerator * config = mergedProjects.at(i); - t << "!MESSAGE \"" << configName(config) << "\" (based on \"Win32 (x86) " << config->var("MSVCDSP_TARGETTYPE") << "\")" << endl; - } - } else { - t << "!MESSAGE \"" << configName(config) << "\" (based on \"Win32 (x86) " << config->var("MSVCDSP_TARGETTYPE") << "\")" << endl; - } - t << "!MESSAGE " << endl; - t << endl; - t << "# Begin Project" << endl; - t << "# PROP AllowPerConfigDependencies 0" << endl; - t << "# PROP Scc_ProjName \"\"" << endl; - t << "# PROP Scc_LocalPath \"\"" << endl; - t << "CPP=" << config->var("QMAKE_CC") << endl; - t << "MTL=" << config->var("QMAKE_IDL") << endl; - t << "RSC=" << config->var("QMAKE_RC") << endl; - t << "BSC32=bscmake.exe" << endl; - - return true; -} - - -bool DspMakefileGenerator::writeDspParts(QTextStream &t) -{ - //bool staticLibTarget = var("MSVCDSP_DSPTYPE") == "0x0104"; - - writeDspHeader(t); - writeDspConfig(t, this); - t << endl; - t << "# Begin Target" << endl; - t << endl; - t << "# Name \"" << configName(this) << "\"" << endl; - t << endl; - - - QStringList listNames = QString("SOURCES|DEF_FILE").split("|"); - QStringList allListNames = listNames; - writeFileGroup(t, listNames, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"); - listNames = QStringList("HEADERS"); - allListNames += listNames; - writeFileGroup(t, QStringList("HEADERS"), "Header Files", "h;hpp;hxx;hm;inl"); - listNames = QString("FORMS|INTERFACES|FORMS3").split("|"); - allListNames += listNames; - writeFileGroup(t, listNames, "Form Files", "ui"); - listNames = QStringList("IMAGES"); - allListNames += listNames; - writeFileGroup(t, QStringList("IMAGES"), "Image Files", ""); - listNames = QString("RC_FILE|RESOURCES").split("|"); - allListNames += listNames; - writeFileGroup(t, listNames, "Resources", "rc;qrc"); - listNames = QStringList("TRANSLATIONS"); - allListNames += listNames; - writeFileGroup(t, listNames, "Translations", "ts;xlf"); - listNames = QStringList("LEXSOURCES"); - allListNames += listNames; - writeFileGroup(t, listNames, "Lexables", "l"); - listNames = QStringList("YACCSOURCES"); - allListNames += listNames; - writeFileGroup(t, listNames, "Yaccables", "y"); - listNames = QStringList("TYPELIBS"); - allListNames += listNames; - writeFileGroup(t, listNames, "Type Libraries", "tlb;olb"); - - if (!project->isEmpty("QMAKE_EXTRA_COMPILERS")) { - const QStringList &quc = project->values("QMAKE_EXTRA_COMPILERS"); - for (QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { - const QStringList &inputs = project->values((*it)+".input"); - for (QStringList::ConstIterator input = inputs.begin(); input != inputs.end(); ++input) { - if (!allListNames.contains((*input)) && *input != "UIC3_HEADERS") - writeFileGroup(t, QStringList((*input)), (*input) + " Files", ""); - } - } - } - - project->values("SWAPPED_BUILD_STEPS") = swappedBuildSteps.keys(); - - writeFileGroup(t, QString("GENERATED_SOURCES|GENERATED_FILES|SWAPPED_BUILD_STEPS").split("|"), "Generated", ""); - - t << "# End Target" << endl; - t << "# End Project" << endl; - return true; -} - -void -DspMakefileGenerator::init() -{ - if(init_flag) - return; - QStringList::Iterator it; - init_flag = true; - - platform = "Win32"; - if(!project->values("QMAKE_PLATFORM").isEmpty()) - platform = varGlue("QMAKE_PLATFORM", "", " ", ""); - - // this should probably not be here, but I'm using it to wrap the .t files - if(project->first("TEMPLATE") == "vcapp") - project->values("QMAKE_APP_FLAG").append("1"); - else if(project->first("TEMPLATE") == "vclib") - project->values("QMAKE_LIB_FLAG").append("1"); - - if(project->values("QMAKESPEC").isEmpty()) - project->values("QMAKESPEC").append(qgetenv("QMAKESPEC")); - - project->values("QMAKE_LIBS") += escapeFilePaths(project->values("LIBS")); - processVars(); - - if(!project->values("VERSION").isEmpty()) { - QString version = project->values("VERSION").first(); - int firstDot = version.indexOf("."); - QString major = version.left(firstDot); - QString minor = version.right(version.length() - firstDot - 1); - minor.replace(".", ""); - project->values("MSVCDSP_LFLAGS").append("/VERSION:" + major + "." + minor); - } - - QString msvcdsp_project; - if(!project->isEmpty("TARGET")) { - project->values("TARGET") = unescapeFilePaths(project->values("TARGET")); - msvcdsp_project = project->first("TARGET"); - } - - MakefileGenerator::init(); - - if(msvcdsp_project.isEmpty()) - msvcdsp_project = Option::output.fileName(); - - msvcdsp_project = msvcdsp_project.right(msvcdsp_project.length() - msvcdsp_project.lastIndexOf("\\") - 1); - int dotFind = msvcdsp_project.lastIndexOf("."); - if(dotFind != -1) - msvcdsp_project = msvcdsp_project.left(dotFind); - msvcdsp_project.replace("-", ""); - - project->values("MSVCDSP_PROJECT").append(msvcdsp_project); - - QStringList &proj = project->values("MSVCDSP_PROJECT"); - - for(QStringList::Iterator it = proj.begin(); it != proj.end(); ++it) - (*it).replace(QRegExp("\\.[a-zA-Z0-9_]*$"), ""); - - if(!project->values("QMAKE_APP_FLAG").isEmpty()) { - if(project->isActiveConfig("console")) { - project->values("MSVCDSP_TARGETTYPE").append("Console Application"); - project->values("MSVCDSP_DSPTYPE").append("0x0103"); - project->values("MSVCDSP_DEFINES").append(" /D \"_CONSOLE\" "); - } else { - project->values("MSVCDSP_TARGETTYPE").append("Application"); - project->values("MSVCDSP_DSPTYPE").append("0x0101"); - project->values("MSVCDSP_DEFINES").append(" /D \"_WINDOWS\" "); - } - } else { - if(project->isActiveConfig("dll")) { - project->values("MSVCDSP_TARGETTYPE").append("Dynamic-Link Library"); - project->values("MSVCDSP_DSPTYPE").append("0x0102"); - project->values("MSVCDSP_DEFINES").append(" /D \"_USRDLL\" "); - } else { - project->values("MSVCDSP_TARGETTYPE").append("Static Library"); - project->values("MSVCDSP_DSPTYPE").append("0x0104"); - project->values("MSVCDSP_DEFINES").append(" /D \"_LIB\" "); - } - } - - project->values("MSVCDSP_LFLAGS") += project->values("QMAKE_LFLAGS"); - - if(!project->values("QMAKE_LIBDIR").isEmpty()) - project->values("MSVCDSP_LFLAGS").append(valGlue( - escapeFilePaths(project->values("QMAKE_LIBDIR")), - "/LIBPATH:"," /LIBPATH:","")); - - project->values("MSVCDSP_DEFINES").append(varGlue("DEFINES","/D ","" " /D ","")); - project->values("MSVCDSP_DEFINES").append(varGlue("PRL_EXPORT_DEFINES","/D ","" " /D ","")); - project->values("MSVCDSP_DEFINES").append(" /D \"WIN32\" "); - - QStringList &libs = project->values("QMAKE_LIBS"); - for(QStringList::Iterator libit = libs.begin(); libit != libs.end(); ++libit) { - project->values("MSVCDSP_LIBS").append(" " + escapeFilePath(*libit)); - } - - QStringList &incs = project->values("INCLUDEPATH"); - for(QStringList::Iterator incit = incs.begin(); incit != incs.end(); ++incit) { - QString inc = (*incit); - project->values("MSVCDSP_INCPATH").append("/I" + escapeFilePath(inc)); - } - project->values("MSVCDSP_INCPATH").append("/I" + escapeFilePath(specdir())); - - QString dest; - QString preLinkStep; - QString postLinkStep; - QString copyDllStep; - - if(!project->values("QMAKE_PRE_LINK").isEmpty()) - preLinkStep += var("QMAKE_PRE_LINK"); - - if(!project->values("QMAKE_POST_LINK").isEmpty()) - postLinkStep += var("QMAKE_POST_LINK"); - - // don't destroy the target, it is used by prl writer. - if(!project->values("DESTDIR").isEmpty()) { - dest = project->first("DESTDIR"); - project->values("DESTDIR").first() = dest; - dest = project->values("TARGET").first() + project->first("TARGET_EXT"); - dest.prepend(project->first("DESTDIR")); - Option::fixPathToTargetOS(dest); - dest = escapeFilePath(dest); - - project->values("MSVCDSP_TARGET").append( - QString("/out:") + dest); - if(project->isActiveConfig("dll")) { - QString imp = dest; - imp.replace(".dll", ".lib"); - project->values("MSVCDSP_TARGET").append(QString(" /implib:") + escapeFilePath(imp)); - } - } - - if(project->isActiveConfig("dll") && !project->values("DLLDESTDIR").isEmpty()) { - QStringList dlldirs = project->values("DLLDESTDIR"); - if(dlldirs.count()) - copyDllStep += "\t"; - for(QStringList::Iterator dlldir = dlldirs.begin(); dlldir != dlldirs.end(); ++dlldir) { - copyDllStep += "copy \"$(TargetPath)\" " + escapeFilePath(Option::fixPathToTargetOS(*dlldir)) + "\t"; - } - } - - if(!preLinkStep.isEmpty()) { - project->values("MSVCDSP_PRE_LINK").append( - "# Begin Special Build Tool\n" - "SOURCE=$(InputPath)\n" - "PreLink_Desc=Post Build Step\n" - "PreLink_Cmds=" + preLinkStep + "\n" - "# End Special Build Tool\n"); - } - - if(!postLinkStep.isEmpty() || !copyDllStep.isEmpty()) { - project->values("MSVCDSP_POST_LINK").append( - "# Begin Special Build Tool\n" - "SOURCE=$(InputPath)\n" - "PostBuild_Desc=Post Build Step\n" - "PostBuild_Cmds=" + postLinkStep + copyDllStep + "\n" - "# End Special Build Tool\n"); - } - - QStringList &formList = project->values("FORMS"); - for(QStringList::ConstIterator hit = formList.begin(); hit != formList.end(); ++hit) { - if(exists(*hit + ".h")) - project->values("SOURCES").append(*hit + ".h"); - } - QStringList &form3List = project->values("FORMS3"); - for(QStringList::ConstIterator hit = form3List.begin(); hit != form3List.end(); ++hit) { - if(exists(*hit + ".h")) - project->values("SOURCES").append(*hit + ".h"); - } - - project->values("QMAKE_INTERNAL_PRL_LIBS") << "MSVCDSP_LIBS"; - - // Move some files around //### is this compat? - if (!project->values("IMAGES").isEmpty()) { - QString imageFactory(project->first("QMAKE_IMAGE_COLLECTION")); - project->values("GENERATED_SOURCES") += imageFactory; - project->values("SOURCES").removeAll(imageFactory); - } - - // Setup PCH variables - precompH = project->first("PRECOMPILED_HEADER"); - namePCH = fileInfo(precompH).fileName(); - usePCH = !precompH.isEmpty() && project->isActiveConfig("precompile_header"); - if (usePCH) { - // Created files - precompObj = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch" + Option::obj_ext; - precompPch = var("PRECOMPILED_DIR") + project->first("TARGET") + "_pch.pch"; - - // Add PRECOMPILED_HEADER to HEADERS - if (!project->values("HEADERS").contains(precompH)) - project->values("HEADERS") += precompH; - // Add precompile compiler options - project->values("PRECOMPILED_FLAGS") = QStringList("/Fp" + precompPch + " /Yu" + escapeFilePath(namePCH) + " /FI" + escapeFilePath(namePCH) + " "); - // Return to variable pool - project->values("PRECOMPILED_OBJECT") = QStringList(precompObj); - project->values("PRECOMPILED_PCH") = QStringList(precompPch); - } - - QString buildName; - if (!var("BUILD_NAME").isEmpty()) - buildName = var("BUILD_NAME"); - else if (project->isActiveConfig("debug")) - buildName = "Debug"; - else - buildName = "Release"; - - project->values("MSVCDSP_CONFIG_NAME") = QStringList(" - " + platform + " " + buildName); -} - -void DspMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l) -{ - if(var == "QMAKE_PRL_DEFINES") { - QStringList &out = project->values("MSVCDSP_DEFINES"); - for(QStringList::ConstIterator it = l.begin(); it != l.end(); ++it) { - if(out.indexOf((*it)) == -1) - out.append((" /D \"" + *it + "\"")); - } - } else { - MakefileGenerator::processPrlVariable(var, l); - } -} - -bool DspMakefileGenerator::openOutput(QFile &file, const QString &build) const -{ - QString outdir; - if(!file.fileName().isEmpty()) { - if(QDir::isRelativePath(file.fileName())) - file.setFileName(Option::output_dir + "/" + file.fileName()); //pwd when qmake was run - QFileInfo fi(fileInfo(file.fileName())); - if(fi.isDir()) - outdir = file.fileName() + QDir::separator(); - } - - if(!outdir.isEmpty() || file.fileName().isEmpty()) { - QString ext = project->first("DSP_EXTENSION"); - if(project->first("TEMPLATE") == "vcsubdirs") { - if (!project->first("DSW_EXTENSION").isEmpty()) - ext = project->first("DSW_EXTENSION"); - else - ext = ".dsw"; - } - QString outputName = unescapeFilePath(project->first("QMAKE_DSP_PROJECT_NAME")); - if (!project->first("MAKEFILE").isEmpty()) - outputName = unescapeFilePath(project->first("MAKEFILE")); - if (outputName.isEmpty()) - outputName = unescapeFilePath(project->first("QMAKE_ORIG_TARGET")); - file.setFileName(outdir + outputName + ext); - } - - if(QDir::isRelativePath(file.fileName())) { - QString ofile = Option::fixPathToLocalOS(file.fileName()); - int slashfind = ofile.lastIndexOf(Option::dir_sep); - if(slashfind == -1) { - ofile = ofile.replace(QRegExp("-"), "_"); - } else { - int hypenfind = ofile.indexOf('-', slashfind); - while (hypenfind != -1 && slashfind < hypenfind) { - ofile = ofile.replace(hypenfind, 1, "_"); - hypenfind = ofile.indexOf('-', hypenfind + 1); - } - } - file.setFileName(Option::fixPathToLocalOS(qmake_getpwd() + Option::dir_sep + ofile)); - } - return Win32MakefileGenerator::openOutput(file, build); -} - -bool DspMakefileGenerator::mergeBuildProject(MakefileGenerator *other) -{ - - mergedProjects.prepend(static_cast<DspMakefileGenerator*>(other)); - return true; -} - -bool DspMakefileGenerator::writeProjectMakefile() -{ - bool ret = true; - - QTextStream t(&Option::output); - // Check if all requirements are fulfilled - if(!project->values("QMAKE_FAILED_REQUIREMENTS").isEmpty()) { - fprintf(stderr, "Project file not generated because all requirements not met:\n\t%s\n", - var("QMAKE_FAILED_REQUIREMENTS").toLatin1().constData()); - return true; - } - - // Generate project file - if(project->first("TEMPLATE") == "vcapp" || - project->first("TEMPLATE") == "vclib") { - if (!mergedProjects.count()) { - warn_msg(WarnLogic, "Generator: MSVC DSP: no single configuration created, cannot output project!"); - return false; - } - debug_msg(1, "Generator: MSVC 6: Writing project file"); - - writeDspHeader(t); - for (int i = 0; i < mergedProjects.count(); ++i) { - DspMakefileGenerator* config = mergedProjects.at(i); - t << endl; - if (i == 0) - t << "!IF"; - else - t << "!ELSEIF"; - t << " \"$(CFG)\" == \"" << configName(config) << "\"" << endl; - t << endl; - writeDspConfig(t, config); - } - t << endl; - t << "!ENDIF " << endl; - t << endl; - t << "# Begin Target" << endl; - t << endl; - for (int i = 0; i < mergedProjects.count(); ++i) - t << "# Name \"" << configName(mergedProjects.at(i)) << "\"" << endl; - t << endl; - - QMap< QString, QSet<QString> > files; - - // merge source files - for (int i = 0; i < mergedProjects.count(); ++i) { - - DspMakefileGenerator* config = mergedProjects.at(i); - - files["DEF_FILE"] += config->project->values("DEF_FILE").toSet(); - files["SOURCES"] += config->project->values("SOURCES").toSet(); - files["HEADERS"] += config->project->values("HEADERS").toSet(); - files["INTERFACES"] += config->project->values("INTERFACES").toSet(); - files["FORMS"] += config->project->values("FORMS").toSet(); - files["FORMS"] += config->project->values("FORMS3").toSet(); - files["IMAGES"] += config->project->values("IMAGES").toSet(); - files["RC_FILE"] += config->project->values("RC_FILE").toSet(); - files["RESOURCES"] += config->project->values("RESOURCES").toSet(); - files["TRANSLATIONS"] += config->project->values("TRANSLATIONS").toSet(); - files["LEXSOURCES"] += config->project->values("LEXSOURCES").toSet(); - files["YACCSOURCES"] += config->project->values("YACCSOURCES").toSet(); - files["TYPELIBS"] += config->project->values("TYPELIBS").toSet(); - - if (!config->project->isEmpty("QMAKE_EXTRA_COMPILERS")) { - const QStringList &quc = config->project->values("QMAKE_EXTRA_COMPILERS"); - for (QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it) { - const QStringList &inputs = project->values((*it)+".input"); - for (QStringList::ConstIterator input = inputs.begin(); input != inputs.end(); ++input) { - if (*input != "UIC3_HEADERS") - files[(*input)] += config->project->values((*input)).toSet(); - } - } - } - } - - QStringList keys = files.keys(); - for (int k = 0; k < keys.size(); ++k) - project->values(keys.at(k)) = QList<QString>::fromSet(files[keys.at(k)]); - - QStringList listNames = QString("SOURCES|DEF_FILE").split("|"); - QStringList allListNames = listNames; - writeFileGroup(t, listNames, "Source Files", "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"); - listNames = QStringList("HEADERS"); - allListNames += listNames; - writeFileGroup(t, listNames, "Header Files", "h;hpp;hxx;hm;inl"); - listNames = QString("FORMS|INTERFACES|FORMS3").split("|"); - allListNames += listNames; - writeFileGroup(t, listNames, "Form Files", "ui"); - listNames = QStringList("IMAGES"); - allListNames += listNames; - writeFileGroup(t, listNames, "Image Files", ""); - listNames = QString("RC_FILE|RESOURCES").split("|"); - allListNames += listNames; - writeFileGroup(t, listNames, "Resources", "rc;qrc"); - listNames = QStringList("TRANSLATIONS"); - allListNames += listNames; - writeFileGroup(t, listNames, "Translations", "ts;xlf"); - listNames = QStringList("LEXSOURCES"); - allListNames += listNames; - writeFileGroup(t, listNames, "Lexables", "l"); - listNames = QStringList("YACCSOURCES"); - allListNames += listNames; - writeFileGroup(t, listNames, "Yaccables", "y"); - listNames = QStringList("TYPELIBS"); - allListNames += listNames; - writeFileGroup(t, listNames, "Type Libraries", "tlb;olb"); - - for (int l = 0; l < allListNames.size(); ++l) - keys.removeAll(allListNames.at(l)); - - for (int k = 0; k < keys.size(); ++k) - writeFileGroup(t, QStringList(keys.at(k)), keys.at(k) + " Files", ""); - - // done last as generated may have changed when creating build rules for the above - for (int i = 0; i < mergedProjects.count(); ++i) { - - DspMakefileGenerator* config = mergedProjects.at(i); - - config->project->values("SWAPPED_BUILD_STEPS") = config->swappedBuildSteps.keys(); - files["SWAPPED_BUILD_STEPS"] += config->project->values("SWAPPED_BUILD_STEPS").toSet(); - - files["GENERATED_SOURCES"] += config->project->values("GENERATED_SOURCES").toSet(); - files["GENERATED_FILES"] += config->project->values("GENERATED_FILES").toSet(); - } - - project->values("SWAPPED_BUILD_STEPS") = QList<QString>::fromSet(files["SWAPPED_BUILD_STEPS"]); - project->values("GENERATED_SOURCES") = QList<QString>::fromSet(files["GENERATED_SOURCES"]); - project->values("GENERATED_FILES") = QList<QString>::fromSet(files["GENERATED_FILES"]); - - writeFileGroup(t, QString("GENERATED_SOURCES|GENERATED_FILES|SWAPPED_BUILD_STEPS").split("|"), "Generated", ""); - t << endl; - t << "# End Target" << endl; - t << "# End Project" << endl; - }else if(project->first("TEMPLATE") == "vcsubdirs") { - ret = writeMakefile(t); - } - - return ret; -} - -const char _dswHeader60[] = "Microsoft Developer Studio Workspace File, Format Version 6.00\n"; -const char _dswWarning[] = "# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!\n"; -const char _dswDevider[] = "###############################################################################\n"; -const char _dswProjectName[] = "Project: \"%1\"=%2 - Package Owner=<4>\n"; // %1 = project name, %2 = project path -const char _dswPackage5Start[] = "Package=<5>\n{{{\n"; -const char _dswPackage5Stop[] = "}}}\n"; -const char _dswPackage4Start[] = "Package=<4>\n{{{\n"; -const char _dswPackage4Stop[] = "}}}\n"; -const char _dswProjectDep[] = " Begin Project Dependency\n Project_Dep_Name %1\n End Project Dependency\n"; // %1 = project name -const char _dswGlobal[] = "Global:\n\nPackage=<5>\n{{{\n}}}\n\nPackage=<3>\n{{{\n}}}\n\n"; - - -struct WorkspaceDepend { - QString dspProjectFile, orig_target, target; - QStringList dependencies; -}; - -void DspMakefileGenerator::writeSubDirs(QTextStream &t) -{ - // Output headers - t << _dswHeader60; - t << _dswWarning; - t << endl; - - QHash<QString, WorkspaceDepend*> workspace_depends; - QList<WorkspaceDepend*> workspace_cleanup; - QStringList subdirs = project->values("SUBDIRS"); - QString oldpwd = qmake_getpwd(); - - // Make sure that all temp projects are configured - // for release so that the depends are created - // without the debug <lib>dxxx.lib name mangling - QStringList old_after_vars = Option::after_user_vars; - Option::after_user_vars.append("CONFIG+=release"); - - for(int i = 0; i < subdirs.size(); ++i) { - QString tmp = subdirs.at(i); - if(!project->isEmpty(tmp + ".file")) { - if(!project->isEmpty(tmp + ".subdir")) - warn_msg(WarnLogic, "Cannot assign both file and subdir for subdir %s", - tmp.toLatin1().constData()); - tmp = project->first(tmp + ".file"); - } else if(!project->isEmpty(tmp + ".subdir")) { - tmp = project->first(tmp + ".subdir"); - } - - QFileInfo fi(fileInfo(Option::fixPathToLocalOS(tmp, true))); - if(fi.exists()) { - if(fi.isDir()) { - QString profile = tmp; - if(!profile.endsWith(Option::dir_sep)) - profile += Option::dir_sep; - profile += fi.baseName() + Option::pro_ext; - subdirs.append(profile); - } else { - QMakeProject tmp_proj; - QString dir = fi.path(), fn = fi.fileName(); - if(!dir.isEmpty()) { - if(!qmake_setpwd(dir)) - fprintf(stderr, "Cannot find directory: %s\n", dir.toLatin1().constData()); - } - if(tmp_proj.read(fn)) { - // Check if all requirements are fulfilled - if(!tmp_proj.variables()["QMAKE_FAILED_REQUIREMENTS"].isEmpty()) { - fprintf(stderr, "Project file(%s) not added to Workspace because all requirements not met:\n\t%s\n", - fn.toLatin1().constData(), tmp_proj.values("QMAKE_FAILED_REQUIREMENTS").join(" ").toLatin1().constData()); - continue; - } - if(tmp_proj.first("TEMPLATE") == "vcsubdirs") { - QStringList tmp_proj_subdirs = tmp_proj.variables()["SUBDIRS"]; - for(int x = 0; x < tmp_proj_subdirs.size(); ++x) { - QString tmpdir = tmp_proj_subdirs.at(x); - if(!tmp_proj.isEmpty(tmpdir + ".file")) { - if(!tmp_proj.isEmpty(tmpdir + ".subdir")) - warn_msg(WarnLogic, "Cannot assign both file and subdir for subdir %s", - tmpdir.toLatin1().constData()); - tmpdir = tmp_proj.first(tmpdir + ".file"); - } else if(!tmp_proj.isEmpty(tmpdir + ".subdir")) { - tmpdir = tmp_proj.first(tmpdir + ".subdir"); - } - subdirs += fileFixify(tmpdir); - } - } else if(tmp_proj.first("TEMPLATE") == "vcapp" || tmp_proj.first("TEMPLATE") == "vclib") { - // Initialize a 'fake' project to get the correct variables - // and to be able to extract all the dependencies - DspMakefileGenerator tmp_dsp; - tmp_dsp.setNoIO(true); - tmp_dsp.setProjectFile(&tmp_proj); - if(Option::debug_level) { - QMap<QString, QStringList> &vars = tmp_proj.variables(); - for(QMap<QString, QStringList>::Iterator it = vars.begin(); - it != vars.end(); ++it) { - if(it.key().left(1) != "." && !it.value().isEmpty()) - debug_msg(1, "%s: %s === %s", fn.toLatin1().constData(), it.key().toLatin1().constData(), - it.value().join(" :: ").toLatin1().constData()); - } - } - - // We assume project filename is [QMAKE_ORIG_TARGET].vcproj - QString dsp = unescapeFilePath(tmp_dsp.project->first("MSVCDSP_PROJECT") + project->first("DSP_EXTENSION")); - - // If file doesn't exsist, then maybe the users configuration - // doesn't allow it to be created. Skip to next... - if(!exists(qmake_getpwd() + Option::dir_sep + dsp)) { - warn_msg(WarnLogic, "Ignored (not found) '%s'", QString(qmake_getpwd() + Option::dir_sep + dsp).toLatin1().constData()); - goto nextfile; // # Dirty! - } - - WorkspaceDepend *newDep = new WorkspaceDepend; - newDep->dspProjectFile = fileFixify(dsp); - newDep->orig_target = unescapeFilePath(tmp_proj.first("QMAKE_ORIG_TARGET")); - newDep->target = tmp_proj.first("MSVCDSP_PROJECT").section(Option::dir_sep, -1) + tmp_proj.first("TARGET_EXT"); - - // We want to store it as the .lib name. - if(newDep->target.endsWith(".dll")) - newDep->target = newDep->target.left(newDep->target.length()-3) + "lib"; - - // All projects having mocable sourcefiles are dependent on moc.exe - if(tmp_proj.variables()["CONFIG"].contains("moc")) - newDep->dependencies << "moc.exe"; - - // All extra compilers which has valid input are considered dependencies - const QStringList &quc = tmp_proj.variables()["QMAKE_EXTRA_COMPILERS"]; - for(QStringList::ConstIterator it = quc.constBegin(); it != quc.constEnd(); ++it) { - const QStringList &invar = tmp_proj.variables().value((*it) + ".input"); - for(QStringList::ConstIterator iit = invar.constBegin(); iit != invar.constEnd(); ++iit) { - const QStringList fileList = tmp_proj.variables().value(*iit); - if (!fileList.isEmpty()) { - QString dep = tmp_proj.first((*it) + ".commands").section('/', -1).section('\\', -1); - if (!newDep->dependencies.contains(dep)) - newDep->dependencies << dep; - } - } - } - - // Add all unknown libs to the deps - QStringList where("QMAKE_LIBS"); - if(!tmp_proj.isEmpty("QMAKE_INTERNAL_PRL_LIBS")) - where = tmp_proj.variables()["QMAKE_INTERNAL_PRL_LIBS"]; - - for(QStringList::iterator wit = where.begin(); - wit != where.end(); ++wit) { - QStringList &l = tmp_proj.variables()[(*wit)]; - for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) { - QString opt = (*it).trimmed(); - if(!opt.startsWith("/") && // Not a switch - opt != newDep->target && // Not self - opt != "opengl32.lib" && // We don't care about these libs - opt != "glu32.lib" && // to make depgen alittle faster - opt != "kernel32.lib" && - opt != "user32.lib" && - opt != "gdi32.lib" && - opt != "comdlg32.lib" && - opt != "advapi32.lib" && - opt != "shell32.lib" && - opt != "ole32.lib" && - opt != "oleaut32.lib" && - opt != "uuid.lib" && - opt != "imm32.lib" && - opt != "winmm.lib" && - opt != "wsock32.lib" && - opt != "ws2_32.lib" && - opt != "winspool.lib" && - opt != "delayimp.lib") - { - newDep->dependencies << opt.section(Option::dir_sep, -1); - } - } - } - workspace_cleanup.append(newDep); - workspace_depends.insert(newDep->target, newDep); - - debug_msg(1, "Generator: MSVC: Added project (name:'%s' path:'%s' deps:'%s')", - qPrintable(newDep->target) , qPrintable(newDep->dspProjectFile), - qPrintable(newDep->dependencies.join(";"))); - } - } -nextfile: - qmake_setpwd(oldpwd); - } - } - } - - // Restore previous after_user_var options - Option::after_user_vars = old_after_vars; - - // Output all projects - QString dswProjectName = QLatin1String(_dswProjectName); - QString dswProjectDep = QLatin1String(_dswProjectDep); - for(QList<WorkspaceDepend*>::Iterator it = workspace_cleanup.begin(); it != workspace_cleanup.end(); ++it) { - t << _dswDevider; - t << endl; - t << dswProjectName.arg((*it)->orig_target).arg((*it)->dspProjectFile); - t << endl; - t << _dswPackage5Start; - t << _dswPackage5Stop; - t << endl; - t << _dswPackage4Start; - - // Output project dependencies - for(QStringList::iterator dit = (*it)->dependencies.begin(); dit != (*it)->dependencies.end(); ++dit) { - if(WorkspaceDepend *vc = workspace_depends[*dit]) - t << dswProjectDep.arg(vc->orig_target); - } - - t << _dswPackage4Stop; - } - - // Output global part - t << _dswDevider << endl; - t << _dswGlobal; - t << _dswDevider; - t << endl << endl; -} - -class FolderGroup -{ -public: - QString name; - QString filter; - QMap<QString, FolderGroup *> subFolders; - QMap<QString, QString> files; - - void insertStructured(const QString &file, const QString &fileListName) - { - QStringList path = QFileInfo(file).path().split("/"); - if (!path.isEmpty() && path.at(0) == ".") - path.takeAt(0); - FolderGroup *currentFolder = this; - for (int i = 0; i < path.size(); i++) { - if (currentFolder->subFolders.contains(path.at(i))) { - currentFolder = currentFolder->subFolders.value(path.at(i)); - } else { - FolderGroup *newFolder = new FolderGroup; - newFolder->name = path.at(i); - currentFolder->subFolders.insert(path.at(i), newFolder); - currentFolder = newFolder; - } - } - currentFolder->files.insert(file, fileListName); - } - - void insertFlat(const QString &file, const QString &fileListName) - { - files.insert(file, fileListName); - } - - ~FolderGroup() - { - qDeleteAll(subFolders.values()); - } -}; - -bool DspMakefileGenerator::writeFileGroup(QTextStream &t, const QStringList &listNames, const QString &group, const QString &filter) -{ - FolderGroup root; - root.name = group; - root.filter = filter; - - for (int i = 0; i < listNames.count(); ++i) { - QStringList list = project->values(listNames.at(i)); - for (int j = 0; j < list.count(); ++j) { - const QString name = list.at(j); - if (name.isEmpty()) - continue; - if (project->isActiveConfig("flat")) - root.insertFlat(name, listNames.at(i)); - else - root.insertStructured(name, listNames.at(i)); - } - } - - if (root.files.isEmpty() && root.subFolders.isEmpty()) - return true; - - writeSubFileGroup(t, &root); - - return true; -} - -void DspMakefileGenerator::writeSubFileGroup(QTextStream &t, FolderGroup *folder) -{ - t << "# Begin Group \"" << folder->name << "\"" << endl; - t << "# PROP Default_Filter \"" << folder->filter << "\"" << endl; - QMap<QString, FolderGroup *>::const_iterator folderIt = folder->subFolders.begin(); - while (folderIt != folder->subFolders.end()) { - writeSubFileGroup(t, folderIt.value()); - ++folderIt; - } - QMap<QString, QString>::const_iterator it = folder->files.begin(); - while (it != folder->files.end()) { - t << "# Begin Source File" << endl; - t << "SOURCE=" << escapeFilePath(it.key()) << endl; - writeBuildstepForFile(t, it.key(), it.value()); - t << "# End Source File" << endl; - t << endl; - ++it; - } - t << "# End Group" << endl; - t << endl; -} - -bool DspMakefileGenerator::writeBuildstepForFile(QTextStream &t, const QString &file, const QString &listName) -{ - - if (!mergedProjects.count()) { - t << writeBuildstepForFileForConfig(file, listName, this); - return true; - } - - //only add special build rules when needed - - QStringList specialBuilds; - int i = 0; - for (i = 0; i < mergedProjects.count(); ++i) - specialBuilds += writeBuildstepForFileForConfig(file, listName, mergedProjects.at(i)); - - // no special build just return - if (specialBuilds.join("").isEmpty()) - return true; - - for (i = 0; i < mergedProjects.count(); ++i) { - if (i == 0) - t << "!IF"; - else - t << "!ELSEIF"; - t << " \"$(CFG)\" == \"" << configName(mergedProjects.at(i)) << "\"" << endl; - t << endl; - t << specialBuilds.at(i); - t << endl; - } - - t << "!ENDIF" << endl; - - return true; -} - -bool DspMakefileGenerator::writeDspConfig(QTextStream &t, DspMakefileGenerator *config) -{ - - bool isDebug = config->project->isActiveConfig("debug"); - bool staticLibTarget = config->var("MSVCDSP_DSPTYPE") == "0x0104"; - - QString outDir = Option::fixPathToTargetOS(config->project->first("DESTDIR")); - while (outDir.endsWith(Option::dir_sep)) - outDir.chop(1); - outDir = config->escapeFilePath(outDir); - - QString intDir = config->project->first("OBJECTS_DIR"); - while (intDir.endsWith(Option::dir_sep)) - intDir.chop(1); - intDir = config->escapeFilePath(intDir); - - t << "# PROP BASE Use_MFC 0" << endl; - t << "# PROP BASE Use_Debug_Libraries " << (isDebug ? "1" : "0") << endl; - t << "# PROP BASE Output_Dir " << outDir << endl; - t << "# PROP BASE Intermediate_Dir " << intDir << endl; - t << "# PROP BASE Target_Dir \"\"" << endl; - t << "# PROP Use_MFC 0" << endl; - t << "# PROP Use_Debug_Libraries " << (isDebug ? "1" : "0") << endl; - - t << "# PROP Output_Dir " << outDir << endl; - t << "# PROP Intermediate_Dir " << intDir << endl; - if (config->project->isActiveConfig("dll") || config->project->isActiveConfig("plugin")) - t << "# PROP Ignore_Export_Lib 1" << endl; - t << "# PROP Target_Dir \"\"" << endl; - t << "# ADD CPP " << config->var("MSVCDSP_INCPATH") << " /c /FD " << config->var("QMAKE_CXXFLAGS") << " " << config->var("MSVCDSP_DEFINES") << " " << config->var("PRECOMPILED_FLAGS") << endl; - t << "# ADD MTL /nologo /mktyplib203 /win32 /D " << (isDebug ? "\"_DEBUG\"" : "\"NDEBUG\"") << endl; - t << "# ADD RSC /l 0x409 /d " << (isDebug ? "\"_DEBUG\"" : "\"NDEBUG\"") << endl; - t << "# ADD BSC32 /nologo" << endl; - if (staticLibTarget) { - t << "LIB32=" << config->var("QMAKE_LIB") << endl; - t << "# ADD LIB32 " << config->var("MSVCDSP_TARGET") << " " << config->var("PRECOMPILED_OBJECT") << endl; - } else { - t << "LINK32=" << config->var("QMAKE_LINK") << endl; - t << "# ADD LINK32 " << config->var("MSVCDSP_LFLAGS") << " " << config->var("MSVCDSP_LIBS") << " " << config->var("MSVCDSP_TARGET") << " " << config->var("PRECOMPILED_OBJECT") << endl; - } - - if (!config->project->values("MSVCDSP_PRE_LINK").isEmpty()) - t << config->project->values("MSVCDSP_PRE_LINK").first(); - - if (!config->project->values("MSVCDSP_POST_LINK").isEmpty()) - t << config->project->values("MSVCDSP_POST_LINK").first(); - - return true; -} - -QString DspMakefileGenerator::writeBuildstepForFileForConfig(const QString &file, const QString &listName, DspMakefileGenerator *config) -{ - QString ret; - QTextStream t(&ret); - - // exclude from build - if (!config->project->values(listName).contains(file)) { - t << "# PROP Exclude_From_Build 1" << endl; - return ret; - } - - if (config->usePCH) { - bool c_file = false; - for (QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { - if (file.endsWith(*it)) { - c_file = true; - break; - } - } - if(c_file) { - t << "# SUBTRACT CPP /FI" << config->escapeFilePath(config->namePCH) << " /Yu" << config->escapeFilePath(config->namePCH) << " /Fp" << endl; - return ret; - } else if (config->precompH.endsWith(file)) { - // ### dependency list quickly becomes too long for VS to grok... - t << "USERDEP_" << file << "=" << config->valGlue(config->escapeFilePaths(config->findDependencies(config->precompH)), "", "\t", "") << endl; - t << endl; - t << "# Begin Custom Build - Creating precompiled header from " << file << "..." << endl; - t << "InputPath=.\\" << config->escapeFilePath(file) << endl << endl; - t << config->precompPch + ": $(SOURCE) \"$(IntDir)\" \"$(OUTDIR)\"" << endl; - t << "\t" << config->var("QMAKE_CC") << " /TP /W3 /FD /c /Yc /Fp" << config->precompPch << " /Fo" << config->precompObj << " /Fd\"$(IntDir)\\\\\" " << file << " "; - t << config->var("MSVCDSP_INCPATH") << " " << config->var("MSVCDSP_DEFINES") << " " << config->var("QMAKE_CXXFLAGS") << endl; - t << "# End Custom Build" << endl << endl; - return ret; - } - } - - QString fileBase = QFileInfo(file).completeBaseName(); - - bool hasBuiltin = config->hasBuiltinCompiler(file); - BuildStep allSteps; - - if (!config->swappedBuildSteps.contains(file)) { - QStringList compilers = config->project->values("QMAKE_EXTRA_COMPILERS"); - for (int i = 0; i < compilers.count(); ++i) { - QString compiler = compilers.at(i); - if (config->project->values(compiler + ".input").isEmpty()) - continue; - QString input = config->project->values(compiler + ".input").first(); - QStringList inputList = config->project->values(input); - if (!inputList.contains(file)) - continue; - - QStringList compilerCommands = config->project->values(compiler + ".commands"); - QStringList compilerOutput = config->project->values(compiler + ".output"); - if (compilerCommands.isEmpty() || compilerOutput.isEmpty()) - continue; - - QStringList compilerName = config->project->values(compiler + ".name"); - if (compilerName.isEmpty()) - compilerName << compiler; - QStringList compilerDepends = config->project->values(compiler + ".depends"); - QString compilerDependsCommand = config->project->values(compiler + ".depend_command").join(" "); - if (!compilerDependsCommand.isEmpty()) { - if(!config->canExecute(compilerDependsCommand)) - compilerDependsCommand = QString(); - } - QStringList compilerConfig = config->project->values(compiler + ".CONFIG"); - - if (!config->verifyExtraCompiler(compiler, file)) - continue; - - bool combineAll = compilerConfig.contains("combine"); - if (combineAll && inputList.first() != file) - continue; - - QString fileIn("$(InputPath)"); - - if (combineAll && !inputList.isEmpty()) { - fileIn = inputList.join(" "); - compilerDepends += inputList; - } - - QString fileOut = compilerOutput.first(); - QString fileOutBase = QFileInfo(fileOut).completeBaseName(); - fileOut.replace("${QMAKE_FILE_IN}", fileIn); - fileOut.replace("${QMAKE_FILE_BASE}", fileBase); - fileOut.replace("${QMAKE_FILE_OUT_BASE}", fileOutBase); - fileOut.replace('/', '\\'); - - BuildStep step; - for (int i2 = 0; i2 < compilerDepends.count(); ++i2) { - QString dependency = compilerDepends.at(i2); - dependency.replace("${QMAKE_FILE_IN}", fileIn); - dependency.replace("${QMAKE_FILE_BASE}", fileBase); - dependency.replace("${QMAKE_FILE_OUT_BASE}", fileOutBase); - dependency.replace('/', '\\'); - if (!step.deps.contains(dependency, Qt::CaseInsensitive)) - step.deps << dependency; - } - // depends command - if (!compilerDependsCommand.isEmpty() && config->doDepends()) { - char buff[256]; - QString dep_cmd = config->replaceExtraCompilerVariables(compilerDependsCommand, file, - fileOut); - dep_cmd = Option::fixPathToLocalOS(dep_cmd, true, false); - if(config->canExecute(dep_cmd)) { - if(FILE *proc = QT_POPEN(dep_cmd.toLatin1().constData(), "r")) { - QString indeps; - while(!feof(proc)) { - int read_in = (int)fread(buff, 1, 255, proc); - if(!read_in) - break; - indeps += QByteArray(buff, read_in); - } - QT_PCLOSE(proc); - if(!indeps.isEmpty()) - step.deps += config->fileFixify(indeps.replace('\n', ' ').simplified().split(' ')); - } - } - } - - - QString mappedFile; - if (hasBuiltin) { - mappedFile = fileOut; - fileOut = fileIn; - fileIn = file; - } - - step.buildStep += " \\\n\t"; - QString command(compilerCommands.join(" ")); - // Replace any newlines with proper line-continuance - command.replace("\n", " \\\n\t"); - // Might be a macro, and not a valid filename, so the replaceExtraCompilerVariables() would eat it - command.replace("${QMAKE_FILE_IN}", config->escapeFilePath(fileIn)); - command.replace("${QMAKE_FILE_BASE}", config->escapeFilePath(fileBase)); - command.replace("${QMAKE_FILE_OUT_BASE}", config->escapeFilePath(fileOutBase)); - command.replace("${QMAKE_FILE_OUT}", config->escapeFilePath(fileOut)); - - command = config->replaceExtraCompilerVariables(command, fileIn, fileOut); - - step.buildName = compilerName.first(); - step.buildStep += command; - step.buildOutputs += fileOut; - - if (hasBuiltin) { - step.deps << fileIn; - config->swappedBuildSteps[mappedFile] = step; - } else { - allSteps << step; - } - } - } else { - allSteps << config->swappedBuildSteps.value(file); - } - - if (allSteps.buildStep.isEmpty()) - return ret; - - int i; - QStringList dependencyList; - // remove dependencies that are also output - for (i = 0; i < 1; ++i) { - QStringList buildOutput(allSteps.buildOutputs.at(i)); - - for (int i2 = 0; i2 < allSteps.deps.count(); ++i2) { - QString dependency = allSteps.deps.at(i2); - if (!buildOutput.contains(dependency) && !dependencyList.contains(dependency)) - dependencyList << dependency; - } - } - QString allDependencies = config->valGlue(dependencyList, "", "\t", ""); - t << "USERDEP_" << file << "=" << allDependencies << endl; - t << "# PROP Ignore_Default_Tool 1" << endl; - t << "# Begin Custom Build - Running " << allSteps.buildName << " on " << file << endl; - t << "InputPath=" << file << endl; - t << "BuildCmds= " << allSteps.buildStep << endl; - for (i = 0; i < allSteps.buildOutputs.count(); ++i) { - t << config->escapeFilePath(allSteps.buildOutputs.at(i)) - << " : $(SOURCE) $(INTDIR) $(OUTDIR)\n\t$(BuildCmds)\n"; - } - t << endl; - t << "# End Custom Build" << endl; - - return ret; -} - -QT_END_NAMESPACE diff --git a/qmake/generators/win32/msvc_dsp.h b/qmake/generators/win32/msvc_dsp.h deleted file mode 100644 index f3e2435..0000000 --- a/qmake/generators/win32/msvc_dsp.h +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the qmake application of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef MSVC_DSP_H -#define MSVC_DSP_H - -#include "winmakefile.h" - -QT_BEGIN_NAMESPACE - -class FolderGroup; - -class DspMakefileGenerator : public Win32MakefileGenerator -{ - bool init_flag; - bool writeDspHeader(QTextStream &); - bool writeDspParts(QTextStream &); - bool writeFileGroup(QTextStream &t, const QStringList &listNames, const QString &group, const QString &filter); - void writeSubFileGroup(QTextStream &t, FolderGroup *folder); - bool writeBuildstepForFile(QTextStream &t, const QString &file, const QString &listName); - static bool writeDspConfig(QTextStream &t, DspMakefileGenerator *config); - static QString writeBuildstepForFileForConfig(const QString &file, const QString &listName, DspMakefileGenerator *config); - QString configName(DspMakefileGenerator * config); - - bool writeMakefile(QTextStream &); - bool writeProjectMakefile(); - void writeSubDirs(QTextStream &t); - void init(); - -public: - DspMakefileGenerator(); - ~DspMakefileGenerator(); - - bool openOutput(QFile &file, const QString &build) const; - bool hasBuiltinCompiler(const QString &filename) const; - -protected: - virtual bool doDepends() const { return false; } //never necesary - virtual void processSources() { filterIncludedFiles("SOURCES"); filterIncludedFiles("GENERATED_SOURCES"); } - virtual QString replaceExtraCompilerVariables(const QString &, const QStringList &, const QStringList &); - inline QString replaceExtraCompilerVariables(const QString &val, const QString &in, const QString &out) - { return MakefileGenerator::replaceExtraCompilerVariables(val, in, out); } - virtual bool supportsMetaBuild() { return true; } - virtual bool supportsMergedBuilds() { return true; } - virtual bool mergeBuildProject(MakefileGenerator *other); - virtual void processPrlVariable(const QString &, const QStringList &); - virtual bool findLibraries(); - - bool usePCH; - QString precompH, namePCH, - precompObj, precompPch; - - QString platform; - - struct BuildStep { - BuildStep() {} - BuildStep &operator<<(const BuildStep &other) { - deps << other.deps; - buildStep += other.buildStep; - buildName += other.buildName; - buildOutputs += other.buildOutputs; - return *this; - } - - QStringList deps; - QString buildStep; - QString buildName; - QStringList buildOutputs; - }; - QMap<QString, BuildStep> swappedBuildSteps; - - // Holds all configurations for glue (merged) project - QList<DspMakefileGenerator*> mergedProjects; -}; - -inline DspMakefileGenerator::~DspMakefileGenerator() -{ } - -inline bool DspMakefileGenerator::findLibraries() -{ return Win32MakefileGenerator::findLibraries("MSVCDSP_LIBS"); } - -QT_END_NAMESPACE - -#endif // MSVC_DSP_H diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 7566b23..92e8aeb 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -156,8 +156,6 @@ void NmakeMakefileGenerator::init() MakefileGenerator::init(); if(project->values("MAKEFILE").isEmpty()) project->values("MAKEFILE").append("Makefile"); - if(project->values("QMAKE_QMAKE").isEmpty()) - project->values("QMAKE_QMAKE").append("qmake"); if(project->isEmpty("QMAKE_COPY_FILE")) project->values("QMAKE_COPY_FILE").append("$(COPY)"); if(project->isEmpty("QMAKE_COPY_DIR")) diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 58f95e9..f1777e1 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -1626,8 +1626,7 @@ QString VcprojGenerator::findTemplate(QString file) !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2002/" + file))) && !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2003/" + file))) && !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2005/" + file))) && - !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2008/" + file))) && - !exists((ret = (QString(qgetenv("HOME")) + "/.tmake/" + file)))) + !exists((ret = QString(QLibraryInfo::location(QLibraryInfo::DataPath) + "/win32-msvc2008/" + file)))) return ""; debug_msg(1, "Generator: MSVC.NET: Found template \'%s\'", ret.toLatin1().constData()); return ret; diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index c36cc9c..64aaf34 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -595,8 +595,7 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) writeIncPart(t); writeLibsPart(t); - t << "QMAKE = " << (project->isEmpty("QMAKE_QMAKE") ? QString("qmake") : - Option::fixPathToTargetOS(var("QMAKE_QMAKE"), false)) << endl; + t << "QMAKE = " << var("QMAKE_QMAKE") << endl; t << "IDC = " << (project->isEmpty("QMAKE_IDC") ? QString("idc") : Option::fixPathToTargetOS(var("QMAKE_IDC"), false)) << endl; t << "IDL = " << (project->isEmpty("QMAKE_IDL") ? QString("midl") : @@ -768,6 +767,11 @@ QString Win32MakefileGenerator::getLibTarget() return QString(project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".lib"); } +QString Win32MakefileGenerator::getPdbTarget() +{ + return QString(project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".pdb"); +} + QString Win32MakefileGenerator::defaultInstall(const QString &t) { if((t != "target" && t != "dlltarget") || @@ -808,6 +812,18 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t) uninst.append("\n\t"); uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); } + if(project->isActiveConfig("shared") && project->isActiveConfig("debug")) { + QString pdb_target = getPdbTarget(); + pdb_target.remove('"'); + QString src_targ = (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + pdb_target; + QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + pdb_target, FileFixifyAbsolute)); + if(!ret.isEmpty()) + ret += "\n\t"; + ret += QString("-$(INSTALL_FILE)") + " \"" + src_targ + "\" \"" + dst_targ + "\""; + if(!uninst.isEmpty()) + uninst.append("\n\t"); + uninst.append("-$(DEL_FILE) \"" + dst_targ + "\""); + } } if(t == "dlltarget" || project->values(t + ".CONFIG").indexOf("no_dll") == -1) { diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h index 5437524..3a2e3a1 100644 --- a/qmake/generators/win32/winmakefile.h +++ b/qmake/generators/win32/winmakefile.h @@ -83,6 +83,7 @@ protected: virtual void processRcFileVar(); virtual void processFileTagsVar(); virtual QString getLibTarget(); + virtual QString getPdbTarget(); }; inline Win32MakefileGenerator::~Win32MakefileGenerator() diff --git a/qmake/main.cpp b/qmake/main.cpp index 50f9272..42679a2 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -149,7 +149,7 @@ int runQMake(int argc, char **argv) //setup pwd properly debug_msg(1, "Resetting dir to: %s", oldpwd.toLatin1().constData()); qmake_setpwd(oldpwd); //reset the old pwd - int di = fn.lastIndexOf(Option::dir_sep); + int di = fn.lastIndexOf(QDir::separator()); if(di != -1) { debug_msg(1, "Changing dir to: %s", fn.left(di).toLatin1().constData()); if(!qmake_setpwd(fn.left(di))) diff --git a/qmake/option.cpp b/qmake/option.cpp index 5522a80..d7c5397 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -88,7 +88,7 @@ int Option::warn_level = WarnLogic; int Option::debug_level = 0; QFile Option::output; QString Option::output_dir; -bool Option::recursive = false; +Option::QMAKE_RECURSIVE Option::recursive = Option::QMAKE_RECURSIVE_DEFAULT; QStringList Option::before_user_vars; QStringList Option::after_user_vars; QStringList Option::user_configs; @@ -96,13 +96,9 @@ QStringList Option::after_user_configs; QString Option::user_template; QString Option::user_template_prefix; QStringList Option::shellPath; -#if defined(Q_OS_WIN32) -Option::TARG_MODE Option::target_mode = Option::TARG_WIN_MODE; -#elif defined(Q_OS_MAC) -Option::TARG_MODE Option::target_mode = Option::TARG_MACX_MODE; -#else -Option::TARG_MODE Option::target_mode = Option::TARG_UNIX_MODE; -#endif +Option::HOST_MODE Option::host_mode = Option::HOST_UNKNOWN_MODE; +Option::TARG_MODE Option::target_mode = Option::TARG_UNKNOWN_MODE; +bool Option::target_mode_overridden = false; //QMAKE_*_PROPERTY stuff QStringList Option::prop::properties; @@ -126,7 +122,7 @@ QString Option::mkfile::qmakespec_commandline; static Option::QMAKE_MODE default_mode(QString progname) { - int s = progname.lastIndexOf(Option::dir_sep); + int s = progname.lastIndexOf(QDir::separator()); if(s != -1) progname = progname.right(progname.length() - (s + 1)); if(progname == "qmakegen") @@ -136,6 +132,20 @@ static Option::QMAKE_MODE default_mode(QString progname) return Option::QMAKE_GENERATE_MAKEFILE; } +static QString detectProjectFile(const QString &path) +{ + QString ret; + QDir dir(path); + if(dir.exists(dir.dirName() + Option::pro_ext)) { + ret = dir.filePath(dir.dirName()) + Option::pro_ext; + } else { //last try.. + QStringList profiles = dir.entryList(QStringList("*" + Option::pro_ext)); + if(profiles.count() == 1) + ret = dir.filePath(profiles.at(0)); + } + return ret; +} + QString project_builtin_regx(); bool usage(const char *a0) { @@ -170,9 +180,6 @@ bool usage(const char *a0) " * processed as if it was in [files]. These assignments will be parsed *\n" " * before [files]. *\n" " -o file Write output to file\n" - " -unix Run in unix mode\n" - " -win32 Run in win32 mode\n" - " -macx Run in Mac OS X mode\n" " -d Increase debug level\n" " -t templ Overrides TEMPLATE as templ\n" " -tp prefix Overrides TEMPLATE so that prefix is prefixed into the value\n" @@ -209,7 +216,7 @@ Option::parseCommandLine(int argc, char **argv, int skip) if(x == 1) { bool specified = true; if(opt == "project") { - Option::recursive = true; + Option::recursive = Option::QMAKE_RECURSIVE_YES; Option::qmake_mode = Option::QMAKE_GENERATE_PROJECT; } else if(opt == "prl") { Option::mkfile::do_deps = false; @@ -236,14 +243,21 @@ Option::parseCommandLine(int argc, char **argv, int skip) Option::user_template = argv[++x]; } else if(opt == "tp" || opt == "template_prefix") { Option::user_template_prefix = argv[++x]; - } else if(opt == "mac9") { - Option::target_mode = TARG_MAC9_MODE; } else if(opt == "macx") { + fprintf(stderr, "-macx is deprecated.\n"); + Option::host_mode = HOST_MACX_MODE; Option::target_mode = TARG_MACX_MODE; + Option::target_mode_overridden = true; } else if(opt == "unix") { + fprintf(stderr, "-unix is deprecated.\n"); + Option::host_mode = HOST_UNIX_MODE; Option::target_mode = TARG_UNIX_MODE; + Option::target_mode_overridden = true; } else if(opt == "win32") { + fprintf(stderr, "-win32 is deprecated.\n"); + Option::host_mode = HOST_WIN_MODE; Option::target_mode = TARG_WIN_MODE; + Option::target_mode_overridden = true; } else if(opt == "d") { Option::debug_level++; } else if(opt == "version" || opt == "v" || opt == "-version") { @@ -267,9 +281,9 @@ Option::parseCommandLine(int argc, char **argv, int skip) } else if(opt == "Wnone") { Option::warn_level = WarnNone; } else if(opt == "r" || opt == "recursive") { - Option::recursive = true; - } else if(opt == "norecursive") { - Option::recursive = false; + Option::recursive = Option::QMAKE_RECURSIVE_YES; + } else if(opt == "nr" || opt == "norecursive") { + Option::recursive = Option::QMAKE_RECURSIVE_NO; } else if(opt == "config") { Option::user_configs += argv[++x]; } else { @@ -322,12 +336,18 @@ Option::parseCommandLine(int argc, char **argv, int skip) if(!fi.makeAbsolute()) //strange arg = fi.filePath(); if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE || - Option::qmake_mode == Option::QMAKE_GENERATE_PRL) + Option::qmake_mode == Option::QMAKE_GENERATE_PRL) { + if(fi.isDir()) { + QString proj = detectProjectFile(arg); + if (!proj.isNull()) + arg = proj; + } Option::mkfile::project_files.append(arg); - else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) + } else if(Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { Option::projfile::project_dirs.append(arg); - else + } else { handled = false; + } } if(!handled) { return Option::QMAKE_CMDLINE_SHOW_USAGE | Option::QMAKE_CMDLINE_ERROR; @@ -387,8 +407,10 @@ Option::init(int argc, char **argv) #ifdef Q_OS_WIN Option::dirlist_sep = ";"; Option::shellPath = detectShellPath(); + Option::res_ext = ".res"; #else Option::dirlist_sep = ":"; + Option::shellPath = QStringList("sh"); #endif Option::sysenv_mod = "QMAKE_ENV_"; Option::field_sep = ' '; @@ -494,15 +516,9 @@ Option::init(int argc, char **argv) //try REALLY hard to do it for them, lazy.. if(Option::mkfile::project_files.isEmpty()) { - QString pwd = qmake_getpwd(), - proj = pwd + "/" + pwd.right(pwd.length() - (pwd.lastIndexOf('/') + 1)) + Option::pro_ext; - if(QFile::exists(proj)) { + QString proj = detectProjectFile(qmake_getpwd()); + if(!proj.isNull()) Option::mkfile::project_files.append(proj); - } else { //last try.. - QStringList profiles = QDir(pwd).entryList(QStringList("*" + Option::pro_ext)); - if(profiles.count() == 1) - Option::mkfile::project_files.append(pwd + "/" + profiles[0]); - } #ifndef QT_BUILD_QMAKE_LIBRARY if(Option::mkfile::project_files.isEmpty()) { usage(argv[0]); @@ -510,24 +526,37 @@ Option::init(int argc, char **argv) } #endif } + } else if (Option::qmake_mode == Option::QMAKE_GENERATE_PROJECT) { +#if defined(Q_OS_MAC) + Option::host_mode = Option::HOST_MACX_MODE; + Option::target_mode = Option::TARG_MACX_MODE; +#elif defined(Q_OS_UNIX) + Option::host_mode = Option::HOST_UNIX_MODE; + Option::target_mode = Option::TARG_UNIX_MODE; +#else + Option::host_mode = Option::HOST_WIN_MODE; + Option::target_mode = Option::TARG_WIN_MODE; +#endif } //defaults for globals - if(Option::target_mode == Option::TARG_WIN_MODE) { - Option::dir_sep = "\\"; - Option::obj_ext = ".obj"; - Option::res_ext = ".res"; - } else { - if(Option::target_mode == Option::TARG_MAC9_MODE) - Option::dir_sep = ":"; - else - Option::dir_sep = "/"; - Option::obj_ext = ".o"; - } - Option::qmake_abslocation = Option::fixPathToTargetOS(Option::qmake_abslocation); + if (Option::host_mode != Option::HOST_UNKNOWN_MODE) + applyHostMode(); return QMAKE_CMDLINE_SUCCESS; } +void Option::applyHostMode() +{ + if (Option::host_mode == Option::HOST_WIN_MODE) { + Option::dir_sep = "\\"; + Option::obj_ext = ".obj"; + } else { + Option::dir_sep = "/"; + Option::obj_ext = ".o"; + } + Option::qmake_abslocation = Option::fixPathToTargetOS(Option::qmake_abslocation); +} + bool Option::postProcessProject(QMakeProject *project) { Option::cpp_ext = project->variables()["QMAKE_EXT_CPP"]; diff --git a/qmake/option.h b/qmake/option.h index fe9a4ef..9bfdaed 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -106,6 +106,7 @@ struct Option //both of these must be called.. static int init(int argc=0, char **argv=0); //parse cmdline + static void applyHostMode(); static bool postProcessProject(QMakeProject *); enum StringFixFlags { @@ -148,10 +149,15 @@ struct Option static QString output_dir; static int debug_level; static int warn_level; - static bool recursive; + enum QMAKE_RECURSIVE { QMAKE_RECURSIVE_DEFAULT, QMAKE_RECURSIVE_YES, QMAKE_RECURSIVE_NO }; + static QMAKE_RECURSIVE recursive; static QStringList before_user_vars, after_user_vars, user_configs, after_user_configs; - enum TARG_MODE { TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, TARG_MAC9_MODE }; + enum HOST_MODE { HOST_UNKNOWN_MODE, HOST_UNIX_MODE, HOST_WIN_MODE, HOST_MACX_MODE }; + static HOST_MODE host_mode; + enum TARG_MODE { TARG_UNKNOWN_MODE, TARG_UNIX_MODE, TARG_WIN_MODE, TARG_MACX_MODE, + TARG_SYMBIAN_MODE }; static TARG_MODE target_mode; + static bool target_mode_overridden; static QString user_template, user_template_prefix; static QStringList shellPath; @@ -205,7 +211,8 @@ public: TranslationsPath, SettingsPath, DemosPath, - ExamplesPath + ExamplesPath, + ImportsPath }; static QString location(LibraryLocation); }; diff --git a/qmake/project.cpp b/qmake/project.cpp index e4ef7dd..01a3843 100644 --- a/qmake/project.cpp +++ b/qmake/project.cpp @@ -43,6 +43,7 @@ #include "property.h" #include "option.h" #include "cachekeys.h" +#include "generators/metamakefile.h" #include <qdatetime.h> #include <qfile.h> @@ -121,7 +122,7 @@ enum TestFunc { T_REQUIRES=1, T_GREATERTHAN, T_LESSTHAN, T_EQUALS, T_EXISTS, T_EXPORT, T_CLEAR, T_UNSET, T_EVAL, T_CONFIG, T_SYSTEM, T_RETURN, T_BREAK, T_NEXT, T_DEFINED, T_CONTAINS, T_INFILE, T_COUNT, T_ISEMPTY, T_INCLUDE, T_LOAD, T_DEBUG, T_ERROR, - T_MESSAGE, T_WARNING, T_IF }; + T_MESSAGE, T_WARNING, T_IF, T_OPTION }; QMap<QString, TestFunc> qmake_testFunctions() { static QMap<QString, TestFunc> *qmake_test_functions = 0; @@ -155,6 +156,7 @@ QMap<QString, TestFunc> qmake_testFunctions() qmake_test_functions->insert("error", T_ERROR); qmake_test_functions->insert("message", T_MESSAGE); qmake_test_functions->insert("warning", T_WARNING); + qmake_test_functions->insert("option", T_OPTION); } return *qmake_test_functions; } @@ -184,9 +186,7 @@ static QString remove_quotes(const QString &arg) static QString varMap(const QString &x) { QString ret(x); - if(ret.startsWith("TMAKE")) //tmake no more! - ret = "QMAKE" + ret.mid(5); - else if(ret == "INTERFACES") + if(ret == "INTERFACES") ret = "FORMS"; else if(ret == "QMAKE_POST_BUILD") ret = "QMAKE_POST_LINK"; @@ -509,69 +509,6 @@ static void qmake_error_msg(const QString &msg) msg.toLatin1().constData()); } -enum isForSymbian_enum { - isForSymbian_NOT_SET = -1, - isForSymbian_FALSE = 0, - isForSymbian_ABLD = 1, - isForSymbian_SBSV2 = 2, -}; - -static isForSymbian_enum isForSymbian_value = isForSymbian_NOT_SET; - -// Checking for symbian build is primarily determined from the qmake spec, -// but if that is not specified, detect if symbian is the default spec -// by checking the MAKEFILE_GENERATOR variable value. -static void init_symbian(const QMap<QString, QStringList>& vars) -{ - if (isForSymbian_value != isForSymbian_NOT_SET) - return; - - QString spec = QFileInfo(Option::mkfile::qmakespec).fileName(); - if (spec.startsWith("symbian-abld", Qt::CaseInsensitive)) { - isForSymbian_value = isForSymbian_ABLD; - } else if (spec.startsWith("symbian-sbsv2", Qt::CaseInsensitive)) { - isForSymbian_value = isForSymbian_SBSV2; - } else { - QStringList generatorList = vars["MAKEFILE_GENERATOR"]; - - if (!generatorList.isEmpty()) { - QString generator = generatorList.first(); - if (generator.startsWith("SYMBIAN_ABLD")) - isForSymbian_value = isForSymbian_ABLD; - else if (generator.startsWith("SYMBIAN_SBSV2")) - isForSymbian_value = isForSymbian_SBSV2; - else - isForSymbian_value = isForSymbian_FALSE; - } else { - isForSymbian_value = isForSymbian_FALSE; - } - } - - // Force recursive on Symbian, as non-recursive is not really a viable option there - if (isForSymbian_value != isForSymbian_FALSE) - Option::recursive = true; -} - -bool isForSymbian() -{ - // If isForSymbian_value has not been initialized explicitly yet, - // call initializer with dummy map to check qmake spec. - if (isForSymbian_value == isForSymbian_NOT_SET) - init_symbian(QMap<QString, QStringList>()); - - return (isForSymbian_value != isForSymbian_FALSE); -} - -bool isForSymbianSbsv2() -{ - // If isForSymbian_value has not been initialized explicitly yet, - // call initializer with dummy map to check qmake spec. - if (isForSymbian_value == isForSymbian_NOT_SET) - init_symbian(QMap<QString, QStringList>()); - - return (isForSymbian_value == isForSymbian_SBSV2); -} - /* 1) environment variable QMAKEFEATURES (as separated by colons) 2) property variable QMAKEFEATURES (as separated by colons) @@ -597,25 +534,15 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) concat << base_concat + QDir::separator() + "macx"; concat << base_concat + QDir::separator() + "unix"; break; + default: // Can't happen, just make the compiler shut up case Option::TARG_UNIX_MODE: - { - if (isForSymbian()) - concat << base_concat + QDir::separator() + "symbian"; - else - concat << base_concat + QDir::separator() + "unix"; - break; - } + concat << base_concat + QDir::separator() + "unix"; + break; case Option::TARG_WIN_MODE: - { - if (isForSymbian()) - concat << base_concat + QDir::separator() + "symbian"; - else - concat << base_concat + QDir::separator() + "win32"; - break; - } - case Option::TARG_MAC9_MODE: - concat << base_concat + QDir::separator() + "mac"; - concat << base_concat + QDir::separator() + "mac9"; + concat << base_concat + QDir::separator() + "win32"; + break; + case Option::TARG_SYMBIAN_MODE: + concat << base_concat + QDir::separator() + "symbian"; break; } concat << base_concat; @@ -629,7 +556,7 @@ QStringList qmake_feature_paths(QMakeProperty *prop=0) feature_roots += splitPathList(prop->value("QMAKEFEATURES")); if(!Option::mkfile::cachefile.isEmpty()) { QString path; - int last_slash = Option::mkfile::cachefile.lastIndexOf(Option::dir_sep); + int last_slash = Option::mkfile::cachefile.lastIndexOf(QDir::separator()); if(last_slash != -1) path = Option::fixPathToLocalOS(Option::mkfile::cachefile.left(last_slash)); for(QStringList::Iterator concat_it = concat.begin(); @@ -772,6 +699,7 @@ QMakeProject::reset() scope_blocks.push(ScopeBlock()); iterator = 0; function = 0; + recursive = false; } bool @@ -1362,16 +1290,7 @@ bool QMakeProject::read(uchar cmd) { if(cfile.isEmpty()) { - //find out where qmake (myself) lives - if (!base_vars.contains("QMAKE_QMAKE")) { - if (!Option::qmake_abslocation.isNull()) - base_vars["QMAKE_QMAKE"] = QStringList(Option::qmake_abslocation); - else - base_vars["QMAKE_QMAKE"] = QStringList("qmake"); - } - // hack to get the Option stuff in there - base_vars["QMAKE_EXT_OBJ"] = QStringList(Option::obj_ext); base_vars["QMAKE_EXT_CPP"] = Option::cpp_ext; base_vars["QMAKE_EXT_C"] = Option::c_ext; base_vars["QMAKE_EXT_H"] = Option::h_ext; @@ -1457,16 +1376,12 @@ QMakeProject::read(uchar cmd) while(qmakespec.endsWith(QString(QChar(QDir::separator())))) qmakespec.truncate(qmakespec.length()-1); QString spec = qmakespec + QDir::separator() + "qmake.conf"; - if(!QFile::exists(spec) && - QFile::exists(qmakespec + QDir::separator() + "tmake.conf")) - spec = qmakespec + QDir::separator() + "tmake.conf"; debug_msg(1, "QMAKESPEC conf: reading %s", spec.toLatin1().constData()); if(!read(spec, base_vars)) { fprintf(stderr, "Failure to read QMAKESPEC conf file %s.\n", spec.toLatin1().constData()); return false; } - - init_symbian(base_vars); + validateModes(); if(Option::mkfile::do_cache && !Option::mkfile::cachefile.isEmpty()) { debug_msg(1, "QMAKECACHE file: reading %s", Option::mkfile::cachefile.toLatin1().constData()); @@ -1590,6 +1505,48 @@ QMakeProject::read(uchar cmd) return true; } +void QMakeProject::validateModes() +{ +#if !defined(QT_BUILD_QMAKE_NO_GENERATORS) + if (Option::host_mode == Option::HOST_UNKNOWN_MODE + || Option::target_mode == Option::TARG_UNKNOWN_MODE) { + Option::HOST_MODE host_mode; + Option::TARG_MODE target_mode; + const QStringList &gen = base_vars.value("MAKEFILE_GENERATOR"); + if (gen.isEmpty()) { + fprintf(stderr, "%s:%d: Using OS scope before setting MAKEFILE_GENERATOR\n", + parser.file.toLatin1().constData(), parser.line_no); + } else if (MetaMakefileGenerator::modesForGenerator(gen.first(), + &host_mode, &target_mode)) { + if (Option::host_mode == Option::HOST_UNKNOWN_MODE) { + Option::host_mode = host_mode; + Option::applyHostMode(); + } + + if (Option::target_mode == Option::TARG_UNKNOWN_MODE) { + const QStringList &tgt = base_vars.value("TARGET_PLATFORM"); + if (!tgt.isEmpty()) { + const QString &os = tgt.first(); + if (os == "unix") + Option::target_mode = Option::TARG_UNIX_MODE; + else if (os == "macx") + Option::target_mode = Option::TARG_MACX_MODE; + else if (os == "symbian") + Option::target_mode = Option::TARG_SYMBIAN_MODE; + else if (os == "win32") + Option::target_mode = Option::TARG_WIN_MODE; + else + fprintf(stderr, "Unknown target platform specified: %s\n", + os.toLatin1().constData()); + } else { + Option::target_mode = target_mode; + } + } + } + } +#endif // !defined(QT_BUILD_QMAKE_NO_GENERATORS) +} + bool QMakeProject::isActiveConfig(const QString &x, bool regex, QMap<QString, QStringList> *place) { @@ -1602,31 +1559,26 @@ QMakeProject::isActiveConfig(const QString &x, bool regex, QMap<QString, QString else if(x == "false") return false; + if (x == "unix") { + validateModes(); + return Option::target_mode == Option::TARG_UNIX_MODE + || Option::target_mode == Option::TARG_MACX_MODE + || Option::target_mode == Option::TARG_SYMBIAN_MODE; + } else if (x == "macx" || x == "mac") { + validateModes(); + return Option::target_mode == Option::TARG_MACX_MODE; + } else if (x == "symbian") { + validateModes(); + return Option::target_mode == Option::TARG_SYMBIAN_MODE; + } else if (x == "win32") { + validateModes(); + return Option::target_mode == Option::TARG_WIN_MODE; + } + + //mkspecs static QString spec; if(spec.isEmpty()) spec = QFileInfo(Option::mkfile::qmakespec).fileName(); - - // Symbian is an exception to how scopes are resolved. Since we do not - // have a separate target mode for Symbian, but we expect the scope to resolve - // on other platforms we base it entirely on the mkspec. This means that - // using a mkspec starting with 'symbian*' will resolve both the 'symbian' - // and the 'unix' (because of Open C) scopes to true. - if(isForSymbian() && (x == "symbian" || x == "unix")) - return true; - - //mkspecs - if((Option::target_mode == Option::TARG_MACX_MODE || - Option::target_mode == Option::TARG_UNIX_MODE) && x == "unix") - return !isForSymbian(); - else if(Option::target_mode == Option::TARG_MACX_MODE && x == "macx") - return !isForSymbian(); - else if(Option::target_mode == Option::TARG_MAC9_MODE && x == "mac9") - return !isForSymbian(); - else if((Option::target_mode == Option::TARG_MAC9_MODE || Option::target_mode == Option::TARG_MACX_MODE) && - x == "mac") - return !isForSymbian(); - else if(Option::target_mode == Option::TARG_WIN_MODE && x == "win32") - return !isForSymbian(); QRegExp re(x, Qt::CaseSensitive, QRegExp::Wildcard); if((regex && re.exactMatch(spec)) || (!regex && spec == x)) return true; @@ -1718,7 +1670,7 @@ QMakeProject::doProjectInclude(QString file, uchar flags, QMap<QString, QStringL if(file.indexOf(Option::dir_sep) == -1 || !QFile::exists(file)) { static QStringList *feature_roots = 0; if(!feature_roots) { - init_symbian(base_vars); + validateModes(); feature_roots = new QStringList(qmake_feature_paths(prop)); qmakeAddCacheClear(qmakeDeleteCacheClear_QStringList, (void**)&feature_roots); } @@ -2782,6 +2734,21 @@ QMakeProject::doProjectTest(QString func, QList<QStringList> args_list, QMap<QSt exit(2); #endif return true; } + case T_OPTION: + if (args.count() != 1) { + fprintf(stderr, "%s:%d: option() requires one argument.\n", + parser.file.toLatin1().constData(), parser.line_no); + return false; + } + if (args.first() == "recursive") { + recursive = true; + } else { + fprintf(stderr, "%s:%d: unrecognized option() argument '%s'.\n", + parser.file.toLatin1().constData(), parser.line_no, + args.first().toLatin1().constData()); + return false; + } + return true; default: fprintf(stderr, "%s:%d: Unknown test function: %s\n", parser.file.toLatin1().constData(), parser.line_no, func.toLatin1().constData()); @@ -3081,8 +3048,6 @@ QStringList &QMakeProject::values(const QString &_var, QMap<QString, QStringList QString orig_template = place["TEMPLATE"].first(), real_template; if(!Option::user_template_prefix.isEmpty() && !orig_template.startsWith(Option::user_template_prefix)) real_template = Option::user_template_prefix + orig_template; - if(real_template.endsWith(".t")) - real_template = real_template.left(real_template.length()-2); if(!real_template.isEmpty()) { var = ".BUILTIN." + var; place[var] = QStringList(real_template); @@ -3166,6 +3131,19 @@ QStringList &QMakeProject::values(const QString &_var, QMap<QString, QStringList } else if (var == QLatin1String("QMAKE_DIR_SEP")) { if (place[var].isEmpty()) return values("DIR_SEPARATOR", place); + } else if (var == QLatin1String("QMAKE_EXT_OBJ")) { + if (place[var].isEmpty()) { + var = ".BUILTIN." + var; + place[var] = QStringList(Option::obj_ext); + } + } else if (var == QLatin1String("QMAKE_QMAKE")) { + if (place[var].isEmpty()) { + if (!Option::qmake_abslocation.isNull()) + place[var] = QStringList(Option::qmake_abslocation); + else + place[var] = QStringList(Option::fixPathToTargetOS( + QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmake", false)); + } } else if (var == QLatin1String("EPOCROOT")) { if (place[var].isEmpty()) place[var] = QStringList(epocRoot()); diff --git a/qmake/project.h b/qmake/project.h index 1f53bf2..bfebed0 100644 --- a/qmake/project.h +++ b/qmake/project.h @@ -78,6 +78,7 @@ class QMakeProject FunctionBlock *function; QMap<QString, FunctionBlock*> testFunctions, replaceFunctions; + bool recursive; bool own_prop; QString pfile, cfile; QMakeProperty *prop; @@ -105,6 +106,7 @@ class QMakeProject QStringList doVariableReplaceExpand(const QString &str, QMap<QString, QStringList> &place, bool *ok=0); void init(QMakeProperty *, const QMap<QString, QStringList> *); QStringList &values(const QString &v, QMap<QString, QStringList> &place); + void validateModes(); public: QMakeProject() { init(0, 0); } @@ -154,6 +156,8 @@ public: QString first(const QString &v); QMap<QString, QStringList> &variables(); + bool isRecursive() const { return recursive; } + protected: friend class MakefileGenerator; bool read(const QString &file, QMap<QString, QStringList> &place); @@ -192,10 +196,6 @@ inline QString QMakeProject::first(const QString &v) inline QMap<QString, QStringList> &QMakeProject::variables() { return vars; } -// Helper functions needed for Symbian -bool isForSymbian(); -bool isForSymbianSbsv2(); - QT_END_NAMESPACE #endif // PROJECT_H diff --git a/qmake/property.cpp b/qmake/property.cpp index 34368cd..fde7c65 100644 --- a/qmake/property.cpp +++ b/qmake/property.cpp @@ -95,6 +95,8 @@ QMakeProperty::value(QString v, bool just_check) return QLibraryInfo::location(QLibraryInfo::BinariesPath); else if(v == "QT_INSTALL_PLUGINS") return QLibraryInfo::location(QLibraryInfo::PluginsPath); + else if(v == "QT_INSTALL_IMPORTS") + return QLibraryInfo::location(QLibraryInfo::ImportsPath); else if(v == "QT_INSTALL_TRANSLATIONS") return QLibraryInfo::location(QLibraryInfo::TranslationsPath); else if(v == "QT_INSTALL_CONFIGURATION") @@ -104,7 +106,7 @@ QMakeProperty::value(QString v, bool just_check) else if(v == "QT_INSTALL_DEMOS") return QLibraryInfo::location(QLibraryInfo::DemosPath); else if(v == "QMAKE_MKSPECS") - return qmake_mkspec_paths().join(Option::target_mode == Option::TARG_WIN_MODE ? ";" : ":"); + return qmake_mkspec_paths().join(Option::dirlist_sep); else if(v == "QMAKE_VERSION") return qmake_version(); #ifdef QT_VERSION_STR @@ -191,6 +193,7 @@ QMakeProperty::exec() specialProps.append("QT_INSTALL_LIBS"); specialProps.append("QT_INSTALL_BINS"); specialProps.append("QT_INSTALL_PLUGINS"); + specialProps.append("QT_INSTALL_IMPORTS"); specialProps.append("QT_INSTALL_TRANSLATIONS"); specialProps.append("QT_INSTALL_CONFIGURATION"); specialProps.append("QT_INSTALL_EXAMPLES"); diff --git a/qmake/qmake.pri b/qmake/qmake.pri index 05debe6..0821f00 100644 --- a/qmake/qmake.pri +++ b/qmake/qmake.pri @@ -12,7 +12,7 @@ SOURCES += project.cpp property.cpp main.cpp generators/makefile.cpp \ generators/makefiledeps.cpp generators/metamakefile.cpp generators/mac/pbuilder_pbx.cpp \ generators/xmloutput.cpp generators/win32/borland_bmake.cpp \ generators/win32/msvc_nmake.cpp generators/projectgenerator.cpp \ - generators/win32/msvc_dsp.cpp generators/win32/msvc_vcproj.cpp \ + generators/win32/msvc_vcproj.cpp \ generators/win32/msvc_objectmodel.cpp \ generators/symbian/symmake.cpp \ generators/symbian/symmake_abld.cpp \ @@ -26,7 +26,7 @@ HEADERS += project.h property.h generators/makefile.h \ generators/win32/winmakefile.h generators/projectgenerator.h \ generators/makefiledeps.h generators/metamakefile.h generators/mac/pbuilder_pbx.h \ generators/xmloutput.h generators/win32/borland_bmake.h generators/win32/msvc_nmake.h \ - generators/win32/msvc_dsp.h generators/win32/msvc_vcproj.h \ + generators/win32/msvc_vcproj.h \ generators/win32/mingw_make.h generators/win32/msvc_objectmodel.h \ generators/symbian/symmake.h \ generators/symbian/symmake_abld.h \ |