diff options
author | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-06-03 10:23:56 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-06-03 10:23:56 +0200 |
commit | e2f66f921594b7be4af4a058c959557489e86879 (patch) | |
tree | cc44931708b57bd5a761906797c7dee0360d1d6b /qmake | |
parent | 933bf178aab88ab5df8a68cbf02611d6d8744b1b (diff) | |
parent | 754efa57d89c62d1796e01b407e9222e67450f52 (diff) |
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts:
src/corelib/global/qnamespace.qdoc
src/corelib/io/qwindowspipereader.cpp
src/corelib/io/qwindowspipereader_p.h
src/corelib/statemachine/qstatemachine.cpp
src/corelib/statemachine/qstatemachine_p.h
src/plugins/platforms/xcb/qxcbconnection.h
tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp
tests/auto/tools/qmake/tst_qmake.cpp
tests/manual/touch/main.cpp
Change-Id: I917d694890e79ee3da7d65134b5b085e23e0dd62
Diffstat (limited to 'qmake')
-rw-r--r-- | qmake/generators/mac/pbuilder_pbx.cpp | 18 | ||||
-rw-r--r-- | qmake/generators/makefile.cpp | 4 | ||||
-rw-r--r-- | qmake/generators/unix/unixmake.cpp | 26 | ||||
-rw-r--r-- | qmake/generators/unix/unixmake2.cpp | 23 | ||||
-rw-r--r-- | qmake/generators/win32/msbuild_objectmodel.cpp | 7 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_nmake.cpp | 28 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_objectmodel.h | 3 | ||||
-rw-r--r-- | qmake/generators/win32/msvc_vcproj.cpp | 11 | ||||
-rw-r--r-- | qmake/generators/win32/winmakefile.cpp | 11 | ||||
-rw-r--r-- | qmake/library/proitems.cpp | 31 | ||||
-rw-r--r-- | qmake/library/proitems.h | 3 | ||||
-rw-r--r-- | qmake/library/qmakebuiltins.cpp | 10 | ||||
-rw-r--r-- | qmake/library/qmakeevaluator.cpp | 43 | ||||
-rw-r--r-- | qmake/library/qmakeevaluator.h | 2 | ||||
-rw-r--r-- | qmake/library/qmakeglobals.h | 1 | ||||
-rw-r--r-- | qmake/main.cpp | 71 |
16 files changed, 213 insertions, 79 deletions
diff --git a/qmake/generators/mac/pbuilder_pbx.cpp b/qmake/generators/mac/pbuilder_pbx.cpp index fcd6bf8308..deacac2c83 100644 --- a/qmake/generators/mac/pbuilder_pbx.cpp +++ b/qmake/generators/mac/pbuilder_pbx.cpp @@ -810,7 +810,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!project->isActiveConfig("staticlib")) { //DUMP LIBRARIES ProStringList &libdirs = project->values("QMAKE_PBX_LIBPATHS"), &frameworkdirs = project->values("QMAKE_FRAMEWORKPATH"); - static const char * const libs[] = { "QMAKE_LFLAGS", "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; + static const char * const libs[] = { "QMAKE_LIBS", "QMAKE_LIBS_PRIVATE", 0 }; for (int i = 0; libs[i]; i++) { tmp = project->values(libs[i]); for(int x = 0; x < tmp.count();) { @@ -821,9 +821,6 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) QString r = opt.mid(2).toQString(); fixForOutput(r); libdirs.append(r); - } else if(opt == "-prebind") { - project->values("QMAKE_DO_PREBINDING").append("TRUE"); - remove = true; } else if(opt.startsWith("-l")) { name = opt.mid(2).toQString(); QString lib("lib" + name); @@ -921,7 +918,7 @@ ProjectBuilderMakefileGenerator::writeMakeParts(QTextStream &t) if(!path.isEmpty() && !libdirs.contains(path)) libdirs += path; } - library = fileFixify(library, FileFixifyFromOutdir); + library = fileFixify(library, FileFixifyFromOutdir | FileFixifyAbsolute); QString key = keyFor(library); if (!project->values("QMAKE_PBX_LIBRARIES").contains(key)) { bool is_frmwrk = (library.endsWith(".framework")); @@ -1812,11 +1809,14 @@ ProjectBuilderMakefileGenerator::openOutput(QFile &file, const QString &build) c } output += QString("project.pbxproj"); file.setFileName(output); + bool ret = UnixMakefileGenerator::openOutput(file, build); + ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); + Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); + return ret; } - bool ret = UnixMakefileGenerator::openOutput(file, build); - ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir.section(Option::dir_sep, 0, -1); - Option::output_dir = pbx_dir.section(Option::dir_sep, 0, -2); - return ret; + + ((ProjectBuilderMakefileGenerator*)this)->pbx_dir = Option::output_dir; + return UnixMakefileGenerator::openOutput(file, build); } /* This function is such a hack it is almost pointless, but it diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index f5e8248af5..4a03fafd77 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -2019,7 +2019,7 @@ MakefileGenerator::writeExtraCompilerTargets(QTextStream &t) for(int i = 0; i < pre_deps.size(); ++i) deps << replaceExtraCompilerVariables(pre_deps.at(i), inpf, out, NoShell); } - QString cmd = replaceExtraCompilerVariables(tmp_cmd, inpf, out, LocalShell); + QString cmd = replaceExtraCompilerVariables(tmp_cmd, inpf, out, TargetShell); // NOTE: The var -> QMAKE_COMP_var replace feature is unsupported, do not use! for (ProStringList::ConstIterator it3 = vars.constBegin(); it3 != vars.constEnd(); ++it3) cmd.replace("$(" + (*it3) + ")", "$(QMAKE_COMP_" + (*it3)+")"); @@ -2240,7 +2240,7 @@ QString MakefileGenerator::buildArgs() QString ret; foreach (const QString &arg, Option::globals->qmake_args) - ret += " " + escapeFilePath(arg); + ret += " " + shellQuote(arg); return ret; } diff --git a/qmake/generators/unix/unixmake.cpp b/qmake/generators/unix/unixmake.cpp index efea807209..c4750cb8a4 100644 --- a/qmake/generators/unix/unixmake.cpp +++ b/qmake/generators/unix/unixmake.cpp @@ -612,7 +612,7 @@ UnixMakefileGenerator::processPrlFiles() 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+1, prl_libs.at(prl).toQString()); + l.insert(++lit, prl_libs.at(prl)); prl_libs.clear(); } } @@ -699,6 +699,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) return QString(); enum { NoBundle, SolidBundle, SlicedBundle } bundle = NoBundle; + bool isAux = (project->first("TEMPLATE") == "aux"); const QString root = "$(INSTALL_ROOT)"; ProStringList &uninst = project->values(ProKey(t + ".uninstall")); QString ret, destdir = project->first("DESTDIR").toQString(); @@ -773,21 +774,21 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } src_targ = escapeFilePath(src_targ); dst_targ = escapeFilePath(dst_targ); - if(!ret.isEmpty()) - ret += "\n\t"; - QString copy_cmd("-"); + QString copy_cmd; if (bundle == SolidBundle) { - copy_cmd += "$(INSTALL_DIR) " + src_targ + ' ' + plain_targ; + copy_cmd += "-$(INSTALL_DIR) " + src_targ + ' ' + plain_targ; } else if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) { - copy_cmd += "$(INSTALL_FILE) " + src_targ + ' ' + dst_targ; - } else { + copy_cmd += "-$(INSTALL_FILE) " + src_targ + ' ' + dst_targ; + } else if (!isAux) { if (bundle == SlicedBundle) ret += mkdir_p_asstring("\"`dirname " + dst_targ + "`\"", false) + "\n\t"; - copy_cmd += "$(INSTALL_PROGRAM) " + src_targ + ' ' + dst_targ; + copy_cmd += "-$(INSTALL_PROGRAM) " + src_targ + ' ' + dst_targ; } if(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib") && project->values(ProKey(t + ".CONFIG")).indexOf("fix_rpath") != -1) { + if (!ret.isEmpty()) + ret += "\n\t"; if(!project->isEmpty("QMAKE_FIX_RPATH")) { ret += copy_cmd; ret += "\n\t-" + var("QMAKE_FIX_RPATH") + ' ' + dst_targ + ' ' + dst_targ; @@ -797,11 +798,14 @@ UnixMakefileGenerator::defaultInstall(const QString &t) } else { ret += copy_cmd; } - } else { + } else if (!copy_cmd.isEmpty()) { + if (!ret.isEmpty()) + ret += "\n\t"; ret += copy_cmd; } - if(project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) { + if (isAux) { + } else if (project->first("TEMPLATE") == "lib" && project->isActiveConfig("staticlib")) { if(!project->isEmpty("QMAKE_RANLIB")) ret += QString("\n\t$(RANLIB) ") + dst_targ; } else if (!project->isActiveConfig("debug_info") && !project->isActiveConfig("nostrip") @@ -820,7 +824,7 @@ UnixMakefileGenerator::defaultInstall(const QString &t) uninst.append("\n\t"); if (bundle == SolidBundle) uninst.append("-$(DEL_FILE) -r " + plain_targ); - else + else if (!isAux) uninst.append("-$(DEL_FILE) " + dst_targ); if (bundle == SlicedBundle) { int dstlen = project->first("DESTDIR").length(); diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 7c5f4b13ea..5cde7c4ac2 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -922,17 +922,18 @@ UnixMakefileGenerator::writeMakeParts(QTextStream &t) } } } - QString bundle_dir_f = escapeFilePath(bundle_dir); - QHash<QString, QString>::ConstIterator symIt = symlinks.constBegin(), - symEnd = symlinks.constEnd(); - for (; symIt != symEnd; ++symIt) { - bundledFiles << symIt.key(); - alldeps << symIt.key(); - t << escapeDependencyPath(symIt.key()) << ":\n\t" - << mkdir_p_asstring(bundle_dir) << "\n\t" - << "@$(SYMLINK) " << escapeFilePath(symIt.value()) << ' ' << bundle_dir_f << endl; - } - if (!project->first("QMAKE_FRAMEWORK_VERSION").isEmpty()) { + if (!symlinks.isEmpty()) { + QString bundle_dir_f = escapeFilePath(bundle_dir); + QHash<QString, QString>::ConstIterator symIt = symlinks.constBegin(), + symEnd = symlinks.constEnd(); + for (; symIt != symEnd; ++symIt) { + bundledFiles << symIt.key(); + alldeps << symIt.key(); + t << escapeDependencyPath(symIt.key()) << ":\n\t" + << mkdir_p_asstring(bundle_dir) << "\n\t" + << "@$(SYMLINK) " << escapeFilePath(symIt.value()) << ' ' << bundle_dir_f << endl; + } + QString currentLink = bundle_dir + "Versions/Current"; QString currentLink_f = escapeDependencyPath(currentLink); bundledFiles << currentLink; diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp index 6c2d2c6206..cbf7cf26dc 100644 --- a/qmake/generators/win32/msbuild_objectmodel.cpp +++ b/qmake/generators/win32/msbuild_objectmodel.cpp @@ -608,10 +608,13 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) xml.setIndentString(" "); + const QString toolsVersion = (tool.SdkVersion == QStringLiteral("10.0")) ? QStringLiteral("14.0") + : QStringLiteral("4.0"); + xml << decl("1.0", "utf-8") << tag("Project") << attrTag("DefaultTargets","Build") - << attrTag("ToolsVersion", "4.0") + << attrTag("ToolsVersion", toolsVersion) << attrTag("xmlns", "http://schemas.microsoft.com/developer/msbuild/2003") << tag("ItemGroup") << attrTag("Label", "ProjectConfigurations"); @@ -640,7 +643,7 @@ void VCXProjectWriter::write(XmlOutput &xml, VCProject &tool) << tagValue("DefaultLanguage", "en") << tagValue("AppContainerApplication", "true") << tagValue("ApplicationType", isWinPhone ? "Windows Phone" : "Windows Store") - << tagValue("ApplicationTypeRevision", tool.SdkVersion); + << tagValue("ApplicationTypeRevision", tool.SdkVersion == "10.0" ? "8.2" : tool.SdkVersion); } xml << closetag(); diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index eb8ae23384..dfa8f8837b 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -176,11 +176,34 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) const QString vcInstallDir = "/fake/vc_install_dir"; const QString kitDir = "/fake/sdk_install_dir"; #endif // Q_OS_WIN - QStringList incDirs; QStringList libDirs; QStringList binDirs; - if (isPhone) { + if (msvcVer == QStringLiteral("14.0")) { + binDirs << vcInstallDir + QStringLiteral("bin/") + compiler; + binDirs << vcInstallDir + QStringLiteral("bin/"); // Maybe remove for x86 again? + binDirs << kitDir + QStringLiteral("bin/") + (arch == QStringLiteral("arm") ? QStringLiteral("x86") : arch); + binDirs << vcInstallDir + QStringLiteral("../Common7/Tools/bin"); + binDirs << vcInstallDir + QStringLiteral("../Common7/Tools"); + binDirs << vcInstallDir + QStringLiteral("../Common7/ide"); + binDirs << kitDir + QStringLiteral("Windows Performance Toolkit/"); + + incDirs << vcInstallDir + QStringLiteral("include"); + incDirs << vcInstallDir + QStringLiteral("atlmfc/include"); + // ### Investigate why VS uses 10056 first + incDirs << kitDir + QStringLiteral("Include/10.0.10056.0/ucrt"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/ucrt"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/um"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/shared"); + incDirs << kitDir + QStringLiteral("Include/10.0.10069.0/winrt"); + + libDirs << vcInstallDir + QStringLiteral("lib/store/") + compilerArch; + libDirs << vcInstallDir + QStringLiteral("atlmfc/lib") + compilerArch; + // ### Investigate why VS uses 10056 first + libDirs << kitDir + QStringLiteral("lib/10.0.10056.0/ucrt/") + arch; + libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/ucrt/") + arch; + libDirs << kitDir + QStringLiteral("lib/10.0.10069.0/um/") + arch; + } else if (isPhone) { QString sdkDir = vcInstallDir; if (!QDir(sdkDir).exists()) { fprintf(stderr, "Failed to find the Windows Phone SDK in %s.\n" @@ -208,7 +231,6 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) << kitDir + QStringLiteral("/include/shared") << kitDir + QStringLiteral("/include/winrt"); } - // Inherit PATH binDirs << QString::fromLocal8Bit(qgetenv("PATH")).split(QLatin1Char(';')); diff --git a/qmake/generators/win32/msvc_objectmodel.h b/qmake/generators/win32/msvc_objectmodel.h index 59136b16c8..7092da3e59 100644 --- a/qmake/generators/win32/msvc_objectmodel.h +++ b/qmake/generators/win32/msvc_objectmodel.h @@ -56,7 +56,8 @@ enum DotNET { NET2008 = 0x90, NET2010 = 0xa0, NET2012 = 0xb0, - NET2013 = 0xc0 + NET2013 = 0xc0, + NET2015 = 0xd0 }; /* diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 20113e5746..b8f9c8135d 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -71,6 +71,7 @@ struct DotNetCombo { const char *regKey; } dotNetCombo[] = { #ifdef Q_OS_WIN64 + {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Wow6432Node\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, {NET2012, "MSVC.NET 2012 (11.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"}, @@ -84,6 +85,7 @@ struct DotNetCombo { {NET2003, "MSVC.NET 2003 (7.1)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.1\\Setup\\VC\\ProductDir"}, {NET2002, "MSVC.NET 2002 (7.0)", "Software\\Wow6432Node\\Microsoft\\VisualStudio\\7.0\\Setup\\VC\\ProductDir"}, #else + {NET2015, "MSVC.NET 2015 (14.0)", "Software\\Microsoft\\VisualStudio\\14.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 (12.0)", "Software\\Microsoft\\VisualStudio\\12.0\\Setup\\VC\\ProductDir"}, {NET2013, "MSVC.NET 2013 Express Edition (12.0)", "Software\\Microsoft\\VCExpress\\12.0\\Setup\\VC\\ProductDir"}, {NET2012, "MSVC.NET 2012 (11.0)", "Software\\Microsoft\\VisualStudio\\11.0\\Setup\\VC\\ProductDir"}, @@ -175,6 +177,8 @@ const char _slnHeader110[] = "Microsoft Visual Studio Solution File, Format "\n# Visual Studio 2012"; const char _slnHeader120[] = "Microsoft Visual Studio Solution File, Format Version 12.00" "\n# Visual Studio 2013"; +const char _slnHeader140[] = "Microsoft Visual Studio Solution File, Format Version 12.00" + "\n# Visual Studio 2015"; // The following UUID _may_ change for later servicepacks... // If so we need to search through the registry at // HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\7.0\Projects @@ -401,6 +405,8 @@ QString VcprojGenerator::retrievePlatformToolSet() const return QStringLiteral("v110") + suffix; case NET2013: return QStringLiteral("v120") + suffix; + case NET2015: + return QStringLiteral("v140") + suffix; default: return QString(); } @@ -647,6 +653,8 @@ void VcprojGenerator::writeSubDirs(QTextStream &t) } switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2015: + t << _slnHeader140; case NET2013: t << _slnHeader120; break; @@ -972,6 +980,9 @@ void VcprojGenerator::initProject() // Own elements ----------------------------- vcProject.Name = project->first("QMAKE_ORIG_TARGET").toQString(); switch (which_dotnet_version(project->first("MSVC_VER").toLatin1())) { + case NET2015: + vcProject.Version = "14.00"; + break; case NET2013: vcProject.Version = "12.00"; break; diff --git a/qmake/generators/win32/winmakefile.cpp b/qmake/generators/win32/winmakefile.cpp index ab4f48685b..0d761b08a2 100644 --- a/qmake/generators/win32/winmakefile.cpp +++ b/qmake/generators/win32/winmakefile.cpp @@ -100,10 +100,13 @@ ProString Win32MakefileGenerator::fixLibFlag(const ProString &lib) { if (lib.startsWith('/')) { if (lib.startsWith("/LIBPATH:")) - return QStringLiteral("/LIBPATH:") + escapeFilePath(lib.mid(9)); + return QLatin1String("/LIBPATH:") + + escapeFilePath(Option::fixPathToTargetOS(lib.mid(9).toQString(), false)); + // This appears to be a user-supplied flag. Assume sufficient quoting. return lib; } - return escapeFilePath(lib); + // This must be a fully resolved library path. + return escapeFilePath(Option::fixPathToTargetOS(lib.toQString(), false)); } bool @@ -231,7 +234,7 @@ Win32MakefileGenerator::processPrlFiles() } ProStringList &prl_libs = project->values("QMAKE_CURRENT_PRL_LIBS"); for (int prl = 0; prl < prl_libs.size(); ++prl) - l.insert(lit + prl + 1, prl_libs.at(prl)); + l.insert(++lit, prl_libs.at(prl)); prl_libs.clear(); } @@ -791,7 +794,7 @@ QString Win32MakefileGenerator::defaultInstall(const QString &t) { if((t != "target" && t != "dlltarget") || (t == "dlltarget" && (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("shared"))) || - project->first("TEMPLATE") == "subdirs") + project->first("TEMPLATE") == "subdirs" || project->first("TEMPLATE") == "aux") return QString(); const QString root = "$(INSTALL_ROOT)"; diff --git a/qmake/library/proitems.cpp b/qmake/library/proitems.cpp index e780259417..a610da6b69 100644 --- a/qmake/library/proitems.cpp +++ b/qmake/library/proitems.cpp @@ -159,6 +159,18 @@ QString &ProString::toQString(QString &tmp) const return tmp.setRawData(m_string.constData() + m_offset, m_length); } +/*! + * \brief ProString::prepareExtend + * \param extraLen number of new characters to be added + * \param thisTarget offset to which current contents should be moved + * \param extraTarget offset at which new characters will be added + * \return pointer to storage location for new characters + * + * Prepares the string for adding new characters. + * If the string is detached and has enough space, it will be changed in place. + * Otherwise, it will be replaced with a new string object, thus detaching. + * In either case, the hash will be reset. + */ QChar *ProString::prepareExtend(int extraLen, int thisTarget, int extraTarget) { if (m_string.isDetached() && m_length + extraLen <= m_string.capacity()) { @@ -473,4 +485,23 @@ ProFile::~ProFile() { } +ProString ProFile::getStr(const ushort *&tPtr) +{ + uint len = *tPtr++; + ProString ret(items(), tPtr - tokPtr(), len); + ret.setSource(this); + tPtr += len; + return ret; +} + +ProKey ProFile::getHashStr(const ushort *&tPtr) +{ + uint hash = *tPtr++; + hash |= (uint)*tPtr++ << 16; + uint len = *tPtr++; + ProKey ret(items(), tPtr - tokPtr(), len, hash); + tPtr += len; + return ret; +} + QT_END_NAMESPACE diff --git a/qmake/library/proitems.h b/qmake/library/proitems.h index d31367361d..9430d28521 100644 --- a/qmake/library/proitems.h +++ b/qmake/library/proitems.h @@ -352,6 +352,9 @@ public: bool isHostBuild() const { return m_hostBuild; } void setHostBuild(bool host_build) { m_hostBuild = host_build; } + ProString getStr(const ushort *&tPtr); + ProKey getHashStr(const ushort *&tPtr); + private: ProItemRefCount m_refCount; QString m_proitems; diff --git a/qmake/library/qmakebuiltins.cpp b/qmake/library/qmakebuiltins.cpp index e384d26f4c..02d5d5dd31 100644 --- a/qmake/library/qmakebuiltins.cpp +++ b/qmake/library/qmakebuiltins.cpp @@ -214,7 +214,7 @@ static QString windowsErrorCode() NULL); QString ret = QString::fromWCharArray(string); LocalFree((HLOCAL)string); - return ret; + return ret.trimmed(); } #endif @@ -362,7 +362,7 @@ QMakeEvaluator::writeFile(const QString &ctx, const QString &fn, QIODevice::Open { QString errStr; if (!m_vfs->writeFile(fn, mode, contents, &errStr)) { - evalError(fL1S("Cannot write %1file %2: %3.") + evalError(fL1S("Cannot write %1file %2: %3") .arg(ctx, QDir::toNativeSeparators(fn), errStr)); return ReturnFalse; } @@ -1121,7 +1121,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( switch (func_t) { case T_DEFINED: { if (args.count() < 1 || args.count() > 2) { - evalError(fL1S("defined(function, [\"test\"|\"replace\"])" + evalError(fL1S("defined(function, [\"test\"|\"replace\"|\"var\"])" " requires one or two arguments.")); return ReturnFalse; } @@ -1582,7 +1582,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (rHand == INVALID_HANDLE_VALUE) { - evalError(fL1S("Cannot open() reference file %1: %2.").arg(rfn, windowsErrorCode())); + evalError(fL1S("Cannot open reference file %1: %2").arg(rfn, windowsErrorCode())); return ReturnFalse; } FILETIME ft; @@ -1592,7 +1592,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional( GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (wHand == INVALID_HANDLE_VALUE) { - evalError(fL1S("Cannot open() %1: %2.").arg(tfn, windowsErrorCode())); + evalError(fL1S("Cannot open %1: %2").arg(tfn, windowsErrorCode())); return ReturnFalse; } SetFileTime(wHand, 0, 0, &ft); diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp index 723d5c7271..8e247d9afa 100644 --- a/qmake/library/qmakeevaluator.cpp +++ b/qmake/library/qmakeevaluator.cpp @@ -259,24 +259,6 @@ uint QMakeEvaluator::getBlockLen(const ushort *&tokPtr) return len; } -ProString QMakeEvaluator::getStr(const ushort *&tokPtr) -{ - uint len = *tokPtr++; - ProString ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len); - ret.setSource(m_current.pro); - tokPtr += len; - return ret; -} - -ProKey QMakeEvaluator::getHashStr(const ushort *&tokPtr) -{ - uint hash = getBlockLen(tokPtr); - uint len = *tokPtr++; - ProKey ret(m_current.pro->items(), tokPtr - m_current.pro->tokPtr(), len, hash); - tokPtr += len; - return ret; -} - void QMakeEvaluator::skipStr(const ushort *&tokPtr) { uint len = *tokPtr++; @@ -315,7 +297,8 @@ ProStringList QMakeEvaluator::split_value_list(const QString &vals, const ProFil switch (unicode) { case '"': case '\'': - quote = unicode; + if (!quote) + quote = unicode; hadWord = true; break; case ' ': @@ -430,6 +413,7 @@ void QMakeEvaluator::evaluateExpression( const ushort *&tokPtr, ProStringList *ret, bool joined) { debugMsg(2, joined ? "evaluating joined expression" : "evaluating expression"); + ProFile *pro = m_current.pro; if (joined) *ret << ProString(); bool pending = false; @@ -445,35 +429,35 @@ void QMakeEvaluator::evaluateExpression( m_current.line = *tokPtr++; break; case TokLiteral: { - const ProString &val = getStr(tokPtr); + const ProString &val = pro->getStr(tokPtr); debugMsg(2, "literal %s", dbgStr(val)); addStr(val, ret, pending, joined); break; } case TokHashLiteral: { - const ProKey &val = getHashStr(tokPtr); + const ProKey &val = pro->getHashStr(tokPtr); debugMsg(2, "hashed literal %s", dbgStr(val.toString())); addStr(val, ret, pending, joined); break; } case TokVariable: { - const ProKey &var = getHashStr(tokPtr); + const ProKey &var = pro->getHashStr(tokPtr); const ProStringList &val = values(map(var)); debugMsg(2, "variable %s => %s", dbgKey(var), dbgStrList(val)); addStrList(val, tok, ret, pending, joined); break; } case TokProperty: { - const ProKey &var = getHashStr(tokPtr); + const ProKey &var = pro->getHashStr(tokPtr); const ProString &val = propertyValue(var); debugMsg(2, "property %s => %s", dbgKey(var), dbgStr(val)); addStr(val, ret, pending, joined); break; } case TokEnvVar: { - const ProString &var = getStr(tokPtr); + const ProString &var = pro->getStr(tokPtr); const ProString &val = ProString(m_option->getEnv(var.toQString(m_tmp1))); debugMsg(2, "env var %s => %s", dbgStr(var), dbgStr(val)); addStr(val, ret, pending, joined); break; } case TokFuncName: { - const ProKey &func = getHashStr(tokPtr); + const ProKey &func = pro->getHashStr(tokPtr); debugMsg(2, "function %s", dbgKey(func)); addStrList(evaluateExpandFunction(func, tokPtr), tok, ret, pending, joined); break; } @@ -538,6 +522,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( { traceMsg("entering block"); ProStringList curr; + ProFile *pro = m_current.pro; bool okey = true, or_op = false, invert = false; uint blockLen; while (ushort tok = *tokPtr++) { @@ -597,7 +582,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( blockLen = getBlockLen(tokPtr); ret = visitProBlock(tokPtr); } else if (okey != or_op) { - const ProKey &variable = getHashStr(tokPtr); + const ProKey &variable = pro->getHashStr(tokPtr); uint exprLen = getBlockLen(tokPtr); const ushort *exprPtr = tokPtr; tokPtr += exprLen; @@ -617,7 +602,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProBlock( case TokTestDef: case TokReplaceDef: if (m_cumulative || okey != or_op) { - const ProKey &name = getHashStr(tokPtr); + const ProKey &name = pro->getHashStr(tokPtr); blockLen = getBlockLen(tokPtr); visitProFunctionDef(tok, name, tokPtr); traceMsg("defined %s function %s", @@ -797,8 +782,8 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProLoop( forever { if (infinite) { if (!variable.isEmpty()) - m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index++))); - if (index > 1000) { + m_valuemapStack.top()[variable] = ProStringList(ProString(QString::number(index))); + if (++index > 1000) { evalError(fL1S("Ran into infinite loop (> 1000 iterations).")); break; } diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h index 4f2acf25ee..a60adde84e 100644 --- a/qmake/library/qmakeevaluator.h +++ b/qmake/library/qmakeevaluator.h @@ -150,8 +150,6 @@ public: { return b ? ReturnTrue : ReturnFalse; } static ALWAYS_INLINE uint getBlockLen(const ushort *&tokPtr); - ProString getStr(const ushort *&tokPtr); - ProKey getHashStr(const ushort *&tokPtr); void evaluateExpression(const ushort *&tokPtr, ProStringList *ret, bool joined); static ALWAYS_INLINE void skipStr(const ushort *&tokPtr); static ALWAYS_INLINE void skipHashStr(const ushort *&tokPtr); diff --git a/qmake/library/qmakeglobals.h b/qmake/library/qmakeglobals.h index 7c77450523..de46ebbe74 100644 --- a/qmake/library/qmakeglobals.h +++ b/qmake/library/qmakeglobals.h @@ -135,6 +135,7 @@ public: bool initProperties(); # else void setProperties(const QHash<QString, QString> &props); + void setProperties(const QHash<ProKey, ProString> &props) { properties = props; } # endif ProString propertyValue(const ProKey &name) const { return properties.value(name); } #endif diff --git a/qmake/main.cpp b/qmake/main.cpp index 27969932bc..bde537dcca 100644 --- a/qmake/main.cpp +++ b/qmake/main.cpp @@ -163,6 +163,75 @@ static int doSed(int argc, char **argv) return 0; } +static int doLink(int argc, char **argv) +{ + bool isSymlink = false; + bool force = false; + QList<const char *> inFiles; + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-s")) { + isSymlink = true; + } else if (!strcmp(argv[i], "-f")) { + force = true; + } else if (argv[i][0] == '-') { + fprintf(stderr, "Error: unrecognized ln option '%s'\n", argv[i]); + return 3; + } else { + inFiles << argv[i]; + } + } + if (inFiles.size() != 2) { + fprintf(stderr, "Error: this ln requires exactly two file arguments\n"); + return 3; + } + if (!isSymlink) { + fprintf(stderr, "Error: this ln supports faking symlinks only\n"); + return 3; + } + QString target = QString::fromLocal8Bit(inFiles[0]); + QString linkname = QString::fromLocal8Bit(inFiles[1]); + + QDir destdir; + QFileInfo tfi(target); + QFileInfo lfi(linkname); + if (lfi.isDir()) { + destdir.setPath(linkname); + lfi.setFile(destdir, tfi.fileName()); + } else { + destdir.setPath(lfi.path()); + } + if (!destdir.exists()) { + fprintf(stderr, "Error: destination directory %s does not exist\n", qPrintable(destdir.path())); + return 1; + } + tfi.setFile(destdir.absoluteFilePath(tfi.filePath())); + if (!tfi.exists()) { + fprintf(stderr, "Error: this ln does not support symlinking non-existing targets\n"); + return 3; + } + if (tfi.isDir()) { + fprintf(stderr, "Error: this ln does not support symlinking directories\n"); + return 3; + } + if (lfi.exists()) { + if (!force) { + fprintf(stderr, "Error: %s exists\n", qPrintable(lfi.filePath())); + return 1; + } + if (!QFile::remove(lfi.filePath())) { + fprintf(stderr, "Error: cannot overwrite %s\n", qPrintable(lfi.filePath())); + return 1; + } + } + if (!QFile::copy(tfi.filePath(), lfi.filePath())) { + fprintf(stderr, "Error: cannot copy %s to %s\n", + qPrintable(tfi.filePath()), qPrintable(lfi.filePath())); + return 1; + } + + return 0; +} + static int doInstall(int argc, char **argv) { if (!argc) { @@ -171,6 +240,8 @@ static int doInstall(int argc, char **argv) } if (!strcmp(argv[0], "sed")) return doSed(argc - 1, argv + 1); + if (!strcmp(argv[0], "ln")) + return doLink(argc - 1, argv + 1); fprintf(stderr, "Error: unrecognized -install subcommand '%s'\n", argv[0]); return 3; } |