diff options
Diffstat (limited to 'qmake')
26 files changed, 550 insertions, 973 deletions
diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix index 86f884fe20..405bbf9212 100644 --- a/qmake/Makefile.unix +++ b/qmake/Makefile.unix @@ -13,7 +13,7 @@ OBJS=project.o option.o property.o main.o ioutils.o proitems.o \ #qt code QOBJS=qtextcodec.o qutfcodec.o qstring.o qstring_compat.o qstringbuilder.o qtextstream.o qiodevice.o \ - qdebug.o qmalloc.o qglobal.o \ + qringbuffer.o qdebug.o qmalloc.o qglobal.o \ qarraydata.o qbytearray.o qbytearraymatcher.o qdatastream.o qbuffer.o qlist.o qfiledevice.o qfile.o \ qfilesystementry.o qfilesystemengine.o qfsfileengine.o qfsfileengine_iterator.o qregexp.o qvector.o \ qbitarray.o qdir.o qdiriterator.o quuid.o qhash.o qfileinfo.o qdatetime.o qstringlist.o \ @@ -44,6 +44,7 @@ DEPEND_SRC = \ $(SOURCE_PATH)/src/corelib/tools/qstring_compat.cpp \ $(SOURCE_PATH)/src/corelib/io/qfiledevice.cpp \ $(SOURCE_PATH)/src/corelib/io/qtextstream.cpp $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp \ + $(SOURCE_PATH)/src/corelib/tools/qringbuffer.cpp \ $(SOURCE_PATH)/src/corelib/io/qdebug.cpp \ $(SOURCE_PATH)/src/corelib/global/qmalloc.cpp \ $(SOURCE_PATH)/src/corelib/global/qglobal.cpp $(SOURCE_PATH)/src/corelib/tools/qregexp.cpp \ @@ -101,6 +102,7 @@ CPPFLAGS = -g $(EXTRA_CPPFLAGS) \ -I$(BUILD_PATH)/src/corelib/global -DHAVE_QCONFIG_CPP \ -I$(QMAKESPEC) \ -I$(SOURCE_PATH)/tools/shared \ + -DQT_VERSION_STR=\"$(QT_VERSION)\" -DQT_VERSION_MAJOR=$(QT_MAJOR_VERSION) -DQT_VERSION_MINOR=$(QT_MINOR_VERSION) -DQT_VERSION_PATCH=$(QT_PATCH_VERSION) \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \ -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -242,6 +244,9 @@ qsettings_win.o: $(SOURCE_PATH)/src/corelib/io/qsettings_win.cpp qiodevice.o: $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qiodevice.cpp +qringbuffer.o: $(SOURCE_PATH)/src/corelib/tools/qringbuffer.cpp + $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/tools/qringbuffer.cpp + qdebug.o: $(SOURCE_PATH)/src/corelib/io/qdebug.cpp $(CXX) -c -o $@ $(CXXFLAGS) $(SOURCE_PATH)/src/corelib/io/qdebug.cpp diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 index 9dda6ca1e7..e61e9503f3 100644 --- a/qmake/Makefile.win32 +++ b/qmake/Makefile.win32 @@ -22,7 +22,7 @@ CFLAGS_EXTRA = /Zc:wchar_t- ! elseif "$(QMAKESPEC)" == "win32-msvc2008" || "$(QMAKESPEC)" == "win32-msvc2010" || "$(QMAKESPEC)" == "win32-msvc2012" || "$(QMAKESPEC)" == "win32-msvc2013" CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS $(CFLAGS_CRT) ! elseif "$(QMAKESPEC)" == "win32-msvc2015" -CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS /Zc:strictStrings /w44456 /w44457 /w44458 $(CFLAGS_CRT) +CFLAGS_EXTRA = /MP /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS /Zc:strictStrings /w44456 /w44457 /w44458 /wd4577 $(CFLAGS_CRT) ! else ! error Unsupported compiler for this Makefile ! endif @@ -36,6 +36,7 @@ CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \ -I$(BUILD_PATH)\src\corelib\global -DHAVE_QCONFIG_CPP \ -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ -I$(SOURCE_PATH)\tools\shared \ + -DQT_VERSION_STR=\"$(QT_VERSION)\" -DQT_VERSION_MAJOR=$(QT_MAJOR_VERSION) -DQT_VERSION_MINOR=$(QT_MINOR_VERSION) -DQT_VERSION_PATCH=$(QT_PATCH_VERSION) \ -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \ -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \ -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ @@ -88,6 +89,7 @@ QTOBJS= \ qglobal.obj \ qhash.obj \ qiodevice.obj \ + qringbuffer.obj \ qdebug.obj \ qlist.obj \ qlinkedlist.obj \ diff --git a/qmake/doc/snippets/code/doc_src_qmake-manual.pro b/qmake/doc/snippets/code/doc_src_qmake-manual.pro index 43de125446..6fa3ca085d 100644 --- a/qmake/doc/snippets/code/doc_src_qmake-manual.pro +++ b/qmake/doc/snippets/code/doc_src_qmake-manual.pro @@ -186,21 +186,6 @@ DEFINES += USE_MY_STUFF #! [27] -#! [28] -myFiles.files = path\*.png -DEPLOYMENT += myFiles -#! [28] - - -#! [29] -myFiles.files = path\file1.ext1 path2\file2.ext1 path3\* -myFiles.path = \some\path\on\device -someother.files = C:\additional\files\* -someother.path = \myFiles\path2 -DEPLOYMENT += myFiles someother -#! [29] - - #! [30] DESTDIR = ../../lib #! [30] @@ -989,8 +974,12 @@ VERSION_PE_HEADER = 1.2 #! [185] #! [186] +RC_DEFINES += USE_MY_STUFF +#! [186] + +#! [187] win32-g++:contains(QMAKE_HOST.arch, x86_64):{ message("Host is 64bit") ... } -#! [186] +#! [187] diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index ccb8d95973..535b500fd3 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -728,7 +728,7 @@ \section2 Creating and Moving Xcode Projects Developers on OS X can take advantage of the qmake support for Xcode - project files, as described in \l{Additional Command-Line Options}, + project files, as described in \l{Qt for OS X#Additional Command-Line Options}{Qt for OS X} documentation. by running qmake to generate an Xcode project from an existing qmake project file. For example: @@ -1119,38 +1119,6 @@ Specifies a list of all directories to look in to resolve dependencies. This variable is used when crawling through \c included files. - \target DEPLOYMENT - \section1 DEPLOYMENT - - \note This variable is used only on the Windows CE platform. - - Specifies which additional files will be deployed. Deployment means the - transfer of files from the development system to the target device or - emulator. - - Files can be deployed by either creating a Visual Studio project or using - the \l {Using Qt Test remotely on Windows CE}{cetest} executable. - - For example, the following definition uploads all PNG images in \c path to - the directory where the build target is deployed: - - \snippet code/doc_src_qmake-manual.pro 28 - - The default deployment target path for Windows CE is - \c{%CSIDL_PROGRAM_FILES%\target}, which usually gets expanded to - \c{\Program Files\target}. - - It is also possible to specify multiple \c sources to be deployed on - target \c paths. In addition, different variables can be used for - deployment to different directories. - - For example: - - \snippet code/doc_src_qmake-manual.pro 29 - - \note In Windows CE all linked Qt libraries will be deployed to the path - specified by \c{myFiles.path}. - \target DEPLOYMENT_PLUGIN \section1 DEPLOYMENT_PLUGIN @@ -1275,6 +1243,13 @@ For more information, see \l{Installing Files}. + This variable is also used to specify which additional files will be + deployed to embedded devices. + + For Windows CE, the default deployment target path is + \c{%CSIDL_PROGRAM_FILES%\target}, which usually gets expanded to + \c{\Program Files\target}. + \target LEXIMPLS \section1 LEXIMPLS @@ -1755,7 +1730,7 @@ \row \li .version_string \li Host OS version string \endtable - \snippet code/doc_src_qmake-manual.pro 186 + \snippet code/doc_src_qmake-manual.pro 187 \target QMAKE_INCDIR \section1 QMAKE_INCDIR @@ -1870,6 +1845,22 @@ The value of this variable is typically handled by qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. + \section1 QMAKE_LFLAGS_REL_RPATH + + Specifies the linker flags needed to enable relative paths in + \l{QMAKE_RPATHDIR}. + + The value of this variable is typically handled by + qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. + + \section1 QMAKE_REL_RPATH_BASE + + Specifies the string the dynamic linker understands to be the + location of the referring executable or library. + + The value of this variable is typically handled by + qmake or \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. + \section1 QMAKE_LFLAGS_RPATHLINK Specifies the linker flags needed to use the values from @@ -2120,6 +2111,13 @@ executable at link time so that the paths will be preferentially searched at runtime. + When relative paths are specified, qmake will mangle them into a form + understood by the dynamic linker to be relative to the location of + the referring executable or library. + This is supported only by some platforms (currently Linux and + Darwin-based ones) and is detectable by checking whether + \l{QMAKE_REL_RPATH_BASE} is set. + \section1 QMAKE_RPATHLINKDIR Specifies a list of library paths for the static linker to search for implicit @@ -2228,52 +2226,10 @@ \section1 QT - Specifies the Qt modules that are used by your project. - - The table below shows the options that can be used with the \c QT variable - and the Qt modules that are associated with each of them: - - \table - \header \li Option \li Module Enabled - \row \li axcontainer \li \l{Using ActiveX controls and COM in Qt} - {QAxContainer}, which is - part of the \l{Active Qt} framework - \row \li axserver \li \l{Building ActiveX servers in Qt} - {QAxServer}, which is - part of the \l{Active Qt} framework - \row \li concurrent \li \l{Qt Concurrent} - \row \li core (included by default) \li \l{Qt Core} - \row \li dbus \li \l{Qt D-Bus} - \row \li declarative \li \l{Qt Quick 1} (deprecated) - \row \li designer \li \l{Qt Designer} - \row \li gui (included by default) \li \l{Qt GUI} - \row \li help \li \l{Qt Help} - \row \li multimedia \li \l{Qt Multimedia} - \row \li multimediawidgets \li \l{Qt Multimedia Widgets} - \row \li network \li \l{Qt Network} - \row \li opengl \li \l{Qt OpenGL} (deprecated) - \row \li printsupport \li \l{Qt Print Support} - \row \li qml \li \l{Qt QML} - \row \li qmltest \li \l{Qt QML Test} - \row \li x11extras \li \l{Qt X11 Extras} - \row \li quick \li \l{Qt Quick} - \row \li script \li \l{Qt Script} (deprecated) - \row \li scripttools \li \l{Qt Script Tools} (deprecated) - \row \li sensors \li \l{Qt Sensors} - \row \li serialport \li \l{Qt Serial Port} - \row \li sql \li \l{Qt SQL} - \row \li svg \li \l{Qt SVG} - \row \li testlib \li \l{Qt Test} - \row \li uitools \li \l{Qt UI Tools} - \row \li webkit \li \l{Qt WebKit} - \row \li webkitwidgets \li \l{Qt WebKit Widgets} - \row \li widgets \li \l{Qt Widgets} - \row \li winextras \li \l{Qt Windows Extras} - \row \li xml \li \l{Qt XML} (deprecated) - \row \li xmlpatterns \li \l{Qt XML Patterns} - \endtable + Specifies the \l{All Modules}{Qt modules} that are used by your project. For + the value to add for each module, see the module documentation. - By default, \c QT contains both \c core and \c gui, ensuring that standard + By default, \c QT contains \c core and \c gui, ensuring that standard GUI applications can be built without further configuration. If you want to build a project \e without the \l{Qt GUI} module, you need to @@ -2336,6 +2292,14 @@ .rc file. This is only utilized if the \l{VERSION} or \l{RC_ICONS} variable is set and the \l{RC_FILE} and \l{RES_FILE} variables are not set. + \target RC_DEFINES + \section1 RC_DEFINES + + Windows only. qmake adds the values of this variable as RC preprocessor macros + (/d option). If this variable is not set, the \l{DEFINES} variable is used instead. + + \snippet code/doc_src_qmake-manual.pro 186 + \target RC_ICONS \section1 RC_ICONS @@ -4525,7 +4489,7 @@ */ /*! - \target qmake-getting-started + \keyword qmake-getting-started \page qmake-tutorial.html \title Getting Started \contentspage {qmake Manual}{Contents} diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index 7ff1d97b16..ccb3cfe810 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -417,20 +417,24 @@ public: inline QString groupName() const { return group; } inline QString compilerName() const { return compiler; } inline bool isObjectOutput(const QString &file) const { - bool ret = object_output; - for(int i = 0; !ret && i < Option::c_ext.size(); ++i) { - if(file.endsWith(Option::c_ext.at(i))) { - ret = true; - break; - } + if (object_output) + return true; + + if (file.endsWith(Option::objc_ext)) + return true; + if (file.endsWith(Option::objcpp_ext)) + return true; + + for (int i = 0; i < Option::c_ext.size(); ++i) { + if (file.endsWith(Option::c_ext.at(i))) + return true; } - for(int i = 0; !ret && i < Option::cpp_ext.size(); ++i) { - if(file.endsWith(Option::cpp_ext.at(i))) { - ret = true; - break; - } + for (int i = 0; i < Option::cpp_ext.size(); ++i) { + if (file.endsWith(Option::cpp_ext.at(i))) + return true; } - return ret; + + return false; } }; @@ -490,9 +494,9 @@ static QString xcodeFiletypeForFilename(const QString &filename) return "sourcecode.c.h"; } - if (filename.endsWith(QStringLiteral(".mm"))) + if (filename.endsWith(Option::objcpp_ext)) return QStringLiteral("sourcecode.cpp.objcpp"); - if (filename.endsWith(QStringLiteral(".m"))) + if (filename.endsWith(Option::objc_ext)) return QStringLiteral("sourcecode.c.objc"); if (filename.endsWith(QStringLiteral(".framework"))) return QStringLiteral("wrapper.framework"); @@ -816,7 +820,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) for(int x = 0; x < tmp.count();) { bool remove = false; QString library, name; - ProString opt = tmp[x].trimmed(); + ProString opt = tmp[x]; if(opt.startsWith("-L")) { QString r = opt.mid(2).toQString(); fixForOutput(r); @@ -833,8 +837,8 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) encode the version number in the Project file which might be a bad things in days to come? --Sam */ - QString lib_file = (*lit) + Option::dir_sep + lib; - if(QMakeMetaInfo::libExists(lib_file)) { + QString lib_file = QMakeMetaInfo::findLib(Option::normalizePath((*lit) + Option::dir_sep + lib)); + if (!lib_file.isEmpty()) { QMakeMetaInfo libinfo(project); if(libinfo.readLib(lib_file)) { if(!libinfo.isEmpty("QMAKE_PRL_TARGET")) { diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 7d4026c292..a54083c04d 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -252,10 +252,11 @@ MakefileGenerator::setProjectFile(QMakeProject *p) else target_mode = TARG_UNIX_MODE; init(); - findLibraries(); - if(Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE && - project->isActiveConfig("link_prl")) //load up prl's' - processPrlFiles(); + bool linkPrl = (Option::qmake_mode == Option::QMAKE_GENERATE_MAKEFILE) + && project->isActiveConfig("link_prl"); + bool mergeLflags = !project->isActiveConfig("no_smart_library_merge") + && !project->isActiveConfig("no_lflags_merge"); + findLibraries(linkPrl, mergeLflags); } ProStringList @@ -377,6 +378,13 @@ MakefileGenerator::init() ProValueMap &v = project->variables(); + v["QMAKE_BUILTIN_COMPILERS"] = ProStringList() << "C" << "CXX"; + + v["QMAKE_LANGUAGE_C"] = ProString("c"); + v["QMAKE_LANGUAGE_CXX"] = ProString("c++"); + v["QMAKE_LANGUAGE_OBJC"] = ProString("objective-c"); + v["QMAKE_LANGUAGE_OBJCXX"] = ProString("objective-c++"); + if (v["TARGET"].isEmpty()) warn_msg(WarnLogic, "TARGET is empty"); @@ -871,65 +879,60 @@ MakefileGenerator::init() bool MakefileGenerator::processPrlFile(QString &file) { - bool ret = false, try_replace_file=false; - QString meta_file, orig_file = file; - if(QMakeMetaInfo::libExists(file)) { + bool try_replace_file = false; + QString f = fileFixify(file, FileFixifyBackwards); + QString meta_file = QMakeMetaInfo::findLib(f); + if (!meta_file.isEmpty()) { try_replace_file = true; - meta_file = file; - file = ""; } else { - QString tmp = file; + QString tmp = f; int ext = tmp.lastIndexOf('.'); if(ext != -1) tmp = tmp.left(ext); - meta_file = tmp; - } -// meta_file = fileFixify(meta_file); - QString real_meta_file = Option::normalizePath(meta_file); - if(!meta_file.isEmpty()) { - QString f = fileFixify(real_meta_file, FileFixifyBackwards); - if(QMakeMetaInfo::libExists(f)) { - QMakeMetaInfo libinfo(project); - debug_msg(1, "Processing PRL file: %s", real_meta_file.toLatin1().constData()); - if(!libinfo.readLib(f)) { - fprintf(stderr, "Error processing meta file: %s\n", real_meta_file.toLatin1().constData()); - } else if(project->isActiveConfig("no_read_prl_" + libinfo.type().toLower())) { - debug_msg(2, "Ignored meta file %s [%s]", real_meta_file.toLatin1().constData(), libinfo.type().toLatin1().constData()); - } else { - ret = true; - project->values("QMAKE_CURRENT_PRL_LIBS") = libinfo.values("QMAKE_PRL_LIBS"); - ProStringList &defs = project->values("DEFINES"); - const ProStringList &prl_defs = project->values("PRL_EXPORT_DEFINES"); - foreach (const ProString &def, libinfo.values("QMAKE_PRL_DEFINES")) - if (!defs.contains(def) && prl_defs.contains(def)) - defs.append(def); - if(try_replace_file && !libinfo.isEmpty("QMAKE_PRL_TARGET")) { - QString dir; - int slsh = real_meta_file.lastIndexOf('/'); - if(slsh != -1) - dir = real_meta_file.left(slsh+1); - file = libinfo.first("QMAKE_PRL_TARGET").toQString(); - if(QDir::isRelativePath(file)) - file.prepend(dir); - } - } - } - if(ret) { - QString mf = QMakeMetaInfo::findLib(meta_file); - if(project->values("QMAKE_PRL_INTERNAL_FILES").indexOf(mf) == -1) - project->values("QMAKE_PRL_INTERNAL_FILES").append(mf); - if(project->values("QMAKE_INTERNAL_INCLUDED_FILES").indexOf(mf) == -1) - project->values("QMAKE_INTERNAL_INCLUDED_FILES").append(mf); - } + meta_file = QMakeMetaInfo::findLib(tmp); } - if(try_replace_file && file.isEmpty()) { -#if 0 - warn_msg(WarnLogic, "Found prl [%s] file with no target [%s]!", meta_file.toLatin1().constData(), - orig_file.toLatin1().constData()); -#endif - file = orig_file; + if (meta_file.isEmpty()) + return false; + QMakeMetaInfo libinfo(project); + debug_msg(1, "Processing PRL file: %s", meta_file.toLatin1().constData()); + if (!libinfo.readLib(meta_file)) { + fprintf(stderr, "Error processing meta file %s\n", meta_file.toLatin1().constData()); + return false; } - return ret; + if (project->isActiveConfig("no_read_prl_" + libinfo.type().toLower())) { + debug_msg(2, "Ignored meta file %s [%s]", + meta_file.toLatin1().constData(), libinfo.type().toLatin1().constData()); + return false; + } + project->values("QMAKE_CURRENT_PRL_LIBS") = libinfo.values("QMAKE_PRL_LIBS"); + ProStringList &defs = project->values("DEFINES"); + const ProStringList &prl_defs = project->values("PRL_EXPORT_DEFINES"); + foreach (const ProString &def, libinfo.values("QMAKE_PRL_DEFINES")) + if (!defs.contains(def) && prl_defs.contains(def)) + defs.append(def); + if (try_replace_file) { + ProString tgt = libinfo.first("QMAKE_PRL_TARGET"); + if (tgt.isEmpty()) { + fprintf(stderr, "Error: %s does not define QMAKE_PRL_TARGET\n", + meta_file.toLatin1().constData()); + } else if (!tgt.contains('.') + && !libinfo.values("QMAKE_PRL_CONFIG").contains("lib_bundle")) { + fprintf(stderr, "Error: %s defines QMAKE_PRL_TARGET without extension\n", + meta_file.toLatin1().constData()); + } else { + int off = qMax(file.lastIndexOf('/'), file.lastIndexOf('\\')) + 1; + debug_msg(1, " Replacing library reference %s with %s", + file.mid(off).toLatin1().constData(), + tgt.toQString().toLatin1().constData()); + file.replace(off, 1000, tgt.toQString()); + } + } + QString mf = fileFixify(meta_file); + if (!project->values("QMAKE_PRL_INTERNAL_FILES").contains(mf)) + project->values("QMAKE_PRL_INTERNAL_FILES").append(mf); + if (!project->values("QMAKE_INTERNAL_INCLUDED_FILES").contains(mf)) + project->values("QMAKE_INTERNAL_INCLUDED_FILES").append(mf); + return true; } void @@ -944,12 +947,6 @@ MakefileGenerator::filterIncludedFiles(const char *var) } } -void -MakefileGenerator::processPrlFiles() -{ - qFatal("MakefileGenerator::processPrlFiles() called!"); -} - static QString qv(const ProString &val) { @@ -968,10 +965,6 @@ qv(const ProStringList &val) void MakefileGenerator::writePrlFile(QTextStream &t) { - ProString target = project->first("TARGET"); - int slsh = target.lastIndexOf(Option::dir_sep); - if(slsh != -1) - target.chopFront(slsh + 1); QString bdir = Option::output_dir; if(bdir.isEmpty()) bdir = qmake_getpwd(); @@ -981,7 +974,7 @@ MakefileGenerator::writePrlFile(QTextStream &t) if(!project->isEmpty("QMAKE_ABSOLUTE_SOURCE_PATH")) t << "QMAKE_PRL_SOURCE_DIR =" << qv(project->first("QMAKE_ABSOLUTE_SOURCE_PATH")) << endl; - t << "QMAKE_PRL_TARGET =" << qv(target) << endl; + t << "QMAKE_PRL_TARGET =" << qv(project->first("LIB_TARGET")) << endl; if(!project->isEmpty("PRL_EXPORT_DEFINES")) t << "QMAKE_PRL_DEFINES =" << qv(project->values("PRL_EXPORT_DEFINES")) << endl; if(!project->isEmpty("PRL_EXPORT_CFLAGS")) @@ -1151,12 +1144,28 @@ MakefileGenerator::writeObj(QTextStream &t, const char *src) << " " << escapeDependencyPaths(findDependencies(srcf)).join(" \\\n\t\t"); ProKey comp; - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) { - if((*sit).endsWith((*cppit))) { - comp = "QMAKE_RUN_CXX"; - break; + foreach (const ProString &compiler, project->values("QMAKE_BUILTIN_COMPILERS")) { + // Unfortunately we were not consistent about the C++ naming + ProString extensionSuffix = compiler; + if (extensionSuffix == "CXX") + extensionSuffix = ProString("CPP"); + + // Nor the C naming + ProString compilerSuffix = compiler; + if (compilerSuffix == "C") + compilerSuffix = ProString("CC"); + + foreach (const ProString &extension, project->values(ProKey("QMAKE_EXT_" + extensionSuffix))) { + if ((*sit).endsWith(extension)) { + comp = ProKey("QMAKE_RUN_" + compilerSuffix); + break; + } } + + if (!comp.isNull()) + break; } + if (comp.isEmpty()) comp = "QMAKE_RUN_CC"; if (!project->isEmpty(comp)) { @@ -2744,6 +2753,22 @@ MakefileGenerator::fileInfo(QString file) const return fi; } +MakefileGenerator::LibFlagType +MakefileGenerator::parseLibFlag(const ProString &flag, ProString *arg) +{ + if (flag.startsWith("-L")) { + *arg = flag.mid(2); + return LibFlagPath; + } + if (flag.startsWith("-l")) { + *arg = flag.mid(2); + return LibFlagLib; + } + if (flag.startsWith('-')) + return LibFlagOther; + return LibFlagFile; +} + ProStringList MakefileGenerator::fixLibFlags(const ProKey &var) { diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index 07483dbcb0..61b8f9ac60 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -197,11 +197,10 @@ protected: QString prlFileName(bool fixify=true); void writePrlFile(); bool processPrlFile(QString &); - virtual void processPrlFiles(); virtual void writePrlFile(QTextStream &); //make sure libraries are found - virtual bool findLibraries(); + virtual bool findLibraries(bool linkPrl, bool mergeLflags); //for retrieving values and lists of values virtual QString var(const ProKey &var) const; @@ -221,6 +220,8 @@ protected: QString filePrefixRoot(const QString &, const QString &); + enum LibFlagType { LibFlagLib, LibFlagPath, LibFlagFile, LibFlagOther }; + virtual LibFlagType parseLibFlag(const ProString &flag, ProString *arg); ProStringList fixLibFlags(const ProKey &var); virtual ProString fixLibFlag(const ProString &lib); @@ -276,7 +277,7 @@ inline bool MakefileGenerator::noIO() const inline QString MakefileGenerator::defaultInstall(const QString &) { return QString(""); } -inline bool MakefileGenerator::findLibraries() +inline bool MakefileGenerator::findLibraries(bool, bool) { return true; } inline MakefileGenerator::~MakefileGenerator() diff --git a/qmake/generators/projectgenerator.cpp b/qmake/generators/projectgenerator.cpp index 9b1796c45d..7d042ce66c 100644 --- a/qmake/generators/projectgenerator.cpp +++ b/qmake/generators/projectgenerator.cpp @@ -166,7 +166,7 @@ ProjectGenerator::init() QString nd = newdir; if(nd == ".") nd = ""; - else if(!nd.isEmpty() && !nd.endsWith(QString(QChar(QDir::separator())))) + else if (!nd.isEmpty() && !nd.endsWith(QDir::separator())) nd += QDir::separator(); nd += profiles[i]; fileFixify(nd); diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index c4750cb8a4..57c0a97228 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -45,21 +45,11 @@ QT_BEGIN_NAMESPACE void UnixMakefileGenerator::init() { - if(project->isEmpty("QMAKE_EXTENSION_SHLIB")) { - if(project->isEmpty("QMAKE_CYGWIN_SHLIB")) { - project->values("QMAKE_EXTENSION_SHLIB").append("so"); - } else { - project->values("QMAKE_EXTENSION_SHLIB").append("dll"); - } - } - ProStringList &configs = project->values("CONFIG"); if(project->isEmpty("ICON") && !project->isEmpty("RC_FILE")) project->values("ICON") = project->values("RC_FILE"); if(project->isEmpty("QMAKE_EXTENSION_PLUGIN")) project->values("QMAKE_EXTENSION_PLUGIN").append(project->first("QMAKE_EXTENSION_SHLIB")); - if(project->isEmpty("QMAKE_LIBTOOL")) - project->values("QMAKE_LIBTOOL").append("libtool --silent"); project->values("QMAKE_ORIG_TARGET") = project->values("TARGET"); @@ -111,11 +101,6 @@ UnixMakefileGenerator::init() project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_PREBIND"); if(!project->isEmpty("QMAKE_INCDIR")) project->values("INCLUDEPATH") += project->values("QMAKE_INCDIR"); - project->values("QMAKE_L_FLAG") - << (project->isActiveConfig("rvct_linker") ? "--userlibpath " - : project->isActiveConfig("armcc_linker") ? "-L--userlibpath=" - : project->isActiveConfig("ti_linker") ? "--search_path=" - : "-L"); ProStringList ldadd; if(!project->isEmpty("QMAKE_LIBDIR")) { const ProStringList &libdirs = project->values("QMAKE_LIBDIR"); @@ -140,8 +125,23 @@ UnixMakefileGenerator::init() const ProStringList &rpathdirs = project->values("QMAKE_RPATHDIR"); for (int i = 0; i < rpathdirs.size(); ++i) { QString rpathdir = rpathdirs[i].toQString(); - if (!rpathdir.startsWith('@') && !rpathdir.startsWith('$')) - rpathdir = QFileInfo(rpathdir).absoluteFilePath(); + if (rpathdir.length() > 1 && rpathdir.at(0) == '$' && rpathdir.at(1) != '(') { + rpathdir.replace(0, 1, "\\$$"); // Escape from make and the shell + } else if (!rpathdir.startsWith('@') && fileInfo(rpathdir).isRelative()) { + QString rpathbase = project->first("QMAKE_REL_RPATH_BASE").toQString(); + if (rpathbase.isEmpty()) { + fprintf(stderr, "Error: This platform does not support relative paths in QMAKE_RPATHDIR (%s)\n", + rpathdir.toLatin1().constData()); + continue; + } + if (rpathbase.startsWith('$')) + rpathbase.replace(0, 1, "\\$$"); // Escape from make and the shell + if (rpathdir == ".") + rpathdir = rpathbase; + else + rpathdir.prepend(rpathbase + '/'); + project->values("QMAKE_LFLAGS").insertUnique(project->values("QMAKE_LFLAGS_REL_RPATH")); + } project->values("QMAKE_LFLAGS") += var("QMAKE_LFLAGS_RPATH") + escapeFilePath(rpathdir); } } @@ -155,19 +155,19 @@ UnixMakefileGenerator::init() if(project->isActiveConfig("GNUmake") && !project->isEmpty("QMAKE_CFLAGS_DEPS")) include_deps = true; //do not generate deps - if(project->isActiveConfig("compile_libtool")) - Option::obj_ext = ".lo"; //override the .o MakefileGenerator::init(); - QString comps[] = { "C", "CXX", "OBJC", "OBJCXX", QString() }; - for(int i = 0; !comps[i].isNull(); i++) { + if (project->isActiveConfig("objective_c")) + project->values("QMAKE_BUILTIN_COMPILERS") << "OBJC" << "OBJCXX"; + + foreach (const ProString &compiler, project->values("QMAKE_BUILTIN_COMPILERS")) { QString compile_flag = var("QMAKE_COMPILE_FLAG"); if(compile_flag.isEmpty()) compile_flag = "-c"; if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { - QString pchFlags = var(ProKey("QMAKE_" + comps[i] + "FLAGS_USE_PRECOMPILE")); + QString pchFlags = var(ProKey("QMAKE_" + compiler + "FLAGS_USE_PRECOMPILE")); QString pchBaseName; if(!project->isEmpty("PRECOMPILED_DIR")) { @@ -194,22 +194,11 @@ UnixMakefileGenerator::init() pchBaseName += project->first("QMAKE_PCH_OUTPUT_EXT").toQString(); pchBaseName += Option::dir_sep; - QString pchOutputFile; - - if(comps[i] == "C") { - pchOutputFile = "c"; - } else if(comps[i] == "CXX") { - pchOutputFile = "c++"; - } else if(project->isActiveConfig("objective_c")) { - if(comps[i] == "OBJC") - pchOutputFile = "objective-c"; - else if(comps[i] == "OBJCXX") - pchOutputFile = "objective-c++"; - } - if(!pchOutputFile.isEmpty()) { + ProString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler)); + if (!language.isEmpty()) { pchFlags.replace("${QMAKE_PCH_OUTPUT}", - escapeFilePath(pchBaseName + pchOutputFile + headerSuffix)); + escapeFilePath(pchBaseName + language + headerSuffix)); } } @@ -217,26 +206,30 @@ UnixMakefileGenerator::init() compile_flag += " " + pchFlags; } - QString cflags; - if(comps[i] == "OBJC" || comps[i] == "OBJCXX") - cflags += " $(CFLAGS)"; - else - cflags += " $(" + comps[i] + "FLAGS)"; - compile_flag += cflags + " $(INCPATH)"; + QString compilerExecutable; + if (compiler == "C" || compiler == "OBJC") { + compilerExecutable = "$(CC)"; + compile_flag += " $(CFLAGS)"; + } else { + compilerExecutable = "$(CXX)"; + compile_flag += " $(CXXFLAGS)"; + } + + compile_flag += " $(INCPATH)"; - QString compiler = comps[i]; - if (compiler == "C") - compiler = "CC"; + ProString compilerVariable = compiler; + if (compilerVariable == "C") + compilerVariable = ProString("CC"); - const ProKey runComp("QMAKE_RUN_" + compiler); + const ProKey runComp("QMAKE_RUN_" + compilerVariable); if(project->isEmpty(runComp)) - project->values(runComp).append("$(" + compiler + ") " + compile_flag + " " + var("QMAKE_CC_O_FLAG") + "$obj $src"); - const ProKey runCompImp("QMAKE_RUN_" + compiler + "_IMP"); + project->values(runComp).append(compilerExecutable + " " + compile_flag + " " + var("QMAKE_CC_O_FLAG") + "$obj $src"); + const ProKey runCompImp("QMAKE_RUN_" + compilerVariable + "_IMP"); if(project->isEmpty(runCompImp)) - project->values(runCompImp).append("$(" + compiler + ") " + compile_flag + " " + var("QMAKE_CC_O_FLAG") + "\"$@\" \"$<\""); + project->values(runCompImp).append(compilerExecutable + " " + compile_flag + " " + var("QMAKE_CC_O_FLAG") + "\"$@\" \"$<\""); } - if (project->isActiveConfig("mac") && !project->isEmpty("TARGET") && !project->isActiveConfig("compile_libtool") && + if (project->isActiveConfig("mac") && !project->isEmpty("TARGET") && ((project->isActiveConfig("build_pass") || project->isEmpty("BUILDS")))) { ProString bundle; if(project->isActiveConfig("bundle") && !project->isEmpty("QMAKE_BUNDLE_EXTENSION")) { @@ -290,6 +283,11 @@ UnixMakefileGenerator::init() init2(); project->values("QMAKE_INTERNAL_PRL_LIBS") << "QMAKE_LIBS"; + ProString target = project->first("TARGET"); + int slsh = target.lastIndexOf(Option::dir_sep); + if (slsh != -1) + target.chopFront(slsh + 1); + project->values("LIB_TARGET").prepend(target); if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) { bool ok; int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(&ok); @@ -313,56 +311,14 @@ UnixMakefileGenerator::init() project->values("QMAKE_INTERNAL_PRL_LIBS") << "QMAKE_AR_SUBLIBS"; } } - - if(project->isActiveConfig("compile_libtool")) { - static const char * const libtoolify[] = { - "QMAKE_RUN_CC", "QMAKE_RUN_CC_IMP", "QMAKE_RUN_CXX", "QMAKE_RUN_CXX_IMP", - "QMAKE_LINK_THREAD", "QMAKE_LINK", "QMAKE_AR_CMD", "QMAKE_LINK_SHLIB_CMD", 0 - }; - for (int i = 0; libtoolify[i]; i++) { - ProStringList &l = project->values(libtoolify[i]); - if(!l.isEmpty()) { - QString libtool_flags, comp_flags; - if (!strncmp(libtoolify[i], "QMAKE_LINK", 10) || !strcmp(libtoolify[i], "QMAKE_AR_CMD")) { - libtool_flags += " --mode=link"; - if(project->isActiveConfig("staticlib")) { - libtool_flags += " -static"; - } else { - if(!project->isEmpty("QMAKE_LIB_FLAG")) { - int maj = project->first("VER_MAJ").toInt(); - int min = project->first("VER_MIN").toInt(); - int pat = project->first("VER_PAT").toInt(); - comp_flags += " -version-info " + QString::number(10*maj + min) + - ":" + QString::number(pat) + ":0"; - if (strcmp(libtoolify[i], "QMAKE_AR_CMD")) { - QString rpath = Option::output_dir; - if(!project->isEmpty("DESTDIR")) { - rpath = project->first("DESTDIR").toQString(); - if(QDir::isRelativePath(rpath)) - rpath.prepend(Option::output_dir + Option::dir_sep); - } - comp_flags += " -rpath " + escapeFilePath(Option::fixPathToTargetOS(rpath, false)); - } - } - } - if(project->isActiveConfig("plugin")) - libtool_flags += " -module"; - } else { - libtool_flags += " --mode=compile"; - } - l.first().prepend("$(LIBTOOL)" + libtool_flags + " "); - if(!comp_flags.isEmpty()) - l.first() += comp_flags; - } - } - } } QStringList -&UnixMakefileGenerator::findDependencies(const QString &file) +&UnixMakefileGenerator::findDependencies(const QString &f) { - QStringList &ret = MakefileGenerator::findDependencies(file); + QStringList &ret = MakefileGenerator::findDependencies(f); if (doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { + ProString file = f; QString header_prefix; if(!project->isEmpty("PRECOMPILED_DIR")) header_prefix = project->first("PRECOMPILED_DIR").toQString(); @@ -382,45 +338,33 @@ QStringList QString header_suffix = project->isActiveConfig("clang_pch_style") ? project->first("QMAKE_PCH_OUTPUT_EXT").toQString() : ""; header_prefix += Option::dir_sep + project->first("QMAKE_PRECOMP_PREFIX"); - for(QStringList::Iterator it = Option::c_ext.begin(); it != Option::c_ext.end(); ++it) { - if(file.endsWith(*it)) { - if(!project->isEmpty("QMAKE_CFLAGS_PRECOMPILE")) { - QString precomp_c_h = header_prefix + "c" + header_suffix; - if(!ret.contains(precomp_c_h)) - ret += precomp_c_h; - } - if(project->isActiveConfig("objective_c")) { - if(!project->isEmpty("QMAKE_OBJCFLAGS_PRECOMPILE")) { - QString precomp_objc_h = header_prefix + "objective-c" + header_suffix; - if(!ret.contains(precomp_objc_h)) - ret += precomp_objc_h; - } - if(!project->isEmpty("QMAKE_OBJCXXFLAGS_PRECOMPILE")) { - QString precomp_objcpp_h = header_prefix + "objective-c++" + header_suffix; - if(!ret.contains(precomp_objcpp_h)) - ret += precomp_objcpp_h; - } - } - break; - } - } - for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) { - if(file.endsWith(*it)) { - if(!project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE")) { - QString precomp_cpp_h = header_prefix + "c++" + header_suffix; - if(!ret.contains(precomp_cpp_h)) - ret += precomp_cpp_h; - } - if(project->isActiveConfig("objective_c")) { - if(!project->isEmpty("QMAKE_OBJCXXFLAGS_PRECOMPILE")) { - QString precomp_objcpp_h = header_prefix + "objective-c++" + header_suffix; - if(!ret.contains(precomp_objcpp_h)) - ret += precomp_objcpp_h; - } - } - break; + + foreach (const ProString &compiler, project->values("QMAKE_BUILTIN_COMPILERS")) { + if (project->isEmpty(ProKey("QMAKE_" + compiler + "FLAGS_PRECOMPILE"))) + continue; + + ProString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler)); + if (language.isEmpty()) + continue; + + // Unfortunately we were not consistent about the C++ naming + ProString extensionSuffix = compiler; + if (extensionSuffix == "CXX") + extensionSuffix = ProString("CPP"); + + foreach (const ProString &extension, project->values(ProKey("QMAKE_EXT_" + extensionSuffix))) { + if (!file.endsWith(extension.toQString())) + continue; + + QString precompiledHeader = header_prefix + language + header_suffix; + if (!ret.contains(precompiledHeader)) + ret += precompiledHeader; + + goto foundPrecompiledDependency; } } + foundPrecompiledDependency: + ; // Hurray!! } } return ret; @@ -433,20 +377,19 @@ UnixMakefileGenerator::fixLibFlag(const ProString &lib) } bool -UnixMakefileGenerator::findLibraries() +UnixMakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) { - ProString libArg = project->first("QMAKE_L_FLAG"); - if (libArg == "-L") - libArg.clear(); - QList<QMakeLocalFileName> libdirs; - int libidx = 0; + QList<QMakeLocalFileName> libdirs, frameworkdirs; + int libidx = 0, fwidx = 0; foreach (const ProString &dlib, project->values("QMAKE_DEFAULT_LIBDIRS")) libdirs.append(QMakeLocalFileName(dlib.toQString())); + frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks")); + frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks")); static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; for (int i = 0; lflags[i]; i++) { ProStringList &l = project->values(lflags[i]); for (ProStringList::Iterator it = l.begin(); it != l.end(); ) { - QString stub, dir, extn, opt = (*it).trimmed().toQString(); + QString opt = (*it).toQString(); if(opt.startsWith("-")) { if(opt.startsWith("-L")) { QString lib = opt.mid(2); @@ -457,173 +400,60 @@ UnixMakefileGenerator::findLibraries() continue; } libdirs.insert(libidx++, f); - if (!libArg.isEmpty()) - *it = libArg + f.real(); } else if(opt.startsWith("-l")) { - if (project->isActiveConfig("rvct_linker") || project->isActiveConfig("armcc_linker")) { - (*it) = "lib" + opt.mid(2) + ".so"; - } else if (project->isActiveConfig("ti_linker")) { - (*it) = opt.mid(2); - } else { - stub = opt.mid(2); - } - } else if (target_mode == TARG_MAC_MODE && opt.startsWith("-framework")) { - if (opt.length() == 10) - ++it; - // Skip - } - } else { - extn = dir = ""; - stub = opt; - int slsh = opt.lastIndexOf(Option::dir_sep); - if(slsh != -1) { - dir = opt.left(slsh); - stub = opt.mid(slsh+1); - } - QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$"); - if(stub_reg.exactMatch(stub)) { - stub = stub_reg.cap(1); - extn = stub_reg.cap(2); - } - } - if(!stub.isEmpty()) { - stub += project->first(ProKey("QMAKE_" + stub.toUpper() + "_SUFFIX")).toQString(); - bool found = false; - ProStringList extens; - if(!extn.isNull()) - extens << extn; - else + QString lib = opt.mid(2); + ProStringList extens; extens << project->first("QMAKE_EXTENSION_SHLIB") << "a"; - for (ProStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { - if(dir.isNull()) { - for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) { - QString pathToLib = ((*dep_it).local() + '/' - + project->first("QMAKE_PREFIX_SHLIB") - + stub + "." + (*extit)); - if(exists(pathToLib)) { - (*it) = "-l" + stub; - found = true; - break; - } - } - } else { - QString lib = dir + project->first("QMAKE_PREFIX_SHLIB") + stub + "." + (*extit); - if (exists(lib)) { - (*it) = lib; - found = true; - break; - } - } - } - if(!found && project->isActiveConfig("compile_libtool")) { - for(int dep_i = 0; dep_i < libdirs.size(); ++dep_i) { - if (exists(libdirs[dep_i].local() + '/' + project->first("QMAKE_PREFIX_SHLIB") + stub + Option::libtool_ext)) { - (*it) = libdirs[dep_i].real() + Option::dir_sep + project->first("QMAKE_PREFIX_SHLIB") + stub + Option::libtool_ext; - found = true; - break; - } - } - } - } - ++it; - } - } - return false; -} - -QString linkLib(const QString &file, const QString &libName) { - QString ret; - QRegExp reg("^.*lib(" + QRegExp::escape(libName) + "[^./=]*).*$"); - if(reg.exactMatch(file)) - ret = "-l" + reg.cap(1); - return ret; -} - -void -UnixMakefileGenerator::processPrlFiles() -{ - const QString libArg = project->first("QMAKE_L_FLAG").toQString(); - QList<QMakeLocalFileName> libdirs, frameworkdirs; - int libidx = 0, fwidx = 0; - foreach (const ProString &dlib, project->values("QMAKE_DEFAULT_LIBDIRS")) - libdirs.append(QMakeLocalFileName(dlib.toQString())); - frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks")); - frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks")); - static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; - for (int i = 0; lflags[i]; i++) { - ProStringList &l = project->values(lflags[i]); - for(int lit = 0; lit < l.size(); ++lit) { - QString opt = l.at(lit).trimmed().toQString(); - if(opt.startsWith("-")) { - if (opt.startsWith(libArg)) { - QMakeLocalFileName l(opt.mid(libArg.length())); - if(!libdirs.contains(l)) - libdirs.insert(libidx++, l); - } else if(opt.startsWith("-l")) { - QString lib = opt.right(opt.length() - 2); - QString prl_ext = project->first(ProKey("QMAKE_" + lib.toUpper() + "_SUFFIX")).toQString(); - 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() + '/' + project->first("QMAKE_PREFIX_SHLIB") + lib + Option::libtool_ext; - if (exists(la) && QFile::exists(lfn.local() + "/.libs")) { - QString dot_libs = lfn.real() + Option::dir_sep + ".libs"; - l.append("-L" + dot_libs); - libdirs.insert(libidx++, QMakeLocalFileName(dot_libs)); - } - } - - QString prl = lfn.local() + '/' + project->first("QMAKE_PREFIX_SHLIB") + lib + prl_ext; - if(processPrlFile(prl)) { - if(prl.startsWith(lfn.local())) - prl.replace(0, lfn.local().length(), lfn.real()); - opt = linkLib(prl, lib); - break; + for (QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); + dep_it != libdirs.end(); ++dep_it) { + QString libBase = (*dep_it).local() + '/' + + project->first("QMAKE_PREFIX_SHLIB") + lib; + if (linkPrl && processPrlFile(libBase)) + goto found; + for (ProStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) { + if (exists(libBase + '.' + (*extit))) + goto found; } } + found: ; } else if (target_mode == TARG_MAC_MODE && opt.startsWith("-F")) { - QMakeLocalFileName f(opt.right(opt.length()-2)); - if(!frameworkdirs.contains(f)) + QMakeLocalFileName f(opt.mid(2)); + if (!frameworkdirs.contains(f)) frameworkdirs.insert(fwidx++, f); } else if (target_mode == TARG_MAC_MODE && opt.startsWith("-framework")) { - if(opt.length() > 11) - opt = opt.mid(11); - else - opt = l.at(++lit).toQString(); - opt = opt.trimmed(); - foreach (const QMakeLocalFileName &dir, frameworkdirs) { - QString prl = dir.local() + "/" + opt + ".framework/" + opt + Option::prl_ext; - if(processPrlFile(prl)) - break; + if (linkPrl) { + if (opt.length() == 10) + opt = (*++it).toQString(); + else + opt = opt.mid(10).trimmed(); + foreach (const QMakeLocalFileName &dir, frameworkdirs) { + QString prl = dir.local() + "/" + opt + ".framework/" + opt + Option::prl_ext; + if (processPrlFile(prl)) + break; + } + } else { + if (opt.length() == 10) + ++it; + // Skip } } - } else if(!opt.isNull()) { - QString lib = opt; - processPrlFile(lib); -#if 0 - if(ret) - opt = linkLib(lib, ""); -#endif - if(!opt.isEmpty()) - for (int k = 0; k < l.size(); ++k) - l[k] = l.at(k).toQString().replace(lib, opt); + } else if (linkPrl) { + processPrlFile(opt); } ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); - if(!prl_libs.isEmpty()) { - for(int prl = 0; prl < prl_libs.size(); ++prl) - l.insert(++lit, prl_libs.at(prl)); - prl_libs.clear(); - } + for (int prl = 0; prl < prl_libs.size(); ++prl) + it = l.insert(++it, prl_libs.at(prl)); + prl_libs.clear(); + ++it; } - //merge them into a logical order - if(!project->isActiveConfig("no_smart_library_merge") && !project->isActiveConfig("no_lflags_merge")) { + if (mergeLflags) { QHash<ProKey, ProStringList> lflags; for(int lit = 0; lit < l.size(); ++lit) { ProKey arch("default"); - ProString opt = l.at(lit).trimmed(); - if(opt.startsWith("-")) { + ProString opt = l.at(lit); + if (opt.startsWith('-')) { if (target_mode == TARG_MAC_MODE && opt.startsWith("-Xarch")) { if (opt.length() > 7) { arch = opt.mid(7).toKey(); @@ -631,36 +461,27 @@ UnixMakefileGenerator::processPrlFiles() } } - if (opt.startsWith(libArg) || - (target_mode == TARG_MAC_MODE && opt.startsWith("-F"))) { - if(!lflags[arch].contains(opt)) + if (opt.startsWith("-L") + || (target_mode == TARG_MAC_MODE && opt.startsWith("-F"))) { + if (!lflags[arch].contains(opt)) lflags[arch].append(opt); - } else if(opt.startsWith("-l") || opt == "-pthread") { - // Make sure we keep the dependency-order of libraries - if (lflags[arch].contains(opt)) - lflags[arch].removeAll(opt); + } else if (opt.startsWith("-l") || opt == "-pthread") { + // Make sure we keep the dependency order of libraries + lflags[arch].removeAll(opt); lflags[arch].append(opt); } else if (target_mode == TARG_MAC_MODE && opt.startsWith("-framework")) { - if(opt.length() > 11) - opt = opt.mid(11); - else { + if (opt.length() > 10) { + opt = opt.mid(10).trimmed(); + } else { opt = l.at(++lit); - if (target_mode == TARG_MAC_MODE && opt.startsWith("-Xarch")) + if (opt.startsWith("-Xarch")) opt = l.at(++lit); // The user has done the right thing and prefixed each part } bool found = false; for(int x = 0; x < lflags[arch].size(); ++x) { - ProString xf = lflags[arch].at(x); - if(xf.startsWith("-framework")) { - ProString framework; - if(xf.length() > 11) - framework = xf.mid(11); - else - framework = lflags[arch].at(++x); - if(framework == opt) { - found = true; - break; - } + if (lflags[arch].at(x) == "-framework" && lflags[arch].at(++x) == opt) { + found = true; + break; } } if(!found) { @@ -690,6 +511,7 @@ UnixMakefileGenerator::processPrlFiles() } } } + return false; } QString @@ -718,7 +540,6 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } else if(project->first("TEMPLATE") == "app") { target = "$(QMAKE_TARGET)"; } else if(project->first("TEMPLATE") == "lib") { - if(project->isEmpty("QMAKE_CYGWIN_SHLIB")) { if (!project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin") && !project->isActiveConfig("unversioned_libname")) { @@ -728,7 +549,6 @@ UnixMakefileGenerator::defaultInstall(const QString &t) links << "$(TARGET0)"; } } - } } for(int i = 0; i < targets.size(); ++i) { QString src = targets.at(i).toQString(), @@ -741,16 +561,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) uninst.append("-$(DEL_FILE) " + dst); } - if (bundle == NoBundle && project->isActiveConfig("compile_libtool")) { - QString src_targ = escapeFilePath(target); - if(src_targ == "$(TARGET)") - src_targ = "$(TARGETL)"; - QString dst_dir = fileFixify(targetdir, FileFixifyAbsolute); - if(QDir::isRelativePath(dst_dir)) - dst_dir = Option::fixPathToTargetOS(Option::output_dir + Option::dir_sep + dst_dir); - ret = "-$(LIBTOOL) --mode=install cp " + src_targ + ' ' + escapeFilePath(filePrefixRoot(root, dst_dir)); - uninst.append("-$(LIBTOOL) --mode=uninstall " + src_targ); - } else { + { QString src_targ = target; if(!destdir.isEmpty()) src_targ = Option::fixPathToTargetOS(destdir + target, false); @@ -868,7 +679,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) if(type == "prl" && project->isActiveConfig("create_prl") && !project->isActiveConfig("no_install_prl") && !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) meta = prlFileName(false); - if(type == "libtool" && project->isActiveConfig("create_libtool") && !project->isActiveConfig("compile_libtool")) + if (type == "libtool" && project->isActiveConfig("create_libtool")) meta = libtoolFileName(false); if(type == "pkgconfig" && project->isActiveConfig("create_pc")) meta = pkgConfigFileName(false); diff --git a/qmake/generators/unix/unixmake.h b/qmake/generators/unix/unixmake.h index b136ea04d0..db3f59f517 100644 --- a/qmake/generators/unix/unixmake.h +++ b/qmake/generators/unix/unixmake.h @@ -54,9 +54,8 @@ protected: virtual bool doDepends() const { return !Option::mkfile::do_stub_makefile && MakefileGenerator::doDepends(); } virtual QString defaultInstall(const QString &); virtual ProString fixLibFlag(const ProString &lib); - virtual void processPrlFiles(); - virtual bool findLibraries(); + virtual bool findLibraries(bool linkPrl, bool mergeLflags); virtual QString escapeFilePath(const QString &path) const; ProString escapeFilePath(const ProString &path) const { return MakefileGenerator::escapeFilePath(path); } virtual QStringList &findDependencies(const QString &); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index e4973157cd..9db64bebee 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -53,13 +53,8 @@ UnixMakefileGenerator::writePrlFile(QTextStream &t) { MakefileGenerator::writePrlFile(t); // libtool support - if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib") { //write .la - if(project->isActiveConfig("compile_libtool")) - warn_msg(WarnLogic, "create_libtool specified with compile_libtool can lead to conflicting .la\n" - "formats, create_libtool has been disabled\n"); - else - writeLibtoolFile(); + writeLibtoolFile(); } // pkg-config support if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") @@ -214,8 +209,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "AR = " << var("QMAKE_AR") << endl; t << "RANLIB = " << var("QMAKE_RANLIB") << endl; - if(project->isActiveConfig("compile_libtool")) - t << "LIBTOOL = " << var("QMAKE_LIBTOOL") << endl; t << "SED = " << var("QMAKE_STREAM_EDITOR") << endl; t << "STRIP = " << var("QMAKE_STRIP") << endl; @@ -269,13 +262,13 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "DIST = " << valList(fileFixify(project->values("DISTFILES").toQStringList())) << " " << fileVarList("HEADERS") << ' ' << fileVarList("SOURCES") << endl; t << "QMAKE_TARGET = " << fileVar("QMAKE_ORIG_TARGET") << endl; - // The comment is important for mingw32-make.exe on Windows as otherwise trailing slashes - // would be interpreted as line continuation. The lack of spacing between the value and the - // comment is also important as otherwise quoted use of "$(DESTDIR)" would include this - // spacing. - t << "DESTDIR = " << fileVar("DESTDIR") << "#avoid trailing-slash linebreak\n"; - if(project->isActiveConfig("compile_libtool")) - t << "TARGETL = " << fileVar("TARGET_la") << endl; + QString destd = fileVar("DESTDIR"); + // When building on non-MSys MinGW, the path ends with a backslash, which + // GNU make will interpret that as a line continuation. Doubling the backslash + // avoids the problem, at the cost of the variable containing *both* backslashes. + if (destd.endsWith('\\')) + destd += '\\'; + t << "DESTDIR = " << destd << endl; t << "TARGET = " << fileVar("TARGET") << endl; // ### mixed use! if(project->isActiveConfig("plugin")) { t << "TARGETD = " << fileVar("TARGET") << endl; @@ -306,18 +299,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "include " << escapeDependencyPath(*it) << endl; /* rules */ - t << "first: all\n"; - t << "####### Implicit rules\n\n"; - t << ".SUFFIXES: " << Option::obj_ext; - for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit) - t << " " << (*cit); - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) - t << " " << (*cppit); - t << endl << endl; - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) - t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit) - t << (*cit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; + t << "first:" << (!project->isActiveConfig("no_default_goal_deps") ? " all" : "") << "\n"; if(include_deps) { if (project->isActiveConfig("gcc_MD_depends")) { @@ -600,10 +582,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_PRE_LINK")) t << "\n\t" << var("QMAKE_PRE_LINK"); - if(project->isActiveConfig("compile_libtool")) { - t << "\n\t" - << var("QMAKE_LINK_SHLIB_CMD"); - } else if(project->isActiveConfig("plugin")) { + if (project->isActiveConfig("plugin")) { t << "\n\t" << "-$(DEL_FILE) $(TARGET)\n\t" << var("QMAKE_LINK_SHLIB_CMD"); @@ -703,15 +682,12 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) << " $(OBJECTS) $(OBJCOMP) " << depVar("POST_TARGETDEPS") << "\n\t"; if(!destdir.isEmpty()) t << mkdir_p_asstring(destdir, false) << "\n\t"; - t << "-$(DEL_FILE) $(TARGET)\n\t" + t << "-$(DEL_FILE) " << destdir << "$(TARGET)\n\t" << var("QMAKE_AR_CMD") << "\n"; if(!project->isEmpty("QMAKE_POST_LINK")) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) - t << "\t$(RANLIB) $(TARGET)\n"; - if(!destdir.isEmpty()) - t << "\t-$(DEL_FILE) " << destdir << "$(TARGET)\n" - << "\t-$(MOVE) $(TARGET) " << destdir << " \n"; + t << "\t$(RANLIB) " << destdir << "$(TARGET)\n"; } else { int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(); ProStringList objs = project->values("OBJECTS") + project->values("OBJCOMP"), @@ -723,14 +699,15 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) for(int cnt = 0; cnt < max_files && objit != objs.end(); ++objit, cnt++) build << (*objit); QString ar; - ProString lib = escapeFilePath(*libit); + ProString lib = destdir + escapeFilePath(*libit); if((*libit) == "$(TARGET)") { t << destdir_d << "$(TARGET): " << depVar("PRE_TARGETDEPS") << ' ' << depVar("POST_TARGETDEPS") << valList(escapeDependencyPaths(build)) << "\n\t"; ar = project->first("QMAKE_AR_CMD").toQString(); ar.replace("$(OBJECTS)", escapeFilePaths(build).join(' ')); } else { - t << escapeDependencyPath(*libit) << ": " << valList(escapeDependencyPaths(build)) << "\n\t"; + t << destdir_d << escapeDependencyPath(*libit) << ": " + << valList(escapeDependencyPaths(build)) << "\n\t"; ar = "$(AR) " + lib + ' ' + escapeFilePaths(build).join(' '); } if(!destdir.isEmpty()) @@ -741,9 +718,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "\t" << var("QMAKE_POST_LINK") << "\n"; if(!project->isEmpty("QMAKE_RANLIB")) t << "\t$(RANLIB) " << lib << "\n"; - if(!destdir.isEmpty()) - t << "\t-$(DEL_FILE) " << destdir << lib << "\n" - << "\t-$(MOVE) " << lib << ' ' << destdir << " \n"; } } t << endl << endl; @@ -752,8 +726,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) writeMakeQmake(t); if(project->isEmpty("QMAKE_FAILED_REQUIREMENTS") && !project->isActiveConfig("no_autoqmake")) { QStringList meta_files; - if(project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib" && - !project->isActiveConfig("compile_libtool")) { //libtool + if (project->isActiveConfig("create_libtool") && project->first("TEMPLATE") == "lib") { //libtool meta_files += libtoolFileName(); } if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") { //pkg-config @@ -807,11 +780,10 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } else { info_plist = escapeFilePath(fileFixify(info_plist)); } - bool isApp = (project->first("TEMPLATE") == "app"); - QString info_plist_out = - bundle_dir + (isApp ? "Contents/Info.plist" - : "Versions/" + project->first("QMAKE_FRAMEWORK_VERSION") - + "/Resources/Info.plist"); + bool isFramework = project->first("TEMPLATE") == "lib" && project->isActiveConfig("lib_bundle"); + QString info_plist_out = bundle_dir + + (isFramework ? ("Versions/" + project->first("QMAKE_FRAMEWORK_VERSION") + "/Resources/Info.plist") + : "Contents/Info.plist"); bundledFiles << info_plist_out; alldeps << info_plist_out; QString destdir = info_plist_out.section(Option::dir_sep, 0, -2); @@ -844,7 +816,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) bundleIdentifier.replace('_', '-'); commonSedArgs << "-e \"s,@BUNDLEIDENTIFIER@," << bundleIdentifier << ",g\" "; - if (isApp) { + if (!isFramework) { QString icon = fileFixify(var("ICON")); t << "@$(DEL_FILE) " << info_plist_out << "\n\t" << "@sed "; @@ -852,6 +824,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << arg; t << "-e \"s,@ICON@," << icon.section(Option::dir_sep, -1) << ",g\" " << "-e \"s,@EXECUTABLE@," << var("QMAKE_ORIG_TARGET") << ",g\" " + << "-e \"s,@LIBRARY@," << var("QMAKE_ORIG_TARGET") << ",g\" " << "-e \"s,@TYPEINFO@,"<< (project->isEmpty("QMAKE_PKGINFO_TYPEINFO") ? QString::fromLatin1("????") : project->first("QMAKE_PKGINFO_TYPEINFO").left(4)) << ",g\" " << "" << info_plist << " >" << info_plist_out << endl; @@ -988,10 +961,7 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) t << "clean:" << clean_targets << "\n\t"; if(!project->isEmpty("OBJECTS")) { - if(project->isActiveConfig("compile_libtool")) - t << "-$(LIBTOOL) --mode=clean $(DEL_FILE) $(OBJECTS)\n\t"; - else - t << "-$(DEL_FILE) $(OBJECTS)\n\t"; + t << "-$(DEL_FILE) $(OBJECTS)\n\t"; } if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { ProStringList precomp_files; @@ -1022,15 +992,14 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) ProString header_suffix = project->isActiveConfig("clang_pch_style") ? project->first("QMAKE_PCH_OUTPUT_EXT") : ""; - if(!project->isEmpty("QMAKE_CFLAGS_PRECOMPILE")) - precomp_files += precomph_out_dir + header_prefix + "c" + header_suffix; - if(!project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE")) - precomp_files += precomph_out_dir + header_prefix + "c++" + header_suffix; - if(project->isActiveConfig("objective_c")) { - if(!project->isEmpty("QMAKE_OBJCFLAGS_PRECOMPILE")) - precomp_files += precomph_out_dir + header_prefix + "objective-c" + header_suffix; - if(!project->isEmpty("QMAKE_OBJCXXFLAGS_PRECOMPILE")) - precomp_files += precomph_out_dir + header_prefix + "objective-c++" + header_suffix; + foreach (const ProString &compiler, project->values("QMAKE_BUILTIN_COMPILERS")) { + if (project->isEmpty(ProKey("QMAKE_" + compiler + "FLAGS_PRECOMPILE"))) + continue; + ProString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler)); + if (language.isEmpty()) + continue; + + precomp_files += precomph_out_dir + header_prefix + language + header_suffix; } } t << "-$(DEL_FILE) " << escapeFilePaths(precomp_files).join(' ') << "\n\t"; @@ -1048,8 +1017,6 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isEmpty("QMAKE_BUNDLE")) { QString bundlePath = escapeFilePath(destdir + project->first("QMAKE_BUNDLE")); t << "\t-$(DEL_FILE) -r " << bundlePath << endl; - } else if(project->isActiveConfig("compile_libtool")) { - t << "\t-$(LIBTOOL) --mode=clean $(DEL_FILE) $(TARGET)\n"; } else if (project->isActiveConfig("staticlib") || project->isActiveConfig("plugin")) { t << "\t-$(DEL_FILE) " << escapeFilePath(destdir) << "$(TARGET) \n"; } else if (project->values("QMAKE_APP_FLAG").isEmpty()) { @@ -1087,17 +1054,16 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) { QString pchInput = project->first("PRECOMPILED_HEADER").toQString(); t << "###### Precompiled headers\n"; - QString comps[] = { "C", "CXX", "OBJC", "OBJCXX", QString() }; - for(int i = 0; !comps[i].isNull(); i++) { - QString pchFlags = var(ProKey("QMAKE_" + comps[i] + "FLAGS_PRECOMPILE")); + foreach (const ProString &compiler, project->values("QMAKE_BUILTIN_COMPILERS")) { + QString pchFlags = var(ProKey("QMAKE_" + compiler + "FLAGS_PRECOMPILE")); if(pchFlags.isEmpty()) continue; QString cflags; - if(comps[i] == "OBJC" || comps[i] == "OBJCXX") + if (compiler == "C" || compiler == "OBJC") cflags += " $(CFLAGS)"; else - cflags += " $(" + comps[i] + "FLAGS)"; + cflags += " $(CXXFLAGS)"; ProString pchBaseName = project->first("QMAKE_ORIG_TARGET"); ProString pchOutput; @@ -1125,21 +1091,13 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) ProString header_suffix = project->isActiveConfig("clang_pch_style") ? project->first("QMAKE_PCH_OUTPUT_EXT") : ""; pchOutput += Option::dir_sep; - QString pchOutputDir = pchOutput.toQString(), pchOutputFile; - - if(comps[i] == "C") { - pchOutputFile = "c"; - } else if(comps[i] == "CXX") { - pchOutputFile = "c++"; - } else if(project->isActiveConfig("objective_c")) { - if(comps[i] == "OBJC") - pchOutputFile = "objective-c"; - else if(comps[i] == "OBJCXX") - pchOutputFile = "objective-c++"; - } - if(pchOutputFile.isEmpty()) + QString pchOutputDir = pchOutput.toQString(); + + QString language = project->first(ProKey("QMAKE_LANGUAGE_" + compiler)).toQString(); + if (language.isEmpty()) continue; - pchOutput += header_prefix + pchOutputFile + header_suffix; + + pchOutput += header_prefix + language + header_suffix; t << escapeDependencyPath(pchOutput) << ": " << escapeDependencyPath(pchInput) << ' ' << escapeDependencyPaths(findDependencies(pchInput)).join(" \\\n\t\t") @@ -1149,14 +1107,14 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) .replace("${QMAKE_PCH_OUTPUT_BASE}", escapeFilePath(pchBaseName.toQString())) .replace("${QMAKE_PCH_OUTPUT}", escapeFilePath(pchOutput.toQString())); - QString compiler; - if(comps[i] == "C" || comps[i] == "OBJC" || comps[i] == "OBJCXX") - compiler = "$(CC)"; + QString compilerExecutable; + if (compiler == "C" || compiler == "OBJC") + compilerExecutable = "$(CC)"; else - compiler = "$(CXX)"; + compilerExecutable = "$(CXX)"; // compile command - t << "\n\t" << compiler << cflags << " $(INCPATH) " << pchFlags << endl << endl; + t << "\n\t" << compilerExecutable << cflags << " $(INCPATH) " << pchFlags << endl << endl; } } @@ -1182,27 +1140,21 @@ void UnixMakefileGenerator::init2() } if(!project->isEmpty("TARGET")) project->values("TARGET").first().prepend(project->first("DESTDIR")); - if (!project->values("QMAKE_CYGWIN_EXE").isEmpty()) - project->values("TARGET_EXT").append(".exe"); } else if (project->isActiveConfig("staticlib")) { 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)"); + project->values("QMAKE_AR_CMD").append("$(AR) $(DESTDIR)$(TARGET) $(OBJECTS)"); } else { 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") = ProStringList(project->first("DESTDIR") + "lib" + project->first("TARGET") + Option::libtool_ext); ProStringList &ar_cmd = project->values("QMAKE_AR_CMD"); if (!ar_cmd.isEmpty()) ar_cmd[0] = ar_cmd.at(0).toQString().replace("(TARGET)","(TARGETA)"); else ar_cmd.append("$(AR) $(TARGETA) $(OBJECTS)"); - if(project->isActiveConfig("compile_libtool")) { - project->values("TARGET") = project->values("TARGET_la"); - } else if(!project->isEmpty("QMAKE_BUNDLE")) { + if (!project->isEmpty("QMAKE_BUNDLE")) { ProString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION"); if(!bundle_loc.isEmpty() && !bundle_loc.startsWith("/")) bundle_loc.prepend("/"); @@ -1330,7 +1282,7 @@ void UnixMakefileGenerator::init2() soname.prepend(instpath); } else if (!project->isEmpty("QMAKE_SONAME_PREFIX")) { QString sonameprefix = project->first("QMAKE_SONAME_PREFIX").toQString(); - if (!sonameprefix.startsWith('@') && !sonameprefix.startsWith('$')) + if (!sonameprefix.startsWith('@')) sonameprefix = Option::fixPathToTargetOS(sonameprefix, false); if (!sonameprefix.endsWith(Option::dir_sep)) sonameprefix += Option::dir_sep; @@ -1356,7 +1308,7 @@ void UnixMakefileGenerator::init2() project->values("QMAKE_CFLAGS") += project->values("QMAKE_CFLAGS_PLUGIN"); project->values("QMAKE_CXXFLAGS") += project->values("QMAKE_CXXFLAGS_PLUGIN"); project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_PLUGIN"); - if(project->isActiveConfig("plugin_with_soname") && !project->isActiveConfig("compile_libtool")) + if (project->isActiveConfig("plugin_with_soname")) project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SONAME"); } else { project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SHLIB"); @@ -1375,8 +1327,7 @@ void UnixMakefileGenerator::init2() project->first("VER_MIN") + "." + project->first("VER_PAT")); } - if(!project->isActiveConfig("compile_libtool")) - project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SONAME"); + project->values("QMAKE_LFLAGS") += project->values("QMAKE_LFLAGS_SONAME"); } } diff --git a/qmake/generators/win32/cesdkhandler.cpp b/qmake/generators/win32/cesdkhandler.cpp index cbee1d0dbd..f8235bae27 100644 --- a/qmake/generators/win32/cesdkhandler.cpp +++ b/qmake/generators/win32/cesdkhandler.cpp @@ -49,6 +49,7 @@ struct PropertyContainer QString value; QMap<QString, PropertyContainer> properties; }; +Q_DECLARE_TYPEINFO(PropertyContainer, Q_MOVABLE_TYPE); CeSdkInfo::CeSdkInfo() : m_major(0) , m_minor(0) { @@ -60,7 +61,7 @@ CeSdkHandler::CeSdkHandler() struct ContainsPathKey { - bool operator()(const QString &val) + bool operator()(const QString &val) const { return !(val.endsWith(QStringLiteral("MSBuildToolsPath")) || val.endsWith(QStringLiteral("MSBuildToolsRoot"))); @@ -69,8 +70,8 @@ struct ContainsPathKey struct ValueFromKey { - ValueFromKey(const QSettings *settings) : settings(settings){} - QString operator()(const QString &key) + explicit ValueFromKey(const QSettings *settings) : settings(settings) {} + QString operator()(const QString &key) const { return settings->value(key).toString(); } @@ -178,13 +179,14 @@ QStringList CeSdkHandler::filterMsBuildToolPaths(const QStringList &paths) const { QStringList result; foreach (const QString &path, paths) { - QDir dir(path); + QDir dirVC110(path); if (path.endsWith(QStringLiteral("bin"))) - dir.cdUp(); - if (dir.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V110\\Platforms")) - || dir.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V120\\Platforms"))) { - result << dir.absolutePath(); - } + dirVC110.cdUp(); + QDir dirVC120 = dirVC110; + if (dirVC110.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V110\\Platforms"))) + result << dirVC110.absolutePath(); + if (dirVC120.cd(QStringLiteral("Microsoft.Cpp\\v4.0\\V120\\Platforms"))) + result << dirVC120.absolutePath(); } return result; } @@ -286,6 +288,8 @@ void CeSdkHandler::retrieveWEC2013SDKs() currentSdk.m_minor = currentProperty.properties.value(QLatin1String("OSMinor")).value.toInt(); retrieveEnvironment(currentProperty.properties.value(QLatin1String("MSBuild Files110")).value.split(';'), filteredToolPaths, ¤tSdk); + retrieveEnvironment(currentProperty.properties.value(QLatin1String("MSBuild Files120")).value.split(';'), + filteredToolPaths, ¤tSdk); if (!currentSdk.m_include.isEmpty()) m_list.append(currentSdk); } diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index c19e17bc0e..97bfef88a4 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -33,7 +33,6 @@ #include "mingw_make.h" #include "option.h" -#include "meta.h" #include <proitems.h> @@ -56,11 +55,6 @@ QString MingwMakefileGenerator::escapeDependencyPath(const QString &path) const return ret; } -QString MingwMakefileGenerator::getLibTarget() -{ - return QString("lib" + project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".a"); -} - QString MingwMakefileGenerator::getManifestFileForRcFile() const { return project->first("QMAKE_MANIFEST").toQString(); @@ -68,48 +62,21 @@ QString MingwMakefileGenerator::getManifestFileForRcFile() const ProString MingwMakefileGenerator::fixLibFlag(const ProString &lib) { - if (lib.startsWith("lib")) - return QStringLiteral("-l") + escapeFilePath(lib.mid(3)); - return escapeFilePath(lib); + if (lib.startsWith("-l")) // Fallback for unresolved -l libs. + return QLatin1String("-l") + escapeFilePath(lib.mid(2)); + if (lib.startsWith("-L")) // Lib search path. Needed only by -l above. + return QLatin1String("-L") + + escapeFilePath(Option::fixPathToTargetOS(lib.mid(2).toQString(), false)); + if (lib.startsWith("lib")) // Fallback for unresolved MSVC-style libs. + return QLatin1String("-l") + escapeFilePath(lib.mid(3).toQString()); + return escapeFilePath(Option::fixPathToTargetOS(lib.toQString(), false)); } -bool MingwMakefileGenerator::findLibraries() +MakefileGenerator::LibFlagType +MingwMakefileGenerator::parseLibFlag(const ProString &flag, ProString *arg) { - QList<QMakeLocalFileName> dirs; - static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; - for (int i = 0; lflags[i]; i++) { - ProStringList &l = project->values(lflags[i]); - ProStringList::Iterator it = l.begin(); - while (it != l.end()) { - if ((*it).startsWith("-l")) { - QString steam = (*it).mid(2).toQString(); - ProString out; - QString suffix = project->first(ProKey("QMAKE_" + steam.toUpper() + "_SUFFIX")).toQString(); - for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin(); dir_it != dirs.end(); ++dir_it) { - QString extension; - int ver = findHighestVersion((*dir_it).local(), steam, "dll.a|a"); - if (ver > 0) - extension += QString::number(ver); - extension += suffix; - if (QMakeMetaInfo::libExists((*dir_it).local() + '/' + steam) - || exists((*dir_it).local() + '/' + steam + extension + ".a") - || exists((*dir_it).local() + '/' + steam + extension + ".dll.a")) { - out = *it + extension; - break; - } - } - if (!out.isEmpty()) // We assume if it never finds it that its correct - (*it) = out; - } else if ((*it).startsWith("-L")) { - QMakeLocalFileName f((*it).mid(2).toQString()); - dirs.append(f); - *it = "-L" + f.real(); - } - - ++it; - } - } - return true; + // Skip MSVC handling from Win32MakefileGenerator + return MakefileGenerator::parseLibFlag(flag, arg); } bool MingwMakefileGenerator::writeMakefile(QTextStream &t) @@ -183,25 +150,6 @@ void createArObjectScriptFile(const QString &fileName, const QString &target, co } } -void createRvctObjectScriptFile(const QString &fileName, const ProStringList &objList) -{ - QString filePath = Option::output_dir + QDir::separator() + fileName; - QFile file(filePath); - if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { - QTextStream t(&file); - for (ProStringList::ConstIterator it = objList.constBegin(); it != objList.constEnd(); ++it) { - QString path = (*it).toQString(); - // ### quoting? - if (QDir::isRelativePath(path)) - t << "./" << path << endl; - else - t << path << endl; - } - t.flush(); - file.close(); - } -} - void MingwMakefileGenerator::writeMingwParts(QTextStream &t) { writeStandardParts(t); @@ -239,8 +187,6 @@ void MingwMakefileGenerator::init() project->values("TARGET_PRL").append(project->first("TARGET")); - project->values("QMAKE_L_FLAG") << "-L"; - processVars(); project->values("QMAKE_LIBS") += project->values("RES_FILE"); @@ -249,8 +195,7 @@ void MingwMakefileGenerator::init() QString destDir = ""; if(!project->first("DESTDIR").isEmpty()) destDir = Option::fixPathToTargetOS(project->first("DESTDIR") + Option::dir_sep, false, false); - project->values("MINGW_IMPORT_LIB").prepend(destDir + "lib" + project->first("TARGET") - + project->first("TARGET_VERSION_EXT") + ".a"); + project->values("MINGW_IMPORT_LIB").prepend(destDir + project->first("LIB_TARGET")); project->values("QMAKE_LFLAGS").append(QString("-Wl,--out-implib,") + fileVar("MINGW_IMPORT_LIB")); } @@ -335,32 +280,19 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t) ar_script_file += "." + var("BUILD_NAME"); } // QMAKE_LIB is used for win32, including mingw, whereas QMAKE_AR is used on Unix. - if (project->isActiveConfig("rvct_linker")) { - createRvctObjectScriptFile(ar_script_file, project->values("OBJECTS")); - QString ar_cmd = project->values("QMAKE_LIB").join(' '); - if (ar_cmd.isEmpty()) - ar_cmd = "armar --create"; - objectsLinkLine = ar_cmd + ' ' + fileVar("DEST_TARGET") + " --via " + escapeFilePath(ar_script_file); - } else { - // Strip off any options since the ar commands will be read from file. - QString ar_cmd = var("QMAKE_LIB").section(" ", 0, 0);; - if (ar_cmd.isEmpty()) - ar_cmd = "ar"; - createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS")); - objectsLinkLine = ar_cmd + " -M < " + escapeFilePath(ar_script_file); - } + // Strip off any options since the ar commands will be read from file. + QString ar_cmd = var("QMAKE_LIB").section(" ", 0, 0); + if (ar_cmd.isEmpty()) + ar_cmd = "ar"; + createArObjectScriptFile(ar_script_file, var("DEST_TARGET"), project->values("OBJECTS")); + objectsLinkLine = ar_cmd + " -M < " + escapeFilePath(ar_script_file); } else { QString ld_script_file = var("QMAKE_LINK_OBJECT_SCRIPT") + "." + var("TARGET"); if (!var("BUILD_NAME").isEmpty()) { ld_script_file += "." + var("BUILD_NAME"); } - if (project->isActiveConfig("rvct_linker")) { - createRvctObjectScriptFile(ld_script_file, project->values("OBJECTS")); - objectsLinkLine = QString::fromLatin1("--via ") + escapeFilePath(ld_script_file); - } else { - createLdObjectScriptFile(ld_script_file, project->values("OBJECTS")); - objectsLinkLine = escapeFilePath(ld_script_file); - } + createLdObjectScriptFile(ld_script_file, project->values("OBJECTS")); + objectsLinkLine = escapeFilePath(ld_script_file); } Win32MakefileGenerator::writeObjectsPart(t); } @@ -405,9 +337,14 @@ void MingwMakefileGenerator::writeRcFilePart(QTextStream &t) } if (!rc_file.isEmpty()) { + + ProString defines = varGlue("RC_DEFINES", " -D", " -D", ""); + if (defines.isEmpty()) + defines = ProString(" $(DEFINES)"); + t << escapeDependencyPath(var("RES_FILE")) << ": " << escapeDependencyPath(rc_file) << "\n\t" << var("QMAKE_RC") << " -i " << escapeFilePath(rc_file) << " -o " << fileVar("RES_FILE") - << incPathStr << " $(DEFINES)\n\n"; + << incPathStr << defines << "\n\n"; } } diff --git a/qmake/generators/win32/mingw_make.h b/qmake/generators/win32/mingw_make.h index e76391080c..4e94a23ae2 100644 --- a/qmake/generators/win32/mingw_make.h +++ b/qmake/generators/win32/mingw_make.h @@ -47,7 +47,6 @@ protected: QString escapeDependencyPath(const QString &path) const; ProString escapeDependencyPath(const ProString &path) const { return MakefileGenerator::escapeDependencyPath(path); } virtual ProString fixLibFlag(const ProString &lib); - QString getLibTarget(); virtual QString getManifestFileForRcFile() const; bool writeMakefile(QTextStream &); void init(); @@ -63,7 +62,7 @@ private: QString preCompHeaderOut; - virtual bool findLibraries(); + virtual LibFlagType parseLibFlag(const ProString &flag, ProString *arg); QString objectsLinkLine; }; diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index 7646198da1..a546e03b59 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -266,11 +266,6 @@ void NmakeMakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &cal Win32MakefileGenerator::writeSubMakeCall(t, callPrefix, makeArguments); } -QString NmakeMakefileGenerator::getPdbTarget() -{ - return QString(project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".pdb"); -} - QString NmakeMakefileGenerator::defaultInstall(const QString &t) { if((t != "target" && t != "dlltarget") || @@ -288,7 +283,7 @@ QString NmakeMakefileGenerator::defaultInstall(const QString &t) if (project->isActiveConfig("debug_info")) { if (t == "dlltarget" || project->values(ProKey(t + ".CONFIG")).indexOf("no_dll") == -1) { - QString pdb_target = getPdbTarget(); + QString pdb_target = project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".pdb"; 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()) @@ -373,8 +368,6 @@ void NmakeMakefileGenerator::init() return; } - project->values("QMAKE_L_FLAG") << "/LIBPATH:"; - processVars(); project->values("QMAKE_LIBS") += project->values("RES_FILE"); @@ -419,21 +412,22 @@ void NmakeMakefileGenerator::init() project->values("PRECOMPILED_PCH") = ProStringList(precompPch); } - ProString version = project->first("TARGET_VERSION_EXT"); + ProString tgt = project->first("DESTDIR") + + project->first("TARGET") + project->first("TARGET_VERSION_EXT"); if(project->isActiveConfig("shared")) { - project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".exp"); - project->values("QMAKE_DISTCLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".lib"); + project->values("QMAKE_CLEAN").append(tgt + ".exp"); + project->values("QMAKE_DISTCLEAN").append(tgt + ".lib"); } if (project->isActiveConfig("debug_info")) { - QString pdbfile = project->first("DESTDIR") + project->first("TARGET") + version + ".pdb"; + QString pdbfile = tgt + ".pdb"; QString escapedPdbFile = escapeFilePath(pdbfile); project->values("QMAKE_CFLAGS").append("/Fd" + escapedPdbFile); project->values("QMAKE_CXXFLAGS").append("/Fd" + escapedPdbFile); project->values("QMAKE_DISTCLEAN").append(pdbfile); } if (project->isActiveConfig("debug")) { - project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".ilk"); - project->values("QMAKE_CLEAN").append(project->first("DESTDIR") + project->first("TARGET") + version + ".idb"); + project->values("QMAKE_CLEAN").append(tgt + ".ilk"); + project->values("QMAKE_CLEAN").append(tgt + ".idb"); } else { ProStringList &defines = project->values("DEFINES"); if (!defines.contains("NDEBUG")) @@ -454,6 +448,8 @@ QStringList NmakeMakefileGenerator::sourceFilesForImplicitRulesFilter() void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) { + t << "####### Implicit rules\n\n"; + t << ".SUFFIXES:"; for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit) t << " " << (*cit); diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 83ce96c8b7..df72ef394c 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -52,7 +52,6 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator protected: virtual void writeSubMakeCall(QTextStream &t, const QString &callPrefix, const QString &makeArguments); - virtual QString getPdbTarget(); virtual QString defaultInstall(const QString &t); virtual QStringList &findDependencies(const QString &file); QString var(const ProKey &value) const; diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp index 1e522cc8ee..339dae953a 100644 --- a/qmake/generators/win32/msvc_objectmodel.cpp +++ b/qmake/generators/win32/msvc_objectmodel.cpp @@ -2414,7 +2414,7 @@ bool VCFilter::addExtraCompiler(const VCFilterFile &info) // Make sure that all deps are only once QStringList uniqDeps; for (int c = 0; c < deps.count(); ++c) { - QString aDep = deps.at(c).trimmed(); + QString aDep = deps.at(c); if (!aDep.isEmpty()) uniqDeps << aDep; } diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 895bfbaf0d..b1e0745e03 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -810,8 +810,6 @@ void VcprojGenerator::init() else if (project->first("TEMPLATE") == "vclib") project->values("QMAKE_LIB_FLAG").append("1"); - project->values("QMAKE_L_FLAG") << "/LIBPATH:"; - processVars(); // set /VERSION for EXE/DLL header @@ -1225,7 +1223,12 @@ void VcprojGenerator::initLinkerTool() void VcprojGenerator::initResourceTool() { VCConfiguration &conf = vcProject.Configuration; - conf.resource.PreprocessorDefinitions = conf.compiler.PreprocessorDefinitions; + + ProStringList rcDefines = project->values("RC_DEFINES"); + if (rcDefines.size() > 0) + conf.resource.PreprocessorDefinitions = rcDefines.toQStringList(); + else + conf.resource.PreprocessorDefinitions = conf.compiler.PreprocessorDefinitions; foreach (const ProString &path, project->values("RC_INCLUDEPATH")) { QString fixedPath = fileFixify(path.toQString()); @@ -1382,8 +1385,7 @@ void VcprojGenerator::initDeploymentTool() } } - // foreach item in DEPLOYMENT - foreach (const ProString &item, project->values("DEPLOYMENT")) { + foreach (const ProString &item, project->values("INSTALLS")) { // get item.path QString devicePath = project->first(ProKey(item + ".path")).toQString(); if (!conf.WinRT) { diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index 386e2865fa..1fba7057ab 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -49,215 +49,125 @@ Win32MakefileGenerator::Win32MakefileGenerator() : MakefileGenerator() { } -int -Win32MakefileGenerator::findHighestVersion(const QString &d, const QString &stem, const QString &ext) +ProString Win32MakefileGenerator::fixLibFlag(const ProString &lib) { - QString bd = Option::normalizePath(d); - if(!exists(bd)) - return -1; - - QMakeMetaInfo libinfo(project); - bool libInfoRead = libinfo.readLib(bd + '/' + stem); - - // If the library, for which we're trying to find the highest version - // number, is a static library - if (libInfoRead && libinfo.values("QMAKE_PRL_CONFIG").contains("staticlib")) - return -1; - - const ProStringList &vover = project->values(ProKey("QMAKE_" + stem.toUpper() + "_VERSION_OVERRIDE")); - if (!vover.isEmpty()) - return vover.first().toInt(); - - int biggest=-1; - if (project->isActiveConfig("link_highest_lib_version")) { - static QHash<QString, QStringList> dirEntryListCache; - QStringList entries = dirEntryListCache.value(bd); - if (entries.isEmpty()) { - QDir dir(bd); - entries = dir.entryList(); - dirEntryListCache.insert(bd, entries); - } - - QRegExp regx(QString("((lib)?%1([0-9]*)).(%2|prl)$").arg(stem).arg(ext), Qt::CaseInsensitive); - for(QStringList::Iterator it = entries.begin(); it != entries.end(); ++it) { - if(regx.exactMatch((*it))) { - if (!regx.cap(3).isEmpty()) { - bool ok = true; - int num = regx.cap(3).toInt(&ok); - biggest = qMax(biggest, (!ok ? -1 : num)); - } - } - } - } - if(libInfoRead - && !libinfo.values("QMAKE_PRL_CONFIG").contains("staticlib") - && !libinfo.isEmpty("QMAKE_PRL_VERSION")) - biggest = qMax(biggest, libinfo.first("QMAKE_PRL_VERSION").toQString().replace(".", "").toInt()); - return biggest; + if (lib.startsWith("-l")) // Fallback for unresolved -l libs. + return escapeFilePath(lib.mid(2) + QLatin1String(".lib")); + if (lib.startsWith("-L")) // Lib search path. Needed only by -l above. + return QLatin1String("/LIBPATH:") + + escapeFilePath(Option::fixPathToTargetOS(lib.mid(2).toQString(), false)); + return escapeFilePath(Option::fixPathToTargetOS(lib.toQString(), false)); } -ProString Win32MakefileGenerator::fixLibFlag(const ProString &lib) +MakefileGenerator::LibFlagType +Win32MakefileGenerator::parseLibFlag(const ProString &flag, ProString *arg) { - if (lib.startsWith('/')) { - if (lib.startsWith("/LIBPATH:")) - return QLatin1String("/LIBPATH:") - + escapeFilePath(Option::fixPathToTargetOS(lib.mid(9).toQString(), false)); - // This appears to be a user-supplied flag. Assume sufficient quoting. - return lib; + LibFlagType ret = MakefileGenerator::parseLibFlag(flag, arg); + if (ret != LibFlagFile) + return ret; + // MSVC compatibility. This should be deprecated. + if (flag.startsWith("/LIBPATH:")) { + *arg = flag.mid(9); + return LibFlagPath; } - // This must be a fully resolved library path. - return escapeFilePath(Option::fixPathToTargetOS(lib.toQString(), false)); + // These are pure qmake inventions. They *really* should be deprecated. + if (flag.startsWith("/L")) { + *arg = flag.mid(2); + return LibFlagPath; + } + if (flag.startsWith("/l")) { + *arg = flag.mid(2); + return LibFlagLib; + } + return LibFlagFile; } bool -Win32MakefileGenerator::findLibraries() +Win32MakefileGenerator::findLibraries(bool linkPrl, bool mergeLflags) { + ProStringList impexts = project->values("QMAKE_LIB_EXTENSIONS"); + if (impexts.isEmpty()) + impexts = project->values("QMAKE_EXTENSION_STATICLIB"); QList<QMakeLocalFileName> dirs; static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; for (int i = 0; lflags[i]; i++) { ProStringList &l = project->values(lflags[i]); for (ProStringList::Iterator it = l.begin(); it != l.end();) { - bool remove = false; - QString opt = (*it).trimmed().toQString(); - if(opt.startsWith("/LIBPATH:")) { - QString libpath = opt.mid(9); - QMakeLocalFileName l(libpath); - if (!dirs.contains(l)) { - dirs.append(l); - (*it) = "/LIBPATH:" + l.real(); - } else { - remove = true; - } - } else if(opt.startsWith("-L") || opt.startsWith("/L")) { - QString libpath = Option::fixPathToTargetOS(opt.mid(2), false, false); - QMakeLocalFileName l(libpath); - if(!dirs.contains(l)) { - dirs.append(l); - (*it) = "/LIBPATH:" + l.real(); - } else { - remove = true; + const ProString &opt = *it; + ProString arg; + LibFlagType type = parseLibFlag(opt, &arg); + if (type == LibFlagPath) { + QMakeLocalFileName lp(arg.toQString()); + if (dirs.contains(lp)) { + it = l.erase(it); + continue; } - } else if(opt.startsWith("-l") || opt.startsWith("/l")) { - QString lib = opt.right(opt.length() - 2), out; - if(!lib.isEmpty()) { - ProString suffix = project->first(ProKey("QMAKE_" + lib.toUpper() + "_SUFFIX")); - for(QList<QMakeLocalFileName>::Iterator it = dirs.begin(); - it != dirs.end(); ++it) { - QString extension; - int ver = findHighestVersion((*it).local(), lib); - if(ver > 0) - extension += QString::number(ver); - extension += suffix; - extension += ".lib"; - if (QMakeMetaInfo::libExists((*it).local() + '/' + lib) - || exists((*it).local() + '/' + lib + extension)) { - out = (*it).real() + Option::dir_sep + lib + extension; - break; + dirs.append(lp); + (*it) = "-L" + lp.real(); + } else if (type == LibFlagLib) { + QString lib = arg.toQString(); + ProString verovr = + project->first(ProKey("QMAKE_" + lib.toUpper() + "_VERSION_OVERRIDE")); + for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin(); + dir_it != dirs.end(); ++dir_it) { + QString cand = (*dir_it).real() + Option::dir_sep + lib; + if (linkPrl && processPrlFile(cand)) { + (*it) = cand; + goto found; + } + QString libBase = (*dir_it).local() + '/' + lib + verovr; + for (ProStringList::ConstIterator extit = impexts.begin(); + extit != impexts.end(); ++extit) { + if (exists(libBase + '.' + *extit)) { + (*it) = cand + verovr + '.' + *extit; + goto found; } } } - if(out.isEmpty()) - out = lib + ".lib"; - (*it) = out; - } else if (!exists(Option::normalizePath(opt))) { - QList<QMakeLocalFileName> lib_dirs; - QString file = Option::fixPathToTargetOS(opt); - int slsh = file.lastIndexOf(Option::dir_sep); - if(slsh != -1) { - lib_dirs.append(QMakeLocalFileName(file.left(slsh+1))); - file = file.right(file.length() - slsh - 1); + // We assume if it never finds it that it's correct + found: ; + } else if (linkPrl && type == LibFlagFile) { + QString lib = opt.toQString(); + if (fileInfo(lib).isAbsolute()) { + if (processPrlFile(lib)) + (*it) = lib; } else { - lib_dirs = dirs; - } - if(file.endsWith(".lib")) { - file = file.left(file.length() - 4); - if(!file.at(file.length()-1).isNumber()) { - ProString suffix = project->first(ProKey("QMAKE_" + file.toUpper() + "_SUFFIX")); - for(QList<QMakeLocalFileName>::Iterator dep_it = lib_dirs.begin(); dep_it != lib_dirs.end(); ++dep_it) { - QString lib_tmpl(file + "%1" + suffix + ".lib"); - int ver = findHighestVersion((*dep_it).local(), file); - if(ver != -1) { - if(ver) - lib_tmpl = lib_tmpl.arg(ver); - else - lib_tmpl = lib_tmpl.arg(""); - if(slsh != -1) { - QString dir = (*dep_it).real(); - if(!dir.endsWith(Option::dir_sep)) - dir += Option::dir_sep; - lib_tmpl.prepend(dir); - } - (*it) = lib_tmpl; - break; - } + for (QList<QMakeLocalFileName>::Iterator dir_it = dirs.begin(); + dir_it != dirs.end(); ++dir_it) { + QString cand = (*dir_it).real() + Option::dir_sep + lib; + if (processPrlFile(cand)) { + (*it) = cand; + break; } } } } - if(remove) { - it = l.erase(it); - } else { - ++it; - } - } - } - return true; -} -void -Win32MakefileGenerator::processPrlFiles() -{ - const QString libArg = project->first("QMAKE_L_FLAG").toQString(); - QList<QMakeLocalFileName> libdirs; - static const char * const lflags[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; - for (int i = 0; lflags[i]; i++) { - ProStringList &l = project->values(lflags[i]); + ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); + for (int prl = 0; prl < prl_libs.size(); ++prl) + it = l.insert(++it, prl_libs.at(prl)); + prl_libs.clear(); + ++it; + } + if (mergeLflags) { + ProStringList lopts; for (int lit = 0; lit < l.size(); ++lit) { - QString opt = l.at(lit).trimmed().toQString(); - if (opt.startsWith(libArg)) { - QMakeLocalFileName l(opt.mid(libArg.length())); - if (!libdirs.contains(l)) - libdirs.append(l); - } else if (!opt.startsWith("/")) { - if (!processPrlFile(opt) && (QDir::isRelativePath(opt) || opt.startsWith("-l"))) { - QString tmp; - if (opt.startsWith("-l")) - tmp = opt.mid(2); - else - tmp = opt; - for(QList<QMakeLocalFileName>::Iterator it = libdirs.begin(); it != libdirs.end(); ++it) { - QString prl = (*it).local() + '/' + tmp; - if (processPrlFile(prl)) - break; - } - } - } - ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); - for (int prl = 0; prl < prl_libs.size(); ++prl) - l.insert(++lit, prl_libs.at(prl)); - prl_libs.clear(); - } - - // Merge them into a logical order - if (!project->isActiveConfig("no_smart_library_merge") && !project->isActiveConfig("no_lflags_merge")) { - ProStringList lflags; - for (int lit = 0; lit < l.size(); ++lit) { - ProString opt = l.at(lit).trimmed(); - if (opt.startsWith(libArg)) { - if (!lflags.contains(opt)) - lflags.append(opt); - } else { - // Make sure we keep the dependency-order of libraries - lflags.removeAll(opt); - lflags.append(opt); - } + ProString opt = l.at(lit); + if (opt.startsWith(QLatin1String("-L"))) { + if (!lopts.contains(opt)) + lopts.append(opt); + } else { + // Make sure we keep the dependency order of libraries + lopts.removeAll(opt); + lopts.append(opt); } - l = lflags; } + l = lopts; } + } + return true; } - void Win32MakefileGenerator::processVars() { project->values("QMAKE_ORIG_TARGET") = project->values("TARGET"); @@ -286,7 +196,6 @@ void Win32MakefileGenerator::processVars() fixTargetExt(); processRcFileVar(); - ProString libArg = project->first("QMAKE_L_FLAG"); ProStringList libs; ProStringList &libDir = project->values("QMAKE_LIBDIR"); for (ProStringList::Iterator libDir_it = libDir.begin(); libDir_it != libDir.end(); ++libDir_it) { @@ -294,7 +203,7 @@ void Win32MakefileGenerator::processVars() if (!lib.isEmpty()) { if (lib.endsWith('\\')) lib.chop(1); - libs << libArg + Option::fixPathToTargetOS(lib, false, false); + libs << QLatin1String("-L") + lib; } } project->values("QMAKE_LIBS") += libs + project->values("LIBS"); @@ -321,20 +230,19 @@ void Win32MakefileGenerator::processVars() void Win32MakefileGenerator::fixTargetExt() { - if (project->isEmpty("QMAKE_EXTENSION_STATICLIB")) - project->values("QMAKE_EXTENSION_STATICLIB").append("lib"); - if (project->isEmpty("QMAKE_EXTENSION_SHLIB")) - project->values("QMAKE_EXTENSION_SHLIB").append("dll"); - if (!project->values("QMAKE_APP_FLAG").isEmpty()) { project->values("TARGET_EXT").append(".exe"); } else if (project->isActiveConfig("shared")) { + project->values("LIB_TARGET").prepend(project->first("QMAKE_PREFIX_STATICLIB") + + project->first("TARGET") + project->first("TARGET_VERSION_EXT") + + '.' + project->first("QMAKE_EXTENSION_STATICLIB")); project->values("TARGET_EXT").append(project->first("TARGET_VERSION_EXT") + "." + project->first("QMAKE_EXTENSION_SHLIB")); project->values("TARGET").first() = project->first("QMAKE_PREFIX_SHLIB") + project->first("TARGET"); } else { project->values("TARGET_EXT").append("." + project->first("QMAKE_EXTENSION_STATICLIB")); project->values("TARGET").first() = project->first("QMAKE_PREFIX_STATICLIB") + project->first("TARGET"); + project->values("LIB_TARGET").prepend(project->first("TARGET") + project->first("TARGET_EXT")); // for the .prl only } } @@ -662,7 +570,6 @@ void Win32MakefileGenerator::writeStandardParts(QTextStream &t) t << "DESTDIR_TARGET = " << fileVar("DEST_TARGET") << endl; t << endl; - t << "####### Implicit rules\n\n"; writeImplicitRulesPart(t); t << "####### Build rules\n\n"; @@ -734,16 +641,6 @@ void Win32MakefileGenerator::writeObjectsPart(QTextStream &t) void Win32MakefileGenerator::writeImplicitRulesPart(QTextStream &t) { - t << ".SUFFIXES:"; - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) - t << " " << (*cppit); - for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit) - t << " " << (*cit); - t << endl << endl; - for(QStringList::Iterator cppit = Option::cpp_ext.begin(); cppit != Option::cpp_ext.end(); ++cppit) - t << (*cppit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CXX_IMP") << endl << endl; - for(QStringList::Iterator cit = Option::c_ext.begin(); cit != Option::c_ext.end(); ++cit) - t << (*cit) << Option::obj_ext << ":\n\t" << var("QMAKE_RUN_CC_IMP") << endl << endl; } void Win32MakefileGenerator::writeBuildRulesPart(QTextStream &) @@ -755,10 +652,6 @@ void Win32MakefileGenerator::writeRcFilePart(QTextStream &t) if(!project->values("RC_FILE").isEmpty()) { const ProString res_file = project->first("RES_FILE"); const QString rc_file = fileFixify(project->first("RC_FILE").toQString()); - // The resource tool needs to have the same defines passed in as the compiler, since you may - // use these defines in the .rc file itself. Also, we need to add the _DEBUG define manually - // since the compiler defines this symbol by itself, and we use it in the automatically - // created rc file when VERSION is define the .pro file. const ProStringList rcIncPaths = project->values("RC_INCLUDEPATH"); QString incPathStr; @@ -770,19 +663,25 @@ void Win32MakefileGenerator::writeRcFilePart(QTextStream &t) incPathStr += escapeFilePath(path); } + // The resource tool may use defines. This might be the same defines passed in as the + // compiler, since you may use these defines in the .rc file itself. + // As the escape syntax for the command line defines for RC is different from that for CL, + // we might have to set specific defines for RC. + ProString defines = varGlue("RC_DEFINES", " -D", " -D", ""); + if (defines.isEmpty()) + defines = ProString(" $(DEFINES)"); + + // Also, we need to add the _DEBUG define manually since the compiler defines this symbol + // by itself, and we use it in the automatically created rc file when VERSION is defined + // in the .pro file. t << escapeDependencyPath(res_file) << ": " << escapeDependencyPath(rc_file) << "\n\t" << var("QMAKE_RC") << (project->isActiveConfig("debug") ? " -D_DEBUG" : "") - << " $(DEFINES)" << incPathStr << " -fo " << escapeFilePath(res_file) + << defines << incPathStr << " -fo " << escapeFilePath(res_file) << ' ' << escapeFilePath(rc_file); t << endl << endl; } } -QString Win32MakefileGenerator::getLibTarget() -{ - return QString(project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".lib"); -} - QString Win32MakefileGenerator::defaultInstall(const QString &t) { if((t != "target" && t != "dlltarget") || @@ -829,7 +728,7 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t) } } if(project->isActiveConfig("shared") && !project->isActiveConfig("plugin")) { - QString lib_target = getLibTarget(); + ProString lib_target = project->first("LIB_TARGET"); QString src_targ = escapeFilePath( (project->isEmpty("DESTDIR") ? QString("$(DESTDIR)") : project->first("DESTDIR")) + lib_target); diff --git a/qmake/generators/win32/winmakefile.h b/qmake/generators/win32/winmakefile.h index ea763c3175..54c4d3be53 100644 --- a/qmake/generators/win32/winmakefile.h +++ b/qmake/generators/win32/winmakefile.h @@ -57,16 +57,14 @@ protected: virtual void writeRcFilePart(QTextStream &t); - int findHighestVersion(const QString &dir, const QString &stem, const QString &ext = QLatin1String("lib")); - virtual bool findLibraries(); + virtual bool findLibraries(bool linkPrl, bool mergeLflags); + virtual LibFlagType parseLibFlag(const ProString &flag, ProString *arg); virtual ProString fixLibFlag(const ProString &lib); - virtual void processPrlFiles(); void processVars(); void fixTargetExt(); void processRcFileVar(); - virtual QString getLibTarget(); static QString cQuoted(const QString &str); virtual QString getManifestFileForRcFile() const; }; diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 4cfd265591..cfb95b946c 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -188,7 +188,8 @@ void QMakeEvaluator::initStatics() { "QMAKE_RPATH", "QMAKE_LFLAGS_RPATH" }, { "QMAKE_FRAMEWORKDIR", "QMAKE_FRAMEWORKPATH" }, { "QMAKE_FRAMEWORKDIR_FLAGS", "QMAKE_FRAMEWORKPATH_FLAGS" }, - { "IN_PWD", "PWD" } + { "IN_PWD", "PWD" }, + { "DEPLOYMENT", "INSTALLS" } }; for (unsigned i = 0; i < sizeof(mapInits)/sizeof(mapInits[0]); ++i) statics.varMap.insert(ProKey(mapInits[i].oldname), ProKey(mapInits[i].newname)); diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index a60adde84e..8995d49582 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -310,6 +310,7 @@ public: QMakeHandler *m_handler; QMakeVfs *m_vfs; }; +Q_DECLARE_TYPEINFO(QMakeEvaluator::Location, Q_PRIMITIVE_TYPE); Q_DECLARE_OPERATORS_FOR_FLAGS(QMakeEvaluator::LoadFlags) diff --git a/qmake/meta.cpp b/qmake/meta.cpp index d7aa885541..719b2c060f 100644 --- a/qmake/meta.cpp +++ b/qmake/meta.cpp @@ -48,11 +48,8 @@ QMakeMetaInfo::QMakeMetaInfo(QMakeProject *_conf) bool -QMakeMetaInfo::readLib(QString lib) +QMakeMetaInfo::readLib(const QString &meta_file) { - clear(); - QString meta_file = findLib(lib); - if(cache_vars.contains(meta_file)) { vars = cache_vars[meta_file]; return true; @@ -84,18 +81,9 @@ QMakeMetaInfo::readLib(QString lib) } -void -QMakeMetaInfo::clear() -{ - vars.clear(); -} - - QString -QMakeMetaInfo::findLib(QString lib) +QMakeMetaInfo::findLib(const QString &lib) { - lib = Option::normalizePath(lib); - QString ret; QString extns[] = { Option::prl_ext, /*Option::pkgcfg_ext, Option::libtool_ext,*/ QString() }; for(int extn = 0; !extns[extn].isNull(); extn++) { diff --git a/qmake/meta.h b/qmake/meta.h index a08b946916..7c91ffda44 100644 --- a/qmake/meta.h +++ b/qmake/meta.h @@ -52,15 +52,14 @@ class QMakeMetaInfo ProValueMap vars; QString meta_type; static QHash<QString, ProValueMap> cache_vars; - void clear(); public: QMakeMetaInfo(QMakeProject *_conf); - bool readLib(QString lib); - static QString findLib(QString lib); - static bool libExists(QString lib); - QString type() const; + // These functions expect the path to be normalized + static QString findLib(const QString &lib); + bool readLib(const QString &meta_file); + QString type() const; bool isEmpty(const ProKey &v); ProStringList &values(const ProKey &v); ProString first(const ProKey &v); @@ -92,9 +91,6 @@ inline ProString QMakeMetaInfo::first(const ProKey &v) inline ProValueMap &QMakeMetaInfo::variables() { return vars; } -inline bool QMakeMetaInfo::libExists(QString lib) -{ return !findLib(lib).isNull(); } - QT_END_NAMESPACE #endif // META_H diff --git a/qmake/option.cpp b/qmake/option.cpp index 4d20f64d58..da59616e5c 100644 --- a/qmake/option.cpp +++ b/qmake/option.cpp @@ -59,6 +59,8 @@ QStringList Option::h_ext; QString Option::cpp_moc_ext; QStringList Option::cpp_ext; QStringList Option::c_ext; +QString Option::objc_ext; +QString Option::objcpp_ext; QString Option::obj_ext; QString Option::lex_ext; QString Option::yacc_ext; @@ -465,6 +467,8 @@ bool Option::postProcessProject(QMakeProject *project) Option::cpp_ext = project->values("QMAKE_EXT_CPP").toQStringList(); Option::h_ext = project->values("QMAKE_EXT_H").toQStringList(); Option::c_ext = project->values("QMAKE_EXT_C").toQStringList(); + Option::objc_ext = project->first("QMAKE_EXT_OBJC").toQString(); + Option::objcpp_ext = project->first("QMAKE_EXT_OBJCXX").toQString(); Option::res_ext = project->first("QMAKE_EXT_RES").toQString(); Option::pkgcfg_ext = project->first("QMAKE_EXT_PKGCONFIG").toQString(); Option::libtool_ext = project->first("QMAKE_EXT_LIBTOOL").toQString(); diff --git a/qmake/option.h b/qmake/option.h index 0ab0365bb3..663f096072 100644 --- a/qmake/option.h +++ b/qmake/option.h @@ -91,6 +91,8 @@ struct Option static QStringList h_ext; static QStringList cpp_ext; static QStringList c_ext; + static QString objc_ext; + static QString objcpp_ext; static QString cpp_moc_ext; static QString obj_ext; static QString lex_ext; |