aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--share/qbs/module-providers/Qt/templates/core.qbs4
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs16
-rw-r--r--share/qbs/modules/cpp/MingwBaseModule.qbs115
-rw-r--r--share/qbs/modules/cpp/gcc.js26
-rw-r--r--share/qbs/modules/cpp/msvc.js43
-rw-r--r--share/qbs/modules/cpp/windows-clang-mingw.qbs98
-rw-r--r--share/qbs/modules/cpp/windows-mingw.qbs88
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs48
-rw-r--r--src/app/qbs-setup-toolchains/gccprobe.cpp38
-rw-r--r--src/lib/corelib/language/evaluatorscriptclass.cpp13
-rw-r--r--tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs9
-rw-r--r--tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs7
-rw-r--r--tests/auto/api/testdata/timeout-process/timeout.qbs8
-rw-r--r--tests/auto/api/tst_api.cpp13
-rw-r--r--tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs11
-rw-r--r--tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs4
-rw-r--r--tests/auto/blackbox/testdata/autotests/autotests.qbs7
-rw-r--r--tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs17
-rw-r--r--tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs9
-rw-r--r--tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs15
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp24
21 files changed, 454 insertions, 159 deletions
diff --git a/share/qbs/module-providers/Qt/templates/core.qbs b/share/qbs/module-providers/Qt/templates/core.qbs
index 98bc0c4d3..8e990db22 100644
--- a/share/qbs/module-providers/Qt/templates/core.qbs
+++ b/share/qbs/module-providers/Qt/templates/core.qbs
@@ -105,6 +105,10 @@ Module {
condition: moduleConfig.contains("use_gold_linker")
cpp.linkerVariant: "gold"
}
+ Properties {
+ condition: !moduleConfig.contains("use_gold_linker") && qbs.toolchain.contains("gcc")
+ cpp.linkerVariant: original
+ }
cpp.cxxLanguageVersion: Utilities.versionCompare(version, "5.7.0") >= 0 ? "c++11" : original
cpp.enableCompilerDefinesByLanguage: ["cpp"].concat(
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index f9537884e..3b775c9fa 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -135,14 +135,14 @@ CppModule {
: undefined
property string binutilsPath: binutilsProbe.found ? binutilsProbe.path : toolchainInstallPath
- assemblerName: 'as'
+ assemblerName: 'as' + compilerExtension
compilerName: cxxCompilerName
- linkerName: 'ld'
- property string archiverName: 'ar'
- property string nmName: 'nm'
- property string objcopyName: "objcopy"
- property string stripName: "strip"
- property string dsymutilName: "dsymutil"
+ linkerName: 'ld' + compilerExtension
+ property string archiverName: 'ar' + compilerExtension
+ property string nmName: 'nm' + compilerExtension
+ property string objcopyName: "objcopy" + compilerExtension
+ property string stripName: "strip" + compilerExtension
+ property string dsymutilName: "dsymutil" + compilerExtension
property string lipoName
property string sysroot: qbs.sysroot
property string syslibroot: sysroot
@@ -429,7 +429,7 @@ CppModule {
+ PathTools.bundleExecutableFilePath(product)
}
}];
- if (product.qbs.toolchain.contains("mingw")) {
+ if (product.cpp.imageFormat === "pe") {
artifacts.push({
fileTags: ["dynamiclibrary_import"],
filePath: FileInfo.joinPaths(product.destinationDirectory,
diff --git a/share/qbs/modules/cpp/MingwBaseModule.qbs b/share/qbs/modules/cpp/MingwBaseModule.qbs
new file mode 100644
index 000000000..60ad28b08
--- /dev/null
+++ b/share/qbs/modules/cpp/MingwBaseModule.qbs
@@ -0,0 +1,115 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.TextFile
+import qbs.Utilities
+import qbs.WindowsUtils
+
+import "setuprunenv.js" as SetupRunEnv
+
+GenericGCC {
+ condition: false
+
+ staticLibraryPrefix: "lib"
+ staticLibrarySuffix: ".a"
+ dynamicLibrarySuffix: ".dll"
+ executableSuffix: ".exe"
+ debugInfoSuffix: ".debug"
+ imageFormat: "pe"
+ windowsApiCharacterSet: "unicode"
+ platformDefines: base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
+ .concat("WIN32")
+
+ Properties {
+ condition: product.multiplexByQbsProperties.contains("buildVariants")
+ && qbs.buildVariants && qbs.buildVariants.length > 1
+ && qbs.buildVariant !== "release"
+ && product.type.containsAny(["staticlibrary", "dynamiclibrary"])
+ variantSuffix: "d"
+ }
+
+ FileTagger {
+ patterns: ["*.manifest"]
+ fileTags: ["native.pe.manifest"]
+ }
+
+ FileTagger {
+ patterns: ["*.rc"]
+ fileTags: ["rc"]
+ }
+
+ Rule {
+ inputs: ["native.pe.manifest"]
+ multiplex: true
+
+ outputFileTags: ["rc"]
+ outputArtifacts: {
+ if (product.type.containsAny(["application", "dynamiclibrary"])) {
+ return [{
+ filePath: input.completeBaseName + ".rc",
+ fileTags: ["rc"]
+ }];
+ }
+ return [];
+ }
+
+ prepare: {
+ var inputList = inputs["native.pe.manifest"];
+ // TODO: Emulate manifest merging like Microsoft's mt.exe tool does
+ if (inputList.length !== 1) {
+ throw("The MinGW toolchain does not support manifest merging; " +
+ "you may only specify a single manifest file to embed into your assembly.");
+ }
+
+ var cmd = new JavaScriptCommand();
+ cmd.silent = true;
+ cmd.productType = product.type;
+ cmd.inputFilePath = inputList[0].filePath;
+ cmd.outputFilePath = output.filePath;
+ cmd.sourceCode = function() {
+ var tf;
+ try {
+ tf = new TextFile(outputFilePath, TextFile.WriteOnly);
+ if (productType.contains("application"))
+ tf.write("1 "); // CREATEPROCESS_MANIFEST_RESOURCE_ID
+ else if (productType.contains("dynamiclibrary"))
+ tf.write("2 "); // ISOLATIONAWARE_MANIFEST_RESOURCE_ID
+ tf.write("24 "); // RT_MANIFEST
+ tf.writeLine(Utilities.cStringQuote(inputFilePath));
+ } finally {
+ if (tf)
+ tf.close();
+ }
+ };
+ return [cmd];
+ }
+ }
+}
+
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 6936beb5e..f1cee8231 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -78,7 +78,7 @@ function collectLibraryDependencies(product, isDarwin) {
var publicDeps = {};
var objects = [];
var objectByFilePath = {};
- var tagForLinkingAgainstSharedLib = product.qbs.toolchain.contains("mingw")
+ var tagForLinkingAgainstSharedLib = product.cpp.imageFormat === "pe"
? "dynamiclibrary_import" : "dynamiclibrary";
function addObject(obj, addFunc) {
@@ -283,7 +283,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
args.push("-current_version", internalVersion);
escapableLinkerFlags.push("-install_name", UnixUtils.soname(product,
primaryOutput.fileName));
- } else {
+ } else if (product.cpp.imageFormat === "elf") {
escapableLinkerFlags.push("-soname=" + UnixUtils.soname(product,
primaryOutput.fileName));
}
@@ -295,7 +295,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
if (primaryOutput.fileTags.containsAny(["dynamiclibrary", "loadablemodule"])) {
if (isDarwin)
escapableLinkerFlags.push("-headerpad_max_install_names");
- else
+ else if (product.cpp.imageFormat === "elf")
escapableLinkerFlags.push("--as-needed");
}
@@ -344,13 +344,15 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
return rpath;
}
- function isNotSystemRunPath(p) {
- return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p)
- && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)));
- };
- for (i in rpaths) {
- if (isNotSystemRunPath(rpaths[i]))
- escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i]));
+ if (!product.qbs.targetOS.contains("windows")) {
+ function isNotSystemRunPath(p) {
+ return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p)
+ && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)));
+ };
+ for (i in rpaths) {
+ if (isNotSystemRunPath(rpaths[i]))
+ escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i]));
+ }
}
if (product.cpp.entryPoint)
@@ -854,7 +856,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
}
var positionIndependentCode = input.cpp.positionIndependentCode;
- if (positionIndependentCode && !product.qbs.toolchain.contains("mingw"))
+ if (positionIndependentCode && !product.qbs.targetOS.contains("windows"))
args.push('-fPIC');
var cppFlags = input.cpp.cppFlags;
@@ -1035,7 +1037,7 @@ function linkerEnvVars(config, inputs)
function setResponseFileThreshold(command, product)
{
- if (product.qbs.toolchain.contains("mingw") && product.qbs.hostOS.contains("windows"))
+ if (product.qbs.targetOS.contains("windows") && product.qbs.hostOS.contains("windows"))
command.responseFileThreshold = 10000;
}
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index 9deffa064..02facf30a 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -542,3 +542,46 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
return commands;
}
+function createRcCommand(binary, input, output, logo) {
+ var platformDefines = input.cpp.platformDefines;
+ var defines = input.cpp.defines;
+ var includePaths = input.cpp.includePaths;
+ var systemIncludePaths = input.cpp.systemIncludePaths;
+
+ var args = [];
+ if (logo === "can-suppress-logo")
+ args.push("/nologo");
+ for (i in platformDefines) {
+ args.push("/d");
+ args.push(platformDefines[i]);
+ }
+ for (i in defines) {
+ args.push("/d");
+ args.push(defines[i]);
+ }
+ for (i in includePaths) {
+ args.push("/I");
+ args.push(includePaths[i]);
+ }
+ for (i in systemIncludePaths) {
+ args.push("/I");
+ args.push(systemIncludePaths[i]);
+ }
+ args = args.concat(["/FO", output.filePath, input.filePath]);
+ var cmd = new Command(binary, args);
+ cmd.description = 'compiling ' + input.fileName;
+ cmd.highlight = 'compiler';
+ cmd.jobPool = "compiler";
+
+ if (logo === "always-shows-logo") {
+ // Remove the first two lines of stdout. That's the logo.
+ cmd.stdoutFilterFunction = function(output) {
+ var idx = 0;
+ for (var i = 0; i < 3; ++i)
+ idx = output.indexOf('\n', idx + 1);
+ return output.substr(idx + 1);
+ }
+ }
+
+ return cmd;
+}
diff --git a/share/qbs/modules/cpp/windows-clang-mingw.qbs b/share/qbs/modules/cpp/windows-clang-mingw.qbs
new file mode 100644
index 000000000..8389dbf2e
--- /dev/null
+++ b/share/qbs/modules/cpp/windows-clang-mingw.qbs
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of Qbs.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms and
+** conditions see http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs.File
+import qbs.FileInfo
+import qbs.ModUtils
+import qbs.Utilities
+import "msvc.js" as MSVC
+
+import "setuprunenv.js" as SetupRunEnv
+
+MingwBaseModule {
+ condition: qbs.targetOS.contains("windows") &&
+ qbs.toolchain && qbs.toolchain.contains("clang")
+ priority: 0
+
+ // llvm-as and llvm-objopy are not shipped with the official binaries on Windows at the
+ // moment (8.0). We fall back to using the mingw versions in that case.
+ assemblerName: "llvm-as" + compilerExtension
+ assemblerPath: {
+ if (File.exists(base))
+ return base;
+ if (qbs.sysroot)
+ return FileInfo.joinPaths(qbs.sysroot, "bin", "as" + compilerExtension);
+ }
+ objcopyName: "llvm-objcopy" + compilerExtension
+ objcopyPath: {
+ if (File.exists(base))
+ return base;
+ if (qbs.sysroot)
+ return FileInfo.joinPaths(qbs.sysroot, "bin", "objcopy" + compilerExtension);
+ }
+
+ archiverName: "llvm-ar" + compilerExtension
+
+ linkerVariant: "lld"
+ targetVendor: "pc"
+ targetSystem: "windows"
+ targetAbi: "gnu"
+ property string rcFilePath: FileInfo.joinPaths(toolchainInstallPath,
+ "llvm-rc" + compilerExtension)
+
+ setupBuildEnvironment: {
+ if (product.qbs.hostOS.contains("windows") && product.qbs.sysroot) {
+ var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ v.prepend(FileInfo.joinPaths(product.qbs.sysroot, "bin"));
+ v.set();
+ }
+ }
+
+ setupRunEnvironment: {
+ if (product.qbs.hostOS.contains("windows") && product.qbs.sysroot) {
+ var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ v.prepend(FileInfo.joinPaths(product.qbs.sysroot, "bin"));
+ v.set();
+ SetupRunEnv.setupRunEnvironment(product, config);
+ }
+ }
+
+ Rule {
+ inputs: ["rc"]
+ auxiliaryInputs: ["hpp"]
+
+ Artifact {
+ filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res"
+ fileTags: ["obj"]
+ }
+
+ prepare: MSVC.createRcCommand(product.cpp.rcFilePath, input, output);
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-mingw.qbs b/share/qbs/modules/cpp/windows-mingw.qbs
index 27382742f..fe9fd4bf8 100644
--- a/share/qbs/modules/cpp/windows-mingw.qbs
+++ b/share/qbs/modules/cpp/windows-mingw.qbs
@@ -28,39 +28,28 @@
**
****************************************************************************/
+import qbs.File
+import qbs.FileInfo
import qbs.ModUtils
-import qbs.TextFile
import qbs.Utilities
-import qbs.WindowsUtils
import "setuprunenv.js" as SetupRunEnv
-GenericGCC {
+MingwBaseModule {
condition: qbs.targetOS.contains("windows") &&
qbs.toolchain && qbs.toolchain.contains("mingw")
priority: 0
- staticLibraryPrefix: "lib"
- staticLibrarySuffix: ".a"
- dynamicLibrarySuffix: ".dll"
- executableSuffix: ".exe"
- debugInfoSuffix: ".debug"
- imageFormat: "pe"
- windowsApiCharacterSet: "unicode"
- platformDefines: base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
- .concat("WIN32")
+
probeEnv: buildEnv
- Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
- && qbs.buildVariants && qbs.buildVariants.length > 1
- && qbs.buildVariant !== "release"
- && product.type.containsAny(["staticlibrary", "dynamiclibrary"])
- variantSuffix: "d"
+ property string windresName: "windres" + compilerExtension
+ property path windresPath: {
+ var filePath = toolchainPrefix + windresName;
+ if (!File.exists(filePath))
+ filePath = FileInfo.joinPaths(toolchainInstallPath, windresName);
+ return filePath;
}
- property string windresName: 'windres'
- property path windresPath: { return toolchainPathPrefix + windresName }
-
setupBuildEnvironment: {
var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
v.prepend(product.cpp.toolchainInstallPath);
@@ -74,63 +63,6 @@ GenericGCC {
SetupRunEnv.setupRunEnvironment(product, config);
}
- FileTagger {
- patterns: ["*.manifest"]
- fileTags: ["native.pe.manifest"]
- }
-
- Rule {
- inputs: ["native.pe.manifest"]
- multiplex: true
-
- outputFileTags: ["rc"]
- outputArtifacts: {
- if (product.type.containsAny(["application", "dynamiclibrary"])) {
- return [{
- filePath: input.completeBaseName + ".rc",
- fileTags: ["rc"]
- }];
- }
- return [];
- }
-
- prepare: {
- var inputList = inputs["native.pe.manifest"];
- // TODO: Emulate manifest merging like Microsoft's mt.exe tool does
- if (inputList.length !== 1) {
- throw("The MinGW toolchain does not support manifest merging; " +
- "you may only specify a single manifest file to embed into your assembly.");
- }
-
- var cmd = new JavaScriptCommand();
- cmd.silent = true;
- cmd.productType = product.type;
- cmd.inputFilePath = inputList[0].filePath;
- cmd.outputFilePath = output.filePath;
- cmd.sourceCode = function() {
- var tf;
- try {
- tf = new TextFile(outputFilePath, TextFile.WriteOnly);
- if (productType.contains("application"))
- tf.write("1 "); // CREATEPROCESS_MANIFEST_RESOURCE_ID
- else if (productType.contains("dynamiclibrary"))
- tf.write("2 "); // ISOLATIONAWARE_MANIFEST_RESOURCE_ID
- tf.write("24 "); // RT_MANIFEST
- tf.writeLine(Utilities.cStringQuote(inputFilePath));
- } finally {
- if (tf)
- tf.close();
- }
- };
- return [cmd];
- }
- }
-
- FileTagger {
- patterns: ["*.rc"]
- fileTags: ["rc"]
- }
-
Rule {
inputs: ["rc"]
auxiliaryInputs: ["hpp"]
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
index d36daa99f..ae105abe2 100644
--- a/share/qbs/modules/cpp/windows-msvc-base.qbs
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -291,50 +291,10 @@ CppModule {
}
prepare: {
- var platformDefines = input.cpp.platformDefines;
- var defines = input.cpp.defines;
- var includePaths = input.cpp.includePaths;
- var systemIncludePaths = input.cpp.systemIncludePaths;
- var args = [];
- var i;
- var hasNoLogo = product.cpp.compilerVersionMajor >= 16; // 2010
- if (hasNoLogo)
- args.push("/nologo");
-
- for (i in platformDefines) {
- args.push('/d');
- args.push(platformDefines[i]);
- }
- for (i in defines) {
- args.push('/d');
- args.push(defines[i]);
- }
- for (i in includePaths) {
- args.push('/i');
- args.push(includePaths[i]);
- }
- for (i in systemIncludePaths) {
- args.push('/i');
- args.push(systemIncludePaths[i]);
- }
-
- args = args.concat(['/fo', output.filePath, input.filePath]);
- var cmd = new Command('rc', args);
- cmd.description = 'compiling ' + input.fileName;
- cmd.highlight = 'compiler';
- cmd.jobPool = "compiler";
-
- if (!hasNoLogo) {
- // Remove the first two lines of stdout. That's the logo.
- cmd.stdoutFilterFunction = function(output) {
- var idx = 0;
- for (var i = 0; i < 3; ++i)
- idx = output.indexOf('\n', idx + 1);
- return output.substr(idx + 1);
- }
- }
-
- return cmd;
+ // From MSVC 2010 on, the logo can be suppressed.
+ var logo = product.cpp.compilerVersionMajor >= 16
+ ? "can-suppress-logo" : "always-shows-logo";
+ return MSVC.createRcCommand("rc", input, output, logo);
}
}
diff --git a/src/app/qbs-setup-toolchains/gccprobe.cpp b/src/app/qbs-setup-toolchains/gccprobe.cpp
index e979acf59..a8482f8d0 100644
--- a/src/app/qbs-setup-toolchains/gccprobe.cpp
+++ b/src/app/qbs-setup-toolchains/gccprobe.cpp
@@ -46,11 +46,14 @@
#include <tools/hostosinfo.h>
#include <tools/profile.h>
+#include <tools/settings.h>
#include <tools/toolchains.h>
#include <QtCore/qdir.h>
#include <QtCore/qprocess.h>
+#include <algorithm>
+
using namespace qbs;
using Internal::HostOsInfo;
using Internal::Tr;
@@ -395,6 +398,31 @@ Profile createGccProfile(const QFileInfo &compiler, Settings *settings,
setCommonProperties(profile, compiler, toolchainTypes, details);
+ if (HostOsInfo::isWindowsHost() && toolchainTypes.contains(QLatin1String("clang"))) {
+ const QStringList profileNames = settings->profiles();
+ bool foundMingw = false;
+ for (const QString &profileName : profileNames) {
+ const Profile otherProfile(profileName, settings);
+ if (otherProfile.value(QLatin1String("qbs.toolchainType")).toString()
+ == QLatin1String("mingw")
+ || otherProfile.value(QLatin1String("qbs.toolchain"))
+ .toStringList().contains(QLatin1String("mingw"))) {
+ const QFileInfo tcDir(otherProfile.value(QLatin1String("cpp.toolchainInstallPath"))
+ .toString());
+ if (!tcDir.fileName().isEmpty() && tcDir.exists()) {
+ profile.setValue(QLatin1String("qbs.sysroot"), tcDir.path());
+ foundMingw = true;
+ break;
+ }
+ }
+ }
+ if (!foundMingw) {
+ qbsWarning() << Tr::tr("Using clang on Windows requires a mingw installation. "
+ "Please set qbs.sysroot accordingly for profile '%1'.")
+ .arg(profile.name());
+ }
+ }
+
if (!toolchainTypes.contains(QLatin1String("clang"))) {
// Check whether auxiliary tools reside within the toolchain's install path.
// This might not be the case when using icecc or another compiler wrapper.
@@ -466,6 +494,16 @@ void gccProbe(Settings *settings, QList<Profile> &profiles, const QString &compi
return;
}
+ // Sort candidates so that mingw comes first. Information from mingw profiles is potentially
+ // used for setting up clang profiles.
+ if (HostOsInfo::isWindowsHost()) {
+ std::sort(candidates.begin(), candidates.end(),
+ [](const QFileInfo &fi1, const QFileInfo &fi2) {
+ return fi1.absoluteFilePath().contains(QLatin1String("mingw"))
+ && !fi2.absoluteFilePath().contains(QLatin1String("mingw"));
+ });
+ }
+
for (const auto &candidate : qAsConst(candidates)) {
const QStringList toolchainTypes = toolchainTypeFromCompilerName(
candidate.baseName());
diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp
index 55a9e1aac..375954133 100644
--- a/src/lib/corelib/language/evaluatorscriptclass.cpp
+++ b/src/lib/corelib/language/evaluatorscriptclass.cpp
@@ -205,7 +205,18 @@ private:
result.second = false;
return result;
}
- SVConverter converter(scriptClass, object, item->property(*propertyName), item,
+ const ValuePtr v = item->property(*propertyName);
+
+ // This can happen when resolving shadow products. The error will be ignored
+ // in that case.
+ if (!v) {
+ const QString errorMessage = Tr::tr("Error setting up 'original'.");
+ extraScope = engine->currentContext()->throwError(errorMessage);
+ result.second = false;
+ return result;
+ }
+
+ SVConverter converter(scriptClass, object, v, item,
propertyName, data, &originalValue);
converter.start();
} else {
diff --git a/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs b/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
index f0de12df1..f4ea8bf83 100644
--- a/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
+++ b/tests/auto/api/testdata/infinite-loop-process/infinite-loop.qbs
@@ -4,12 +4,21 @@ Project {
consoleApplication: true // suppress bundle generation
files: "main.cpp"
name: "infinite-loop"
+ cpp.cxxLanguageVersion: "c++11"
+ Properties {
+ condition: qbs.toolchain.contains("gcc")
+ cpp.driverFlags: "-pthread"
+ }
}
Product {
type: "mytype"
name: "caller"
Depends { name: "infinite-loop" }
+ Depends {
+ name: "cpp" // Make sure build environment is set up properly.
+ condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ }
Rule {
inputsFromDependencies: "application"
outputFileTags: "mytype"
diff --git a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs
index eade97126..d7ed6c862 100644
--- a/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs
+++ b/tests/auto/api/testdata/link-staticlibs-dynamiclibs/link-staticlibs-dynamiclibs.qbs
@@ -11,6 +11,13 @@ Project {
files: [ "static1.cpp" ]
Depends { name: "cpp" }
Depends { name: "dynamic1" }
+
+ Probe {
+ id: osCheck
+ property bool isNormalUnix: qbs.targetOS.contains("unix")
+ && !qbs.targetOS.contains("darwin")
+ configure: { console.info("is normal unix: " + (isNormalUnix ? "yes" : "no")); }
+ }
}
DynamicLibrary {
diff --git a/tests/auto/api/testdata/timeout-process/timeout.qbs b/tests/auto/api/testdata/timeout-process/timeout.qbs
index 3f79dce96..bdf6833fd 100644
--- a/tests/auto/api/testdata/timeout-process/timeout.qbs
+++ b/tests/auto/api/testdata/timeout-process/timeout.qbs
@@ -5,12 +5,20 @@ Project {
files: "main.cpp"
name: "infinite-loop"
cpp.cxxLanguageVersion: "c++11"
+ Properties {
+ condition: qbs.toolchain.contains("gcc")
+ cpp.driverFlags: "-pthread"
+ }
}
Product {
type: "product-under-test"
name: "caller"
Depends { name: "infinite-loop" }
+ Depends {
+ name: "cpp" // Make sure build environment is set up properly.
+ condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ }
Rule {
inputsFromDependencies: "application"
outputFileTags: "product-under-test"
diff --git a/tests/auto/api/tst_api.cpp b/tests/auto/api/tst_api.cpp
index 1a98f5f21..36a98fdaa 100644
--- a/tests/auto/api/tst_api.cpp
+++ b/tests/auto/api/tst_api.cpp
@@ -1556,9 +1556,13 @@ void TestApi::linkStaticAndDynamicLibs()
BuildDescriptionReceiver bdr;
qbs::BuildOptions options;
options.setEchoMode(qbs::CommandEchoModeCommandLine);
+ m_logSink->output.clear();
const qbs::ErrorInfo errorInfo = doBuildProject("link-staticlibs-dynamiclibs", &bdr, nullptr,
nullptr, options);
VERIFY_NO_ERROR(errorInfo);
+ const bool isNormalUnix = m_logSink->output.contains("is normal unix: yes");
+ const bool isNotNormalUnix = m_logSink->output.contains("is normal unix: no");
+ QVERIFY2(isNormalUnix != isNotNormalUnix, qPrintable(m_logSink->output));
// The dependencies libdynamic1.so and libstatic2.a must not appear in the link command for the
// executable. The -rpath-link line for libdynamic1.so must be there.
@@ -1575,12 +1579,7 @@ void TestApi::linkStaticAndDynamicLibs()
}
}
QVERIFY(!appLinkCmd.isEmpty());
- std::string targetPlatform = buildProfile.value("qbs.targetPlatform")
- .toString().toStdString();
- std::vector<std::string> targetOS = qbs::Internal::HostOsInfo::canonicalOSIdentifiers(
- targetPlatform);
- if (!qbs::Internal::contains(targetOS, "darwin")
- && !qbs::Internal::contains(targetOS, "windows")) {
+ if (isNormalUnix) {
const std::regex rpathLinkRex("-rpath-link=\\S*/"
+ relativeProductBuildDir("dynamic2").toStdString());
const auto ln = appLinkCmd.toStdString();
@@ -2861,7 +2860,7 @@ void TestApi::timeout()
QVERIFY(waitForFinished(buildJob.get(), testTimeoutInMsecs()));
QVERIFY(buildJob->error().hasError());
const auto errorString = buildJob->error().toString();
- QVERIFY(errorString.contains("cancel"));
+ QVERIFY2(errorString.contains("cancel"), qPrintable(errorString));
QVERIFY(errorString.contains("timeout"));
}
diff --git a/tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs b/tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs
index 270fc9eaf..d4f01895f 100644
--- a/tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs
+++ b/tests/auto/blackbox/testdata/autotest-timeout/autotests-timeout.qbs
@@ -4,7 +4,16 @@ Project {
type: ["application", "autotest"]
Depends { name: "autotest" }
cpp.cxxLanguageVersion: "c++11"
+ Properties {
+ condition: qbs.toolchain.contains("gcc")
+ cpp.driverFlags: "-pthread"
+ }
files: "test-main.cpp"
}
- AutotestRunner {}
+ AutotestRunner {
+ Depends {
+ name: "cpp" // Make sure build environment is set up properly.
+ condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ }
+ }
}
diff --git a/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs b/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs
index 92d5ec6dd..7ae6cef73 100644
--- a/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs
+++ b/tests/auto/blackbox/testdata/autotest-with-dependencies/autotest-with-dependencies.qbs
@@ -21,6 +21,10 @@ Project {
}
AutotestRunner {
+ Depends {
+ name: "cpp" // Make sure build environment is set up properly.
+ condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ }
arguments: FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix, "bin")
auxiliaryInputs: "test-helper"
}
diff --git a/tests/auto/blackbox/testdata/autotests/autotests.qbs b/tests/auto/blackbox/testdata/autotests/autotests.qbs
index a2c2646dc..10334156e 100644
--- a/tests/auto/blackbox/testdata/autotests/autotests.qbs
+++ b/tests/auto/blackbox/testdata/autotests/autotests.qbs
@@ -1,4 +1,9 @@
Project {
references: ["test1", "test2", "test3"]
- AutotestRunner {}
+ AutotestRunner {
+ Depends {
+ name: "cpp" // Make sure build environment is set up properly.
+ condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("gcc")
+ }
+ }
}
diff --git a/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs b/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs
index 61f76f4be..6cd334247 100644
--- a/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs
+++ b/tests/auto/blackbox/testdata/lexyacc/one-grammar/one-grammar.qbs
@@ -8,6 +8,23 @@ CppApplication {
cpp.cxxLanguageVersion: "c++11"
cpp.minimumMacosVersion: "10.7"
consoleApplication: true
+ Probe {
+ id: pathCheck
+ property string theDir: {
+ if (qbs.targetOS.contains("windows")) {
+ if (qbs.toolchain.contains("mingw"))
+ return cpp.toolchainInstallPath;
+ if (qbs.toolchain.contains("clang") && qbs.sysroot)
+ return qbs.sysroot + "/bin";
+ }
+ }
+ configure: {
+ if (theDir)
+ console.info("add to PATH: " + theDir);
+ found = true;
+ }
+ }
+
files: [
"lexer.l",
"parser.y",
diff --git a/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs b/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs
index 48bdff904..0b16d1984 100644
--- a/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs
+++ b/tests/auto/blackbox/testdata/separate-debug-info/separate-debug-info.qbs
@@ -4,6 +4,15 @@ Project {
type: ["application"]
files: ["main.cpp"]
cpp.separateDebugInformation: true
+
+ Probe {
+ id: osProbe
+ property stringList targetOS: qbs.targetOS
+ configure: {
+ console.info("is windows: " + (targetOS.contains("windows") ? "yes" : "no"));
+ console.info("is darwin: " + (targetOS.contains("darwin") ? "yes" : "no"));
+ }
+ }
}
DynamicLibrary {
Depends { name: "cpp" }
diff --git a/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs b/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs
index b5ac8b289..d2d47b767 100644
--- a/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs
+++ b/tests/auto/blackbox/testdata/setup-run-environment/setup-run-environment.qbs
@@ -61,6 +61,16 @@ Project {
bundle.isBundle: false
}
+ // Testing shows that clang (8.0) does not find dynamic libraries via
+ // the -L<dir> and -l<libname> mechanism unless the name is "lib<libname>.a".
+ Properties {
+ condition: qbs.hostOS.contains("windows") && qbs.toolchain.contains("clang")
+ cpp.dynamicLibraryPrefix: "lib"
+ cpp.dynamicLibraryImportSuffix: ".a"
+ }
+ cpp.dynamicLibraryPrefix: original
+ cpp.dynamicLibraryImportSuffix: original
+
install: true
installImportLib: true
installDir: "lib4"
@@ -91,8 +101,9 @@ Project {
property string fullInstallPrefix: FileInfo.joinPaths(qbs.installRoot, qbs.installPrefix)
property string lib3FilePath: FileInfo.joinPaths(fullInstallPrefix, "lib3",
- cpp.dynamicLibraryPrefix + "lib3" + (qbs.toolchain.contains("msvc")
- ? ".lib" : cpp.dynamicLibrarySuffix))
+ cpp.dynamicLibraryPrefix + "lib3" + (qbs.targetOS.contains("windows")
+ ? cpp.dynamicLibraryImportSuffix
+ : cpp.dynamicLibrarySuffix))
cpp.dynamicLibraries: [lib3FilePath, "lib4"]
cpp.libraryPaths: FileInfo.joinPaths(fullInstallPrefix, "lib4")
}
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index edc2b51c8..31a5a92ae 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -1806,14 +1806,17 @@ void TestBlackbox::separateDebugInfo()
{
QDir::setCurrent(testDataDir + "/separate-debug-info");
QCOMPARE(runQbs(QbsRunParameters(QStringList("qbs.debugInformation:true"))), 0);
+ const bool isWindows = m_qbsStdout.contains("is windows: yes");
+ const bool isNotWindows = m_qbsStdout.contains("is windows: no");
+ QVERIFY(isWindows != isNotWindows);
+ const bool isDarwin = m_qbsStdout.contains("is darwin: yes");
+ const bool isNotDarwin = m_qbsStdout.contains("is darwin: no");
+ QVERIFY(isDarwin != isNotDarwin);
const SettingsPtr s = settings();
Profile buildProfile(profileName(), s.get());
QStringList toolchain = buildProfile.value("qbs.toolchain").toStringList();
- std::string targetPlatform = buildProfile.value("qbs.targetPlatform").toString().toStdString();
- std::vector<std::string> targetOS = HostOsInfo::canonicalOSIdentifiers(targetPlatform);
- if (qbs::Internal::contains(targetOS, "darwin")
- || (targetPlatform.empty() && HostOsInfo::isMacosHost())) {
+ if (isDarwin) {
QVERIFY(directoryExists(relativeProductBuildDir("app1") + "/app1.app.dSYM"));
QVERIFY(regularFileExists(relativeProductBuildDir("app1")
+ "/app1.app.dSYM/Contents/Info.plist"));
@@ -1878,7 +1881,6 @@ void TestBlackbox::separateDebugInfo()
.entryInfoList(QDir::NoDotAndDotDot | QDir::AllEntries).size(), 1);
QVERIFY(regularFileExists(relativeProductBuildDir("bar5") + "/bar5.bundle.dwarf"));
} else if (toolchain.contains("gcc")) {
- const bool isWindows = qbs::Internal::contains(targetOS, "windows");
const QString exeSuffix = isWindows ? ".exe" : "";
const QString dllPrefix = isWindows ? "" : "lib";
const QString dllSuffix = isWindows ? ".dll" : ".so";
@@ -4354,6 +4356,18 @@ void TestBlackbox::lexyacc()
QCOMPARE(runQbs(), 0);
const QString parserBinary = relativeExecutableFilePath("one-grammar");
QProcess p;
+ const QByteArray magicString = "add to PATH: ";
+ const int magicStringIndex = m_qbsStdout.indexOf(magicString);
+ if (magicStringIndex != -1) {
+ const int newLineIndex = m_qbsStdout.indexOf('\n', magicStringIndex);
+ QVERIFY(newLineIndex != -1);
+ const int dirIndex = magicStringIndex + magicString.length();
+ const QString dir = QString::fromLocal8Bit(m_qbsStdout.mid(dirIndex,
+ newLineIndex - dirIndex));
+ QProcessEnvironment env;
+ env.insert("PATH", dir);
+ p.setProcessEnvironment(env);
+ }
p.start(parserBinary);
QVERIFY2(p.waitForStarted(), qPrintable(p.errorString()));
p.write("a && b || c && !d");