aboutsummaryrefslogtreecommitdiffstats
path: root/share/qbs/modules
diff options
context:
space:
mode:
authorIvan Komissarov <ABBAPOH@gmail.com>2019-03-19 22:24:33 +0100
committerIvan Komissarov <ABBAPOH@gmail.com>2019-04-10 07:27:02 +0000
commit62e07306481373d9d9b6b656d855b204aa6964f3 (patch)
treedac1f681be32eaba98b117a481a9011500af9b91 /share/qbs/modules
parent14324ad4aa9582e07dc687dc63b1b886f2d272e5 (diff)
Add support for the clang-cl compiler
Task-number: QBS-1316 Change-Id: Ibf9da364610c260ead088a8990a70c7739d53c39 Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
Diffstat (limited to 'share/qbs/modules')
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs72
-rw-r--r--share/qbs/modules/cpp/msvc.js28
-rw-r--r--share/qbs/modules/cpp/windows-clang-cl.qbs84
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs372
-rw-r--r--share/qbs/modules/cpp/windows-msvc.qbs344
5 files changed, 523 insertions, 377 deletions
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index 01b0f8af9..35a5de4f0 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -454,42 +454,48 @@ Module {
fileTags: ["hpp"]
}
- validate: {
- var validator = new ModUtils.PropertyValidator("cpp");
- validator.setRequiredProperty("architecture", architecture,
- "you might want to re-run 'qbs-setup-toolchains'");
- validator.addCustomValidator("architecture", architecture, function (value) {
- return !architecture || architecture === Utilities.canonicalArchitecture(architecture);
- }, "'" + architecture + "' is invalid. You must use the canonical name '" +
- Utilities.canonicalArchitecture(architecture) + "'");
- validator.setRequiredProperty("endianness", endianness);
- validator.setRequiredProperty("compilerDefinesByLanguage", compilerDefinesByLanguage);
- validator.setRequiredProperty("compilerVersion", compilerVersion);
- validator.setRequiredProperty("compilerVersionMajor", compilerVersionMajor);
- validator.setRequiredProperty("compilerVersionMinor", compilerVersionMinor);
- validator.setRequiredProperty("compilerVersionPatch", compilerVersionPatch);
- validator.addVersionValidator("compilerVersion", compilerVersion, 3, 3);
- validator.addRangeValidator("compilerVersionMajor", compilerVersionMajor, 1);
- validator.addRangeValidator("compilerVersionMinor", compilerVersionMinor, 0);
- validator.addRangeValidator("compilerVersionPatch", compilerVersionPatch, 0);
- if (minimumWindowsVersion) {
- validator.addVersionValidator("minimumWindowsVersion", minimumWindowsVersion, 2, 2);
- validator.addCustomValidator("minimumWindowsVersion", minimumWindowsVersion, function (v) {
- return !v || v === WindowsUtils.canonicalizeVersion(v);
- }, "'" + minimumWindowsVersion + "' is invalid. Did you mean '" +
- WindowsUtils.canonicalizeVersion(minimumWindowsVersion) + "'?");
- }
- validator.validate();
-
- if (minimumWindowsVersion && !WindowsUtils.isValidWindowsVersion(minimumWindowsVersion)) {
- console.warn("Unknown Windows version '" + minimumWindowsVersion
- + "'; expected one of: "
- + WindowsUtils.knownWindowsVersions().map(function (a) {
- return '"' + a + '"'; }).join(", ")
- + ". See https://docs.microsoft.com/en-us/windows/desktop/SysInfo/operating-system-version");
+ property var validateFunc: {
+ return function() {
+ var validator = new ModUtils.PropertyValidator("cpp");
+ validator.setRequiredProperty("architecture", architecture,
+ "you might want to re-run 'qbs-setup-toolchains'");
+ validator.addCustomValidator("architecture", architecture, function (value) {
+ return !architecture || architecture === Utilities.canonicalArchitecture(architecture);
+ }, "'" + architecture + "' is invalid. You must use the canonical name '" +
+ Utilities.canonicalArchitecture(architecture) + "'");
+ validator.setRequiredProperty("endianness", endianness);
+ validator.setRequiredProperty("compilerDefinesByLanguage", compilerDefinesByLanguage);
+ validator.setRequiredProperty("compilerVersion", compilerVersion);
+ validator.setRequiredProperty("compilerVersionMajor", compilerVersionMajor);
+ validator.setRequiredProperty("compilerVersionMinor", compilerVersionMinor);
+ validator.setRequiredProperty("compilerVersionPatch", compilerVersionPatch);
+ validator.addVersionValidator("compilerVersion", compilerVersion, 3, 3);
+ validator.addRangeValidator("compilerVersionMajor", compilerVersionMajor, 1);
+ validator.addRangeValidator("compilerVersionMinor", compilerVersionMinor, 0);
+ validator.addRangeValidator("compilerVersionPatch", compilerVersionPatch, 0);
+ if (minimumWindowsVersion) {
+ validator.addVersionValidator("minimumWindowsVersion", minimumWindowsVersion, 2, 2);
+ validator.addCustomValidator("minimumWindowsVersion", minimumWindowsVersion, function (v) {
+ return !v || v === WindowsUtils.canonicalizeVersion(v);
+ }, "'" + minimumWindowsVersion + "' is invalid. Did you mean '" +
+ WindowsUtils.canonicalizeVersion(minimumWindowsVersion) + "'?");
+ }
+ validator.validate();
+
+ if (minimumWindowsVersion && !WindowsUtils.isValidWindowsVersion(minimumWindowsVersion)) {
+ console.warn("Unknown Windows version '" + minimumWindowsVersion
+ + "'; expected one of: "
+ + WindowsUtils.knownWindowsVersions().map(function (a) {
+ return '"' + a + '"'; }).join(", ")
+ + ". See https://docs.microsoft.com/en-us/windows/desktop/SysInfo/operating-system-version");
+ }
}
}
+ validate: {
+ return validateFunc();
+ }
+
setupRunEnvironment: {
SetupRunEnv.setupRunEnvironment(product, config);
}
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index 1864c40e1..5da2ad0cf 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -62,7 +62,8 @@ function hasCxx17Option(input)
{
// Probably this is not the earliest version to support the flag, but we have tested this one
// and it's a pain to find out the exact minimum.
- return Utilities.versionCompare(input.cpp.compilerVersion, "19.12.25831") >= 0;
+ return Utilities.versionCompare(input.cpp.compilerVersion, "19.12.25831") >= 0
+ || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 7);
}
function addLanguageVersionFlag(input, args) {
@@ -72,7 +73,9 @@ function addLanguageVersionFlag(input, args) {
return;
// Visual C++ 2013, Update 3
- var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0;
+ var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0
+ // or clang-cl
+ || input.qbs.toolchain.contains("clang-cl");
if (!hasStdOption)
return;
@@ -210,10 +213,20 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var pchInputs = explicitlyDependsOn[tag + "_pch"];
if (pchOutput) {
// create PCH
- args.push("/Yc");
- args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath));
- args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath));
- args.push(FileInfo.toWindowsSeparators(input.filePath));
+ if (input.qbs.toolchain.contains("clang-cl")) {
+ // clang-cl does not support /Yc flag without filename
+ args.push("/Yc" + FileInfo.toWindowsSeparators(input.filePath));
+ // clang-cl complains when pch file is not included
+ args.push("/FI" + FileInfo.toWindowsSeparators(input.filePath));
+ args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath));
+ args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath));
+ } else { // real msvc
+ args.push("/Yc");
+ args.push("/Fp" + FileInfo.toWindowsSeparators(pchOutput.filePath));
+ args.push("/Fo" + FileInfo.toWindowsSeparators(objOutput.filePath));
+ args.push(FileInfo.toWindowsSeparators(input.filePath));
+ }
+
} else if (pchInputs && pchInputs.length === 1
&& ModUtils.moduleProperty(input, "usePrecompiledHeader", tag)) {
// use PCH
@@ -399,7 +412,8 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
'subsystem');
if (subsystemVersion) {
subsystemSwitch += ',' + subsystemVersion;
- args.push('/OSVERSION:' + subsystemVersion);
+ if (product.cpp.linkerName !== "lld-link.exe") // llvm linker does not support /OSVERSION
+ args.push('/OSVERSION:' + subsystemVersion);
}
}
diff --git a/share/qbs/modules/cpp/windows-clang-cl.qbs b/share/qbs/modules/cpp/windows-clang-cl.qbs
new file mode 100644
index 000000000..1b2833060
--- /dev/null
+++ b/share/qbs/modules/cpp/windows-clang-cl.qbs
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com)
+** 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
+import qbs.ModUtils
+import qbs.Probes
+import qbs.FileInfo
+import 'windows-msvc-base.qbs' as MsvcBaseModule
+
+MsvcBaseModule {
+ condition: qbs.hostOS.contains('windows') &&
+ qbs.targetOS.contains('windows') &&
+ qbs.toolchain && qbs.toolchain.contains('clang-cl')
+ priority: 100
+
+ Probes.BinaryProbe {
+ id: clangPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["clang-cl"]
+ }
+
+ Probes.ClangClProbe {
+ id: clangClProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ vcvarsallFilePath: vcvarsallPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ architecture: qbs.architecture
+ }
+
+ compilerVersionMajor: clangClProbe.versionMajor
+ compilerVersionMinor: clangClProbe.versionMinor
+ compilerVersionPatch: clangClProbe.versionPatch
+ compilerIncludePaths: clangClProbe.includePaths
+ compilerDefinesByLanguage: clangClProbe.compilerDefinesByLanguage
+
+ toolchainInstallPath: clangPathProbe.found ? clangPathProbe.path
+ : undefined
+ buildEnv: clangClProbe.buildEnv
+
+ property string vcvarsallPath
+
+ compilerName: "clang-cl.exe"
+ linkerName: "lld-link.exe"
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ validateFunc: {
+ return function() {
+ if (_skipAllChecks)
+ return;
+ var validator = new ModUtils.PropertyValidator("cpp");
+ validator.setRequiredProperty("vcvarsallPath", vcvarsallPath);
+ validator.validate();
+ base();
+ }
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
new file mode 100644
index 000000000..d36daa99f
--- /dev/null
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -0,0 +1,372 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 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.PathTools
+import qbs.Probes
+import qbs.Utilities
+import qbs.WindowsUtils
+import 'msvc.js' as MSVC
+
+CppModule {
+ condition: false
+
+ windowsApiCharacterSet: "unicode"
+ platformDefines: {
+ var defines = base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
+ .concat("WIN32");
+ var def = WindowsUtils.winapiFamilyDefine(windowsApiFamily);
+ if (def)
+ defines.push("WINAPI_FAMILY=WINAPI_FAMILY_" + def);
+ (windowsApiAdditionalPartitions || []).map(function (name) {
+ defines.push("WINAPI_PARTITION_" + WindowsUtils.winapiPartitionDefine(name) + "=1");
+ });
+ return defines;
+ }
+ platformCommonCompilerFlags: {
+ var flags = base;
+ if (compilerVersionMajor >= 18) // 2013
+ flags.push("/FS");
+ return flags;
+ }
+ warningLevel: "default"
+ compilerName: "cl.exe"
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+ assemblerName: {
+ switch (qbs.architecture) {
+ case "armv7":
+ return "armasm.exe";
+ case "arm64":
+ return "armasm64.exe";
+ case "ia64":
+ return "ias.exe";
+ case "x86":
+ return "ml.exe";
+ case "x86_64":
+ return "ml64.exe";
+ }
+ }
+
+ linkerName: "link.exe"
+ runtimeLibrary: "dynamic"
+ separateDebugInformation: true
+
+ property bool generateManifestFile: true
+ property string toolchainInstallPath
+
+ architecture: qbs.architecture
+ endianness: "little"
+ staticLibrarySuffix: ".lib"
+ dynamicLibrarySuffix: ".dll"
+ executableSuffix: ".exe"
+ debugInfoSuffix: ".pdb"
+ imageFormat: "pe"
+ Properties {
+ condition: product.multiplexByQbsProperties.contains("buildVariants")
+ && qbs.buildVariants && qbs.buildVariants.length > 1
+ && qbs.buildVariant !== "release"
+ && product.type.containsAny(["staticlibrary", "dynamiclibrary"])
+ variantSuffix: "d"
+ }
+
+ property var buildEnv
+
+ setupBuildEnvironment: {
+ for (var key in product.cpp.buildEnv) {
+ var v = new ModUtils.EnvironmentVariable(key, ';');
+ v.prepend(product.cpp.buildEnv[key]);
+ v.set();
+ }
+ }
+
+ Rule {
+ condition: useCPrecompiledHeader
+ inputs: ["c_pch_src"]
+ auxiliaryInputs: ["hpp"]
+ Artifact {
+ fileTags: ['obj']
+ filePath: Utilities.getHash(input.completeBaseName) + '_c.obj'
+ }
+ Artifact {
+ fileTags: ['c_pch']
+ filePath: product.name + '_c.pch'
+ }
+ prepare: {
+ return MSVC.prepareCompiler.apply(MSVC, arguments);
+ }
+ }
+
+ Rule {
+ condition: useCxxPrecompiledHeader
+ inputs: ["cpp_pch_src"]
+ explicitlyDependsOn: ["c_pch"] // to prevent vc--0.pdb conflict
+ auxiliaryInputs: ["hpp"]
+ Artifact {
+ fileTags: ['obj']
+ filePath: Utilities.getHash(input.completeBaseName) + '_cpp.obj'
+ }
+ Artifact {
+ fileTags: ['cpp_pch']
+ filePath: product.name + '_cpp.pch'
+ }
+ prepare: {
+ return MSVC.prepareCompiler.apply(MSVC, arguments);
+ }
+ }
+
+ Rule {
+ name: "compiler"
+ inputs: ["cpp", "c"]
+ auxiliaryInputs: ["hpp"]
+ explicitlyDependsOn: ["c_pch", "cpp_pch"]
+
+ outputFileTags: ["obj", "intermediate_obj"]
+ outputArtifacts: {
+ var tags = input.fileTags.contains("cpp_intermediate_object")
+ ? ["intermediate_obj"]
+ : ["obj"];
+ return [{
+ fileTags: tags,
+ filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj"
+ }];
+ }
+
+ prepare: {
+ return MSVC.prepareCompiler.apply(MSVC, arguments);
+ }
+ }
+
+ FileTagger {
+ patterns: ["*.manifest"]
+ fileTags: ["native.pe.manifest"]
+ }
+
+ Rule {
+ name: "applicationLinker"
+ multiplex: true
+ inputs: ['obj', 'native.pe.manifest']
+ inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"]
+
+ outputFileTags: ["application", "debuginfo_app"]
+ outputArtifacts: {
+ var app = {
+ fileTags: ["application"],
+ filePath: FileInfo.joinPaths(
+ product.destinationDirectory,
+ PathTools.applicationFilePath(product))
+ };
+ var artifacts = [app];
+ if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
+ artifacts.push({
+ fileTags: ["debuginfo_app"],
+ filePath: app.filePath.substr(0, app.filePath.length - 4)
+ + product.cpp.debugInfoSuffix
+ });
+ }
+ return artifacts;
+ }
+
+ prepare: {
+ return MSVC.prepareLinker.apply(MSVC, arguments);
+ }
+ }
+
+ Rule {
+ name: "dynamicLibraryLinker"
+ multiplex: true
+ inputs: ['obj', 'native.pe.manifest']
+ inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"]
+
+ outputFileTags: ["dynamiclibrary", "dynamiclibrary_import", "debuginfo_dll"]
+ outputArtifacts: {
+ var artifacts = [
+ {
+ fileTags: ["dynamiclibrary"],
+ filePath: product.destinationDirectory + "/" + PathTools.dynamicLibraryFilePath(product)
+ },
+ {
+ fileTags: ["dynamiclibrary_import"],
+ filePath: product.destinationDirectory + "/" + PathTools.importLibraryFilePath(product),
+ alwaysUpdated: false
+ }
+ ];
+ if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
+ var lib = artifacts[0];
+ artifacts.push({
+ fileTags: ["debuginfo_dll"],
+ filePath: lib.filePath.substr(0, lib.filePath.length - 4)
+ + product.cpp.debugInfoSuffix
+ });
+ }
+ return artifacts;
+ }
+
+ prepare: {
+ return MSVC.prepareLinker.apply(MSVC, arguments);
+ }
+ }
+
+ Rule {
+ name: "libtool"
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: ["staticlibrary", "debuginfo_cl"]
+ outputArtifacts: {
+ var artifacts = [
+ {
+ fileTags: ["staticlibrary"],
+ filePath: FileInfo.joinPaths(product.destinationDirectory,
+ PathTools.staticLibraryFilePath(product))
+ }
+ ];
+ if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
+ artifacts.push({
+ fileTags: ["debuginfo_cl"],
+ filePath: product.targetName + ".cl" + product.cpp.debugInfoSuffix
+ });
+ }
+ return artifacts;
+ }
+ prepare: {
+ var args = ['/nologo']
+ var lib = outputs["staticlibrary"][0];
+ var nativeOutputFileName = FileInfo.toWindowsSeparators(lib.filePath)
+ args.push('/OUT:' + nativeOutputFileName)
+ for (var i in inputs.obj) {
+ var fileName = FileInfo.toWindowsSeparators(inputs.obj[i].filePath)
+ args.push(fileName)
+ }
+ var cmd = new Command("lib.exe", args);
+ cmd.description = 'creating ' + lib.fileName;
+ cmd.highlight = 'linker';
+ cmd.jobPool = "linker";
+ cmd.workingDirectory = FileInfo.path(lib.filePath)
+ cmd.responseFileUsagePrefix = '@';
+ return cmd;
+ }
+ }
+
+ FileTagger {
+ patterns: ["*.rc"]
+ fileTags: ["rc"]
+ }
+
+ Rule {
+ inputs: ["rc"]
+ auxiliaryInputs: ["hpp"]
+
+ Artifact {
+ filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res"
+ fileTags: ["obj"]
+ }
+
+ 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;
+ }
+ }
+
+ FileTagger {
+ patterns: "*.asm"
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ inputs: ["asm"]
+ Artifact {
+ filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".obj"
+ fileTags: ["obj"]
+ }
+ prepare: {
+ var args = ["/nologo", "/c",
+ "/Fo" + FileInfo.toWindowsSeparators(output.filePath),
+ FileInfo.toWindowsSeparators(input.filePath)];
+ if (product.cpp.debugInformation)
+ args.push("/Zi");
+ args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', 'asm'),
+ ModUtils.moduleProperty(input, 'flags', 'asm'));
+ var cmd = new Command(product.cpp.assemblerPath, args);
+ cmd.description = "assembling " + input.fileName;
+ cmd.jobPool = "assembler";
+ cmd.inputFileName = input.fileName;
+ cmd.stdoutFilterFunction = function(output) {
+ var lines = output.split("\r\n").filter(function (s) {
+ return !s.endsWith(inputFileName); });
+ return lines.join("\r\n");
+ };
+ return cmd;
+ }
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs
index 8dd6dd2c0..59032d28a 100644
--- a/share/qbs/modules/cpp/windows-msvc.qbs
+++ b/share/qbs/modules/cpp/windows-msvc.qbs
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
+** Copyright (C) 2019 Ivan Komissarov (abbapoh@gmail.com)
** Contact: http://www.qt.io/licensing
**
** This file is part of Qbs.
@@ -28,19 +29,14 @@
**
****************************************************************************/
-import qbs.File
-import qbs.FileInfo
-import qbs.ModUtils
-import qbs.PathTools
import qbs.Probes
-import qbs.Utilities
-import qbs.WindowsUtils
-import 'msvc.js' as MSVC
+import "windows-msvc-base.qbs" as MsvcBaseModule
-CppModule {
+MsvcBaseModule {
condition: qbs.hostOS.contains('windows') &&
qbs.targetOS.contains('windows') &&
qbs.toolchain && qbs.toolchain.contains('msvc')
+ priority: 50
Probes.BinaryProbe {
id: compilerPathProbe
@@ -62,335 +58,9 @@ CppModule {
compilerVersionMinor: msvcProbe.versionMinor
compilerVersionPatch: msvcProbe.versionPatch
compilerIncludePaths: msvcProbe.includePaths
-
- windowsApiCharacterSet: "unicode"
- platformDefines: {
- var defines = base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
- .concat("WIN32");
- var def = WindowsUtils.winapiFamilyDefine(windowsApiFamily);
- if (def)
- defines.push("WINAPI_FAMILY=WINAPI_FAMILY_" + def);
- (windowsApiAdditionalPartitions || []).map(function (name) {
- defines.push("WINAPI_PARTITION_" + WindowsUtils.winapiPartitionDefine(name) + "=1");
- });
- return defines;
- }
- platformCommonCompilerFlags: {
- var flags = base;
- if (compilerVersionMajor >= 18) // 2013
- flags.push("/FS");
- return flags;
- }
compilerDefinesByLanguage: msvcProbe.compilerDefinesByLanguage
- warningLevel: "default"
- compilerName: "cl.exe"
- compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
- assemblerName: {
- switch (qbs.architecture) {
- case "armv7":
- return "armasm.exe";
- case "arm64":
- return "armasm64.exe";
- case "ia64":
- return "ias.exe";
- case "x86":
- return "ml.exe";
- case "x86_64":
- return "ml64.exe";
- }
- }
-
- linkerName: "link.exe"
- runtimeLibrary: "dynamic"
- separateDebugInformation: true
-
- property bool generateManifestFile: true
- property string toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path
- : undefined
- architecture: qbs.architecture
- endianness: "little"
- staticLibrarySuffix: ".lib"
- dynamicLibrarySuffix: ".dll"
- executableSuffix: ".exe"
- debugInfoSuffix: ".pdb"
- imageFormat: "pe"
- Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
- && qbs.buildVariants && qbs.buildVariants.length > 1
- && qbs.buildVariant !== "release"
- && product.type.containsAny(["staticlibrary", "dynamiclibrary"])
- variantSuffix: "d"
- }
-
- property var buildEnv: msvcProbe.buildEnv
-
- setupBuildEnvironment: {
- for (var key in product.cpp.buildEnv) {
- var v = new ModUtils.EnvironmentVariable(key, ';');
- v.prepend(product.cpp.buildEnv[key]);
- v.set();
- }
- }
-
- Rule {
- condition: useCPrecompiledHeader
- inputs: ["c_pch_src"]
- auxiliaryInputs: ["hpp"]
- Artifact {
- fileTags: ['obj']
- filePath: Utilities.getHash(input.completeBaseName) + '_c.obj'
- }
- Artifact {
- fileTags: ['c_pch']
- filePath: product.name + '_c.pch'
- }
- prepare: {
- return MSVC.prepareCompiler.apply(MSVC, arguments);
- }
- }
-
- Rule {
- condition: useCxxPrecompiledHeader
- inputs: ["cpp_pch_src"]
- explicitlyDependsOn: ["c_pch"] // to prevent vc--0.pdb conflict
- auxiliaryInputs: ["hpp"]
- Artifact {
- fileTags: ['obj']
- filePath: Utilities.getHash(input.completeBaseName) + '_cpp.obj'
- }
- Artifact {
- fileTags: ['cpp_pch']
- filePath: product.name + '_cpp.pch'
- }
- prepare: {
- return MSVC.prepareCompiler.apply(MSVC, arguments);
- }
- }
-
- Rule {
- name: "compiler"
- inputs: ["cpp", "c"]
- auxiliaryInputs: ["hpp"]
- explicitlyDependsOn: ["c_pch", "cpp_pch"]
-
- outputFileTags: ["obj", "intermediate_obj"]
- outputArtifacts: {
- var tags = input.fileTags.contains("cpp_intermediate_object")
- ? ["intermediate_obj"]
- : ["obj"];
- return [{
- fileTags: tags,
- filePath: Utilities.getHash(input.baseDir) + "/" + input.fileName + ".obj"
- }];
- }
-
- prepare: {
- return MSVC.prepareCompiler.apply(MSVC, arguments);
- }
- }
-
- FileTagger {
- patterns: ["*.manifest"]
- fileTags: ["native.pe.manifest"]
- }
-
- Rule {
- name: "applicationLinker"
- multiplex: true
- inputs: ['obj', 'native.pe.manifest']
- inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_app"]
-
- outputFileTags: ["application", "debuginfo_app"]
- outputArtifacts: {
- var app = {
- fileTags: ["application"],
- filePath: FileInfo.joinPaths(
- product.destinationDirectory,
- PathTools.applicationFilePath(product))
- };
- var artifacts = [app];
- if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
- artifacts.push({
- fileTags: ["debuginfo_app"],
- filePath: app.filePath.substr(0, app.filePath.length - 4)
- + product.cpp.debugInfoSuffix
- });
- }
- return artifacts;
- }
- prepare: {
- return MSVC.prepareLinker.apply(MSVC, arguments);
- }
- }
-
- Rule {
- name: "dynamicLibraryLinker"
- multiplex: true
- inputs: ['obj', 'native.pe.manifest']
- inputsFromDependencies: ['staticlibrary', 'dynamiclibrary_import', "debuginfo_dll"]
-
- outputFileTags: ["dynamiclibrary", "dynamiclibrary_import", "debuginfo_dll"]
- outputArtifacts: {
- var artifacts = [
- {
- fileTags: ["dynamiclibrary"],
- filePath: product.destinationDirectory + "/" + PathTools.dynamicLibraryFilePath(product)
- },
- {
- fileTags: ["dynamiclibrary_import"],
- filePath: product.destinationDirectory + "/" + PathTools.importLibraryFilePath(product),
- alwaysUpdated: false
- }
- ];
- if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
- var lib = artifacts[0];
- artifacts.push({
- fileTags: ["debuginfo_dll"],
- filePath: lib.filePath.substr(0, lib.filePath.length - 4)
- + product.cpp.debugInfoSuffix
- });
- }
- return artifacts;
- }
-
- prepare: {
- return MSVC.prepareLinker.apply(MSVC, arguments);
- }
- }
-
- Rule {
- name: "libtool"
- multiplex: true
- inputs: ["obj"]
- inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
- outputFileTags: ["staticlibrary", "debuginfo_cl"]
- outputArtifacts: {
- var artifacts = [
- {
- fileTags: ["staticlibrary"],
- filePath: FileInfo.joinPaths(product.destinationDirectory,
- PathTools.staticLibraryFilePath(product))
- }
- ];
- if (product.cpp.debugInformation && product.cpp.separateDebugInformation) {
- artifacts.push({
- fileTags: ["debuginfo_cl"],
- filePath: product.targetName + ".cl" + product.cpp.debugInfoSuffix
- });
- }
- return artifacts;
- }
- prepare: {
- var args = ['/nologo']
- var lib = outputs["staticlibrary"][0];
- var nativeOutputFileName = FileInfo.toWindowsSeparators(lib.filePath)
- args.push('/OUT:' + nativeOutputFileName)
- for (var i in inputs.obj) {
- var fileName = FileInfo.toWindowsSeparators(inputs.obj[i].filePath)
- args.push(fileName)
- }
- var cmd = new Command("lib.exe", args);
- cmd.description = 'creating ' + lib.fileName;
- cmd.highlight = 'linker';
- cmd.jobPool = "linker";
- cmd.workingDirectory = FileInfo.path(lib.filePath)
- cmd.responseFileUsagePrefix = '@';
- return cmd;
- }
- }
-
- FileTagger {
- patterns: ["*.rc"]
- fileTags: ["rc"]
- }
-
- Rule {
- inputs: ["rc"]
- auxiliaryInputs: ["hpp"]
-
- Artifact {
- filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".res"
- fileTags: ["obj"]
- }
-
- 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;
- }
- }
-
- FileTagger {
- patterns: "*.asm"
- fileTags: ["asm"]
- }
-
- Rule {
- inputs: ["asm"]
- Artifact {
- filePath: Utilities.getHash(input.baseDir) + "/" + input.completeBaseName + ".obj"
- fileTags: ["obj"]
- }
- prepare: {
- var args = ["/nologo", "/c",
- "/Fo" + FileInfo.toWindowsSeparators(output.filePath),
- FileInfo.toWindowsSeparators(input.filePath)];
- if (product.cpp.debugInformation)
- args.push("/Zi");
- args = args.concat(ModUtils.moduleProperty(input, 'platformFlags', 'asm'),
- ModUtils.moduleProperty(input, 'flags', 'asm'));
- var cmd = new Command(product.cpp.assemblerPath, args);
- cmd.description = "assembling " + input.fileName;
- cmd.jobPool = "assembler";
- cmd.inputFileName = input.fileName;
- cmd.stdoutFilterFunction = function(output) {
- var lines = output.split("\r\n").filter(function (s) {
- return !s.endsWith(inputFileName); });
- return lines.join("\r\n");
- };
- return cmd;
- }
- }
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path
+ : undefined
+ buildEnv: msvcProbe.buildEnv
}