aboutsummaryrefslogtreecommitdiffstats
path: root/share/qbs/modules
diff options
context:
space:
mode:
Diffstat (limited to 'share/qbs/modules')
-rw-r--r--share/qbs/modules/Android/sdk/sdk.qbs38
-rw-r--r--share/qbs/modules/Android/sdk/utils.js17
-rw-r--r--share/qbs/modules/Exporter/cmake/cmakeexporter.js239
-rw-r--r--share/qbs/modules/Exporter/cmake/cmakeexporter.qbs84
-rw-r--r--share/qbs/modules/Exporter/exporter.js66
-rw-r--r--share/qbs/modules/Exporter/pkgconfig/pkgconfig.js24
-rw-r--r--share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs6
-rw-r--r--share/qbs/modules/Exporter/qbs/qbsexporter.js44
-rw-r--r--share/qbs/modules/Exporter/qbs/qbsexporter.qbs2
-rw-r--r--share/qbs/modules/Sanitizers/address/asan.qbs76
-rw-r--r--share/qbs/modules/archiver/archiver.qbs9
-rw-r--r--share/qbs/modules/bundle/BundleModule.qbs128
-rw-r--r--share/qbs/modules/bundle/bundle.js27
-rw-r--r--share/qbs/modules/capnproto/capnprotobase.qbs7
-rw-r--r--share/qbs/modules/capnproto/cpp/capnprotocpp.qbs2
-rw-r--r--share/qbs/modules/cli/CLIModule.qbs9
-rw-r--r--share/qbs/modules/cli/cli.js10
-rw-r--r--share/qbs/modules/cli/mono.qbs7
-rw-r--r--share/qbs/modules/cli/windows-dotnet.qbs2
-rw-r--r--share/qbs/modules/codesign/android.qbs5
-rw-r--r--share/qbs/modules/codesign/apple.qbs23
-rw-r--r--share/qbs/modules/codesign/codesign.js106
-rw-r--r--share/qbs/modules/codesign/signtool.qbs11
-rw-r--r--share/qbs/modules/cpp/CppModule.qbs3
-rw-r--r--share/qbs/modules/cpp/DarwinGCC.qbs40
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs37
-rw-r--r--share/qbs/modules/cpp/LinuxGCC.qbs7
-rw-r--r--share/qbs/modules/cpp/MingwBaseModule.qbs7
-rw-r--r--share/qbs/modules/cpp/UnixGCC.qbs4
-rw-r--r--share/qbs/modules/cpp/android-gcc.qbs10
-rw-r--r--share/qbs/modules/cpp/cosmic.js6
-rw-r--r--share/qbs/modules/cpp/cosmic.qbs2
-rw-r--r--share/qbs/modules/cpp/cpp.js42
-rw-r--r--share/qbs/modules/cpp/darwin.js4
-rw-r--r--share/qbs/modules/cpp/dmc.js122
-rw-r--r--share/qbs/modules/cpp/dmc.qbs33
-rw-r--r--share/qbs/modules/cpp/freebsd-gcc.qbs7
-rw-r--r--share/qbs/modules/cpp/gcc.js140
-rw-r--r--share/qbs/modules/cpp/iar.js12
-rw-r--r--share/qbs/modules/cpp/iar.qbs2
-rw-r--r--share/qbs/modules/cpp/ios-gcc.qbs15
-rw-r--r--share/qbs/modules/cpp/keil.js8
-rw-r--r--share/qbs/modules/cpp/keil.qbs3
-rw-r--r--share/qbs/modules/cpp/macos-gcc.qbs4
-rw-r--r--share/qbs/modules/cpp/msvc.js85
-rw-r--r--share/qbs/modules/cpp/qnx-qcc.qbs6
-rw-r--r--share/qbs/modules/cpp/sdcc.js24
-rw-r--r--share/qbs/modules/cpp/sdcc.qbs2
-rw-r--r--share/qbs/modules/cpp/setuprunenv.js27
-rw-r--r--share/qbs/modules/cpp/tvos-gcc.qbs8
-rw-r--r--share/qbs/modules/cpp/watchos-gcc.qbs8
-rw-r--r--share/qbs/modules/cpp/watcom.js568
-rw-r--r--share/qbs/modules/cpp/watcom.qbs196
-rw-r--r--share/qbs/modules/cpp/windows-clang-cl.qbs12
-rw-r--r--share/qbs/modules/cpp/windows-clang-mingw.qbs13
-rw-r--r--share/qbs/modules/cpp/windows-mingw.qbs8
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs7
-rw-r--r--share/qbs/modules/cpp/windows-msvc.qbs7
-rw-r--r--share/qbs/modules/dmg/DMGModule.qbs10
-rw-r--r--share/qbs/modules/dmg/dmg.js27
-rw-r--r--share/qbs/modules/flatbuf/c/flatbuffers-c.qbs61
-rw-r--r--share/qbs/modules/flatbuf/cpp/flatbuffers-cpp.qbs69
-rw-r--r--share/qbs/modules/flatbuf/flatbuffers.js126
-rw-r--r--share/qbs/modules/flatbuf/flatbuffersbase.qbs58
-rw-r--r--share/qbs/modules/freedesktop/FreeDesktop.qbs15
-rw-r--r--share/qbs/modules/ib/IBModule.qbs5
-rw-r--r--share/qbs/modules/ib/ib.js16
-rw-r--r--share/qbs/modules/ico/ico.js6
-rw-r--r--share/qbs/modules/innosetup/InnoSetupModule.qbs2
-rw-r--r--share/qbs/modules/java/JavaModule.qbs9
-rw-r--r--share/qbs/modules/java/utils.js48
-rw-r--r--share/qbs/modules/nodejs/NodeJS.qbs7
-rw-r--r--share/qbs/modules/nsis/NSISModule.qbs9
-rw-r--r--share/qbs/modules/pkgconfig/pkgconfig.qbs2
-rw-r--r--share/qbs/modules/protobuf/cpp/protobufcpp.qbs115
-rw-r--r--share/qbs/modules/protobuf/nanopb/nanopb.qbs1
-rw-r--r--share/qbs/modules/protobuf/protobuf.js1
-rw-r--r--share/qbs/modules/protobuf/protobufbase.qbs2
-rw-r--r--share/qbs/modules/qbs/common.qbs45
-rw-r--r--share/qbs/modules/qnx/qnx.qbs11
-rw-r--r--share/qbs/modules/typescript/TypeScriptModule.qbs2
-rw-r--r--share/qbs/modules/typescript/typescript.js6
-rw-r--r--share/qbs/modules/wix/WiXModule.qbs27
-rw-r--r--share/qbs/modules/xcode/xcode.js39
-rw-r--r--share/qbs/modules/xcode/xcode.qbs25
85 files changed, 2465 insertions, 700 deletions
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index c52b54664..440448dcf 100644
--- a/share/qbs/modules/Android/sdk/sdk.qbs
+++ b/share/qbs/modules/Android/sdk/sdk.qbs
@@ -52,7 +52,7 @@ Module {
Probes.PathProbe {
id: bundletoolProbe
- platformSearchPaths: [Android.sdk.sdkDir]
+ platformSearchPaths: [sdkDir]
names: ["bundletool-all"]
nameSuffixes: ["-0.11.0.jar", "-0.12.0.jar", "-0.13.0.jar", "-0.13.3.jar", "-0.13.4.jar",
"-0.14.0.jar", "-0.15.0.jar", "-1.0.0.jar", "-1.1.0.jar", "-1.2.0.jar", "-1.3.0.jar",
@@ -102,36 +102,36 @@ Module {
Group {
name: "java sources"
- condition: Android.sdk.automaticSources
- prefix: FileInfo.resolvePath(product.sourceDirectory, Android.sdk.sourcesDir + '/')
+ condition: product.Android.sdk.automaticSources
+ prefix: FileInfo.resolvePath(product.sourceDirectory, product.Android.sdk.sourcesDir + '/')
files: "**/*.java"
}
Group {
name: "android resources"
- condition: Android.sdk.automaticSources
+ condition: product.Android.sdk.automaticSources
fileTags: ["android.resources"]
- prefix: FileInfo.resolvePath(product.sourceDirectory, Android.sdk.resourcesDir + '/')
+ prefix: FileInfo.resolvePath(product.sourceDirectory, product.Android.sdk.resourcesDir + '/')
files: "**/*"
}
Group {
name: "android assets"
- condition: Android.sdk.automaticSources
+ condition: product.Android.sdk.automaticSources
fileTags: ["android.assets"]
- prefix: FileInfo.resolvePath(product.sourceDirectory, Android.sdk.assetsDir + '/')
+ prefix: FileInfo.resolvePath(product.sourceDirectory, product.Android.sdk.assetsDir + '/')
files: "**/*"
}
Group {
name: "manifest"
- condition: Android.sdk.automaticSources
+ condition: product.Android.sdk.automaticSources
fileTags: ["android.manifest"]
- files: Android.sdk.manifestFile
- && Android.sdk.manifestFile !== Android.sdk.defaultManifestFile
- ? [Android.sdk.manifestFile]
- : (File.exists(Android.sdk.defaultManifestFile)
- ? [Android.sdk.defaultManifestFile] : [])
+ files: product.Android.sdk.manifestFile
+ && product.Android.sdk.manifestFile !== product.Android.sdk.defaultManifestFile
+ ? [product.Android.sdk.manifestFile]
+ : (File.exists(product.Android.sdk.defaultManifestFile)
+ ? [product.Android.sdk.defaultManifestFile] : [])
}
@@ -196,8 +196,8 @@ Module {
java.languageVersion: platformJavaVersion
java.runtimeVersion: platformJavaVersion
java.bootClassPaths: androidJarFilePath
- codesign.apksignerFilePath: Android.sdk.apksignerFilePath
- codesign._packageName: Android.sdk.apkBaseName + (_generateAab ? ".aab" : ".apk")
+ codesign.apksignerFilePath: apksignerFilePath
+ codesign._packageName: apkBaseName + (_generateAab ? ".aab" : ".apk")
codesign.useApksigner: !_generateAab
}
@@ -256,14 +256,14 @@ Module {
args.push("-I" + aidlSearchPaths[i]);
args.push(input.filePath, output.filePath);
var cmd = new Command(aidl, args);
- cmd.description = "Processing " + input.fileName;
+ cmd.description = "processing " + input.fileName;
return [cmd];
}
}
property bool customManifestProcessing: false
Group {
- condition: !Android.sdk.customManifestProcessing
+ condition: !product.Android.sdk.customManifestProcessing
fileTagsFilter: "android.manifest_processed"
fileTags: "android.manifest_final"
}
@@ -276,7 +276,7 @@ Module {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Ensuring correct package name in Android manifest file";
+ cmd.description = "ensuring correct package name in Android manifest file";
cmd.sourceCode = function() {
var manifestData = new Xml.DomDocument();
manifestData.load(input.filePath);
@@ -421,7 +421,7 @@ Module {
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Generating BuildConfig.java";
+ cmd.description = "generating BuildConfig.java";
cmd.sourceCode = function() {
var debugValue = product.qbs.buildVariant === "debug" ? "true" : "false";
var ofile = new TextFile(output.filePath, TextFile.WriteOnly);
diff --git a/share/qbs/modules/Android/sdk/utils.js b/share/qbs/modules/Android/sdk/utils.js
index d217d113b..232ee5a30 100644
--- a/share/qbs/modules/Android/sdk/utils.js
+++ b/share/qbs/modules/Android/sdk/utils.js
@@ -84,13 +84,20 @@ function prepareDex(project, product, inputs, outputs, input, output, explicitly
return;
dep.artifacts["java.jar"].forEach(function(artifact) {
- if (!jarFiles.contains(artifact.filePath))
+ if (!jarFiles.includes(artifact.filePath))
jarFiles.push(artifact.filePath);
});
dep.dependencies.forEach(traverseJarDeps);
}
product.dependencies.forEach(traverseJarDeps);
+ if (typeof product.artifacts["java.jar"] !== "undefined") {
+ product.artifacts["java.jar"].forEach(function(artifact) {
+ if (!jarFiles.includes(artifact.filePath))
+ jarFiles.push(artifact.filePath);
+ });
+ }
+
args = args.concat(jarFiles);
var cmd;
@@ -159,7 +166,7 @@ function commonAaptPackageArgs(project, product, inputs, outputs, input, output,
throw "File '" + resources[i].filePath + "' is tagged as an Android resource, "
+ "but is not located under a directory called 'res'.";
}
- if (!resourceDirs.contains(resDir))
+ if (!resourceDirs.includes(resDir))
resourceDirs.push(resDir);
}
}
@@ -174,7 +181,7 @@ function commonAaptPackageArgs(project, product, inputs, outputs, input, output,
throw "File '" + assets[i].filePath + "' is tagged as an Android asset, "
+ "but is not located under a directory called 'assets'.";
}
- if (!assetDirs.contains(assetDir))
+ if (!assetDirs.includes(assetDir))
assetDirs.push(assetDir);
}
}
@@ -258,7 +265,7 @@ function prepareAapt2Link(project, product, inputs, outputs, input, output, expl
throw "File '" + assets[i].filePath + "' is tagged as an Android asset, "
+ "but is not located under a directory called 'assets'.";
}
- if (!assetDirs.contains(assetDir))
+ if (!assetDirs.includes(assetDir))
assetDirs.push(assetDir);
}
}
@@ -422,7 +429,7 @@ function stlDeploymentData(product, inputs, type)
return data;
for (var i = 0; i < theInputs.length; ++i) {
var currentInput = theInputs[i];
- if (uniqueFilePaths.contains(currentInput.filePath))
+ if (uniqueFilePaths.includes(currentInput.filePath))
continue;
uniqueFilePaths.push(currentInput.filePath);
data.uniqueInputs.push(currentInput);
diff --git a/share/qbs/modules/Exporter/cmake/cmakeexporter.js b/share/qbs/modules/Exporter/cmake/cmakeexporter.js
new file mode 100644
index 000000000..093032f2e
--- /dev/null
+++ b/share/qbs/modules/Exporter/cmake/cmakeexporter.js
@@ -0,0 +1,239 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Raphaƫl Cotty <raphael.cotty@gmail.com>
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of the 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.
+**
+****************************************************************************/
+
+var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
+var ExporterHelpers = require("../exporter.js");
+
+function tagListToString(tagList)
+{
+ return JSON.stringify(tagList);
+}
+
+function collectAutodetectedData(project, topLevelProduct, outputs)
+{
+ var packageName = topLevelProduct.Exporter.cmake.packageName;
+
+ var data = {};
+ data.packageName = packageName;
+ data.installPrefixDir = "_" + packageName.toUpperCase() + "_INSTALL_PREFIX";
+ data.packages = [];
+
+ function quote(value)
+ {
+ return "\"" + value + "\"";
+ }
+
+ function quoteAndPrefixify(propName)
+ {
+ function quoteAndPrefixifyHelper(value) {
+ var prefixToStrip =
+ ExporterHelpers.getPrefixToStrip(project, topLevelProduct, propName, value);
+ if (typeof value !== "string"
+ || !prefixToStrip
+ || (value.length > prefixToStrip.length
+ && value[prefixToStrip.length] !== '/')) {
+ return quote(value);
+ }
+ return quote("${" + data.installPrefixDir + "}" + value.slice(prefixToStrip.length));
+ }
+ return quoteAndPrefixifyHelper;
+ }
+
+ var installedOutputFilePath = ModUtils.artifactInstalledFilePath(
+ outputs["Exporter.cmake.configFile"][0]);
+ var installedOutputPathName = FileInfo.path(installedOutputFilePath);
+
+ var installRootPath = FileInfo.joinPaths(topLevelProduct.qbs.installRoot, topLevelProduct.qbs.installPrefix);
+ data.installPrefix = FileInfo.relativePath(installedOutputPathName, installRootPath);
+
+ var libArtifacts;
+ var libImportArtifacts;
+ var isProduct = !topLevelProduct.present;
+ var considerFramework = !isProduct || (topLevelProduct.type
+ && topLevelProduct.type.includes("bundle.content"))
+ && topLevelProduct.bundle
+ && topLevelProduct.bundle.isBundle
+ && topLevelProduct.qbs.targetOS.includes("darwin");
+ var considerDynamicLibs = !isProduct || (topLevelProduct.type
+ && topLevelProduct.type.includes("dynamiclibrary"));
+ var considerStaticLibs = !isProduct || (topLevelProduct.type
+ && topLevelProduct.type.includes("staticlibrary"));
+ if (considerFramework) {
+ libArtifacts = topLevelProduct.artifacts["bundle.symlink.executable"];
+ if (considerDynamicLibs)
+ data.type = "SHARED";
+ else if (considerStaticLibs)
+ data.type = "STATIC";
+ else
+ data.type = "INTERFACE";
+ } else if (considerDynamicLibs) {
+ libArtifacts = topLevelProduct.artifacts.dynamiclibrary;
+ libImportArtifacts = topLevelProduct.artifacts.dynamiclibrary_import;
+ data.type = "SHARED";
+ } else if (considerStaticLibs) {
+ libArtifacts = topLevelProduct.artifacts.staticlibrary;
+ data.type = "STATIC";
+ } else {
+ data.type = "INTERFACE";
+ }
+
+ for (var i = 0; i < (libArtifacts || []).length; ++i) {
+ var libArtifact = libArtifacts[i];
+ var libImportArtifact = (libImportArtifacts || [])[i];
+ if (libArtifact.qbs.install) {
+ var installPath = ModUtils.artifactInstalledFilePath(libArtifact);
+ data.importedLocation = quoteAndPrefixify("installRoot")(installPath);
+ data.soName = topLevelProduct.targetName;
+ if (libImportArtifact && libImportArtifact.qbs.install) {
+ installPath = ModUtils.artifactInstalledFilePath(libImportArtifact);
+ data.importedImplibLocation = quoteAndPrefixify("installRoot")(installPath);
+ }
+ break;
+ }
+ }
+ var cpp = topLevelProduct.exports.cpp;
+ if (cpp) {
+ data.libraryPaths = (cpp.libraryPaths || []).map(quoteAndPrefixify("cpp.libraryPaths"));
+
+ data.linkLibraries = [];
+ data.linkLibraries = data.linkLibraries.concat(cpp.dynamicLibraries || []);
+ data.linkLibraries = data.linkLibraries.concat(cpp.staticLibraries || []);
+ data.linkLibraries = data.linkLibraries.map(quoteAndPrefixify("cpp.dynamicLibraries"));
+
+ data.linkOptions = [];
+ data.linkOptions = data.linkOptions.concat(cpp.driverLinkerFlags || []);
+ if ((cpp.linkerFlags || []).length > 0) {
+ data.linkOptions =
+ data.linkOptions.concat("LINKER:" + (cpp.linkerFlags || []).join(","));
+ }
+ data.linkOptions = data.linkOptions.map(quote);
+
+ data.includeDirectories =
+ (cpp.includePaths || []).map(quoteAndPrefixify("cpp.includePaths"));
+ data.compileDefinitions = (cpp.defines || []).map(quote);
+
+ data.compileOptions = [];
+ data.compileOptions = data.compileOptions.concat(cpp.commonCompilerFlags || []);
+ data.compileOptions = data.compileOptions.concat(cpp.driverFlags || []);
+ data.compileOptions = data.compileOptions.concat(cpp.cxxFlags || []);
+ data.compileOptions = data.compileOptions.concat(cpp.cFlags || []);
+ data.compileOptions = data.compileOptions.map(quote);
+ }
+
+ function gatherDeps(dep) {
+ if (dep.name === "Exporter.cmake")
+ return;
+ var depHasExporter = dep.Exporter && dep.Exporter.cmake;
+ if (!depHasExporter)
+ return;
+ data.packages.push(dep.Exporter.cmake.packageName);
+ }
+
+ var exportedDeps = topLevelProduct.exports ? topLevelProduct.exports.dependencies : [];
+ exportedDeps.forEach(gatherDeps);
+
+ return data;
+}
+
+function writeConfigFile(project, product, outputs)
+{
+ var autoDetectedData = collectAutodetectedData(project, product, outputs);
+ var packageName = autoDetectedData.packageName;
+
+ function writeCommand(command, lines)
+ {
+ if ((lines || []).length === 0)
+ return;
+ cmakeConfigFile.writeLine(command + "(" + packageName + " INTERFACE");
+ for (i = 0; i < lines.length; i++) {
+ cmakeConfigFile.writeLine(" " + lines[i]);
+ }
+ cmakeConfigFile.writeLine(")");
+ }
+
+ var cmakeConfigFile = new TextFile(outputs["Exporter.cmake.configFile"][0].filePath,
+ TextFile.WriteOnly);
+ cmakeConfigFile.writeLine("# Generated by Qbs");
+
+ cmakeConfigFile.writeLine("cmake_minimum_required(VERSION 3.5)");
+
+ cmakeConfigFile.writeLine("if(TARGET " + packageName + ")");
+ cmakeConfigFile.writeLine(" return()");
+ cmakeConfigFile.writeLine("endif()");
+
+ cmakeConfigFile.writeLine("set(" + autoDetectedData.installPrefixDir +
+ " \"${CMAKE_CURRENT_LIST_DIR}/" +
+ autoDetectedData.installPrefix + "\")");
+
+ autoDetectedData.packages.forEach(function(packageName) {
+ cmakeConfigFile.writeLine("find_package(" + packageName + " REQUIRED SILENT)");
+ });
+ cmakeConfigFile.writeLine(
+ "add_library(" + packageName + " " + autoDetectedData.type + " IMPORTED)");
+ var configuration = (product.qbs.buildVariant) ?
+ product.qbs.buildVariant.toUpperCase() : "NONE";
+ cmakeConfigFile.writeLine("set_property(TARGET " + packageName +
+ " APPEND PROPERTY IMPORTED_CONFIGURATIONS " +
+ configuration + ")");
+
+ cmakeConfigFile.writeLine("set_target_properties(" + packageName + " PROPERTIES");
+ cmakeConfigFile.writeLine(" IMPORTED_LINK_INTERFACE_LANGUAGES_" + configuration +
+ " CXX");
+ if (autoDetectedData.type !== "INTERFACE") {
+ cmakeConfigFile.writeLine(" IMPORTED_LOCATION_" + configuration + " " +
+ autoDetectedData.importedLocation);
+ }
+ if (autoDetectedData.importedImplibLocation) {
+ cmakeConfigFile.writeLine(" IMPORTED_IMPLIB_" + configuration + " " +
+ autoDetectedData.importedImplibLocation);
+ }
+ cmakeConfigFile.writeLine(")");
+
+ writeCommand("target_link_directories", autoDetectedData.libraryPaths);
+ writeCommand("target_link_libraries",
+ autoDetectedData.linkLibraries.concat(autoDetectedData.packages));
+ writeCommand("target_link_options", autoDetectedData.linkOptions);
+ writeCommand("target_include_directories", autoDetectedData.includeDirectories);
+ writeCommand("target_compile_definitions", autoDetectedData.compileDefinitions);
+ writeCommand("target_compile_options", autoDetectedData.compileOptions);
+
+ cmakeConfigFile.close();
+}
+
+function writeVersionFile(product, outputs)
+{
+ var cmakeVersionFile = new TextFile(
+ outputs["Exporter.cmake.versionFile"][0].filePath, TextFile.WriteOnly);
+ cmakeVersionFile.writeLine("# Generated by Qbs");
+ cmakeVersionFile.writeLine("set(PACKAGE_VERSION \"" + product.version + "\")");
+ cmakeVersionFile.close();
+}
diff --git a/share/qbs/modules/Exporter/cmake/cmakeexporter.qbs b/share/qbs/modules/Exporter/cmake/cmakeexporter.qbs
new file mode 100644
index 000000000..a578e938b
--- /dev/null
+++ b/share/qbs/modules/Exporter/cmake/cmakeexporter.qbs
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 Raphaƫl Cotty <raphael.cotty@gmail.com>
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://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 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import qbs.File
+import qbs.FileInfo
+import qbs.ModUtils
+import qbs.TextFile
+
+import "cmakeexporter.js" as HelperFunctions
+
+Module {
+ property string configFileName: packageName + "Config.cmake"
+ property string versionFileName: packageName + "ConfigVersion.cmake"
+ property string packageName: product.targetName
+
+ additionalProductTypes: ["Exporter.cmake.package"]
+
+ Rule {
+ multiplex: true
+ requiresInputs: false
+
+ auxiliaryInputs: {
+ if (product.type.includes("staticlibrary"))
+ return ["staticlibrary"];
+ if (product.type.includes("dynamiclibrary"))
+ return ["dynamiclibrary"];
+ }
+
+ Artifact {
+ filePath: product.Exporter.cmake.configFileName
+ fileTags: ["Exporter.cmake.package", "Exporter.cmake.configFile"]
+ }
+ Artifact {
+ filePath: product.Exporter.cmake.versionFileName
+ fileTags: ["Exporter.cmake.package", "Exporter.cmake.versionFile"]
+ }
+ prepare: {
+ var cmd = new JavaScriptCommand();
+ cmd.description = "generate cmake package files";
+ cmd.sourceCode = function() {
+ HelperFunctions.writeConfigFile(project, product, outputs);
+ HelperFunctions.writeVersionFile(product, outputs);
+ }
+ return [cmd];
+ }
+ }
+}
diff --git a/share/qbs/modules/Exporter/exporter.js b/share/qbs/modules/Exporter/exporter.js
new file mode 100644
index 000000000..65a632ac8
--- /dev/null
+++ b/share/qbs/modules/Exporter/exporter.js
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2018 The Qt Company Ltd.
+** Copyright (C) 2024 Ivan Komissarov (abbapoh@gmail.com)
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of the 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.
+**
+****************************************************************************/
+
+function getPrefixToStrip(project, product, propName, value)
+{
+ function checkValuePrefix(forbiddenPrefix, prefixDescription)
+ {
+ if (value.startsWith(forbiddenPrefix)) {
+ throw "Value '" + value + "' for exported property '" + propName + "' in product '"
+ + product.name + "' points into " + prefixDescription + ".\n"
+ + "Did you forget to set the prefixMapping property in an Export item?";
+ }
+ }
+
+ // Catch user oversights: Paths that point into the project source or build directories
+ // make no sense in the module.
+ if (!value.startsWith(product.qbs.installRoot)) {
+ checkValuePrefix(project.buildDirectory, "project build directory");
+ checkValuePrefix(project.sourceDirectory, "project source directory");
+ }
+
+ // Adapt file paths pointing into the install dir, that is, make them relative to the
+ // module file for relocatability. We accept them with or without the install root.
+ // The latter form will typically be a result of applying the prefixMapping property,
+ // while the first one could be an untransformed path, for instance if the project
+ // file is written in such a way that include paths are picked up from the installed
+ // location rather than the source directory.
+ var result;
+ var fullInstallPrefix = FileInfo.joinPaths(product.qbs.installRoot, product.qbs.installPrefix);
+ if (fullInstallPrefix.length > 1 && value.startsWith(fullInstallPrefix)) {
+ result = fullInstallPrefix;
+ } else {
+ var installPrefix = FileInfo.joinPaths("/", product.qbs.installPrefix);
+ if (installPrefix.length > 1 && value.startsWith(installPrefix))
+ result = installPrefix;
+ }
+ return result;
+}
diff --git a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js
index 52b4dffe3..50bba536c 100644
--- a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js
+++ b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.js
@@ -33,7 +33,7 @@ var ModUtils = require("qbs.ModUtils");
function quote(value)
{
- if (value.contains(" ") || value.contains("'") || value.contains('"')) {
+ if (value.includes(" ") || value.includes("'") || value.includes('"')) {
return '"' + value.replace(/(["'\\])/g, "\\$1") + '"';
}
return value;
@@ -105,12 +105,12 @@ function collectAutodetectedData(topLevelProduct)
var libArtifacts;
var isProduct = !productOrModule.present;
var considerDynamicLibs = !isProduct || (productOrModule.type
- && productOrModule.type.contains("dynamiclibrary"));
+ && productOrModule.type.includes("dynamiclibrary"));
if (considerDynamicLibs) {
libArtifacts = productOrModule.artifacts.dynamiclibrary;
} else {
var considerStaticLibs = !isProduct || (productOrModule.type
- && productOrModule.type.contains("staticlibrary"));
+ && productOrModule.type.includes("staticlibrary"));
if (considerStaticLibs)
libArtifacts = productOrModule.artifacts.staticlibrary;
}
@@ -186,7 +186,7 @@ function collectAutodetectedData(topLevelProduct)
exportedDepNames.push(exportedDeps[i].name);
for (i = 0; i < (productOrModule.dependencies || []).length; ++i) {
var dep = productOrModule.dependencies[i];
- if (exportedDepNames.contains(dep.name))
+ if (exportedDepNames.includes(dep.name))
continue;
privateDeps.push(dep);
}
@@ -197,22 +197,22 @@ function collectAutodetectedData(topLevelProduct)
var depHasPkgConfig = dep.Exporter && dep.Exporter.pkgconfig;
if (depHasPkgConfig) {
var entry = FileInfo.completeBaseName(dep.Exporter.pkgconfig.fileName);
- if (excludedDeps.contains(entry))
+ if (excludedDeps.includes(entry))
return;
- if (isPrivateDep && !data.requiresPrivate.contains(entry)
- && !explicitRequiresPrivate.contains(entry)) {
+ if (isPrivateDep && !data.requiresPrivate.includes(entry)
+ && !explicitRequiresPrivate.includes(entry)) {
data.requiresPrivate.push(entry);
}
- if (!isPrivateDep && !data.requires.contains(entry)
- && !explicitRequires.contains(entry)) {
+ if (!isPrivateDep && !data.requires.includes(entry)
+ && !explicitRequires.includes(entry)) {
data.requires.push(entry);
}
} else {
- if (excludedDeps.contains(dep.name))
+ if (excludedDeps.includes(dep.name))
return;
- if (isPrivateDep && explicitRequiresPrivate.contains(dep.name))
+ if (isPrivateDep && explicitRequiresPrivate.includes(dep.name))
return;
- if (!isPrivateDep && explicitRequires.contains(dep.name))
+ if (!isPrivateDep && explicitRequires.includes(dep.name))
return;
collectAutodetectedDataRecursive(dep, isPrivateDep);
}
diff --git a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs
index 8cc55f885..feb0e017c 100644
--- a/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs
+++ b/share/qbs/modules/Exporter/pkgconfig/pkgconfig.qbs
@@ -34,9 +34,9 @@ Module {
auxiliaryInputs: {
if (!autoDetect)
return undefined;
- if (product.type.contains("staticlibrary"))
+ if (product.type.includes("staticlibrary"))
return ["staticlibrary"];
- if (product.type.contains("dynamiclibrary"))
+ if (product.type.includes("dynamiclibrary"))
return ["dynamiclibrary"];
}
@@ -46,7 +46,7 @@ Module {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() {
var f = new TextFile(output.filePath, TextFile.WriteOnly);
if (product.Exporter.pkgconfig._usePrefix)
diff --git a/share/qbs/modules/Exporter/qbs/qbsexporter.js b/share/qbs/modules/Exporter/qbs/qbsexporter.js
index be46372c3..145474a4b 100644
--- a/share/qbs/modules/Exporter/qbs/qbsexporter.js
+++ b/share/qbs/modules/Exporter/qbs/qbsexporter.js
@@ -30,6 +30,7 @@
var FileInfo = require("qbs.FileInfo");
var ModUtils = require("qbs.ModUtils");
+var ExporterHelpers = require("../exporter.js");
function tagListToString(tagList)
{
@@ -74,7 +75,7 @@ function writeTargetArtifactGroups(product, output, moduleFile)
var tag = product.Exporter.qbs._artifactTypes[i];
var artifactsForTag = product.artifacts[tag] || [];
for (var j = 0; j < artifactsForTag.length; ++j) {
- if (!relevantArtifacts.contains(artifactsForTag[j]))
+ if (!relevantArtifacts.includes(artifactsForTag[j]))
relevantArtifacts.push(artifactsForTag[j]);
}
}
@@ -82,7 +83,7 @@ function writeTargetArtifactGroups(product, output, moduleFile)
var artifactCount = relevantArtifacts ? relevantArtifacts.length : 0;
for (i = 0; i < artifactCount; ++i) {
var artifact = relevantArtifacts[i];
- if (!artifact.fileTags.contains("installable"))
+ if (!artifact.fileTags.includes("installable"))
continue;
// Put all artifacts with the same set of file tags into the same group, so we don't
@@ -102,15 +103,6 @@ function writeTargetArtifactGroups(product, output, moduleFile)
}
}
-function checkValuePrefix(name, value, forbiddenPrefix, prefixDescription)
-{
- if (value.startsWith(forbiddenPrefix)) {
- throw "Value '" + value + "' for exported property '" + name + "' in product '"
- + product.name + "' points into " + prefixDescription + ".\n"
- + "Did you forget to set the prefixMapping property in an Export item?";
- }
-}
-
function stringifyValue(project, product, moduleInstallDir, prop, value)
{
if (value instanceof Array) {
@@ -128,29 +120,9 @@ function stringifyValue(project, product, moduleInstallDir, prop, value)
return value;
}
- // Catch user oversights: Paths that point into the project source or build directories
- // make no sense in the module.
- if (!value.startsWith(product.qbs.installRoot)) {
- checkValuePrefix(prop.name, value, project.buildDirectory, "project build directory");
- checkValuePrefix(prop.name, value, project.sourceDirectory, "project source directory");
- }
-
- // Adapt file paths pointing into the install dir, that is, make them relative to the
- // module file for relocatability. We accept them with or without the install root.
- // The latter form will typically be a result of applying the prefixMapping property,
- // while the first one could be an untransformed path, for instance if the project
- // file is written in such a way that include paths are picked up from the installed
- // location rather than the source directory.
- var valuePrefixToStrip;
- var fullInstallPrefix = FileInfo.joinPaths(product.qbs.installRoot, product.qbs.installPrefix);
- if (fullInstallPrefix.length > 1 && value.startsWith(fullInstallPrefix)) {
- valuePrefixToStrip = fullInstallPrefix;
- } else {
- var installPrefix = FileInfo.joinPaths("/", product.qbs.installPrefix);
- if (installPrefix.length > 1 && value.startsWith(installPrefix))
- valuePrefixToStrip = installPrefix;
- }
+ var valuePrefixToStrip = ExporterHelpers.getPrefixToStrip(project, product, prop.name, value);
if (valuePrefixToStrip) {
+ var fullInstallPrefix = FileInfo.joinPaths(product.qbs.installRoot, product.qbs.installPrefix);
var deployedModuleInstallDir = moduleInstallDir.slice(fullInstallPrefix.length);
return "FileInfo.cleanPath(FileInfo.joinPaths(path, FileInfo.relativePath("
+ JSON.stringify(deployedModuleInstallDir) + ", "
@@ -172,7 +144,7 @@ function writeProperty(project, product, moduleInstallDir, prop, indentation, co
var moduleName;
if (isModuleProperty) {
moduleName = prop.name.slice(0, separatorIndex);
- if ((product.Exporter.qbs.excludedDependencies || []).contains(moduleName))
+ if ((product.Exporter.qbs.excludedDependencies || []).includes(moduleName))
return;
}
line += prop.name + ": ";
@@ -244,7 +216,7 @@ function isExcludedDependency(product, childItem)
for (var i = 0; i < childItem.properties.length; ++i) {
var prop = childItem.properties[i];
var unquotedRhs = prop.sourceCode.slice(1, -1);
- if (prop.name === "name" && product.Exporter.qbs.excludedDependencies.contains(unquotedRhs))
+ if (prop.name === "name" && product.Exporter.qbs.excludedDependencies.includes(unquotedRhs))
return true;
}
return false;
@@ -264,7 +236,7 @@ function writeImportStatements(product, moduleFile)
var imports = product.exports.imports;
// We potentially use FileInfo ourselves when transforming paths in stringifyValue().
- if (!imports.contains("import qbs.FileInfo"))
+ if (!imports.includes("import qbs.FileInfo"))
imports.push("import qbs.FileInfo");
for (var i = 0; i < imports.length; ++i)
diff --git a/share/qbs/modules/Exporter/qbs/qbsexporter.qbs b/share/qbs/modules/Exporter/qbs/qbsexporter.qbs
index b08639e38..1e7cb02d5 100644
--- a/share/qbs/modules/Exporter/qbs/qbsexporter.qbs
+++ b/share/qbs/modules/Exporter/qbs/qbsexporter.qbs
@@ -59,7 +59,7 @@ Module {
}
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = "Creating " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.sourceCode = function() {
var f = new TextFile(output.filePath, TextFile.WriteOnly);
HelperFunctions.writeImportStatements(product, f);
diff --git a/share/qbs/modules/Sanitizers/address/asan.qbs b/share/qbs/modules/Sanitizers/address/asan.qbs
new file mode 100644
index 000000000..9d8f5b97e
--- /dev/null
+++ b/share/qbs/modules/Sanitizers/address/asan.qbs
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 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.Utilities
+
+Module {
+ Depends { name: "cpp" }
+
+ property bool enabled: true
+ readonly property bool _supported: qbs.toolchain.includes("gcc")
+ || qbs.toolchain.includes("clang-cl")
+ || (qbs.toolchain.includes("msvc")
+ && Utilities.versionCompare(cpp.compilerVersion, "19.28.29500.0") >= 0)
+ readonly property bool _enabled: enabled && _supported
+
+ property string detectUseAfterReturn: "always"
+ PropertyOptions {
+ name: "detectUseAfterReturn"
+ description: "Whether to detect problems with stack use after return from a function"
+ allowedValues: ["never", "runtime", "always"]
+ }
+
+ property bool detectUseAfterScope: true
+
+ cpp.driverFlags: {
+ var flags = [];
+ if (!_enabled)
+ return flags;
+ if (qbs.toolchain.includes("msvc") && !qbs.toolchain.includes("clang-cl")) {
+ flags.push("/fsanitize=address");
+ if (detectUseAfterReturn !== "never")
+ flags.push("/fsanitize-address-use-after-return");
+ return flags;
+ }
+ flags.push("-fsanitize=address", "-fno-omit-frame-pointer");
+ if (detectUseAfterScope)
+ flags.push("-fsanitize-address-use-after-scope");
+ if (detectUseAfterReturn) {
+ if (qbs.toolchain.includes("llvm")) {
+ var minVersion = qbs.toolchain.contains("xcode") ? "14" : "13";
+ if (Utilities.versionCompare(cpp.compilerVersion, minVersion) >= 0)
+ flags.push("-fsanitize-address-use-after-return=" + detectUseAfterReturn);
+ } else if (detectUseAfterReturn === "never") {
+ flags.push("--param", "asan-use-after-return=0");
+ }
+ }
+ return flags;
+ }
+}
diff --git a/share/qbs/modules/archiver/archiver.qbs b/share/qbs/modules/archiver/archiver.qbs
index 6ae53dd37..069e76717 100644
--- a/share/qbs/modules/archiver/archiver.qbs
+++ b/share/qbs/modules/archiver/archiver.qbs
@@ -30,6 +30,7 @@
import qbs.Environment
import qbs.File
+import qbs.Host
import qbs.FileInfo
import qbs.Probes
@@ -53,7 +54,7 @@ Module {
names: ["7z"]
platformSearchPaths: {
var paths = base;
- if (qbs.hostOS.contains("windows")) {
+ if (Host.os().includes("windows")) {
var env32 = Environment.getEnv("PROGRAMFILES(X86)");
var env64 = Environment.getEnv("PROGRAMFILES");
if (env64 === env32 && env64.endsWith(" (x86)"))
@@ -211,7 +212,7 @@ Module {
args.push("-0");
} else {
compression = compression === "bz2" ? "bzip2" : compression;
- if (["store", "deflate", "bzip2"].contains(compression))
+ if (["store", "deflate", "bzip2"].includes(compression))
args.push("-Z", compression);
if (compressionLevel)
@@ -220,7 +221,7 @@ Module {
args.push("-r", output.filePath, ".", "-i@" + input.filePath);
args = args.concat(product.moduleProperty("archiver", "flags"));
- } else if (["tar", "zip", "jar"].contains(binaryName)) {
+ } else if (["tar", "zip", "jar"].includes(binaryName)) {
throw binaryName + ": unrecognized archive type: '" + type + "'";
} else if (binaryName) {
throw "unrecognized archive tool: '" + binaryName + "'";
@@ -229,7 +230,7 @@ Module {
}
var archiverCommand = new Command(binary, args);
- archiverCommand.description = "Creating archive file " + output.fileName;
+ archiverCommand.description = "creating archive file " + output.fileName;
archiverCommand.highlight = "linker";
archiverCommand.workingDirectory
= product.moduleProperty("archiver", "workingDirectory");
diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs
index 2568f3435..f640fd55f 100644
--- a/share/qbs/modules/bundle/BundleModule.qbs
+++ b/share/qbs/modules/bundle/BundleModule.qbs
@@ -33,6 +33,7 @@ import qbs.DarwinTools
import qbs.Environment
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.PropertyList
import qbs.TextFile
@@ -46,13 +47,13 @@ Module {
Probe {
id: bundleSettingsProbe
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
property string xcodeDeveloperPath: xcode.developerPath
property var xcodeArchSettings: xcode._architectureSettings
property string productTypeIdentifier: _productTypeIdentifier
- property bool useXcodeBuildSpecs: _useXcodeBuildSpecs
- property bool isMacOs: qbs.targetOS.contains("macos")
+ property bool useXcodeBuildSpecs: !useBuiltinXcodeBuildSpecs
+ property bool isMacOs: qbs.targetOS.includes("macos")
property bool xcodePresent: xcode.present
property string xcodeVersion: xcode.version
@@ -73,9 +74,9 @@ Module {
"LOCAL_LIBRARY_DIR": Environment.getEnv("HOME") + "/Library",
// actually, this is cpp.targetAbi, but XCode does not set it for non-simulator builds
// while Qbs set it to "macho".
- "LLVM_TARGET_TRIPLE_SUFFIX": qbs.targetOS.contains("simulator") ? "-simulator" : "",
+ "LLVM_TARGET_TRIPLE_SUFFIX": qbs.targetOS.includes("simulator") ? "-simulator" : "",
"SWIFT_PLATFORM_TARGET_PREFIX": isMacOs ? "macos"
- : qbs.targetOS.contains("ios") ? "ios" : "",
+ : qbs.targetOS.includes("ios") ? "ios" : "",
"TARGET_BUILD_DIR": product.buildDirectory,
"WRAPPER_NAME": bundleName,
"WRAPPER_EXTENSION": extension
@@ -117,7 +118,7 @@ Module {
additionalProductTypes: !(product.multiplexed || product.aggregate)
|| !product.multiplexConfigurationId ? ["bundle.content"] : []
- property bool isBundle: !product.consoleApplication && qbs.targetOS.contains("darwin")
+ property bool isBundle: !product.consoleApplication && qbs.targetOS.includes("darwin")
readonly property bool isShallow: bundleSettingsProbe.xcodeSettings["SHALLOW_BUNDLE"] === "YES"
@@ -151,7 +152,7 @@ Module {
property var infoPlist
property bool processInfoPlist: true
property bool embedInfoPlist: product.consoleApplication && !isBundle
- property string infoPlistFormat: qbs.targetOS.contains("macos") ? "same-as-input" : "binary1"
+ property string infoPlistFormat: qbs.targetOS.includes("macos") ? "same-as-input" : "binary1"
property string localizedResourcesFolderSuffix: ".lproj"
@@ -186,11 +187,18 @@ Module {
readonly property string unlocalizedResourcesFolderPath: bundleSettingsProbe.xcodeSettings["UNLOCALIZED_RESOURCES_FOLDER_PATH"]
readonly property string versionsFolderPath: bundleSettingsProbe.xcodeSettings["VERSIONS_FOLDER_PATH"]
+ property bool useBuiltinXcodeBuildSpecs: !_useXcodeBuildSpecs // true to use ONLY the qbs build specs
+
// private properties
property string _productTypeIdentifier: Bundle.productTypeIdentifier(product.type)
property stringList _productTypeIdentifierChain: bundleSettingsProbe.productTypeIdentifierChain
- property bool _useXcodeBuildSpecs: true // false to use ONLY the qbs build specs
+ readonly property path _developerPath: xcode.developerPath
+ readonly property path _platformInfoPlist: xcode.platformInfoPlist
+ readonly property path _sdkSettingsPlist: xcode.sdkSettingsPlist
+ readonly property path _toolchainInfoPlist: xcode.toolchainInfoPlist
+
+ property bool _useXcodeBuildSpecs: true // TODO: remove in 1.25
property var extraEnv: ({
"PRODUCT_BUNDLE_IDENTIFIER": identifier
@@ -224,7 +232,7 @@ Module {
}
validate: {
- if (!qbs.targetOS.contains("darwin"))
+ if (!qbs.targetOS.includes("darwin"))
return;
if (!bundleSettingsProbe.found) {
var error = "Bundle product type " + _productTypeIdentifier + " is not supported.";
@@ -270,7 +278,7 @@ Module {
}
Rule {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
multiplex: true
requiresInputs: false // TODO: The resources property should probably be a tag instead.
inputs: ["infoplist", "partial_infoplist"]
@@ -278,8 +286,8 @@ Module {
outputFileTags: ["bundle.input", "aggregate_infoplist"]
outputArtifacts: {
var artifacts = [];
- var embed = ModUtils.moduleProperty(product, "embedInfoPlist");
- if (ModUtils.moduleProperty(product, "isBundle") || embed) {
+ var embed = product.bundle.embedInfoPlist;
+ if (product.bundle.isBundle || embed) {
artifacts.push({
filePath: FileInfo.joinPaths(
product.destinationDirectory, product.name + "-Info.plist"),
@@ -287,7 +295,7 @@ Module {
bundle: {
_bundleFilePath: FileInfo.joinPaths(
product.destinationDirectory,
- ModUtils.moduleProperty(product, "infoPlistPath")),
+ product.bundle.infoPlistPath),
}
});
}
@@ -298,20 +306,21 @@ Module {
var cmd = new JavaScriptCommand();
cmd.description = "generating Info.plist for " + product.name;
cmd.highlight = "codegen";
- cmd.infoPlist = ModUtils.moduleProperty(product, "infoPlist") || {};
- cmd.processInfoPlist = ModUtils.moduleProperty(product, "processInfoPlist");
- cmd.infoPlistFormat = ModUtils.moduleProperty(product, "infoPlistFormat");
- cmd.extraEnv = ModUtils.moduleProperty(product, "extraEnv");
- cmd.qmakeEnv = ModUtils.moduleProperty(product, "qmakeEnv");
+ cmd.infoPlist = product.bundle.infoPlist || {};
+ cmd.processInfoPlist = product.bundle.processInfoPlist;
+ cmd.infoPlistFormat = product.bundle.infoPlistFormat;
+ cmd.extraEnv = product.bundle.extraEnv;
+ cmd.qmakeEnv = product.bundle.qmakeEnv;
+ // TODO: bundle module should know nothing about cpp module
cmd.buildEnv = product.moduleProperty("cpp", "buildEnv");
- cmd.developerPath = product.moduleProperty("xcode", "developerPath");
- cmd.platformInfoPlist = product.moduleProperty("xcode", "platformInfoPlist");
- cmd.sdkSettingsPlist = product.moduleProperty("xcode", "sdkSettingsPlist");
- cmd.toolchainInfoPlist = product.moduleProperty("xcode", "toolchainInfoPlist");
+ cmd.developerPath = product.bundle._developerPath;
+ cmd.platformInfoPlist = product.bundle._platformInfoPlist;
+ cmd.sdkSettingsPlist = product.bundle._sdkSettingsPlist;
+ cmd.toolchainInfoPlist = product.bundle._toolchainInfoPlist;
- cmd.osBuildVersion = product.moduleProperty("qbs", "hostOSBuildVersion");
+ cmd.osBuildVersion = product.qbs.hostOSBuildVersion;
cmd.sourceCode = function() {
var plist, process, key, i;
@@ -340,7 +349,7 @@ Module {
if (processInfoPlist) {
// Add default values to the aggregate plist if the corresponding keys
// for those values are not already present
- var defaultValues = ModUtils.moduleProperty(product, "defaultInfoPlist");
+ var defaultValues = product.bundle.defaultInfoPlist;
for (key in defaultValues) {
if (defaultValues.hasOwnProperty(key) && !(key in aggregatePlist))
aggregatePlist[key] = defaultValues[key];
@@ -452,7 +461,7 @@ Module {
infoPlistFormat = "xml1";
var validFormats = [ "xml1", "binary1", "json" ];
- if (!validFormats.contains(infoPlistFormat))
+ if (!validFormats.includes(infoPlistFormat))
throw("Invalid Info.plist format " + infoPlistFormat + ". " +
"Must be in [xml1, binary1, json].");
@@ -470,18 +479,18 @@ Module {
}
Rule {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
multiplex: true
inputs: ["aggregate_infoplist"]
outputFileTags: ["bundle.input", "pkginfo"]
outputArtifacts: {
var artifacts = [];
- if (ModUtils.moduleProperty(product, "isBundle") && ModUtils.moduleProperty(product, "generatePackageInfo")) {
+ if (product.bundle.isBundle && product.bundle.generatePackageInfo) {
artifacts.push({
filePath: FileInfo.joinPaths(product.destinationDirectory, "PkgInfo"),
fileTags: ["bundle.input", "pkginfo"],
- bundle: { _bundleFilePath: FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "pkgInfoPath")) }
+ bundle: { _bundleFilePath: FileInfo.joinPaths(product.destinationDirectory, product.bundle.pkgInfoPath) }
});
}
return artifacts;
@@ -511,7 +520,7 @@ Module {
}
Rule {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
multiplex: true
inputs: ["bundle.input",
"aggregate_infoplist", "pkginfo", "hpp",
@@ -532,12 +541,12 @@ Module {
"bundle.code-signature"]
outputArtifacts: {
var i, artifacts = [];
- if (ModUtils.moduleProperty(product, "isBundle")) {
+ if (product.bundle.isBundle) {
for (i in inputs["bundle.input"]) {
- var fp = inputs["bundle.input"][i].moduleProperty("bundle", "_bundleFilePath");
+ var fp = inputs["bundle.input"][i].bundle._bundleFilePath;
if (!fp)
throw("Artifact " + inputs["bundle.input"][i].filePath + " has no associated bundle file path");
- var extraTags = inputs["bundle.input"][i].fileTags.contains("application")
+ var extraTags = inputs["bundle.input"][i].fileTags.includes("application")
? ["bundle.application-executable"] : [];
artifacts.push({
filePath: fp,
@@ -549,20 +558,19 @@ Module {
for (i in provprofiles) {
artifacts.push({
filePath: FileInfo.joinPaths(product.destinationDirectory,
- ModUtils.moduleProperty(product,
- "contentsFolderPath"),
+ product.bundle.contentsFolderPath,
provprofiles[i].fileName),
fileTags: ["bundle.provisioningprofile", "bundle.content"]
});
}
- var packageType = ModUtils.moduleProperty(product, "packageType");
- var isShallow = ModUtils.moduleProperty(product, "isShallow");
+ var packageType = product.bundle.packageType;
+ var isShallow = product.bundle.isShallow;
if (packageType === "FMWK" && !isShallow) {
- var publicHeaders = ModUtils.moduleProperty(product, "publicHeaders");
+ var publicHeaders = product.bundle.publicHeaders;
if (publicHeaders && publicHeaders.length) {
artifacts.push({
- filePath: FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "bundleName"), "Headers"),
+ filePath: FileInfo.joinPaths(product.destinationDirectory, product.bundle.bundleName, "Headers"),
fileTags: ["bundle.symlink.headers", "bundle.content"]
});
}
@@ -570,23 +578,23 @@ Module {
var privateHeaders = ModUtils.moduleProperty(product, "privateHeaders");
if (privateHeaders && privateHeaders.length) {
artifacts.push({
- filePath: FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "bundleName"), "PrivateHeaders"),
+ filePath: FileInfo.joinPaths(product.destinationDirectory, product.bundle.bundleName, "PrivateHeaders"),
fileTags: ["bundle.symlink.private-headers", "bundle.content"]
});
}
artifacts.push({
- filePath: FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "bundleName"), "Resources"),
+ filePath: FileInfo.joinPaths(product.destinationDirectory, product.bundle.bundleName, "Resources"),
fileTags: ["bundle.symlink.resources", "bundle.content"]
});
artifacts.push({
- filePath: FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "bundleName"), product.targetName),
+ filePath: FileInfo.joinPaths(product.destinationDirectory, product.bundle.bundleName, product.targetName),
fileTags: ["bundle.symlink.executable", "bundle.content"]
});
artifacts.push({
- filePath: FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "versionsFolderPath"), "Current"),
+ filePath: FileInfo.joinPaths(product.destinationDirectory, product.bundle.versionsFolderPath, "Current"),
fileTags: ["bundle.symlink.version", "bundle.content"]
});
}
@@ -603,7 +611,7 @@ Module {
}
}
- sources = ModUtils.moduleProperty(product, "resources");
+ sources = product.bundle.resources;
for (i in sources) {
destination = BundleTools.destinationDirectoryForResource(product, {baseDir: FileInfo.path(sources[i]), fileName: FileInfo.fileName(sources[i])});
artifacts.push({
@@ -614,11 +622,11 @@ Module {
var wrapperPath = FileInfo.joinPaths(
product.destinationDirectory,
- ModUtils.moduleProperty(product, "bundleName"));
+ product.bundle.bundleName);
for (var i = 0; i < artifacts.length; ++i)
artifacts[i].bundle = { wrapperPath: wrapperPath };
- if (product.qbs.hostOS.contains("darwin") && product.codesign
+ if (Host.os().includes("darwin") && product.codesign
&& product.codesign.enableCodeSigning) {
artifacts.push({
filePath: FileInfo.joinPaths(product.bundle.contentsFolderPath, "_CodeSignature/CodeResources"),
@@ -631,7 +639,7 @@ Module {
prepare: {
var i, cmd, commands = [];
- var packageType = ModUtils.moduleProperty(product, "packageType");
+ var packageType = product.bundle.packageType;
var bundleType = "bundle";
if (packageType === "APPL")
@@ -649,7 +657,7 @@ Module {
var symlinks = outputs["bundle.symlink.version"];
for (i in symlinks) {
- cmd = new Command("ln", ["-sfn", ModUtils.moduleProperty(product, "frameworkVersion"),
+ cmd = new Command("ln", ["-sfn", product.bundle.frameworkVersion,
symlinks[i].filePath]);
cmd.silent = true;
commands.push(cmd);
@@ -696,8 +704,8 @@ Module {
}
var bundleInputs = sortedArtifactList(inputs["bundle.input"], function (a, b) {
- return a.moduleProperty("bundle", "_bundleFilePath").localeCompare(
- b.moduleProperty("bundle", "_bundleFilePath"));
+ return a.bundle._bundleFilePath.localeCompare(
+ b.bundle._bundleFilePath);
});
var bundleContents = sortedArtifactList(outputs["bundle.content.copied"]);
for (i in bundleContents) {
@@ -730,8 +738,8 @@ Module {
cmd = new JavaScriptCommand();
cmd.description = "copying public headers";
cmd.highlight = "filegen";
- cmd.sources = ModUtils.moduleProperty(product, "publicHeaders");
- cmd.destination = FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "publicHeadersFolderPath"));
+ cmd.sources = product.bundle.publicHeaders;
+ cmd.destination = FileInfo.joinPaths(product.destinationDirectory, product.bundle.publicHeadersFolderPath);
cmd.sourceCode = function() {
var i;
for (var i in sources) {
@@ -744,8 +752,8 @@ Module {
cmd = new JavaScriptCommand();
cmd.description = "copying private headers";
cmd.highlight = "filegen";
- cmd.sources = ModUtils.moduleProperty(product, "privateHeaders");
- cmd.destination = FileInfo.joinPaths(product.destinationDirectory, ModUtils.moduleProperty(product, "privateHeadersFolderPath"));
+ cmd.sources = product.bundle.privateHeaders;
+ cmd.destination = FileInfo.joinPaths(product.destinationDirectory, product.bundle.privateHeadersFolderPath);
cmd.sourceCode = function() {
var i;
for (var i in sources) {
@@ -758,7 +766,7 @@ Module {
cmd = new JavaScriptCommand();
cmd.description = "copying resources";
cmd.highlight = "filegen";
- cmd.sources = ModUtils.moduleProperty(product, "resources");
+ cmd.sources = product.bundle.resources;
cmd.sourceCode = function() {
var i;
for (var i in sources) {
@@ -769,15 +777,17 @@ Module {
if (cmd.sources && cmd.sources.length)
commands.push(cmd);
- if (product.moduleProperty("qbs", "hostOS").contains("darwin")) {
+ if (product.qbs.hostOS.includes("darwin")) {
Array.prototype.push.apply(commands, Codesign.prepareSign(
project, product, inputs, outputs, input, output));
if (bundleType === "application"
- && product.moduleProperty("qbs", "targetOS").contains("macos")) {
- cmd = new Command(ModUtils.moduleProperty(product, "lsregisterPath"),
- ["-f", product.bundle.bundleName]);
- cmd.description = "register " + ModUtils.moduleProperty(product, "bundleName");
+ && product.qbs.targetOS.includes("macos")) {
+ var bundlePath = FileInfo.joinPaths(
+ product.destinationDirectory, product.bundle.bundleName);
+ cmd = new Command(product.bundle.lsregisterPath,
+ ["-f", bundlePath]);
+ cmd.description = "registering " + product.bundle.bundleName;
commands.push(cmd);
}
}
diff --git a/share/qbs/modules/bundle/bundle.js b/share/qbs/modules/bundle/bundle.js
index 293f53225..cf765f7be 100644
--- a/share/qbs/modules/bundle/bundle.js
+++ b/share/qbs/modules/bundle/bundle.js
@@ -83,7 +83,7 @@ var _productTypeIdentifiers = {
function productTypeIdentifier(productType) {
for (var k in _productTypeIdentifiers) {
- if (productType.contains(k))
+ if (productType.includes(k))
return _productTypeIdentifiers[k];
}
return "com.apple.package-type.wrapper";
@@ -152,13 +152,21 @@ function _assign(target, source) {
function macOSSpecsPaths(version, developerPath) {
var result = [];
- if (Utilities.versionCompare(version, "12.5") >= 0) {
+ if (Utilities.versionCompare(version, "15.3") >= 0) {
+ result.push(FileInfo.joinPaths(
+ developerPath, "..", "SharedFrameworks", "XCBuild.framework", "PlugIns",
+ "XCBBuildService.bundle", "Contents", "PlugIns", "XCBSpecifications.ideplugin",
+ "Contents", "Resources"));
+ }
+ if (Utilities.versionCompare(version, "14.3") >= 0) {
+ result.push(FileInfo.joinPaths(
+ developerPath, "Library", "Xcode", "Plug-ins", "XCBSpecifications.ideplugin",
+ "Contents", "Resources"));
+ } else if (Utilities.versionCompare(version, "12.5") >= 0) {
result.push(FileInfo.joinPaths(
developerPath, "..", "PlugIns", "XCBSpecifications.ideplugin",
"Contents", "Resources"));
- }
-
- if (Utilities.versionCompare(version, "12") >= 0) {
+ } else if (Utilities.versionCompare(version, "12") >= 0) {
result.push(FileInfo.joinPaths(
developerPath, "Platforms", "MacOSX.platform", "Developer", "Library", "Xcode",
"PrivatePlugIns", "IDEOSXSupportCore.ideplugin", "Contents", "Resources"));
@@ -181,15 +189,15 @@ var XcodeBuildSpecsReader = (function () {
var i, j;
for (i = 0; i < specsPaths.length; ++i) {
var specsPath = specsPaths[i];
- var names = ["Darwin", "MacOSX"];
+ var names = ["", "Darwin", "MacOSX"];
for (j = 0; j < names.length; ++j) {
var name = names[j];
var plist = new PropertyList2();
var plist2 = new PropertyList2();
try
{
- var plistName = [name, "Package", "Types.xcspec"].join(separator);
- var plistName2 = [name, "Product", "Types.xcspec"].join(separator);
+ var plistName = [name, "Package", "Types.xcspec"].join(name ? separator : "");
+ var plistName2 = [name, "Product", "Types.xcspec"].join(name ? separator : "");
var plistPath = FileInfo.joinPaths(specsPath, plistName);
var plistPath2 = FileInfo.joinPaths(specsPath, plistName2);
if (File.exists(plistPath)) {
@@ -311,7 +319,8 @@ var XcodeBuildSpecsReader = (function () {
};
XcodeBuildSpecsReader.prototype.expandedSetting = function (typeIdentifier, baseSettings,
settingName) {
- var obj = baseSettings || {};
+ var obj = {};
+ _assign(obj, baseSettings); // todo: copy recursively
obj = _assign(obj, this.settings(typeIdentifier, true));
if (obj) {
for (var x in this._additionalSettings) {
diff --git a/share/qbs/modules/capnproto/capnprotobase.qbs b/share/qbs/modules/capnproto/capnprotobase.qbs
index e84d39433..916e53a51 100644
--- a/share/qbs/modules/capnproto/capnprotobase.qbs
+++ b/share/qbs/modules/capnproto/capnprotobase.qbs
@@ -28,6 +28,7 @@
**
****************************************************************************/
+import qbs.FileInfo
import qbs.Probes
import "capnproto.js" as HelperFunctions
@@ -40,16 +41,20 @@ Module {
property pathList importPaths: []
- readonly property string outputDir: product.buildDirectory + "/capnp"
+ property string outputDir: product.buildDirectory + "/capnp"
+
+ property var _searchPaths
Probes.BinaryProbe {
id: compilerProbe
names: compilerName ? [compilerName] : []
+ searchPaths: _searchPaths
}
Probes.BinaryProbe {
id: pluginProbe
names: pluginName ? [pluginName] : []
+ searchPaths: _searchPaths
}
FileTagger {
diff --git a/share/qbs/modules/capnproto/cpp/capnprotocpp.qbs b/share/qbs/modules/capnproto/cpp/capnprotocpp.qbs
index f33bc9a48..83192b7de 100644
--- a/share/qbs/modules/capnproto/cpp/capnprotocpp.qbs
+++ b/share/qbs/modules/capnproto/cpp/capnprotocpp.qbs
@@ -39,6 +39,8 @@ CapnProtoBase {
Depends { name: "capnp-rpc"; condition: useRpc }
pluginName: "capnpc-c++"
+ version: capnp.version
+ _searchPaths: capnp.hostBinDirs
cpp.systemIncludePaths: outputDir
cpp.cxxLanguageVersion: "c++14"
diff --git a/share/qbs/modules/cli/CLIModule.qbs b/share/qbs/modules/cli/CLIModule.qbs
index cea4c09ca..3b12284ed 100644
--- a/share/qbs/modules/cli/CLIModule.qbs
+++ b/share/qbs/modules/cli/CLIModule.qbs
@@ -1,12 +1,13 @@
// base for Common Language Infrastructure modules
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import "cli.js" as CLI
Module {
- Depends { name: "bundle"; condition: qbs.targetOS.contains("darwin") }
+ Depends { name: "bundle"; condition: qbs.targetOS.includes("darwin") }
Properties {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
bundle.isBundle: false
}
@@ -87,8 +88,8 @@ Module {
}
setupBuildEnvironment: {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator,
- product.qbs.hostOS.contains("windows"));
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(),
+ Host.os().includes("windows"));
v.prepend(product.cli.toolchainInstallPath);
v.set();
}
diff --git a/share/qbs/modules/cli/cli.js b/share/qbs/modules/cli/cli.js
index 38833ac51..faa812201 100644
--- a/share/qbs/modules/cli/cli.js
+++ b/share/qbs/modules/cli/cli.js
@@ -59,16 +59,16 @@ function prepareCompiler(product, inputs, output) {
"cli.fsharp": fsharpCompilerPath
};
- var pathFunction = product.moduleProperty("qbs", "hostOS").contains("windows")
+ var pathFunction = product.moduleProperty("qbs", "hostOS").includes("windows")
? FileInfo.toWindowsSeparators
: function (path) { return path; };
var outputDescription = "assembly";
- if (output.fileTags.contains("application")) {
+ if (output.fileTags.includes("application")) {
args.push("/target:" + (product.consoleApplication === false ? "winexe" : "exe"));
- } else if (output.fileTags.contains("dynamiclibrary")) {
+ } else if (output.fileTags.includes("dynamiclibrary")) {
args.push("/target:library");
- } else if (output.fileTags.contains("cli.netmodule")) {
+ } else if (output.fileTags.includes("cli.netmodule")) {
args.push("/target:module");
outputDescription = "netmodule";
}
@@ -77,7 +77,7 @@ function prepareCompiler(product, inputs, output) {
var keys = Object.keys(inputs);
var language;
for (i in keys) {
- if (Object.keys(compilers).contains(keys[i])) {
+ if (Object.keys(compilers).includes(keys[i])) {
if (language)
throw("You cannot compile source files in more than one CLI language into a single " + outputDescription + ".");
language = keys[i];
diff --git a/share/qbs/modules/cli/mono.qbs b/share/qbs/modules/cli/mono.qbs
index f04956a5e..f16387dd7 100644
--- a/share/qbs/modules/cli/mono.qbs
+++ b/share/qbs/modules/cli/mono.qbs
@@ -1,8 +1,9 @@
import qbs.File
+import qbs.Host
import qbs.Probes
CLIModule {
- condition: qbs.toolchain && qbs.toolchain.contains("mono")
+ condition: qbs.toolchain && qbs.toolchain.includes("mono")
debugInfoSuffix: ".mdb"
csharpCompilerName: "mcs"
@@ -14,9 +15,9 @@ CLIModule {
names: ["mono"]
platformSearchPaths: {
var paths = [];
- if (qbs.hostOS.contains("macos"))
+ if (Host.os().includes("macos"))
paths.push("/Library/Frameworks/Mono.framework/Commands");
- if (qbs.hostOS.contains("unix"))
+ if (Host.os().includes("unix"))
paths.push("/usr/bin");
return paths;
}
diff --git a/share/qbs/modules/cli/windows-dotnet.qbs b/share/qbs/modules/cli/windows-dotnet.qbs
index 6fde50b85..a4d27c207 100644
--- a/share/qbs/modules/cli/windows-dotnet.qbs
+++ b/share/qbs/modules/cli/windows-dotnet.qbs
@@ -1,7 +1,7 @@
import qbs.Utilities
CLIModule {
- condition: qbs.toolchain && qbs.toolchain.contains("dotnet")
+ condition: qbs.toolchain && qbs.toolchain.includes("dotnet")
debugInfoSuffix: ".pdb"
csharpCompilerName: "csc"
diff --git a/share/qbs/modules/codesign/android.qbs b/share/qbs/modules/codesign/android.qbs
index f4535aa9c..b1811dcfd 100644
--- a/share/qbs/modules/codesign/android.qbs
+++ b/share/qbs/modules/codesign/android.qbs
@@ -31,12 +31,13 @@
import qbs.Environment
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Probes
import "codesign.js" as CodeSign
CodeSignModule {
- condition: qbs.targetOS.contains("android")
+ condition: qbs.targetOS.includes("android")
priority: 1
enableCodeSigning: true
@@ -54,7 +55,7 @@ CodeSignModule {
property string keytoolName: "keytool"
property string debugKeystorePath: FileInfo.joinPaths(
- Environment.getEnv(qbs.hostOS.contains("windows")
+ Environment.getEnv(Host.os().includes("windows")
? "USERPROFILE" : "HOME"),
".android", "debug.keystore")
readonly property string debugKeystorePassword: "android"
diff --git a/share/qbs/modules/codesign/apple.qbs b/share/qbs/modules/codesign/apple.qbs
index 4340e3037..0d1335d92 100644
--- a/share/qbs/modules/codesign/apple.qbs
+++ b/share/qbs/modules/codesign/apple.qbs
@@ -34,6 +34,7 @@ import qbs.DarwinTools
import qbs.Environment
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.PropertyList
import qbs.Probes
@@ -42,14 +43,14 @@ import "codesign.js" as CodeSign
import "../xcode/xcode.js" as XcodeUtils
CodeSignModule {
- Depends { name: "xcode"; required: qbs.toolchain && qbs.toolchain.contains("xcode") }
+ Depends { name: "xcode"; required: qbs.toolchain && qbs.toolchain.includes("xcode") }
Probes.BinaryProbe {
id: codesignProbe
names: [codesignName]
}
- condition: qbs.hostOS.contains("macos") && qbs.targetOS.contains("darwin")
+ condition: Host.os().includes("macos") && qbs.targetOS.includes("darwin")
priority: 0
enableCodeSigning: _codeSigningRequired
@@ -77,15 +78,15 @@ CodeSignModule {
var isDebug = qbs.buildVariant !== "release";
- if (qbs.targetOS.contains("ios") || qbs.targetOS.contains("tvos")
- || qbs.targetOS.contains("watchos")) {
+ if (qbs.targetOS.includes("ios") || qbs.targetOS.includes("tvos")
+ || qbs.targetOS.includes("watchos")) {
switch (signingType) {
case "app-store":
return isDebug ? "iPhone Developer" : "iPhone Distribution";
}
}
- if (qbs.targetOS.contains("macos")) {
+ if (qbs.targetOS.includes("macos")) {
switch (signingType) {
case "app-store":
return isDebug ? "Mac Developer" : "3rd Party Mac Developer Application";
@@ -160,27 +161,27 @@ CodeSignModule {
readonly property bool _provisioningProfileAllowed:
product.bundle
&& product.bundle.isBundle
- && product.type.contains("application")
+ && product.type.includes("application")
&& xcode.platformType !== "simulator"
// Required for tvOS, iOS, and watchOS (not simulators)
// PROVISIONING_PROFILE_REQUIRED is specified only in Embedded-Device.xcspec in the
// IDEiOSSupportCore IDE plugin, so we'll just write out the logic here manually
readonly property bool _provisioningProfileRequired:
- _provisioningProfileAllowed && !qbs.targetOS.contains("macos")
+ _provisioningProfileAllowed && !qbs.targetOS.includes("macos")
// Not used on simulator platforms either but provisioning profiles aren't used there anyways
readonly property string _provisioningProfilePlatform: {
- if (qbs.targetOS.contains("macos"))
+ if (qbs.targetOS.includes("macos"))
return "OSX";
- if (qbs.targetOS.contains("ios") || qbs.targetOS.contains("watchos"))
+ if (qbs.targetOS.includes("ios") || qbs.targetOS.includes("watchos"))
return "iOS";
- if (qbs.targetOS.contains("tvos"))
+ if (qbs.targetOS.includes("tvos"))
return "tvOS";
}
readonly property string _embeddedProfileName:
- (xcode._platformProps || {})["EMBEDDED_PROFILE_NAME"]
+ (xcode._platformProps || {})["EMBEDDED_PROFILE_NAME"] || "embedded.mobileprovision"
setupBuildEnvironment: {
var prefixes = product.xcode ? [
diff --git a/share/qbs/modules/codesign/codesign.js b/share/qbs/modules/codesign/codesign.js
index 463e7cbb7..482225ea2 100644
--- a/share/qbs/modules/codesign/codesign.js
+++ b/share/qbs/modules/codesign/codesign.js
@@ -43,10 +43,12 @@ function findSigningIdentities(searchString, team) {
var matchedIdentities = {};
for (var key in identities) {
var identity = identities[key];
- if (team && ![identity.subjectInfo.O, identity.subjectInfo.OU].contains(team))
+ if (team && ![identity.subjectInfo.O, identity.subjectInfo.OU].includes(team))
continue;
- if (searchString === key || identity.subjectInfo.CN.startsWith(searchString))
+ if (searchString === key
+ || (identity.subjectInfo.CN && identity.subjectInfo.CN.startsWith(searchString))) {
matchedIdentities[key] = identity;
+ }
}
return matchedIdentities;
}
@@ -103,7 +105,7 @@ function findBestProvisioningProfile(product, files) {
// Provisioning profiles are not normally used with ad-hoc code signing or non-apps
// We do these checks down here only for the automatic selection but not above because
// if the user explicitly selects a provisioning profile it should be used no matter what
- if (actualSigningIdentity.SHA1 === "-" || !product.type.contains("application"))
+ if (actualSigningIdentity.SHA1 === "-" || !product.type.includes("application"))
return undefined;
// Filter out any provisioning profiles we know to be unsuitable from the start
@@ -114,7 +116,7 @@ function findBestProvisioningProfile(product, files) {
var certCommonNames = (data["DeveloperCertificates"] || []).map(function (cert) {
return Utilities.certificateInfo(cert).subjectInfo.CN;
});
- if (!certCommonNames.contains(actualSigningIdentity.subjectInfo.CN)) {
+ if (!certCommonNames.includes(actualSigningIdentity.subjectInfo.CN)) {
console.log("Skipping provisioning profile with no matching certificate names for '"
+ actualSigningIdentity.subjectInfo.CN
+ "' (found " + certCommonNames.join(", ") + "): "
@@ -124,7 +126,7 @@ function findBestProvisioningProfile(product, files) {
}
var platforms = data["Platform"] || [];
- if (platforms.length > 0 && profilePlatform && !platforms.contains(profilePlatform)) {
+ if (platforms.length > 0 && profilePlatform && !platforms.includes(profilePlatform)) {
console.log("Skipping provisioning profile for platform " + platforms.join(", ")
+ " (current platform " + profilePlatform + ")"
+ ": " + profile.filePath);
@@ -132,7 +134,7 @@ function findBestProvisioningProfile(product, files) {
}
if (teamIdentifier
- && !data["TeamIdentifier"].contains(teamIdentifier)
+ && !data["TeamIdentifier"].includes(teamIdentifier)
&& data["TeamName"] !== teamIdentifier) {
console.log("Skipping provisioning profile for team " + data["TeamIdentifier"]
+ " (" + data["TeamName"] + ") (current team " + teamIdentifier + ")"
@@ -223,7 +225,7 @@ function findBestSignToolSearchPaths(arch) {
});
function addSearchPath(searchPath) {
- if (File.exists(searchPath) && !searchPaths.contains(searchPath)) {
+ if (File.exists(searchPath) && !searchPaths.includes(searchPath)) {
searchPaths.push(searchPath);
return true;
}
@@ -278,20 +280,21 @@ function prepareSign(project, product, inputs, outputs, input, output) {
return cmds;
var isBundle = "bundle.content" in outputs;
- var outputFilePath = isBundle
- ? FileInfo.joinPaths(product.destinationDirectory, product.bundle.bundleName)
- : outputs["codesign.signed_artifact"][0].filePath;
- var outputFileName = isBundle
- ? product.bundle.bundleName
- : outputs["codesign.signed_artifact"][0].fileName;
- var isProductBundle = product.bundle && product.bundle.isBundle;
- // If the product is a bundle, just sign the bundle
- // instead of signing the bundle and executable separately
+ var artifacts = [];
+ if (isBundle) {
+ artifacts = [{
+ filePath: FileInfo.joinPaths(product.destinationDirectory, product.bundle.bundleName),
+ fileName: product.bundle.bundleName
+ }];
+ } else {
+ artifacts = outputs["codesign.signed_artifact"];
+ }
+ var isProductBundle = product.bundle && product.bundle.isBundle;
var shouldSignArtifact = !isProductBundle || isBundle;
var enableCodeSigning = product.codesign.enableCodeSigning;
- if (enableCodeSigning && shouldSignArtifact) {
+ if (enableCodeSigning) {
var actualSigningIdentity = product.codesign._actualSigningIdentity;
if (!actualSigningIdentity) {
throw "No codesigning identities (i.e. certificate and private key pairs) matching ā€œ"
@@ -308,36 +311,53 @@ function prepareSign(project, product, inputs, outputs, input, output) {
}
}
- var args = ["--force", "--sign", actualSigningIdentity.SHA1];
-
- // If signingTimestamp is undefined or empty, do not specify the flag at all -
- // this uses the system-specific default behavior
- var signingTimestamp = product.codesign.signingTimestamp;
- if (signingTimestamp) {
- // If signingTimestamp is an empty string, specify the flag but do
- // not specify a value - this uses a default Apple-provided server
- var flag = "--timestamp";
- if (signingTimestamp)
- flag += "=" + signingTimestamp;
- args.push(flag);
+ // The codesign tool behaves weirdly. It can sign a bundle with a single artifact, but if
+ // say debug build variant is present, it starts complaining that it is not signed.
+ // We could always sign everything, but again, in case of a framework (but not in case of
+ // app or loadable bundle), codesign produces a warning that artifact is already signed.
+ // So, we skip signing the release artifact and only sign if other build variants present.
+ if (!shouldSignArtifact && artifacts.length == 1) {
+ artifacts = [];
}
+ for (var i = 0; i < artifacts.length; ++i) {
+ if (!shouldSignArtifact
+ && artifacts[i].qbs && artifacts[i].qbs.buildVariant === "release") {
+ continue;
+ }
+ var outputFilePath = artifacts[i].filePath;
+ var outputFileName = artifacts[i].fileName;
+
+ var args = ["--force", "--sign", actualSigningIdentity.SHA1];
+
+ // If signingTimestamp is undefined or empty, do not specify the flag at all -
+ // this uses the system-specific default behavior
+ var signingTimestamp = product.codesign.signingTimestamp;
+ if (signingTimestamp) {
+ // If signingTimestamp is an empty string, specify the flag but do
+ // not specify a value - this uses a default Apple-provided server
+ var flag = "--timestamp";
+ if (signingTimestamp)
+ flag += "=" + signingTimestamp;
+ args.push(flag);
+ }
- for (var j in inputs["codesign.xcent"]) {
- args.push("--entitlements", inputs["codesign.xcent"][j].filePath);
- break; // there should only be one
- }
+ for (var j in inputs["codesign.xcent"]) {
+ args.push("--entitlements", inputs["codesign.xcent"][j].filePath);
+ break; // there should only be one
+ }
- args = args.concat(product.codesign.codesignFlags || []);
+ args = args.concat(product.codesign.codesignFlags || []);
- args.push(outputFilePath + subpath);
- cmd = new Command(product.codesign.codesignPath, args);
- cmd.description = "codesign " + outputFileName
- + " (" + actualSigningIdentity.subjectInfo.CN + ")";
- cmd.outputFilePath = outputFilePath;
- cmd.stderrFilterFunction = function(stderr) {
- return stderr.replace(outputFilePath + ": replacing existing signature\n", "");
- };
- cmds.push(cmd);
+ args.push(outputFilePath + subpath);
+ cmd = new Command(product.codesign.codesignPath, args);
+ cmd.description = "codesign " + outputFileName
+ + " (" + actualSigningIdentity.subjectInfo.CN + ")";
+ cmd.outputFilePath = outputFilePath;
+ cmd.stderrFilterFunction = function(stderr) {
+ return stderr.replace(outputFilePath + ": replacing existing signature\n", "");
+ };
+ cmds.push(cmd);
+ }
}
if (isBundle) {
diff --git a/share/qbs/modules/codesign/signtool.qbs b/share/qbs/modules/codesign/signtool.qbs
index afc91e7fc..111f0a307 100644
--- a/share/qbs/modules/codesign/signtool.qbs
+++ b/share/qbs/modules/codesign/signtool.qbs
@@ -29,21 +29,22 @@
****************************************************************************/
import qbs.File
+import qbs.Host
import qbs.ModUtils
import qbs.Probes
import "codesign.js" as CODESIGN
CodeSignModule {
- condition: qbs.targetOS.contains("windows")
- && qbs.hostOS.contains("windows")
- && qbs.toolchain.contains("msvc")
+ condition: qbs.targetOS.includes("windows")
+ && Host.os().includes("windows")
+ && qbs.toolchain.includes("msvc")
_canSignArtifacts: true
Probes.BinaryProbe {
id: signtoolProbe
names: [codesignName]
- searchPaths: CODESIGN.findBestSignToolSearchPaths(qbs.hostArchitecture)
+ searchPaths: CODESIGN.findBestSignToolSearchPaths(Host.architecture())
}
codesignName: "signtool"
@@ -82,7 +83,7 @@ CodeSignModule {
description: "Path to the signing certificate PFX file."
}
- property path certificatePassword
+ property string certificatePassword
PropertyOptions {
name: "certificatePassword"
description: "Password to use when opening a certificate PFX file."
diff --git a/share/qbs/modules/cpp/CppModule.qbs b/share/qbs/modules/cpp/CppModule.qbs
index 0a3050370..bd1eaa242 100644
--- a/share/qbs/modules/cpp/CppModule.qbs
+++ b/share/qbs/modules/cpp/CppModule.qbs
@@ -29,6 +29,7 @@
****************************************************************************/
// base for Cpp modules
+import qbs.FileInfo
import qbs.ModUtils
import qbs.Utilities
import qbs.WindowsUtils
@@ -216,7 +217,7 @@ Module {
property stringList knownArchitectures: []
property var toolchainDetails
- property string compilerExtension: qbs.hostOS.contains("windows") ? ".exe" : ""
+ property string compilerExtension: FileInfo.executableSuffix()
property string linkerMode: "automatic"
PropertyOptions {
diff --git a/share/qbs/modules/cpp/DarwinGCC.qbs b/share/qbs/modules/cpp/DarwinGCC.qbs
index 158c3c061..e20973acc 100644
--- a/share/qbs/modules/cpp/DarwinGCC.qbs
+++ b/share/qbs/modules/cpp/DarwinGCC.qbs
@@ -43,7 +43,7 @@ import "gcc.js" as Gcc
UnixGCC {
condition: false
- Depends { name: "xcode"; required: qbs.toolchain && qbs.toolchain.contains("xcode") }
+ Depends { name: "xcode"; required: qbs.toolchain && qbs.toolchain.includes("xcode") }
Probes.BinaryProbe {
id: lipoProbe
@@ -76,7 +76,7 @@ UnixGCC {
dynamicLibrarySuffix: ".dylib"
Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
+ condition: product.multiplexByQbsProperties.includes("buildVariants")
&& qbs.buildVariants && qbs.buildVariants.length > 1
&& (!product.aggregate || !!product.multiplexConfigurationId)
&& qbs.buildVariant !== "release"
@@ -107,32 +107,42 @@ UnixGCC {
property var defaultInfoPlist: {
var dict = {};
- if (qbs.targetOS.contains("macos")) {
+ if (qbs.targetOS.includes("macos")) {
dict["NSPrincipalClass"] = "NSApplication"; // needed for Retina display support
+ // QBS-1670: set this flag by default to avoid extensive GPU usage
+ dict["NSSupportsAutomaticGraphicsSwitching"] = true;
+
if (minimumMacosVersion)
dict["LSMinimumSystemVersion"] = minimumMacosVersion;
}
+ if (qbs.targetOS.includes("ios") && minimumIosVersion)
+ dict["MinimumOSVersion"] = minimumIosVersion;
+ else if (qbs.targetOS.includes("tvos") && minimumTvosVersion)
+ dict["MinimumOSVersion"] = minimumTvosVersion;
+ else if (qbs.targetOS.includes("watchos") && minimumWatchosVersion)
+ dict["MinimumOSVersion"] = minimumWatchosVersion;
+
if (qbs.targetOS.containsAny(["ios", "tvos"])) {
dict["LSRequiresIPhoneOS"] = true;
if (xcode.platformType === "device") {
- if (qbs.targetOS.contains("ios")) {
+ if (qbs.targetOS.includes("ios")) {
if (qbs.architecture === "arm64")
dict["UIRequiredDeviceCapabilities"] = ["arm64"];
else
dict["UIRequiredDeviceCapabilities"] = ["armv7"];
}
- if (qbs.targetOS.contains("tvos"))
+ if (qbs.targetOS.includes("tvos"))
dict["UIRequiredDeviceCapabilities"] = ["arm64"];
}
}
if (xcode.present) {
var targetDevices = DarwinTools.targetedDeviceFamily(xcode.targetDevices);
- if (qbs.targetOS.contains("ios"))
+ if (qbs.targetOS.includes("ios"))
dict["UIDeviceFamily"] = targetDevices;
if (qbs.targetOS.containsAny(["ios", "watchos"])) {
@@ -143,13 +153,13 @@ UnixGCC {
"UIInterfaceOrientationLandscapeRight"
];
- if (targetDevices.contains("ipad"))
+ if (targetDevices.includes("ipad"))
dict["UISupportedInterfaceOrientations~ipad"] = orientations;
- if (targetDevices.contains("watch"))
+ if (targetDevices.includes("watch"))
dict["UISupportedInterfaceOrientations"] = orientations.slice(0, 2);
- if (targetDevices.contains("iphone")) {
+ if (targetDevices.includes("iphone")) {
orientations.splice(1, 1);
dict["UISupportedInterfaceOrientations"] = orientations;
}
@@ -189,13 +199,13 @@ UnixGCC {
// Set the corresponding environment variable even if the minimum OS version is undefined,
// because this indicates the default deployment target for that OS
- if (qbs.targetOS.contains("ios") && minimumIosVersion)
+ if (qbs.targetOS.includes("ios") && minimumIosVersion)
env["IPHONEOS_DEPLOYMENT_TARGET"] = minimumIosVersion;
- if (qbs.targetOS.contains("macos") && minimumMacosVersion)
+ if (qbs.targetOS.includes("macos") && minimumMacosVersion)
env["MACOSX_DEPLOYMENT_TARGET"] = minimumMacosVersion;
- if (qbs.targetOS.contains("watchos") && minimumWatchosVersion)
+ if (qbs.targetOS.includes("watchos") && minimumWatchosVersion)
env["WATCHOS_DEPLOYMENT_TARGET"] = minimumWatchosVersion;
- if (qbs.targetOS.contains("tvos") && minimumTvosVersion)
+ if (qbs.targetOS.includes("tvos") && minimumTvosVersion)
env["TVOS_DEPLOYMENT_TARGET"] = minimumTvosVersion;
if (xcode.present)
@@ -208,7 +218,7 @@ UnixGCC {
property string minimumDarwinVersionCompilerFlag
property string minimumDarwinVersionLinkerFlag
- property bool libcxxAvailable: qbs.toolchain.contains("clang") && cxxLanguageVersion !== "c++98"
+ property bool libcxxAvailable: qbs.toolchain.includes("clang") && cxxLanguageVersion !== "c++98"
Rule {
condition: enableAggregationRules
@@ -261,7 +271,7 @@ UnixGCC {
}
Rule {
- condition: qbs.targetOS.contains("darwin")
+ condition: qbs.targetOS.includes("darwin")
multiplex: true
Artifact {
diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index 5060af2d6..f84028940 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -30,6 +30,7 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.PathTools
import qbs.Probes
@@ -42,7 +43,7 @@ import 'cpp.js' as Cpp
import 'gcc.js' as Gcc
CppModule {
- condition: qbs.toolchain && qbs.toolchain.contains("gcc")
+ condition: qbs.toolchain && qbs.toolchain.includes("gcc")
priority: -100
Depends { name: "codesign" }
@@ -122,9 +123,9 @@ CppModule {
precompiledHeaderSuffix: ".gch"
- property bool compilerHasTargetOption: qbs.toolchain.contains("clang")
+ property bool compilerHasTargetOption: qbs.toolchain.includes("clang")
&& Utilities.versionCompare(compilerVersion, "3.1") >= 0
- property bool assemblerHasTargetOption: qbs.toolchain.contains("xcode")
+ property bool assemblerHasTargetOption: qbs.toolchain.includes("xcode")
&& Utilities.versionCompare(compilerVersion, "7") >= 0
property string target: targetArch
? [targetArch, targetVendor, targetSystem, targetAbi].join("-")
@@ -169,7 +170,7 @@ CppModule {
property string linkerVariant
PropertyOptions {
name: "linkerVariant"
- allowedValues: ["bfd", "gold", "lld"]
+ allowedValues: ["bfd", "gold", "lld", "mold"]
description: "Allows to specify the linker variant. Maps to gcc's and clang's -fuse-ld "
+ "option."
}
@@ -181,9 +182,9 @@ CppModule {
property string toolchainPathPrefix: Gcc.pathPrefix(toolchainInstallPath, toolchainPrefix)
property string binutilsPathPrefix: Gcc.pathPrefix(binutilsPath, toolchainPrefix)
- property string cCompilerName: (qbs.toolchain.contains("clang") ? "clang" : "gcc")
+ property string cCompilerName: (qbs.toolchain.includes("clang") ? "clang" : "gcc")
+ compilerExtension
- property string cxxCompilerName: (qbs.toolchain.contains("clang") ? "clang++" : "g++")
+ property string cxxCompilerName: (qbs.toolchain.includes("clang") ? "clang++" : "g++")
+ compilerExtension
compilerPathByLanguage: ({
@@ -215,7 +216,7 @@ CppModule {
linkerScriptFlag: "-T"
readonly property bool shouldCreateSymlinks: {
- return createSymlinks && internalVersion && ["macho", "elf"].contains(cpp.imageFormat);
+ return createSymlinks && internalVersion && ["macho", "elf"].includes(imageFormat);
}
readonly property bool shouldSignArtifacts: codesign._canSignArtifacts
@@ -250,18 +251,18 @@ CppModule {
property var buildEnv: {
var env = {};
- if (qbs.toolchain.contains("mingw"))
- env.PATH = [toolchainInstallPath]; // For libwinpthread etc
+ if (qbs.toolchain.includes("mingw"))
+ env.PATH = toolchainInstallPath; // For libwinpthread etc
return env;
}
exceptionHandlingModel: {
- if (qbs.toolchain.contains("mingw")) {
+ if (qbs.toolchain.includes("mingw")) {
// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html claims
// __USING_SJLJ_EXCEPTIONS__ is defined as 1 when using SJLJ exceptions, but there don't
// seem to be defines for the other models, so use the presence of the DLLs for now.
var prefix = toolchainInstallPath;
- if (!qbs.hostOS.contains("windows"))
+ if (!Host.os().includes("windows"))
prefix = FileInfo.joinPaths(toolchainInstallPath, "..", "lib", "gcc",
toolchainPrefix,
[compilerVersionMajor, compilerVersionMinor].join("."));
@@ -313,7 +314,7 @@ CppModule {
if (gccProbe.targetPlatform) {
// Can't differentiate Darwin OSes at the compiler level alone
if (gccProbe.targetPlatform === "darwin"
- ? !qbs.targetOS.contains("darwin")
+ ? !qbs.targetOS.includes("darwin")
: qbs.targetPlatform !== gccProbe.targetPlatform)
isWrongTriple = true;
} else if (qbs.targetPlatform) {
@@ -350,7 +351,7 @@ CppModule {
var validateFlagsFunction = function (value) {
if (value) {
for (var i = 0; i < value.length; ++i) {
- if (["-target", "-triple", "-arch"].contains(value[i]))
+ if (["-target", "-triple", "-arch"].includes(value[i]))
return false;
}
}
@@ -402,7 +403,7 @@ CppModule {
inputs: {
var tags = ["obj", "res", "linkerscript", "versionscript"];
if (product.bundle && product.bundle.embedInfoPlist
- && product.qbs.targetOS.contains("darwin")) {
+ && product.qbs.targetOS.includes("darwin")) {
tags.push("aggregate_infoplist");
}
return tags;
@@ -482,9 +483,9 @@ CppModule {
var objCount = objs ? objs.length : 0;
for (var i = 0; i < objCount; ++i) {
var ft = objs[i].fileTags;
- if (ft.contains("c_obj"))
+ if (ft.includes("c_obj"))
tags.push("c_staticlibrary");
- if (ft.contains("cpp_obj"))
+ if (ft.includes("cpp_obj"))
tags.push("cpp_staticlibrary");
}
return [{
@@ -520,7 +521,7 @@ CppModule {
inputs: {
var tags = ["obj", "res", "linkerscript"];
if (product.bundle && product.bundle.embedInfoPlist
- && product.qbs.targetOS.contains("darwin")) {
+ && product.qbs.targetOS.includes("darwin")) {
tags.push("aggregate_infoplist");
}
return tags;
@@ -563,7 +564,7 @@ CppModule {
inputs: {
var tags = ["obj", "res", "linkerscript"];
if (product.bundle && product.bundle.embedInfoPlist
- && product.qbs.targetOS.contains("darwin")) {
+ && product.qbs.targetOS.includes("darwin")) {
tags.push("aggregate_infoplist");
}
return tags;
diff --git a/share/qbs/modules/cpp/LinuxGCC.qbs b/share/qbs/modules/cpp/LinuxGCC.qbs
index 14fb0a7e9..4b594a0aa 100644
--- a/share/qbs/modules/cpp/LinuxGCC.qbs
+++ b/share/qbs/modules/cpp/LinuxGCC.qbs
@@ -28,11 +28,12 @@
**
****************************************************************************/
+import qbs.Host
import qbs.Process
UnixGCC {
- condition: qbs.targetOS.contains('linux') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('linux') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
priority: 1
targetVendor: "pc"
@@ -41,7 +42,7 @@ UnixGCC {
Probe {
id: runPathsProbe
- condition: !_skipAllChecks && qbs.targetPlatform === qbs.hostPlatform
+ condition: !_skipAllChecks && qbs.targetPlatform === Host.platform()
property stringList systemRunPaths: []
configure: {
var paths = [];
diff --git a/share/qbs/modules/cpp/MingwBaseModule.qbs b/share/qbs/modules/cpp/MingwBaseModule.qbs
index 831512c5c..c9cfe9bd8 100644
--- a/share/qbs/modules/cpp/MingwBaseModule.qbs
+++ b/share/qbs/modules/cpp/MingwBaseModule.qbs
@@ -44,9 +44,10 @@ GenericGCC {
windowsApiCharacterSet: "unicode"
platformDefines: base.concat(WindowsUtils.characterSetDefines(windowsApiCharacterSet))
.concat("WIN32")
+ runtimeLibrary: "dynamic"
Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
+ condition: product.multiplexByQbsProperties.includes("buildVariants")
&& qbs.buildVariants && qbs.buildVariants.length > 1
&& qbs.buildVariant !== "release"
&& product.type.containsAny(["staticlibrary", "dynamiclibrary"])
@@ -95,9 +96,9 @@ GenericGCC {
var tf;
try {
tf = new TextFile(outputFilePath, TextFile.WriteOnly);
- if (productType.contains("application"))
+ if (productType.includes("application"))
tf.write("1 "); // CREATEPROCESS_MANIFEST_RESOURCE_ID
- else if (productType.contains("dynamiclibrary"))
+ else if (productType.includes("dynamiclibrary"))
tf.write("2 "); // ISOLATIONAWARE_MANIFEST_RESOURCE_ID
tf.write("24 "); // RT_MANIFEST
tf.writeLine(Utilities.cStringQuote(inputFilePath));
diff --git a/share/qbs/modules/cpp/UnixGCC.qbs b/share/qbs/modules/cpp/UnixGCC.qbs
index 94dfb1907..6f377c5c8 100644
--- a/share/qbs/modules/cpp/UnixGCC.qbs
+++ b/share/qbs/modules/cpp/UnixGCC.qbs
@@ -31,8 +31,8 @@
import qbs.File
GenericGCC {
- condition: qbs.toolchain && qbs.toolchain.contains("gcc")
- && qbs.targetOS.contains("unix")
+ condition: qbs.toolchain && qbs.toolchain.includes("gcc")
+ && qbs.targetOS.includes("unix")
priority: -50
dynamicLibraryPrefix: "lib"
diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs
index 6e19a0e7d..7c45d3c6b 100644
--- a/share/qbs/modules/cpp/android-gcc.qbs
+++ b/share/qbs/modules/cpp/android-gcc.qbs
@@ -39,7 +39,7 @@ import 'gcc.js' as Gcc
LinuxGCC {
Depends { name: "Android.ndk" }
- condition: qbs.targetOS.contains("android") && qbs.toolchain && qbs.toolchain.contains("llvm")
+ condition: qbs.targetOS.includes("android") && qbs.toolchain && qbs.toolchain.includes("llvm")
priority: 2
rpaths: []
@@ -58,7 +58,7 @@ LinuxGCC {
return "i686";
}
}
- property string targetDir: "android" + (["armeabi", "armeabi-v7a"].contains(Android.ndk.abi) ? "eabi" : "")
+ property string targetDir: "android" + (["armeabi", "armeabi-v7a"].includes(Android.ndk.abi) ? "eabi" : "")
property string triple: [archLibsDir, targetSystem, targetDir].join("-")
property string libsDir: FileInfo.joinPaths(sysroot, "usr", "lib", triple);
@@ -128,7 +128,7 @@ LinuxGCC {
// When using ndk r19c, llvm doesn't add sysroot/usr/include/c++/v1 to the path
// But it works starting with ndk r20b
systemIncludePaths: (Utilities.versionCompare(Android.ndk.version, "20") < 0) ?
- FileInfo.joinPaths(sysroot, "usr", "include", "c++", "v1") : ""
+ FileInfo.joinPaths(sysroot, "usr", "include", "c++", "v1") : []
defines: ["ANDROID", "__ANDROID__"]
@@ -155,7 +155,7 @@ LinuxGCC {
target: [targetArch, targetSystem, targetAbi].join("-")
targetSystem: "linux"
- targetAbi: "android" + (["armeabi", "armeabi-v7a"].contains(Android.ndk.abi) ? "eabi" : "") +
+ targetAbi: "android" + (["armeabi", "armeabi-v7a"].includes(Android.ndk.abi) ? "eabi" : "") +
Android.ndk.platformVersion
endianness: "little"
@@ -170,7 +170,7 @@ LinuxGCC {
prepare: {
var stripArgs = ["--strip-all", "-o", output.filePath, input.filePath];
var stripCmd = new Command(product.cpp.stripPath, stripArgs);
- stripCmd.description = "Stripping unneeded symbols from " + input.fileName;
+ stripCmd.description = "stripping unneeded symbols from " + input.fileName;
return stripCmd;
}
}
diff --git a/share/qbs/modules/cpp/cosmic.js b/share/qbs/modules/cpp/cosmic.js
index 50aea6e25..4979f33f7 100644
--- a/share/qbs/modules/cpp/cosmic.js
+++ b/share/qbs/modules/cpp/cosmic.js
@@ -387,6 +387,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
cmd.workingDirectory = product.buildDirectory;
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
cmds.push(cmd);
cmds.push(renameObjectFile(project, product, inputs, outputs, input, output));
@@ -415,6 +416,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output, expl
cmd.workingDirectory = product.buildDirectory;
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
cmds.push(cmd);
return cmds;
}
@@ -426,6 +428,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
cmd.workingDirectory = product.buildDirectory;
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
return [cmd];
}
@@ -433,7 +436,8 @@ function prepareArchiver(project, product, inputs, outputs, input, output) {
var args = archiverFlags(project, product, inputs, outputs);
var cmd = new Command(product.cpp.archiverPath, args);
cmd.workingDirectory = product.buildDirectory;
- cmd.description = "linking " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
return [cmd];
}
diff --git a/share/qbs/modules/cpp/cosmic.qbs b/share/qbs/modules/cpp/cosmic.qbs
index 46c904ac5..8bf0f22a3 100644
--- a/share/qbs/modules/cpp/cosmic.qbs
+++ b/share/qbs/modules/cpp/cosmic.qbs
@@ -37,7 +37,7 @@ import "cosmic.js" as COSMIC
import "cpp.js" as Cpp
CppModule {
- condition: qbs.toolchain && qbs.toolchain.contains("cosmic")
+ condition: qbs.toolchain && qbs.toolchain.includes("cosmic")
Probes.BinaryProbe {
id: compilerPathProbe
diff --git a/share/qbs/modules/cpp/cpp.js b/share/qbs/modules/cpp/cpp.js
index 315b902ee..9f907580a 100644
--- a/share/qbs/modules/cpp/cpp.js
+++ b/share/qbs/modules/cpp/cpp.js
@@ -42,7 +42,7 @@ function languageVersion(versionArray, knownValues, lang) {
return versions[0];
for (var i = 0; i < knownValues.length; ++i) {
var candidate = knownValues[i];
- if (versions.contains(candidate))
+ if (versions.includes(candidate))
return candidate;
}
var version = versions[0];
@@ -51,9 +51,15 @@ function languageVersion(versionArray, knownValues, lang) {
return version;
}
-function extractMacros(output) {
+function extractMacros(output, regexp) {
var m = {};
- output.trim().split(/\r?\n/g).map(function (line) {
+ output.trim().split(/\r?\n/g).map(function(line) {
+ if (regexp) {
+ var match = regexp.exec(line);
+ if (!match)
+ return;
+ line = match[1];
+ }
var prefix = "#define ";
if (!line.startsWith(prefix))
return;
@@ -128,7 +134,7 @@ function assemblerOutputArtifacts(input) {
}
function compilerOutputArtifacts(input, inputs) {
- var objTags = input.fileTags.contains("cpp_intermediate_object")
+ var objTags = input.fileTags.includes("cpp_intermediate_object")
? ["intermediate_obj"]
: ["obj"];
if (inputs) {
@@ -214,6 +220,7 @@ function precompiledHeaderOutputArtifacts(input, product, lang, generateObjects)
function collectLibraryDependencies(product) {
var seen = {};
+ var seenObjectFiles = [];
var result = [];
function addFilePath(filePath, wholeArchive, productName) {
@@ -226,7 +233,7 @@ function collectLibraryDependencies(product) {
var artifactFilePaths = artifacts.map(function(a) { return a.filePath; });
var wholeArchive = dep.parameters.cpp && dep.parameters.cpp.linkWholeArchive;
var artifactsAreImportLibs = artifacts.length > 0
- && artifacts[0].fileTags.contains("dynamiclibrary_import");
+ && artifacts[0].fileTags.includes("dynamiclibrary_import");
for (var i = 0; i < artifactFilePaths.length; ++i) {
addFilePath(artifactFilePaths[i], wholeArchive,
artifactsAreImportLibs ? dep.name : undefined);
@@ -242,16 +249,23 @@ function collectLibraryDependencies(product) {
function sanitizedModuleListProperty(obj, moduleName, propertyName) {
return ensureArray(ModUtils.sanitizedModuleProperty(obj, moduleName, propertyName));
}
- function handleExternalLibraries(tag, suffix) {
+ function handleExternalLibraries(tag, libSuffix, objSuffix) {
var externalLibs = sanitizedModuleListProperty(obj, "cpp", tag) || [];
externalLibs.forEach(function(libName) {
- if (!libName.endsWith(suffix) && !libName.startsWith('@'))
- libName += suffix;
+ var isObjectFile = objSuffix && libName.endsWith(objSuffix);
+ if (isObjectFile) {
+ if (seenObjectFiles.includes(libName))
+ return;
+ seenObjectFiles.push(libName);
+ }
+ if (!libName.endsWith(libSuffix) && !isObjectFile && !libName.startsWith('@'))
+ libName += libSuffix;
addFilePath(libName, false);
});
}
handleExternalLibraries("staticLibraries",
- obj.moduleProperty("cpp", "staticLibrarySuffix"));
+ obj.moduleProperty("cpp", "staticLibrarySuffix"),
+ obj.moduleProperty("cpp", "objectSuffix"));
handleExternalLibraries("dynamicLibraries",
obj.moduleProperty("cpp", "dynamicLibraryImportSuffix"));
}
@@ -313,7 +327,10 @@ function collectIncludePaths(input) {
var includePaths = input.cpp.includePaths;
if (includePaths)
allIncludePaths = allIncludePaths.uniqueConcat(includePaths);
- return allIncludePaths;
+ var builtIns = input.cpp.compilerIncludePaths;
+ return allIncludePaths.filter(function(p) {
+ return !builtIns.includes(p);
+ });
}
function collectSystemIncludePaths(input) {
@@ -324,7 +341,10 @@ function collectSystemIncludePaths(input) {
var distributionIncludePaths = input.cpp.distributionIncludePaths;
if (distributionIncludePaths)
allIncludePaths = allIncludePaths.uniqueConcat(distributionIncludePaths);
- return allIncludePaths;
+ var builtIns = input.cpp.compilerIncludePaths;
+ return allIncludePaths.filter(function(p) {
+ return !builtIns.includes(p);
+ });
}
function collectPreincludePaths(input) {
diff --git a/share/qbs/modules/cpp/darwin.js b/share/qbs/modules/cpp/darwin.js
index e4f740dbe..0223c5ed3 100644
--- a/share/qbs/modules/cpp/darwin.js
+++ b/share/qbs/modules/cpp/darwin.js
@@ -73,7 +73,7 @@ function lipoOutputArtifacts(product, inputs, fileTag, debugSuffix) {
// approach for all bundle types.
var defaultVariant;
if (!buildVariants.some(function (x) { return x.name === "release"; })
- && product.multiplexByQbsProperties.contains("buildVariants")
+ && product.multiplexByQbsProperties.includes("buildVariants")
&& product.qbs.buildVariants && product.qbs.buildVariants.length > 1) {
var defaultBuildVariant = product.qbs.defaultBuildVariant;
buildVariants.map(function (variant) {
@@ -137,7 +137,7 @@ function prepareLipo(project, product, inputs, outputs, input, output) {
for (var p in inputs)
inputs[p] = inputs[p].filter(function(inp) { return inp.product.name === product.name; });
var allInputs = [].concat.apply([], Object.keys(inputs).map(function (tag) {
- return ["application", "dynamiclibrary", "staticlibrary", "loadablemodule"].contains(tag)
+ return ["application", "dynamiclibrary", "staticlibrary", "loadablemodule"].includes(tag)
? inputs[tag] : [];
}));
diff --git a/share/qbs/modules/cpp/dmc.js b/share/qbs/modules/cpp/dmc.js
index 7303c67fc..ea7cd7bb5 100644
--- a/share/qbs/modules/cpp/dmc.js
+++ b/share/qbs/modules/cpp/dmc.js
@@ -38,7 +38,47 @@ var TemporaryDir = require("qbs.TemporaryDir");
var TextFile = require("qbs.TextFile");
var Utilities = require("qbs.Utilities");
-function dumpMacros(compilerFilePath, tag) {
+function targetFlags(platform, architecture, extender, consoleApp, type) {
+ if (platform === "dos") {
+ if (architecture === "x86_16") {
+ if (extender === "dosz")
+ return ["-mz"];
+ else if (extender === "dosr")
+ return ["-mr"];
+ return ["-mc"];
+ } else if (architecture === "x86") {
+ if (extender === "dosx")
+ return ["-mx"];
+ else if (extender === "dosp")
+ return ["-mp"];
+ }
+ } else if (platform === "windows") {
+ var flags = [];
+ if (architecture === "x86_16") {
+ flags.push("-ml");
+ if (type.includes("application") && !consoleApp)
+ flags.push("-WA");
+ else if (type.includes("dynamiclibrary"))
+ flags.push("-WD");
+ } else if (architecture === "x86") {
+ flags.push("-mn");
+ if (type.includes("application"))
+ flags.push("-WA");
+ else if (type.includes("dynamiclibrary"))
+ flags.push("-WD");
+ }
+ return flags;
+ }
+ return [];
+}
+
+function languageFlags(tag) {
+ if (tag === "cpp")
+ return ["-cpp"];
+ return [];
+}
+
+function dumpMacros(compilerPath, platform, architecture, extender, tag) {
// Note: The DMC compiler does not support the predefined/ macros dumping. So, we do it
// with the following trick, where we try to create and compile a special temporary file
// and to parse the console output with the own magic pattern: #define <key> <value>.
@@ -55,7 +95,8 @@ function dumpMacros(compilerFilePath, tag) {
"_MSDOS", "MSDOS",
// Prepare the OS/2 target macros.
"__OS2__",
- "WIN32", "_WIN32",
+ // Prepare the Windows target macros.
+ "WIN32", "_WIN32", "__NT__",
// Prepare extended the 32 and 16 bit DOS target macros.
"DOS386", "DOS16RM",
// Prepare the memory model macros.
@@ -96,9 +137,10 @@ function dumpMacros(compilerFilePath, tag) {
var process = new Process();
process.setWorkingDirectory(outputDirectory.path());
- var args = ["-c"].concat((tag === "cpp") ? ["-cpp"] : [],
- FileInfo.toWindowsSeparators(outputFilePath));
- process.exec(compilerFilePath, args, false);
+ var lang = languageFlags(tag);
+ var target = targetFlags(platform, architecture, extender, false, ["application"]);
+ var args = ["-c"].concat(lang, target, FileInfo.toWindowsSeparators(outputFilePath));
+ process.exec(compilerPath, args, false);
File.remove(outputFilePath);
var out = process.readStdOut();
return Cpp.extractMacros(out);
@@ -166,6 +208,12 @@ function depsOutputArtifacts(input, product) {
function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
var args = ["-c"];
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+ args = args.concat(languageFlags(tag));
+ args = args.concat(targetFlags(product.qbs.targetPlatform, product.qbs.architecture,
+ product.cpp.extenderName, product.consoleApplication,
+ product.type));
+
// Input.
args.push(FileInfo.toWindowsSeparators(input.filePath));
// Output.
@@ -178,7 +226,6 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
// Defines.
args = args.concat(Cpp.collectDefinesArguments(input));
- var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
if (tag === "cpp") {
// We need to add the paths to the STL includes, because the DMC compiler does
// not handle it by default (because the STL libraries is a separate port).
@@ -226,8 +273,6 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("-wx");
if (tag === "cpp") {
- args.push("-cpp");
-
// Exceptions flag.
if (input.cpp.enableExceptions)
args.push("-Ae");
@@ -285,6 +330,10 @@ function linkerFlags(project, product, inputs, outputs) {
var useCompilerDriver = useCompilerDriverLinker(product);
if (useCompilerDriver) {
+ args = args.concat(targetFlags(product.qbs.targetPlatform, product.qbs.architecture,
+ product.cpp.extenderName, product.consoleApplication,
+ product.type));
+
// Input objects.
args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
return FileInfo.toWindowsSeparators(path);
@@ -301,19 +350,24 @@ function linkerFlags(project, product, inputs, outputs) {
}));
// Output.
- if (product.type.contains("application")) {
+ if (product.type.includes("application")) {
args.push("-o" + FileInfo.toWindowsSeparators(outputs.application[0].filePath));
- args.push("-WA");
- args.push("/SUBSYSTEM:" + (product.consoleApplication ? "CONSOLE" : "WINDOWS"));
- } else if (product.type.contains("dynamiclibrary")) {
+ args.push("-L/" + (product.cpp.generateLinkerMapFile ? "MAP" : "NOMAP"));
+ if (product.qbs.targetPlatform === "windows" && product.qbs.architecture === "x86")
+ args.push("-L/SUBSYSTEM:" + (product.consoleApplication ? "CONSOLE" : "WINDOWS"));
+ } else if (product.type.includes("dynamiclibrary")) {
args.push("-o" + FileInfo.toWindowsSeparators(outputs.dynamiclibrary[0].filePath));
- args.push("-WD");
+ if (product.qbs.targetPlatform === "windows" && product.qbs.architecture === "x86") {
+ args.push("kernel32.lib");
+ args.push("-L/IMPLIB:" + FileInfo.toWindowsSeparators(
+ outputs.dynamiclibrary_import[0].filePath));
+ }
}
if (product.cpp.debugInformation)
- args.push("/DEBUG");
+ args.push("-L/DEBUG");
- args.push("/NOLOGO", "/SILENT");
+ args.push("-L/NOLOGO", "-L/SILENT");
}
// Misc flags.
@@ -383,20 +437,10 @@ function renameLinkerMapFile(project, product, inputs, outputs, input, output) {
cmd.newMapFilePath = buildLinkerMapFilePath(target, product.cpp.linkerMapSuffix);
cmd.oldMapFilePath = buildLinkerMapFilePath(target, ".map");
cmd.silent = true;
- cmd.sourceCode = function() { File.move(oldMapFilePath, newMapFilePath); };
- return cmd;
-}
-
-// It is a workaround to generate the import library file from the dynamic library.
-// Because the DMC compiler use the separate `implib.exe` tool for that.
-function createImportLib(project, product, inputs, outputs, input, output) {
- var args = [
- FileInfo.toWindowsSeparators(outputs.dynamiclibrary_import[0].filePath),
- FileInfo.toWindowsSeparators(outputs.dynamiclibrary[0].filePath)
- ];
- var cmd = new Command(input.cpp.implibPath, args);
- cmd.workingDirectory = product.buildDirectory;
- cmd.silent = true;
+ cmd.sourceCode = function() {
+ if (oldMapFilePath !== newMapFilePath)
+ File.move(oldMapFilePath, newMapFilePath);
+ };
return cmd;
}
@@ -406,6 +450,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
cmd.workingDirectory = product.buildDirectory;
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
return [cmd];
}
@@ -415,6 +460,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output, expl
cmd.workingDirectory = product.buildDirectory;
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
return [cmd];
}
@@ -428,18 +474,14 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
cmd.workingDirectory = product.buildDirectory;
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
cmds.push(cmd);
- if (outputs.dynamiclibrary
- || (outputs.application && !product.cpp.generateLinkerMapFile)) {
- if (outputs.dynamiclibrary)
- cmds.push(createImportLib(project, product, inputs, outputs, input, output));
- cmds.push(removeLinkerMapFile(project, product, inputs, outputs, input, output));
- } else if (outputs.application
- && product.cpp.generateLinkerMapFile
- && (product.cpp.linkerMapSuffix !== ".map")) {
+ if (product.cpp.generateLinkerMapFile)
cmds.push(renameLinkerMapFile(project, product, inputs, outputs, input, output));
- }
+ else
+ cmds.push(removeLinkerMapFile(project, product, inputs, outputs, input, output));
+
return cmds;
}
@@ -447,8 +489,9 @@ function prepareArchiver(project, product, inputs, outputs, input, output) {
var args = archiverFlags(project, product, inputs, outputs);
var cmd = new Command(product.cpp.archiverPath, args);
cmd.workingDirectory = product.buildDirectory;
- cmd.description = "linking " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
return [cmd];
}
@@ -458,5 +501,6 @@ function prepareRccCompiler(project, product, inputs, outputs, input, output) {
cmd.workingDirectory = product.buildDirectory;
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
return [cmd];
}
diff --git a/share/qbs/modules/cpp/dmc.qbs b/share/qbs/modules/cpp/dmc.qbs
index 68a0033e0..ac89550e8 100644
--- a/share/qbs/modules/cpp/dmc.qbs
+++ b/share/qbs/modules/cpp/dmc.qbs
@@ -30,6 +30,7 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.PathTools
import qbs.Probes
import qbs.Utilities
@@ -37,12 +38,12 @@ import "dmc.js" as DMC
import "cpp.js" as Cpp
CppModule {
- condition: qbs.hostOS.contains("windows") && qbs.toolchain && qbs.toolchain.contains("dmc")
+ condition: Host.os().includes("windows") && qbs.toolchain && qbs.toolchain.includes("dmc")
Probes.BinaryProbe {
id: compilerPathProbe
condition: !toolchainInstallPath && !_skipAllChecks
- names: ["cxcorm"]
+ names: ["dmc"]
}
Probes.DmcProbe {
@@ -50,10 +51,13 @@ CppModule {
condition: !_skipAllChecks
compilerFilePath: compilerPath
enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ _targetPlatform: qbs.targetPlatform
+ _targetArchitecture: qbs.architecture
+ _targetExtender: extenderName
}
qbs.architecture: dmcProbe.found ? dmcProbe.architecture : original
- qbs.targetPlatform: dmcProbe.targetPlatform
+ qbs.targetPlatform: dmcProbe.found ? dmcProbe.targetPlatform : original
compilerVersionMajor: dmcProbe.versionMajor
compilerVersionMinor: dmcProbe.versionMinor
@@ -80,11 +84,21 @@ CppModule {
property string archiverName: "lib.exe"
property string archiverPath: FileInfo.joinPaths(toolchainInstallPath, archiverName)
- property string implibName: "implib.exe"
- property string implibPath: FileInfo.joinPaths(toolchainInstallPath, implibName)
property string rccCompilerName: "rcc.exe"
property string rccCompilerPath: FileInfo.joinPaths(toolchainInstallPath, rccCompilerName)
+ property string extenderName
+ PropertyOptions {
+ name: "extenderName"
+ allowedValues: [undefined, "dosz", "dosr", "dosx", "dosp"]
+ description: "Specifies the DOS memory extender to compile with:\n"
+ + " - \"dosz\" is the ZPM 16 bit DOS Extender\n"
+ + " - \"dosr\" is the Rational 16 bit DOS Extender\n"
+ + " - \"dosx\" is the DOSX 32 bit DOS Extender\n"
+ + " - \"dosp\" is the Pharlap 32 bit DOS Extender\n"
+ ;
+ }
+
runtimeLibrary: "dynamic"
staticLibrarySuffix: ".lib"
@@ -92,7 +106,12 @@ CppModule {
executableSuffix: ".exe"
objectSuffix: ".obj"
- imageFormat: "pe"
+ imageFormat: {
+ if (qbs.targetPlatform === "dos")
+ return "mz";
+ else if (qbs.targetPlatform === "windows")
+ return "pe";
+ }
defineFlag: "-D"
includeFlag: "-I"
@@ -100,7 +119,7 @@ CppModule {
preincludeFlag: "-HI"
libraryPathFlag: "-L/packcode"
- knownArchitectures: ["x86"]
+ knownArchitectures: ["x86", "x86_16"]
Rule {
id: assembler
diff --git a/share/qbs/modules/cpp/freebsd-gcc.qbs b/share/qbs/modules/cpp/freebsd-gcc.qbs
index 929c4e557..e04ed7f2b 100644
--- a/share/qbs/modules/cpp/freebsd-gcc.qbs
+++ b/share/qbs/modules/cpp/freebsd-gcc.qbs
@@ -29,13 +29,14 @@
****************************************************************************/
import "freebsd.js" as FreeBSD
+import qbs.Host
UnixGCC {
- condition: qbs.targetOS.contains("freebsd") &&
- qbs.toolchain && qbs.toolchain.contains("gcc")
+ condition: qbs.targetOS.includes("freebsd") &&
+ qbs.toolchain && qbs.toolchain.includes("gcc")
priority: 1
- targetSystem: "freebsd" + (qbs.hostOS.contains("freebsd") ? FreeBSD.hostKernelRelease() : "")
+ targetSystem: "freebsd" + (Host.os().includes("freebsd") ? FreeBSD.hostKernelRelease() : "")
distributionIncludePaths: ["/usr/local/include"]
distributionLibraryPaths: ["/usr/local/lib"]
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 13cdb4a3d..90f8fc933 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -32,6 +32,7 @@ var Codesign = require("../codesign/codesign.js");
var Cpp = require("cpp.js");
var File = require("qbs.File");
var FileInfo = require("qbs.FileInfo");
+var Host = require("qbs.Host");
var DarwinTools = require("qbs.DarwinTools");
var ModUtils = require("qbs.ModUtils");
var PathTools = require("qbs.PathTools");
@@ -77,6 +78,7 @@ function useCompilerDriverLinker(product, inputs) {
function collectLibraryDependencies(product, isDarwin) {
var publicDeps = {};
+ var privateDeps = {};
var objects = [];
var objectByFilePath = {};
var tagForLinkingAgainstSharedLib = product.cpp.imageFormat === "pe"
@@ -169,6 +171,8 @@ function collectLibraryDependencies(product, isDarwin) {
&& typeof dep.artifacts[tagForLinkingAgainstSharedLib] !== "undefined";
if (!isStaticLibrary && !isDynamicLibrary)
return;
+ if (isBelowIndirectDynamicLib && privateDeps[dep.name])
+ return;
var nextIsBelowIndirectDynamicLib = isBelowIndirectDynamicLib || isDynamicLibrary;
dep.dependencies.forEach(function(depdep) {
@@ -192,6 +196,7 @@ function collectLibraryDependencies(product, isDarwin) {
publicDeps[dep.name] = true;
} else {
addArtifactFilePaths(dep, tagForLinkingAgainstSharedLib, addPrivateFilePath);
+ privateDeps[dep.name] = true;
}
}
}
@@ -203,7 +208,6 @@ function collectLibraryDependencies(product, isDarwin) {
product.dependencies.forEach(traverseDirectDependency);
addExternalLibs(product);
- var seenRPathLinkDirs = {};
var result = { libraries: [], rpath_link: [] };
objects.forEach(
function (obj) {
@@ -214,10 +218,7 @@ function collectLibraryDependencies(product, isDarwin) {
framework: obj.framework });
} else {
var dirPath = FileInfo.path(obj.filePath);
- if (!seenRPathLinkDirs.hasOwnProperty(dirPath)) {
- seenRPathLinkDirs[dirPath] = true;
- result.rpath_link.push(dirPath);
- }
+ result.rpath_link.push(dirPath);
}
});
return result;
@@ -229,7 +230,7 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
if (useCompilerDriverLinker(product, inputs)) {
var sep = ",";
- var useXlinker = linkerFlags.some(function (f) { return f.contains(sep); });
+ var useXlinker = linkerFlags.some(function (f) { return f.includes(sep); });
if (useXlinker) {
// One or more linker arguments contain the separator character itself
// Use -Xlinker to handle these
@@ -246,7 +247,7 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
return xlinkerFlags;
}
- if (product.cpp.enableSuspiciousLinkerFlagWarnings && linkerFlags.contains("-Xlinker")) {
+ if (product.cpp.enableSuspiciousLinkerFlagWarnings && linkerFlags.includes("-Xlinker")) {
console.warn("Encountered -Xlinker linker flag escape sequence. This may cause the " +
"target to fail to link. Please do not escape these flags manually; " +
"qbs does that for you.");
@@ -261,7 +262,7 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
}
function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPath) {
- var isDarwin = product.qbs.targetOS.contains("darwin");
+ var isDarwin = product.qbs.targetOS.includes("darwin");
var libraryDependencies = collectLibraryDependencies(product, isDarwin);
var frameworks = product.cpp.frameworks;
var weakFrameworks = product.cpp.weakFrameworks;
@@ -274,7 +275,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var escapableLinkerFlags = [];
- if (primaryOutput.fileTags.contains("dynamiclibrary")) {
+ if (primaryOutput.fileTags.includes("dynamiclibrary")) {
if (isDarwin) {
args.push((function () {
var tags = ["c", "cpp", "objc", "objcpp", "asm_cpp"];
@@ -299,7 +300,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
}
}
- if (primaryOutput.fileTags.contains("loadablemodule"))
+ if (primaryOutput.fileTags.includes("loadablemodule"))
args.push(isDarwin ? "-bundle" : "-shared");
if (primaryOutput.fileTags.containsAny(["dynamiclibrary", "loadablemodule"])) {
@@ -322,7 +323,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var sysroot = product.cpp.syslibroot;
if (sysroot) {
- if (product.qbs.toolchain.contains("qcc"))
+ if (product.qbs.toolchain.includes("qcc"))
escapableLinkerFlags.push("--sysroot=" + sysroot);
else if (isDarwin)
escapableLinkerFlags.push("-syslibroot", sysroot);
@@ -339,7 +340,7 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
function fixupRPath(rpath) {
// iOS, tvOS, watchOS, and others, are fine
- if (!product.qbs.targetOS.contains("macos"))
+ if (!product.qbs.targetOS.includes("macos"))
return rpath;
// ...as are newer versions of macOS
@@ -355,11 +356,11 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
}
function isNotSystemRunPath(p) {
- return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.contains(p)
- && !canonicalSystemRunPaths.contains(File.canonicalFilePath(p)));
+ return !FileInfo.isAbsolutePath(p) || (!systemRunPaths.includes(p)
+ && !canonicalSystemRunPaths.includes(File.canonicalFilePath(p)));
};
- if (!product.qbs.targetOS.contains("windows")) {
+ if (!product.qbs.targetOS.includes("windows")) {
for (i in rpaths) {
if (isNotSystemRunPath(rpaths[i]))
escapableLinkerFlags.push("-rpath", fixupRPath(rpaths[i]));
@@ -369,13 +370,16 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
if (product.cpp.entryPoint)
escapableLinkerFlags.push("-e", product.cpp.entryPoint);
- if (product.qbs.toolchain.contains("mingw")) {
+ if (product.qbs.toolchain.includes("mingw")) {
if (product.consoleApplication !== undefined)
escapableLinkerFlags.push("-subsystem",
product.consoleApplication ? "console" : "windows");
var minimumWindowsVersion = product.cpp.minimumWindowsVersion;
if (minimumWindowsVersion) {
+ // workaround for QBS-1724, mingw seems to be broken
+ if (Utilities.versionCompare(minimumWindowsVersion, "6.2") > 0)
+ minimumWindowsVersion = "6.2";
var subsystemVersion = WindowsUtils.getWindowsVersionInFormat(minimumWindowsVersion, 'subsystem');
if (subsystemVersion) {
var major = subsystemVersion.split('.')[0];
@@ -397,13 +401,13 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var stdlib = isLinkingCppObjects
? product.cpp.cxxStandardLibrary
: undefined;
- if (stdlib && product.qbs.toolchain.contains("clang"))
+ if (stdlib && product.qbs.toolchain.includes("clang"))
args.push("-stdlib=" + stdlib);
// Flags for library search paths
var allLibraryPaths = Cpp.collectLibraryPaths(product);
- if (systemRunPaths.length > 0)
- allLibraryPaths = allLibraryPaths.filter(isNotSystemRunPath);
+ var builtIns = product.cpp.compilerLibraryPaths
+ allLibraryPaths = allLibraryPaths.filter(function(p) { return !builtIns.includes(p); });
args = args.concat(allLibraryPaths.map(function(path) { return product.cpp.libraryPathFlag + path }));
escapableLinkerFlags = escapableLinkerFlags.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs));
@@ -471,9 +475,12 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
var symbolLinkMode = dep.symbolLinkMode;
if (isDarwin && symbolLinkMode) {
- if (!["lazy", "reexport", "upward", "weak"].contains(symbolLinkMode))
+ if (!["lazy", "reexport", "upward", "weak"].includes(symbolLinkMode))
throw new Error("unknown value '" + symbolLinkMode + "' for cpp.symbolLinkMode");
+ }
+ var supportsLazyMode = Utilities.versionCompare(product.cpp.compilerVersion, "15.0.0") < 0;
+ if (isDarwin && symbolLinkMode && (symbolLinkMode !== "lazy" || supportsLazyMode)) {
if (FileInfo.isAbsolutePath(lib) || lib.startsWith('@'))
escapableLinkerFlags.push("-" + symbolLinkMode + "_library", lib);
else if (dep.framework)
@@ -529,6 +536,8 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
Array.prototype.push.apply(escapedLinkerFlags, args);
if (useCompilerDriver)
escapedLinkerFlags = escapedLinkerFlags.concat(Cpp.collectMiscLinkerArguments(product));
+ if (product.qbs.toolchain.includes("mingw") && product.cpp.runtimeLibrary === "static")
+ escapedLinkerFlags = ['-static-libgcc', '-static-libstdc++'].concat(escapedLinkerFlags);
return escapedLinkerFlags;
}
@@ -574,7 +583,7 @@ function languageTagFromFileExtension(toolchain, fileName) {
"s" : "asm",
"S" : "asm_cpp"
};
- if (!toolchain.contains("clang"))
+ if (!toolchain.includes("clang"))
m["sx"] = "asm_cpp"; // clang does NOT recognize .sx
return m[fileName.substring(i + 1)];
}
@@ -582,7 +591,7 @@ function languageTagFromFileExtension(toolchain, fileName) {
// Older versions of the QNX SDK have C and C++ compilers whose filenames differ only by case,
// which won't work in case insensitive environments like Win32+NTFS, HFS+ and APFS
function isLegacyQnxSdk(config) {
- return config.qbs.toolchain.contains("qcc") && config.qnx && !config.qnx.qnx7;
+ return config.qbs.toolchain.includes("qcc") && config.qnx && !config.qnx.qnx7;
}
function effectiveCompilerInfo(toolchain, input, output) {
@@ -590,7 +599,7 @@ function effectiveCompilerInfo(toolchain, input, output) {
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
// Whether we're compiling a precompiled header or normal source file
- var pchOutput = output.fileTags.contains(tag + "_pch");
+ var pchOutput = output.fileTags.includes(tag + "_pch");
var compilerPathByLanguage = input.cpp.compilerPathByLanguage;
if (compilerPathByLanguage)
@@ -598,7 +607,7 @@ function effectiveCompilerInfo(toolchain, input, output) {
if (!compilerPath
|| tag !== languageTagFromFileExtension(toolchain, input.fileName)
|| isLegacyQnxSdk(input)) {
- if (input.qbs.toolchain.contains("qcc"))
+ if (input.qbs.toolchain.includes("qcc"))
language = qnxLangArgs(input, tag);
else
language = ["-x", languageName(tag) + (pchOutput ? '-header' : '')];
@@ -692,6 +701,22 @@ function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVers
{"name": "gcc", "version": "4.7"}
]
},
+ "c17": {
+ "fallback": "c11",
+ "toolchains": [
+ {"name": "xcode", "version": "10.2"},
+ {"name": "clang", "version": "7.0"},
+ {"name": "gcc", "version": "8.1"}
+ ]
+ },
+ "c2x": {
+ "fallback": "c17",
+ "toolchains": [
+ {"name": "xcode", "version": "11.4"},
+ {"name": "clang", "version": "9.0"},
+ {"name": "gcc", "version": "9.0"}
+ ]
+ },
"c++14": {
"fallback": "c++1y",
"toolchains": [
@@ -711,7 +736,7 @@ function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVers
"c++20": {
"fallback": "c++2a",
"toolchains": [
- {"name": "xcode"}, // ??
+ {"name": "xcode", "version": "12.5"},
{"name": "clang", "version": "11.0"},
{"name": "gcc", "version": "10.1"}
]
@@ -730,7 +755,7 @@ function standardFallbackValueOrDefault(toolchain, compilerVersion, languageVers
if (m) {
for (var idx = 0; idx < m.toolchains.length; ++idx) {
var tc = m.toolchains[idx];
- if (toolchain.contains(tc.name)) {
+ if (toolchain.includes(tc.name)) {
// If we found our toolchain and it doesn't yet support the language standard
// we're requesting, or we're using an older version that only supports the
// preliminary flag, use that.
@@ -752,7 +777,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
// Determine which C-language we're compiling
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(output.fileTags));
- if (!["c", "cpp", "objc", "objcpp", "asm_cpp"].contains(tag))
+ if (!["c", "cpp", "objc", "objcpp", "asm_cpp"].includes(tag))
throw ("unsupported source language: " + tag);
var compilerInfo = effectiveCompilerInfo(product.qbs.toolchain,
@@ -785,12 +810,12 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
args = args.concat(configFlags(input));
- if (!input.qbs.toolchain.contains("qcc"))
+ if (!input.qbs.toolchain.includes("qcc"))
args.push('-pipe');
if (input.cpp.enableReproducibleBuilds) {
var toolchain = product.qbs.toolchain;
- if (!toolchain.contains("clang")) {
+ if (!toolchain.includes("clang")) {
var hashString = FileInfo.relativePath(project.sourceDirectory, input.filePath);
var hash = Utilities.getHash(hashString);
args.push("-frandom-seed=0x" + hash.substring(0, 8));
@@ -798,8 +823,8 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
var major = product.cpp.compilerVersionMajor;
var minor = product.cpp.compilerVersionMinor;
- if ((toolchain.contains("clang") && (major > 3 || (major === 3 && minor >= 5))) ||
- (toolchain.contains("gcc") && (major > 4 || (major === 4 && minor >= 9)))) {
+ if ((toolchain.includes("clang") && (major > 3 || (major === 3 && minor >= 5))) ||
+ (toolchain.includes("gcc") && (major > 4 || (major === 4 && minor >= 9)))) {
args.push("-Wdate-time");
}
}
@@ -827,7 +852,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
}
var visibility = input.cpp.visibility;
- if (!product.qbs.toolchain.contains("mingw")) {
+ if (!product.qbs.toolchain.includes("mingw")) {
if (visibility === 'hidden' || visibility === 'minimal')
args.push('-fvisibility=hidden');
if ((visibility === 'hiddenInlines' || visibility === 'minimal') && tag === 'cpp')
@@ -843,7 +868,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
args = args.concat(Cpp.collectMiscCompilerArguments(input, tag));
var pchTag = compilerInfo.tag + "_pch";
- var pchOutput = output.fileTags.contains(pchTag);
+ var pchOutput = output.fileTags.includes(pchTag);
var pchInputs = explicitlyDependsOn[pchTag];
if (!pchOutput && pchInputs && pchInputs.length === 1
&& ModUtils.moduleProperty(input, 'usePrecompiledHeader', tag)) {
@@ -856,7 +881,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
args = args.concat(Cpp.collectPreincludePathsArguments(input));
var positionIndependentCode = input.cpp.positionIndependentCode;
- if (positionIndependentCode && !product.qbs.targetOS.contains("windows"))
+ if (positionIndependentCode && !product.qbs.targetOS.includes("windows"))
args.push('-fPIC');
var cppFlags = input.cpp.cppFlags;
@@ -868,7 +893,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
args = args.concat(Cpp.collectSystemIncludePathsArguments(input));
var minimumWindowsVersion = input.cpp.minimumWindowsVersion;
- if (minimumWindowsVersion && product.qbs.targetOS.contains("windows")) {
+ if (minimumWindowsVersion && product.qbs.targetOS.includes("windows")) {
var hexVersion = WindowsUtils.getWindowsVersionInFormat(minimumWindowsVersion, 'hex');
if (hexVersion) {
var versionDefs = [ 'WINVER', '_WIN32_WINNT', '_WIN32_WINDOWS' ];
@@ -881,7 +906,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
switch (tag) {
case "c":
case "objc":
- var knownValues = ["c11", "c99", "c90", "c89"];
+ var knownValues = ["c2x", "c17", "c11", "c99", "c90", "c89"];
return Cpp.languageVersion(input.cpp.cLanguageVersion, knownValues, "C");
case "cpp":
case "objcpp":
@@ -902,7 +927,7 @@ function compilerFlags(project, product, input, output, explicitlyDependsOn) {
if (tag === "cpp" || tag === "objcpp") {
var cxxStandardLibrary = product.cpp.cxxStandardLibrary;
- if (cxxStandardLibrary && product.qbs.toolchain.contains("clang")) {
+ if (cxxStandardLibrary && product.qbs.toolchain.includes("clang")) {
args.push("-stdlib=" + cxxStandardLibrary);
}
}
@@ -917,7 +942,7 @@ function additionalCompilerAndLinkerFlags(product) {
var args = []
var requireAppExtensionSafeApi = product.cpp.requireAppExtensionSafeApi;
- if (requireAppExtensionSafeApi !== undefined && product.qbs.targetOS.contains("darwin")) {
+ if (requireAppExtensionSafeApi !== undefined && product.qbs.targetOS.includes("darwin")) {
args.push(requireAppExtensionSafeApi ? "-fapplication-extension" : "-fno-application-extension");
}
@@ -968,7 +993,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output) {
function compilerEnvVars(config, compilerInfo)
{
- if (config.qbs.toolchain.contains("qcc"))
+ if (config.qbs.toolchain.includes("qcc"))
return ["QCC_CONF_PATH"];
var list = ["CPATH", "TMPDIR"];
@@ -980,15 +1005,15 @@ function compilerEnvVars(config, compilerInfo)
list.push("OBJC_INCLUDE_PATH");
else if (compilerInfo.tag === "objccpp")
list.push("OBJCPLUS_INCLUDE_PATH");
- if (config.qbs.targetOS.contains("macos"))
+ if (config.qbs.targetOS.includes("macos"))
list.push("MACOSX_DEPLOYMENT_TARGET");
- else if (config.qbs.targetOS.contains("ios"))
+ else if (config.qbs.targetOS.includes("ios"))
list.push("IPHONEOS_DEPLOYMENT_TARGET");
- else if (config.qbs.targetOS.contains("tvos"))
+ else if (config.qbs.targetOS.includes("tvos"))
list.push("TVOS_DEPLOYMENT_TARGET");
- else if (config.qbs.targetOS.contains("watchos"))
+ else if (config.qbs.targetOS.includes("watchos"))
list.push("WATCHOS_DEPLOYMENT_TARGET");
- if (config.qbs.toolchain.contains("clang")) {
+ if (config.qbs.toolchain.includes("clang")) {
list.push("TEMP", "TMP");
} else {
list.push("LANG", "LC_CTYPE", "LC_MESSAGES", "LC_ALL", "GCC_COMPARE_DEBUG",
@@ -999,7 +1024,7 @@ function compilerEnvVars(config, compilerInfo)
function linkerEnvVars(config, inputs)
{
- if (config.qbs.toolchain.contains("clang") || config.qbs.toolchain.contains("qcc"))
+ if (config.qbs.toolchain.includes("clang") || config.qbs.toolchain.includes("qcc"))
return [];
var list = ["GNUTARGET", "LDEMULATION", "COLLECT_NO_DEMANGLE"];
if (useCompilerDriverLinker(config, inputs))
@@ -1009,7 +1034,7 @@ function linkerEnvVars(config, inputs)
function setResponseFileThreshold(command, product)
{
- if (product.qbs.targetOS.contains("windows") && product.qbs.hostOS.contains("windows"))
+ if (product.qbs.targetOS.includes("windows") && Host.os().includes("windows"))
command.responseFileThreshold = 10000;
}
@@ -1017,7 +1042,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var compilerInfo = effectiveCompilerInfo(product.qbs.toolchain,
input, output);
var compilerPath = compilerInfo.path;
- var pchOutput = output.fileTags.contains(compilerInfo.tag + "_pch");
+ var pchOutput = output.fileTags.includes(compilerInfo.tag + "_pch");
var args = compilerFlags(project, product, input, output, explicitlyDependsOn);
var wrapperArgsLength = 0;
@@ -1107,7 +1132,7 @@ function getSymbolInfo(product, inputFile)
// construct the list of defined symbols by subtracting.
var undefinedGlobalSymbols = collectStdoutLines(command, args.concat(["-u", inputFile]));
result.definedGlobalSymbols = result.allGlobalSymbols.filter(function(line) {
- return !undefinedGlobalSymbols.contains(line); });
+ return !undefinedGlobalSymbols.includes(line); });
result.success = true;
} catch (e) {
console.debug("Failed to collect symbols for shared library: nm command '"
@@ -1207,8 +1232,13 @@ function createSymbolCheckingCommands(product, outputs) {
oldSymbols = oldNmResult.allGlobalSymbols;
newSymbols = newNmResult.allGlobalSymbols;
} else {
- oldSymbols = oldNmResult.definedGlobalSymbols;
- newSymbols = newNmResult.definedGlobalSymbols;
+ var weakFilter = function(line) {
+ var symbolType = line.split(/\s+/)[1];
+ return symbolType != "v" && symbolType != "V"
+ && symbolType != "w" && symbolType != "W";
+ };
+ oldSymbols = oldNmResult.definedGlobalSymbols.filter(weakFilter);
+ newSymbols = newNmResult.definedGlobalSymbols.filter(weakFilter);
}
if (oldSymbols.length !== newSymbols.length) {
console.debug("List of relevant symbols differs for '" + libFilePath + "'.");
@@ -1314,7 +1344,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var responseFileArgumentIndex = wrapperArgsLength;
// qcc doesn't properly handle response files, so we have to do it manually
- var useQnxResponseFileHack = product.qbs.toolchain.contains("qcc")
+ var useQnxResponseFileHack = product.qbs.toolchain.includes("qcc")
&& useCompilerDriverLinker(product, inputs);
if (useQnxResponseFileHack) {
// qcc needs to see at least one object/library file to think it has something to do,
@@ -1334,7 +1364,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
setResponseFileThreshold(cmd, product);
commands.push(cmd);
- if (product.qbs.targetOS.contains("darwin")) {
+ if (product.qbs.targetOS.includes("darwin")) {
if (!product.aggregate) {
commands = commands.concat(separateDebugInfoCommandsDarwin(
product, outputs, [primaryOutput]));
@@ -1468,7 +1498,7 @@ function dumpDefaultPaths(env, compilerFilePath, args, nullDevice, pathListSepar
if (libraryPaths.length === 0)
libraryPaths.push(sysroot + "/lib", sysroot + "/usr/lib");
- if (frameworkPaths.length === 0 && targetOS.contains("darwin"))
+ if (frameworkPaths.length === 0 && targetOS.includes("darwin"))
frameworkPaths.push(sysroot + "/System/Library/Frameworks");
return {
@@ -1496,9 +1526,9 @@ function targetLinkerFlags(targetArch, targetOS) {
"x86_64": "elf_x86_64",
}
};
- if (targetOS.contains("windows"))
+ if (targetOS.includes("windows"))
return linkerFlags["windows"][targetArch];
- else if (targetOS.contains("freebsd"))
+ else if (targetOS.includes("freebsd"))
return linkerFlags["freebsd"][targetArch];
return linkerFlags["other"][targetArch];
}
diff --git a/share/qbs/modules/cpp/iar.js b/share/qbs/modules/cpp/iar.js
index 3848761f5..ed58ac262 100644
--- a/share/qbs/modules/cpp/iar.js
+++ b/share/qbs/modules/cpp/iar.js
@@ -450,6 +450,7 @@ function dumpMacros(compilerFilePath, tag) {
args.push(cppLanguageOption(compilerFilePath));
var p = new Process();
+ p.setWorkingDirectory(tempDir.path());
p.exec(compilerFilePath, args, true);
var outFile = new TextFile(outFilePath, TextFile.ReadOnly);
return Cpp.extractMacros(outFile.readAll());
@@ -471,6 +472,7 @@ function dumpCompilerIncludePaths(compilerFilePath, tag) {
var includePaths = [];
var p = new Process();
+ p.setWorkingDirectory(tempDir.path());
// It is possible that the process can return an error code in case the
// compiler does not support the `--IDE3` flag. So, don't throw an error in this case.
p.exec(compilerFilePath, args, false);
@@ -573,7 +575,7 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
args.push("--c89");
break;
default:
- // Default C language version is C11/C99 that
+ // Default C language version is C18/C11/C99 that
// depends on the IAR version.
break;
}
@@ -682,7 +684,7 @@ function linkerFlags(project, product, inputs, outputs) {
args = args.concat(Cpp.collectLibraryDependenciesArguments(product));
// Linker scripts.
- args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs));
+ args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs, true));
// Silent output generation flag.
args.push(product.cpp.linkerSilentFlag);
@@ -729,6 +731,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
return [cmd];
}
@@ -738,6 +741,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output, expl
var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
return [cmd];
}
@@ -748,6 +752,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var cmd = new Command(linkerPath, args);
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
return [cmd];
}
@@ -755,8 +760,9 @@ function prepareArchiver(project, product, inputs, outputs, input, output) {
var args = archiverFlags(project, product, inputs, outputs);
var archiverPath = product.cpp.archiverPath;
var cmd = new Command(archiverPath, args);
- cmd.description = "linking " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
cmd.stdoutFilterFunction = function(output) {
return "";
};
diff --git a/share/qbs/modules/cpp/iar.qbs b/share/qbs/modules/cpp/iar.qbs
index f02c033ce..558635ef5 100644
--- a/share/qbs/modules/cpp/iar.qbs
+++ b/share/qbs/modules/cpp/iar.qbs
@@ -37,7 +37,7 @@ import "cpp.js" as Cpp
import "iar.js" as IAR
CppModule {
- condition: qbs.toolchain && qbs.toolchain.contains("iar")
+ condition: qbs.toolchain && qbs.toolchain.includes("iar")
Probes.BinaryProbe {
id: compilerPathProbe
diff --git a/share/qbs/modules/cpp/ios-gcc.qbs b/share/qbs/modules/cpp/ios-gcc.qbs
index 2d73c8125..968b873da 100644
--- a/share/qbs/modules/cpp/ios-gcc.qbs
+++ b/share/qbs/modules/cpp/ios-gcc.qbs
@@ -31,16 +31,17 @@
import qbs.DarwinTools
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Utilities
DarwinGCC {
priority: 1
- condition: qbs.targetOS.contains('ios') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('ios') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
minimumIosVersion: {
- if (qbs.architecture == "armv7a")
+ if (Host.architecture() == "armv7a")
return "6.0";
// XCode 12 requres version (at least 8.0) to be present in the -target triplet
// when compiling for ios-simulator
@@ -50,10 +51,10 @@ DarwinGCC {
targetSystem: "ios" + (minimumIosVersion || "")
minimumDarwinVersion: minimumIosVersion
- minimumDarwinVersionCompilerFlag: qbs.targetOS.contains("ios-simulator")
+ minimumDarwinVersionCompilerFlag: qbs.targetOS.includes("ios-simulator")
? "-mios-simulator-version-min"
: "-miphoneos-version-min"
- minimumDarwinVersionLinkerFlag: qbs.targetOS.contains("ios-simulator")
+ minimumDarwinVersionLinkerFlag: qbs.targetOS.includes("ios-simulator")
? "-ios_simulator_version_min"
: "-iphoneos_version_min"
@@ -68,13 +69,13 @@ DarwinGCC {
readonly property stringList simulatorObjcFlags: {
// default in Xcode and also required for building 32-bit Simulator binaries with ARC
// since the default ABI version is 0 for 32-bit targets
- return qbs.targetOS.contains("ios-simulator")
+ return qbs.targetOS.includes("ios-simulator")
? ["-fobjc-abi-version=2", "-fobjc-legacy-dispatch"]
: [];
}
Rule {
- condition: !product.qbs.targetOS.contains("ios-simulator")
+ condition: !product.qbs.targetOS.includes("ios-simulator")
inputsFromDependencies: ["bundle.content"]
Artifact {
diff --git a/share/qbs/modules/cpp/keil.js b/share/qbs/modules/cpp/keil.js
index 5a5e165c8..8f3297aa2 100644
--- a/share/qbs/modules/cpp/keil.js
+++ b/share/qbs/modules/cpp/keil.js
@@ -818,7 +818,7 @@ function linkerFlags(project, product, inputs, outputs) {
args = args.concat(Cpp.collectLibraryDependenciesArguments(product));
// Linker scripts.
- args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs));
+ args = args.concat(Cpp.collectLinkerScriptPathsArguments(product, inputs, true));
// Map file generation flag.
if (product.cpp.generateLinkerMapFile)
@@ -917,6 +917,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
if (isMcsArchitecture(architecture)) {
cmd.maxExitCode = 1;
cmd.stdoutFilterFunction = filterMcsOutput;
@@ -944,6 +945,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output, expl
var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
if (isMcsArchitecture(architecture)) {
cmd.maxExitCode = 1;
cmd.stdoutFilterFunction = filterMcsOutput;
@@ -962,6 +964,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var cmd = new Command(linkerPath, args);
cmd.description = "linking " + primaryOutput.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
if (isMcsArchitecture(architecture)) {
cmd.maxExitCode = 1;
cmd.stdoutFilterFunction = filterMcsOutput;
@@ -977,8 +980,9 @@ function prepareArchiver(project, product, inputs, outputs, input, output) {
var archiverPath = product.cpp.archiverPath;
var architecture = product.cpp.architecture;
var cmd = new Command(archiverPath, args);
- cmd.description = "linking " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
if (isMcsArchitecture(architecture)) {
cmd.stdoutFilterFunction = filterMcsOutput;
} else if (isC166Architecture(architecture)) {
diff --git a/share/qbs/modules/cpp/keil.qbs b/share/qbs/modules/cpp/keil.qbs
index c66e95a47..5922ad4e2 100644
--- a/share/qbs/modules/cpp/keil.qbs
+++ b/share/qbs/modules/cpp/keil.qbs
@@ -30,12 +30,13 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.Probes
import "cpp.js" as Cpp
import "keil.js" as KEIL
CppModule {
- condition: qbs.hostOS.contains("windows") && qbs.toolchain && qbs.toolchain.contains("keil")
+ condition: Host.os().includes("windows") && qbs.toolchain && qbs.toolchain.includes("keil")
Probes.BinaryProbe {
id: compilerPathProbe
diff --git a/share/qbs/modules/cpp/macos-gcc.qbs b/share/qbs/modules/cpp/macos-gcc.qbs
index 612b46ae8..c667bbc29 100644
--- a/share/qbs/modules/cpp/macos-gcc.qbs
+++ b/share/qbs/modules/cpp/macos-gcc.qbs
@@ -33,8 +33,8 @@ import qbs.Utilities
DarwinGCC {
priority: 1
- condition: qbs.targetOS.contains('macos') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('macos') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
targetSystem: "macosx" + (minimumMacosVersion || "")
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index b206bd4ba..1700c21b3 100644
--- a/share/qbs/modules/cpp/msvc.js
+++ b/share/qbs/modules/cpp/msvc.js
@@ -79,8 +79,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
- || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 7);
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 7)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.12.25831") >= 0;
}
function hasZCplusPlusOption(input)
@@ -92,18 +92,24 @@ function hasZCplusPlusOption(input)
// clang-cl supports this option starting around-ish versions 8/9, but it
// ignores this option, so this doesn't really matter
// https://reviews.llvm.org/D45877
- return Utilities.versionCompare(input.cpp.compilerVersion, "19.14.26433") >= 0
- || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 9);
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 9)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.14.26433") >= 0;
}
function hasCxx20Option(input)
{
- return Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30133.0") >= 0
- || (input.qbs.toolchain.contains("clang-cl") && input.cpp.compilerVersionMajor >= 13);
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 13)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30133.0") >= 0;
+}
+
+function hasCVerOption(input)
+{
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 13)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30138.0") >= 0;
}
function supportsExternalIncludesOption(input) {
- if (input.qbs.toolchain.contains("clang-cl"))
+ if (input.qbs.toolchain.includes("clang-cl"))
return false; // Exclude clang-cl.
// This option was introcuded since MSVC 2017 v15.6 (aka _MSC_VER 19.13).
// But due to some MSVC bugs:
@@ -112,16 +118,15 @@ function supportsExternalIncludesOption(input) {
return Utilities.versionCompare(input.cpp.compilerVersion, "19.16") >= 0;
}
-function addLanguageVersionFlag(input, args) {
+function addCxxLanguageVersionFlag(input, args) {
var cxxVersion = Cpp.languageVersion(input.cpp.cxxLanguageVersion,
["c++23", "c++20", "c++17", "c++14", "c++11", "c++98"], "C++");
if (!cxxVersion)
return;
- // Visual C++ 2013, Update 3
- var hasStdOption = Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0
- // or clang-cl
- || input.qbs.toolchain.contains("clang-cl");
+ // Visual C++ 2013, Update 3 or clang-cl
+ var hasStdOption = input.qbs.toolchain.includes("clang-cl")
+ || Utilities.versionCompare(input.cpp.compilerVersion, "18.00.30723") >= 0;
if (!hasStdOption)
return;
@@ -138,8 +143,27 @@ function addLanguageVersionFlag(input, args) {
args.push(flag);
}
+function addCLanguageVersionFlag(input, args) {
+ var cVersion = Cpp.languageVersion(input.cpp.cLanguageVersion,
+ ["c17", "c11"], "C");
+ if (!cVersion)
+ return;
+
+ var hasStdOption = hasCVerOption(input);
+ if (!hasStdOption)
+ return;
+
+ var flag;
+ if (cVersion === "c17")
+ flag = "/std:c17";
+ else if (cVersion === "c11")
+ flag = "/std:c11";
+ if (flag)
+ args.push(flag);
+}
+
function handleClangClArchitectureFlags(product, architecture, flags) {
- if (product.qbs.toolchain.contains("clang-cl")) {
+ if (product.qbs.toolchain.includes("clang-cl")) {
if (architecture === "x86")
flags.push("-m32");
else if (architecture === "x86_64")
@@ -156,7 +180,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
// Determine which C-language we're compiling
var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(Object.keys(outputs)));
- if (!["c", "cpp"].contains(tag))
+ if (!["c", "cpp"].includes(tag))
throw ("unsupported source language");
var enableExceptions = input.cpp.enableExceptions;
@@ -225,14 +249,17 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
return input.cpp.includeFlag + FileInfo.toWindowsSeparators(path);
}));
- var includeFlag = input.cpp.includeFlag;
- if (supportsExternalIncludesOption(input)) {
- args.push("/experimental:external");
- var enforcesSlashW =
- Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30037") >= 0
- if (enforcesSlashW)
- args.push("/external:W0")
- includeFlag = input.cpp.systemIncludeFlag;
+ var includeFlag = input.qbs.toolchain.includes("clang-cl")
+ ? input.cpp.systemIncludeFlag : input.cpp.includeFlag;
+ if (!input.qbs.toolchain.includes("clang-cl")) {
+ if (supportsExternalIncludesOption(input)) {
+ args.push("/experimental:external");
+ var enforcesSlashW =
+ Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30037") >= 0
+ if (enforcesSlashW)
+ args.push("/external:W0")
+ includeFlag = input.cpp.systemIncludeFlag;
+ }
}
var systemIncludePaths = Cpp.collectSystemIncludePaths(input);
args = args.concat([].uniqueConcat(systemIncludePaths).map(function(path) {
@@ -277,9 +304,10 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
// Language
if (tag === "cpp") {
args.push("/TP");
- addLanguageVersionFlag(input, args);
+ addCxxLanguageVersionFlag(input, args);
} else if (tag === "c") {
args.push("/TC");
+ addCLanguageVersionFlag(input, args);
}
// Whether we're compiling a precompiled header or normal source file
@@ -287,7 +315,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var pchInputs = explicitlyDependsOn[tag + "_pch"];
if (pchOutput) {
// create PCH
- if (input.qbs.toolchain.contains("clang-cl")) {
+ if (input.qbs.toolchain.includes("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
@@ -345,7 +373,8 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
function linkerSupportsWholeArchive(product)
{
- return Utilities.versionCompare(product.cpp.compilerVersion, "19.0.24215.1") >= 0
+ return product.qbs.toolchainType.includes("clang-cl") ||
+ Utilities.versionCompare(product.cpp.compilerVersion, "19.0.24215.1") >= 0
}
function handleDiscardProperty(product, flags) {
@@ -361,16 +390,16 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var linkDLL = (outputs.dynamiclibrary ? true : false)
var primaryOutput = (linkDLL ? outputs.dynamiclibrary[0] : outputs.application[0])
var debugInformation = product.cpp.debugInformation;
- var additionalManifestInputs = Array.prototype.map.call(inputs["native.pe.manifest"],
+ var additionalManifestInputs = Array.prototype.map.call(inputs["native.pe.manifest"] || [],
function (a) {
return a.filePath;
});
- var moduleDefinitionInputs = Array.prototype.map.call(inputs["def"],
+ var moduleDefinitionInputs = Array.prototype.map.call(inputs["def"] || [],
function (a) {
return a.filePath;
});
var generateManifestFiles = !linkDLL && product.cpp.generateManifestFile;
- var useClangCl = product.qbs.toolchain.contains("clang-cl");
+ var useClangCl = product.qbs.toolchain.includes("clang-cl");
var canEmbedManifest = useClangCl || product.cpp.compilerVersionMajor >= 17 // VS 2012
var linkerPath = effectiveLinkerPath(product, inputs);
diff --git a/share/qbs/modules/cpp/qnx-qcc.qbs b/share/qbs/modules/cpp/qnx-qcc.qbs
index a39a6a998..69288ddd8 100644
--- a/share/qbs/modules/cpp/qnx-qcc.qbs
+++ b/share/qbs/modules/cpp/qnx-qcc.qbs
@@ -33,8 +33,8 @@ import qbs.FileInfo
UnixGCC {
Depends { name: "qnx" }
- condition: qbs.targetOS.contains("qnx") &&
- qbs.toolchain && qbs.toolchain.contains("qcc")
+ condition: qbs.targetOS.includes("qnx") &&
+ qbs.toolchain && qbs.toolchain.includes("qcc")
priority: 1
distributionIncludePaths: FileInfo.joinPaths(qnx.targetDir, "usr", "include")
@@ -79,7 +79,7 @@ UnixGCC {
toolchainPrefix: target + "-"
- targetVendor: ["x86", "x86_64"].contains(qbs.architecture) ? "pc" : base
+ targetVendor: ["x86", "x86_64"].includes(qbs.architecture) ? "pc" : base
targetSystem: "nto"
targetAbi: "qnx" + qnx.version + (qnxTargetArchName === "armv7le" ? "eabi" : "")
diff --git a/share/qbs/modules/cpp/sdcc.js b/share/qbs/modules/cpp/sdcc.js
index b3dfd92b4..49da8a715 100644
--- a/share/qbs/modules/cpp/sdcc.js
+++ b/share/qbs/modules/cpp/sdcc.js
@@ -33,6 +33,7 @@ var Cpp = require("cpp.js");
var Environment = require("qbs.Environment");
var File = require("qbs.File");
var FileInfo = require("qbs.FileInfo");
+var Host = require("qbs.Host");
var ModUtils = require("qbs.ModUtils");
var PathTools = require("qbs.PathTools");
var Process = require("qbs.Process");
@@ -285,18 +286,18 @@ function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
// C language version flags.
if (tag === "c") {
- var knownValues = ["c11", "c99", "c89"];
+ var knownValues = ["c2x", "c17", "c11", "c99", "c89"];
var cLanguageVersion = Cpp.languageVersion(
input.cpp.cLanguageVersion, knownValues, "C");
switch (cLanguageVersion) {
+ case "c17":
+ cLanguageVersion = "c11";
+ // fall through
case "c89":
- args.push("--std-c89");
- break;
case "c99":
- args.push("--std-c99");
- break;
case "c11":
- args.push("--std-c11");
+ case "c2x":
+ args.push("--std-" + cLanguageVersion);
break;
}
}
@@ -395,7 +396,7 @@ function buildLinkerMapFilePath(target, suffix) {
// We need to replace the '\r\n\' line endings with the'\n' line
// endings for each generated object file.
function patchObjectFile(project, product, inputs, outputs, input, output) {
- var isWindows = input.qbs.hostOS.contains("windows");
+ var isWindows = Host.os().includes("windows");
if (isWindows && input.cpp.debugInformation) {
var cmd = new JavaScriptCommand();
cmd.objectPath = outputs.obj[0].filePath;
@@ -460,10 +461,9 @@ function renameLinkerMapFile(project, product, inputs, outputs, input, output) {
// remove a listing files only after the linking completes.
function removeCompilerListingFiles(project, product, inputs, outputs, input, output) {
var cmd = new JavaScriptCommand();
- cmd.objects = inputs.obj.map(function(a) { return a; });
cmd.silent = true;
cmd.sourceCode = function() {
- objects.forEach(function(object) {
+ inputs.obj.forEach(function(object) {
if (!object.filePath.endsWith(".c" + object.cpp.objectSuffix))
return; // Skip the assembler generated objects.
if (!object.cpp.generateCompilerListingFiles
@@ -505,6 +505,7 @@ function prepareCompiler(project, product, inputs, outputs, input, output, expli
var cmd = new Command(compilerPath, args);
cmd.description = "compiling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "compiler";
cmds.push(cmd);
cmd = patchObjectFile(project, product, inputs, outputs, input, output);
@@ -525,6 +526,7 @@ function prepareAssembler(project, product, inputs, outputs, input, output, expl
var cmd = new Command(assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.highlight = "compiler";
+ cmd.jobPool = "assembler";
cmds.push(cmd);
cmd = patchObjectFile(project, product, inputs, outputs, input, output);
@@ -541,6 +543,7 @@ function prepareLinker(project, product, inputs, outputs, input, output) {
var cmd = new Command(linkerPath, args);
cmd.description = "linking " + outputs.application[0].fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
cmds.push(cmd);
cmd = removeCompilerListingFiles(project, product, inputs, outputs, input, output);
@@ -562,7 +565,8 @@ function prepareArchiver(project, product, inputs, outputs, input, output) {
var args = archiverFlags(project, product, inputs, outputs);
var archiverPath = product.cpp.archiverPath;
var cmd = new Command(archiverPath, args);
- cmd.description = "linking " + output.fileName;
+ cmd.description = "creating " + output.fileName;
cmd.highlight = "linker";
+ cmd.jobPool = "linker";
return [cmd];
}
diff --git a/share/qbs/modules/cpp/sdcc.qbs b/share/qbs/modules/cpp/sdcc.qbs
index 4e6f05bc0..24cb6d738 100644
--- a/share/qbs/modules/cpp/sdcc.qbs
+++ b/share/qbs/modules/cpp/sdcc.qbs
@@ -35,7 +35,7 @@ import "cpp.js" as Cpp
import "sdcc.js" as SDCC
CppModule {
- condition: qbs.toolchain && qbs.toolchain.contains("sdcc")
+ condition: qbs.toolchain && qbs.toolchain.includes("sdcc")
Probes.BinaryProbe {
id: compilerPathProbe
diff --git a/share/qbs/modules/cpp/setuprunenv.js b/share/qbs/modules/cpp/setuprunenv.js
index 550d08d63..2ea331a30 100644
--- a/share/qbs/modules/cpp/setuprunenv.js
+++ b/share/qbs/modules/cpp/setuprunenv.js
@@ -30,11 +30,12 @@
var FileInfo = require("qbs.FileInfo");
var File = require("qbs.File");
+var Host = require("qbs.Host");
var ModUtils = require("qbs.ModUtils"); // TODO: append/prepend functionality should go to qbs.Environment
function addNewElement(list, elem)
{
- if (!list.contains(elem))
+ if (!list.includes(elem))
list.push(elem);
}
@@ -48,7 +49,7 @@ function artifactDir(artifact)
function addExternalLibPath(product, list, path)
{
addNewElement(list, path);
- if (product.qbs.hostOS.contains("windows") && FileInfo.fileName(path) === "lib") {
+ if (Host.os().includes("windows") && FileInfo.fileName(path) === "lib") {
var binPath = FileInfo.joinPaths(FileInfo.path(path), "bin");
if (File.exists(binPath))
addNewElement(list, binPath);
@@ -57,7 +58,7 @@ function addExternalLibPath(product, list, path)
function gatherPaths(product, libPaths, frameworkPaths, seenProducts)
{
- if (seenProducts.contains(product.name))
+ if (seenProducts.includes(product.name))
return;
seenProducts.push(product.name);
@@ -66,6 +67,8 @@ function gatherPaths(product, libPaths, frameworkPaths, seenProducts)
product.cpp.libraryPaths.forEach(function(p) { addExternalLibPath(product, libPaths, p); });
if (product.cpp && product.cpp.frameworkPaths)
product.cpp.frameworkPaths.forEach(function(p) { addNewElement(frameworkPaths, p); });
+ if (product.cpp && product.cpp.systemFrameworkPaths)
+ product.cpp.systemFrameworkPaths.forEach(function(p) { addNewElement(frameworkPaths, p); });
// Extract paths from dynamic libraries, if they are given as file paths.
if (product.cpp && product.cpp.dynamicLibraries) {
@@ -103,10 +106,10 @@ function gatherPaths(product, libPaths, frameworkPaths, seenProducts)
function setupRunEnvironment(product, config)
{
- if (config.contains("ignore-lib-dependencies"))
+ if (config.includes("ignore-lib-dependencies"))
return;
- if (product.qbs.hostPlatform !== product.qbs.targetPlatform)
+ if (Host.platform() !== product.qbs.targetPlatform)
return;
var libPaths = [];
@@ -117,8 +120,8 @@ function setupRunEnvironment(product, config)
if (runPaths && runPaths.length > 0) {
var canonicalRunPaths = runPaths.map(function(p) { return File.canonicalFilePath(p); });
var filterFunc = function(libPath) {
- return !runPaths.contains(libPath)
- && !canonicalRunPaths.contains(File.canonicalFilePath(libPath));
+ return !runPaths.includes(libPath)
+ && !canonicalRunPaths.includes(File.canonicalFilePath(libPath));
};
libPaths = libPaths.filter(filterFunc);
frameworkPaths = frameworkPaths.filter(filterFunc);
@@ -126,19 +129,19 @@ function setupRunEnvironment(product, config)
if (libPaths.length > 0) {
var envVarName;
- if (product.qbs.targetOS.contains("windows"))
+ if (product.qbs.targetOS.includes("windows"))
envVarName = "PATH";
- else if (product.qbs.targetOS.contains("macos"))
+ else if (product.qbs.targetOS.includes("macos"))
envVarName = "DYLD_LIBRARY_PATH";
else
envVarName = "LD_LIBRARY_PATH";
- var envVar = new ModUtils.EnvironmentVariable(envVarName, product.qbs.pathListSeparator,
- product.qbs.hostOS.contains("windows"));
+ var envVar = new ModUtils.EnvironmentVariable(envVarName, FileInfo.pathListSeparator(),
+ Host.os().includes("windows"));
libPaths.forEach(function(p) { envVar.prepend(p); });
envVar.set();
}
- if (product.qbs.targetOS.contains("macos") && frameworkPaths.length > 0) {
+ if (product.qbs.targetOS.includes("macos") && frameworkPaths.length > 0) {
envVar = new ModUtils.EnvironmentVariable("DYLD_FRAMEWORK_PATH", ':', false);
frameworkPaths.forEach(function(p) { envVar.prepend(p); });
envVar.set();
diff --git a/share/qbs/modules/cpp/tvos-gcc.qbs b/share/qbs/modules/cpp/tvos-gcc.qbs
index 19bc9b787..eba3b091e 100644
--- a/share/qbs/modules/cpp/tvos-gcc.qbs
+++ b/share/qbs/modules/cpp/tvos-gcc.qbs
@@ -30,16 +30,16 @@
DarwinGCC {
priority: 1
- condition: qbs.targetOS.contains('tvos') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('tvos') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
targetSystem: "tvos" + (minimumTvosVersion || "")
minimumDarwinVersion: minimumTvosVersion
- minimumDarwinVersionCompilerFlag: qbs.targetOS.contains("tvos-simulator")
+ minimumDarwinVersionCompilerFlag: qbs.targetOS.includes("tvos-simulator")
? "-mtvos-simulator-version-min"
: "-mtvos-version-min"
- minimumDarwinVersionLinkerFlag: qbs.targetOS.contains("tvos-simulator")
+ minimumDarwinVersionLinkerFlag: qbs.targetOS.includes("tvos-simulator")
? "-tvos_simulator_version_min"
: "-tvos_version_min"
}
diff --git a/share/qbs/modules/cpp/watchos-gcc.qbs b/share/qbs/modules/cpp/watchos-gcc.qbs
index 46e4bf874..3a160f6d0 100644
--- a/share/qbs/modules/cpp/watchos-gcc.qbs
+++ b/share/qbs/modules/cpp/watchos-gcc.qbs
@@ -31,16 +31,16 @@
DarwinGCC {
priority: 1
- condition: qbs.targetOS.contains('watchos') &&
- qbs.toolchain && qbs.toolchain.contains('gcc')
+ condition: qbs.targetOS.includes('watchos') &&
+ qbs.toolchain && qbs.toolchain.includes('gcc')
targetSystem: "watchos" + (minimumWatchosVersion || "")
minimumDarwinVersion: minimumWatchosVersion
- minimumDarwinVersionCompilerFlag: qbs.targetOS.contains("watchos-simulator")
+ minimumDarwinVersionCompilerFlag: qbs.targetOS.includes("watchos-simulator")
? "-mwatchos-simulator-version-min"
: "-mwatchos-version-min"
- minimumDarwinVersionLinkerFlag: qbs.targetOS.contains("watchos-simulator")
+ minimumDarwinVersionLinkerFlag: qbs.targetOS.includes("watchos-simulator")
? "-watchos_simulator_version_min"
: "-watchos_version_min"
}
diff --git a/share/qbs/modules/cpp/watcom.js b/share/qbs/modules/cpp/watcom.js
new file mode 100644
index 000000000..9ae893db9
--- /dev/null
+++ b/share/qbs/modules/cpp/watcom.js
@@ -0,0 +1,568 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 Denis Shienkov <denis.shienkov@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.
+**
+****************************************************************************/
+
+var Cpp = require("cpp.js");
+var Environment = require("qbs.Environment");
+var File = require("qbs.File");
+var FileInfo = require("qbs.FileInfo");
+var ModUtils = require("qbs.ModUtils");
+var PathTools = require("qbs.PathTools");
+var Process = require("qbs.Process");
+var TemporaryDir = require("qbs.TemporaryDir");
+var TextFile = require("qbs.TextFile");
+var Utilities = require("qbs.Utilities");
+
+function toolchainDetails(qbs) {
+ var platform = qbs.targetPlatform;
+ var details = {};
+ if (platform === "dos") {
+ details.imageFormat = "mz";
+ details.executableSuffix = ".exe";
+ } else if (platform === "os2") {
+ details.imageFormat = "pe";
+ details.executableSuffix = ".exe";
+ details.dynamicLibrarySuffix = ".dll";
+ } else if (platform === "windows") {
+ details.imageFormat = "pe";
+ details.executableSuffix = ".exe";
+ details.dynamicLibrarySuffix = ".dll";
+ } else if (platform === "linux") {
+ details.imageFormat = "elf";
+ details.executableSuffix = "";
+ details.dynamicLibrarySuffix = ".so";
+ }
+ return details;
+}
+
+function languageFlag(tag) {
+ if (tag === "c")
+ return "-xc";
+ else if (tag === "cpp")
+ return "-xc++";
+}
+
+function targetFlag(platform, architecture, type) {
+ if (platform === "dos") {
+ if (architecture === "x86_16")
+ return "-bdos";
+ else if (architecture === "x86")
+ return "-bdos4g";
+ } else if (platform === "os2") {
+ if (architecture === "x86_16")
+ return "-bos2";
+ else if (architecture === "x86")
+ return "-bos2v2";
+ } else if (platform === "windows") {
+ if (architecture === "x86_16") {
+ if (type.includes("dynamiclibrary"))
+ return "-bwindows_dll";
+ return "-bwindows";
+ } else if (architecture === "x86") {
+ if (type.includes("dynamiclibrary"))
+ return "-bnt_dll";
+ return "-bnt";
+ }
+ } else if (platform === "linux") {
+ return "-blinux";
+ }
+}
+
+function guessVersion(macros) {
+ var version = parseInt(macros["__WATCOMC__"], 10)
+ || parseInt(macros["__WATCOM_CPLUSPLUS__"], 10);
+ if (version) {
+ return { major: parseInt((version - 1100) / 100),
+ minor: parseInt(version / 10) % 10,
+ patch: ((version % 10) > 0) ? parseInt(version % 10) : 0 }
+ }
+}
+
+function guessEnvironment(hostOs, platform, architecture,
+ toolchainInstallPath, pathListSeparator) {
+ var toolchainRootPath = FileInfo.path(toolchainInstallPath);
+ if (!File.exists(toolchainRootPath)) {
+ throw "Unable to deduce environment due to compiler root directory: '"
+ + toolchainRootPath + "' does not exist";
+ }
+
+ var env = {};
+
+ function setVariable(key, properties, path, separator) {
+ var values = [];
+ for (var i = 0; i < properties.length; ++i) {
+ if (path) {
+ var fullpath = FileInfo.joinPaths(path, properties[i]);
+ values.push(FileInfo.toNativeSeparators(fullpath));
+ } else {
+ values.push(properties[i]);
+ }
+ }
+ env[key] = values.join(separator);
+ }
+
+ setVariable("WATCOM", [toolchainRootPath], undefined, pathListSeparator);
+ setVariable("EDPATH", ["eddat"], toolchainRootPath, pathListSeparator);
+
+ if (hostOs.includes("linux"))
+ setVariable("PATH", ["binl64", "binl"], toolchainRootPath, pathListSeparator);
+ else if (hostOs.includes("windows"))
+ setVariable("PATH", ["binnt64", "binnt"], toolchainRootPath, pathListSeparator);
+
+ if (platform === "linux") {
+ setVariable("INCLUDE", ["lh"], toolchainRootPath, pathListSeparator);
+ } else {
+ // Common for DOS, Windows, OS/2.
+ setVariable("WIPFC", ["wipfc"], toolchainRootPath, pathListSeparator);
+ setVariable("WHTMLHELP", ["binnt/help"], toolchainRootPath, pathListSeparator);
+
+ var includes = ["h"];
+ if (platform === "dos") {
+ // Same includes as before.
+ } else if (platform === "os2") {
+ if (architecture === "x86")
+ includes = includes.concat(["h/os2"]);
+ else if (architecture === "x86_16")
+ includes = includes.concat(["h/os21x"]);
+ } else if (platform === "windows") {
+ if (architecture === "x86")
+ includes = includes.concat(["h/nt", "h/nt/directx", "h/nt/ddk"]);
+ else if (architecture === "x86_16")
+ includes = includes.concat(["h/win"]);
+ } else {
+ throw "Unable to deduce environment for unsupported target platform: '"
+ + platform + "'";
+ }
+
+ setVariable("INCLUDE", includes, toolchainRootPath, pathListSeparator);
+ }
+
+ return env;
+}
+
+function dumpMacros(environment, compilerPath, platform, architecture, tag) {
+ // Note: The Open Watcom compiler does not support the predefined
+ // macros dumping. So, we do it with the following trick, where we try
+ // to create and compile a special temporary file and to parse the console
+ // output with the own magic pattern: #define <key> <value>.
+
+ var outputDirectory = new TemporaryDir();
+ var outputFilePath = FileInfo.joinPaths(outputDirectory.path(), "dump-macros.c");
+ var outputFile = new TextFile(outputFilePath, TextFile.WriteOnly);
+ outputFile.writeLine("#define VALUE_TO_STRING(x) #x");
+ outputFile.writeLine("#define VALUE(x) VALUE_TO_STRING(x)");
+ outputFile.writeLine("#define VAR_NAME_VALUE(var) \"#define \"#var\" \"VALUE(var)");
+ // Declare all available pre-defined macros of Watcon compiler.
+ var keys = [
+ // Prepare the DOS target macros.
+ "__DOS__", "_DOS", "MSDOS",
+ // Prepare the OS/2 target macros.
+ "__OS2__",
+ // Prepare the QNX target macros.
+ "__QNX__",
+ // Prepare the Netware target macros.
+ "__NETWARE__", "__NETWARE_386__",
+ // Prepare the Windows target macros.
+ "__NT__", "__WINDOWS__", "_WINDOWS", "__WINDOWS_386__",
+ // Prepare the Linux and Unix target macros.
+ "__LINUX__", "__UNIX__",
+ // Prepare the 16-bit target specific macros.
+ "__I86__", "M_I86", "_M_I86", "_M_IX86",
+ // Prepare the 32-bit target specific macros.
+ "__386__", "M_I386", "_M_I386", "_M_IX86",
+ // Prepare the indicated options macros.
+ "_MT", "_DLL", "__FPI__", "__CHAR_SIGNED__", "__INLINE_FUNCTIONS__",
+ "_CPPRTTI", "_CPPUNWIND", "NO_EXT_KEYS",
+ // Prepare the common memory model macros.
+ "__FLAT__", "__SMALL__", "__MEDIUM__",
+ "__COMPACT__", "__LARGE__", "__HUGE__",
+ // Prepare the 16-bit memory model macros.
+ "M_I86SM", "_M_I86SM", "M_I86MM", "_M_I86MM", "M_I86CM",
+ "_M_I86CM", "M_I86LM", "_M_I86LM", "M_I86HM", "_M_I86HM",
+ // Prepare the 32-bit memory model macros.
+ "M_386FM", "_M_386FM", "M_386SM", "M_386MM", "_M_386MM",
+ "M_386CM", "_M_386CM", "M_386LM", "_M_386LM",
+ // Prepare the compiler macros.
+ "__X86__", "__cplusplus", "__WATCOMC__", "__WATCOM_CPLUSPLUS__",
+ "_INTEGRAL_MAX_BITS", "_PUSHPOP_SUPPORTED", "_STDCALL_SUPPORTED",
+ // Prepare the other macros.
+ "__3R__", "_based", "_cdecl", "cdecl", "_export", "_far16", "_far", "far",
+ "_fastcall", "_fortran", "fortran", "_huge", "huge", "_inline", "_interrupt",
+ "interrupt", "_loadds", "_near", "near", "_pascal", "pascal", "_saveregs",
+ "_segment", "_segname", "_self", "SOMDLINK", "_STDCALL_SUPPORTED", "__SW_0",
+ "__SW_3R", "__SW_5", "__SW_FP287", "__SW_FP2", "__SW_FP387", "__SW_FP3",
+ "__SW_FPI", "__SW_MF", "__SW_MS", "__SW_ZDP", "__SW_ZFP", "__SW_ZGF",
+ "__SW_ZGP", "_stdcall", "_syscall", "__BIG_ENDIAN"
+ ];
+ for (var i = 0; i < keys.length; ++i) {
+ var key = keys[i];
+ outputFile.writeLine("#if defined(" + key + ")");
+ outputFile.writeLine("#pragma message (VAR_NAME_VALUE(" + key + "))");
+ outputFile.writeLine("#endif");
+ }
+ outputFile.close();
+
+ var process = new Process();
+ process.setWorkingDirectory(outputDirectory.path());
+ for (var envkey in environment)
+ process.setEnv(envkey, environment[envkey]);
+
+ var target = targetFlag(platform, architecture, ["application"]);
+ var lang = languageFlag(tag);
+ var args = [ target, lang, outputFilePath ];
+
+ process.exec(compilerPath, args, false);
+ var m = Cpp.extractMacros(process.readStdOut(), /"?(#define(\s\w+){1,2})"?$/);
+ if (tag === "cpp" && m["__cplusplus"] === "1")
+ return m;
+ else if (tag === "c")
+ return m;
+}
+
+function effectiveLinkerPath(product) {
+ if (product.cpp.linkerMode === "automatic") {
+ var compilerPath = product.cpp.compilerPath;
+ if (compilerPath)
+ return compilerPath;
+ console.log("Found no C-language objects, choosing system linker for " + product.name);
+ }
+ return product.cpp.linkerPath;
+}
+
+function useCompilerDriverLinker(product) {
+ var linker = effectiveLinkerPath(product);
+ var compiler = product.cpp.compilerPath;
+ return linker === compiler;
+}
+
+function escapeLinkerFlags(useCompilerDriver, linkerFlags) {
+ if (!linkerFlags || linkerFlags.length === 0)
+ return [];
+
+ if (useCompilerDriver) {
+ var sep = ",";
+ return [["-Wl"].concat(linkerFlags).join(sep)];
+ }
+ return linkerFlags;
+}
+
+function assemblerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = [FileInfo.toNativeSeparators(input.filePath)];
+ args.push("-fo=" + FileInfo.toNativeSeparators(outputs.obj[0].filePath));
+
+ args = args.concat(Cpp.collectPreincludePaths(input).map(function(path) {
+ return "-fi" + FileInfo.toNativeSeparators(path);
+ }));
+
+ args = args.concat(Cpp.collectDefinesArguments(input, "-d"));
+
+ var includePaths = [].concat(Cpp.collectIncludePaths(input)).concat(
+ Cpp.collectSystemIncludePaths(input));
+ args = args.concat(includePaths.map(function(path) {
+ return "-i" + FileInfo.toNativeSeparators(path);
+ }));
+
+ if (input.cpp.debugInformation)
+ args.push("-d1");
+
+ var warnings = input.cpp.warningLevel
+ if (warnings === "none")
+ args.push("-w0");
+ else if (warnings === "all")
+ args.push("-wx");
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("-we");
+
+ args.push("-zq"); // Silent.
+ args = args.concat(Cpp.collectMiscAssemblerArguments(input));
+ return args;
+}
+
+function compilerFlags(project, product, input, outputs, explicitlyDependsOn) {
+ var args = ["-g" + (input.cpp.debugInformation ? "3" : "0")];
+
+ var target = targetFlag(product.qbs.targetPlatform, product.qbs.architecture,
+ product.type);
+ args.push(target);
+
+ if (product.type.includes("application")) {
+ if (product.qbs.targetPlatform === "windows") {
+ var consoleApplication = product.consoleApplication;
+ args.push(consoleApplication ? "-mconsole" : "-mwindows");
+ }
+ } else if (product.type.includes("dynamiclibrary")) {
+ args.push("-shared");
+ }
+
+ var optimization = input.cpp.optimization
+ if (optimization === "fast")
+ args.push("-Ot");
+ else if (optimization === "small")
+ args.push("-Os");
+ else if (optimization === "none")
+ args.push("-O0");
+
+ var warnings = input.cpp.warningLevel
+ if (warnings === "none") {
+ args.push("-w");
+ } else if (warnings === "all") {
+ args.push("-Wall");
+ args.push("-Wextra");
+ }
+ if (input.cpp.treatWarningsAsErrors)
+ args.push("-Werror");
+
+ var tag = ModUtils.fileTagForTargetLanguage(input.fileTags.concat(outputs.obj[0].fileTags));
+
+ var langFlag = languageFlag(tag);
+ if (langFlag)
+ args.push(langFlag);
+
+ if (tag === "cpp") {
+ var enableExceptions = input.cpp.enableExceptions;
+ if (enableExceptions) {
+ var ehModel = input.cpp.exceptionHandlingModel;
+ switch (ehModel) {
+ case "direct":
+ args.push("-feh-direct");
+ break;
+ case "table":
+ args.push("-feh-table");
+ break;
+ default:
+ args.push("-feh");
+ break;
+ }
+ } else {
+ args.push("-fno-eh");
+ }
+
+ var enableRtti = input.cpp.enableRtti;
+ args.push(enableRtti ? "-frtti" : "-fno-rtti");
+ } else if (tag === "c") {
+ var knownValues = ["c99", "c89"];
+ var cLanguageVersion = Cpp.languageVersion(input.cpp.cLanguageVersion, knownValues, "C");
+ switch (cLanguageVersion) {
+ case "c89":
+ args.push("-std=c89");
+ break;
+ case "c99":
+ args.push("-std=c99");
+ break;
+ }
+ }
+
+ var preincludePaths = Cpp.collectPreincludePaths(input);
+ for (var i = 0; i < preincludePaths.length; ++i)
+ args.push(input.cpp.preincludeFlag, preincludePaths[i]);
+
+ args = args.concat(Cpp.collectDefinesArguments(input));
+
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toNativeSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.systemIncludeFlag + FileInfo.toNativeSeparators(path);
+ }));
+
+ args = args.concat(Cpp.collectMiscCompilerArguments(input, tag),
+ Cpp.collectMiscDriverArguments(input));
+
+ args.push("-o", FileInfo.toNativeSeparators(outputs.obj[0].filePath));
+ args.push("-c", FileInfo.toNativeSeparators(input.filePath));
+
+ return args;
+}
+
+function resourceCompilerFlags(project, product, input, outputs) {
+ var args = [input.filePath];
+ args.push("-fo=" + FileInfo.toNativeSeparators(outputs.res[0].filePath));
+ args = args.concat(Cpp.collectDefinesArguments(input, "-d"));
+
+ args = args.concat(Cpp.collectIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toNativeSeparators(path);
+ }));
+ args = args.concat(Cpp.collectSystemIncludePaths(input).map(function(path) {
+ return input.cpp.includeFlag + FileInfo.toNativeSeparators(path);
+ }));
+ args.push("-q", "-ad", "-r");
+ return args;
+}
+
+function linkerFlags(project, product, inputs, outputs) {
+ var args = [];
+ var useCompilerDriver = useCompilerDriverLinker(product);
+ if (useCompilerDriver) {
+ var target = targetFlag(product.qbs.targetPlatform, product.qbs.architecture,
+ product.type);
+ args.push(target);
+
+ if (product.type.includes("application")) {
+ args.push("-o", FileInfo.toNativeSeparators(outputs.application[0].filePath));
+ if (product.cpp.generateLinkerMapFile)
+ args.push("-fm=" + FileInfo.toNativeSeparators(outputs.mem_map[0].filePath));
+ } else if (product.type.includes("dynamiclibrary")) {
+ if (product.qbs.targetPlatform === "windows") {
+ args.push("-Wl, option implib=" + FileInfo.toNativeSeparators(
+ outputs.dynamiclibrary_import[0].filePath));
+ }
+ args.push("-o", FileInfo.toNativeSeparators(outputs.dynamiclibrary[0].filePath))
+ }
+
+ var escapableLinkerFlags = [];
+ var targetLinkerFlags = product.cpp.targetLinkerFlags;
+ if (targetLinkerFlags)
+ escapableLinkerFlags = escapableLinkerFlags.concat(targetLinkerFlags);
+
+ escapableLinkerFlags = escapableLinkerFlags.concat(
+ Cpp.collectMiscEscapableLinkerArguments(product));
+
+ var escapedLinkerFlags = escapeLinkerFlags(useCompilerDriver, escapableLinkerFlags);
+ if (escapedLinkerFlags)
+ args = args.concat(escapedLinkerFlags);
+
+ args = args.concat(Cpp.collectLibraryPaths(product).map(function(path) {
+ return product.cpp.libraryPathFlag + FileInfo.toNativeSeparators(path);
+ }));
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return FileInfo.toNativeSeparators(path);
+ }));
+
+ var libraryDependencies = Cpp.collectLibraryDependencies(product);
+ for (var i = 0; i < libraryDependencies.length; ++i) {
+ var lib = libraryDependencies[i].filePath;
+ if (FileInfo.isAbsolutePath(lib) || lib.startsWith('@'))
+ args.push(FileInfo.toNativeSeparators(lib));
+ else
+ args.push("-Wl, libfile " + lib);
+ }
+
+ var resourcePaths = Cpp.collectResourceObjectPaths(inputs).map(function(path) {
+ return FileInfo.toNativeSeparators(path);
+ });
+ if (resourcePaths.length > 0)
+ args = args.concat("-Wl, resource " + resourcePaths.join(","));
+ }
+
+ args = args.concat(Cpp.collectMiscLinkerArguments(product),
+ Cpp.collectMiscDriverArguments(product));
+ return args;
+}
+
+function libraryManagerFlags(project, product, inputs, outputs) {
+ var args = ["-b", "-n", "-q"];
+ args = args.concat(Cpp.collectLinkerObjectPaths(inputs).map(function(path) {
+ return "+" + FileInfo.toNativeSeparators(path);
+ }));
+ args.push("-o", FileInfo.toNativeSeparators(outputs.staticlibrary[0].filePath));
+ return args;
+}
+
+function disassemblerFlags(project, product, inputs, outputs) {
+ var objectPath = Cpp.relativePath(product.buildDirectory, outputs.obj[0].filePath);
+ var listingPath = Cpp.relativePath(product.buildDirectory, outputs.lst[0].filePath);
+ var args = [];
+ args.push(FileInfo.toNativeSeparators(objectPath));
+ args.push("-l=" + FileInfo.toNativeSeparators(listingPath));
+ args.push("-s", "-a");
+ return args;
+}
+
+function generateCompilerListing(project, product, inputs, outputs, input, output) {
+ var args = disassemblerFlags(project, product, input, outputs);
+ var cmd = new Command(input.cpp.disassemblerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.silent = true;
+ cmd.jobPool = "watcom_job_pool";
+ return cmd;
+}
+
+function prepareAssembler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
+ var args = assemblerFlags(project, product, input, outputs);
+ var cmd = new Command(input.cpp.assemblerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "assembling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "watcom_job_pool";
+ cmds.push(cmd);
+ if (input.cpp.generateAssemblerListingFiles)
+ cmds.push(generateCompilerListing(project, product, inputs, outputs, input, output));
+ return cmds;
+}
+
+function prepareCompiler(project, product, inputs, outputs, input, output, explicitlyDependsOn) {
+ var cmds = [];
+ var args = compilerFlags(project, product, input, outputs, explicitlyDependsOn);
+ var cmd = new Command(input.cpp.compilerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "watcom_job_pool";
+ cmds.push(cmd);
+ if (input.cpp.generateCompilerListingFiles)
+ cmds.push(generateCompilerListing(project, product, inputs, outputs, input, output));
+ return cmds;
+}
+
+function prepareResourceCompiler(project, product, inputs, outputs, input, output,
+ explicitlyDependsOn) {
+ var args = resourceCompilerFlags(project, product, input, outputs);
+ var cmd = new Command(input.cpp.resourceCompilerPath, args);
+ // Set working directory to source directory as a workaround
+ // to make the resources compilable by resource compiler (it is magic).
+ cmd.workingDirectory = product.sourceDirectory;
+ cmd.description = "compiling " + input.fileName;
+ cmd.highlight = "compiler";
+ cmd.jobPool = "watcom_job_pool";
+ return [cmd];
+}
+
+function prepareLinker(project, product, inputs, outputs, input, output) {
+ var primaryOutput = outputs.dynamiclibrary ? outputs.dynamiclibrary[0]
+ : outputs.application[0];
+ var args = linkerFlags(project, product, inputs, outputs);
+ var linkerPath = effectiveLinkerPath(product);
+ var cmd = new Command(linkerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + primaryOutput.fileName;
+ cmd.highlight = "linker";
+ cmd.jobPool = "watcom_job_pool";
+ return [cmd];
+}
+
+function prepareLibraryManager(project, product, inputs, outputs, input, output) {
+ var args = libraryManagerFlags(project, product, inputs, outputs);
+ var cmd = new Command(product.cpp.libraryManagerPath, args);
+ cmd.workingDirectory = product.buildDirectory;
+ cmd.description = "linking " + outputs.staticlibrary[0].fileName;
+ cmd.highlight = "linker";
+ cmd.jobPool = "watcom_job_pool";
+ return [cmd];
+}
diff --git a/share/qbs/modules/cpp/watcom.qbs b/share/qbs/modules/cpp/watcom.qbs
new file mode 100644
index 000000000..84157b67b
--- /dev/null
+++ b/share/qbs/modules/cpp/watcom.qbs
@@ -0,0 +1,196 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 Denis Shienkov <denis.shienkov@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 1.0
+import qbs.File
+import qbs.FileInfo
+import qbs.ModUtils
+import qbs.Probes
+import "cpp.js" as Cpp
+import "watcom.js" as WATCOM
+
+CppModule {
+ condition: qbs.toolchain && qbs.toolchain.includes("watcom")
+
+ Probes.BinaryProbe {
+ id: compilerPathProbe
+ condition: !toolchainInstallPath && !_skipAllChecks
+ names: ["owcc"]
+ }
+
+ Probes.WatcomProbe {
+ id: watcomProbe
+ condition: !_skipAllChecks
+ compilerFilePath: compilerPath
+ enableDefinesByLanguage: enableCompilerDefinesByLanguage
+ _pathListSeparator: qbs.pathListSeparator
+ _toolchainInstallPath: toolchainInstallPath
+ _targetPlatform: qbs.targetPlatform
+ _targetArchitecture: qbs.architecture
+ }
+
+ qbs.architecture: watcomProbe.found ? watcomProbe.architecture : original
+ qbs.targetPlatform: watcomProbe.found ? watcomProbe.targetPlatform : original
+
+ compilerVersionMajor: watcomProbe.versionMajor
+ compilerVersionMinor: watcomProbe.versionMinor
+ compilerVersionPatch: watcomProbe.versionPatch
+ endianness: watcomProbe.endianness
+
+ compilerDefinesByLanguage: watcomProbe.compilerDefinesByLanguage
+ compilerIncludePaths: watcomProbe.includePaths
+
+ toolchainInstallPath: compilerPathProbe.found ? compilerPathProbe.path : undefined
+
+ /* Work-around for QtCreator which expects these properties to exist. */
+ property string cCompilerName: compilerName
+ property string cxxCompilerName: compilerName
+
+ compilerName: "owcc" + compilerExtension
+ compilerPath: FileInfo.joinPaths(toolchainInstallPath, compilerName)
+
+ assemblerName: "wasm" + compilerExtension
+ assemblerPath: FileInfo.joinPaths(toolchainInstallPath, assemblerName)
+
+ linkerName: "wlink" + compilerExtension
+ linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+
+ property string disassemblerName: "wdis" + compilerExtension
+ property string disassemblerPath: FileInfo.joinPaths(toolchainInstallPath,
+ disassemblerName)
+ property string resourceCompilerName: "wrc" + compilerExtension
+ property string resourceCompilerPath: FileInfo.joinPaths(toolchainInstallPath,
+ resourceCompilerName)
+ property string libraryManagerName: "wlib" + compilerExtension
+ property string libraryManagerPath: FileInfo.joinPaths(toolchainInstallPath,
+ libraryManagerName)
+
+ runtimeLibrary: "dynamic"
+
+ staticLibrarySuffix: ".lib"
+ dynamicLibrarySuffix: toolchainDetails.dynamicLibrarySuffix
+ executableSuffix: toolchainDetails.executableSuffix
+ objectSuffix: ".obj"
+
+ imageFormat: toolchainDetails.imageFormat
+
+ defineFlag: "-D"
+ includeFlag: "-I"
+ systemIncludeFlag: "-I"
+ preincludeFlag: "-include"
+ libraryDependencyFlag: "-l"
+ libraryPathFlag: "-L"
+ linkerScriptFlag: ""
+
+ toolchainDetails: WATCOM.toolchainDetails(qbs)
+
+ knownArchitectures: ["x86", "x86_16"]
+
+ property var buildEnv: watcomProbe.environment
+ setupBuildEnvironment: {
+ for (var key in product.cpp.buildEnv) {
+ var v = new ModUtils.EnvironmentVariable(key, product.qbs.pathListSeparator);
+ v.prepend(product.cpp.buildEnv[key]);
+ v.set();
+ }
+ }
+
+ Rule {
+ id: assembler
+ inputs: ["asm"]
+ outputFileTags: Cpp.assemblerOutputTags(generateAssemblerListingFiles)
+ outputArtifacts: Cpp.assemblerOutputArtifacts(input)
+ prepare: WATCOM.prepareAssembler.apply(WATCOM, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.asm"]
+ fileTags: ["asm"]
+ }
+
+ Rule {
+ id: compiler
+ inputs: ["cpp", "c"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: Cpp.compilerOutputTags(generateCompilerListingFiles)
+ outputArtifacts: Cpp.compilerOutputArtifacts(input)
+ prepare: WATCOM.prepareCompiler.apply(WATCOM, arguments)
+ }
+
+ Rule {
+ id: rccCompiler
+ inputs: ["rc"]
+ auxiliaryInputs: ["hpp"]
+ outputFileTags: Cpp.resourceCompilerOutputTags()
+ outputArtifacts: Cpp.resourceCompilerOutputArtifacts(input)
+ prepare: WATCOM.prepareResourceCompiler.apply(WATCOM, arguments)
+ }
+
+ FileTagger {
+ patterns: ["*.rc"]
+ fileTags: ["rc"]
+ }
+
+ Rule {
+ id: applicationLinker
+ multiplex: true
+ inputs: ["obj", "res", "linkerscript"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.applicationLinkerOutputTags(generateLinkerMapFile)
+ outputArtifacts: Cpp.applicationLinkerOutputArtifacts(product)
+ prepare: WATCOM.prepareLinker.apply(WATCOM, arguments)
+ }
+
+ Rule {
+ id: dynamicLibraryLinker
+ condition: qbs.targetOS.includes("windows")
+ multiplex: true
+ inputs: ["obj", "res"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.dynamicLibraryLinkerOutputTags();
+ outputArtifacts: Cpp.dynamicLibraryLinkerOutputArtifacts(product)
+ prepare: WATCOM.prepareLinker.apply(WATCOM, arguments)
+ }
+
+ Rule {
+ id: libraryManager
+ multiplex: true
+ inputs: ["obj"]
+ inputsFromDependencies: ["staticlibrary", "dynamiclibrary_import"]
+ outputFileTags: Cpp.staticLibraryLinkerOutputTags()
+ outputArtifacts: Cpp.staticLibraryLinkerOutputArtifacts(product)
+ prepare: WATCOM.prepareLibraryManager.apply(WATCOM, arguments)
+ }
+
+ JobLimit {
+ jobPool: "watcom_job_pool"
+ jobCount: 1
+ }
+}
diff --git a/share/qbs/modules/cpp/windows-clang-cl.qbs b/share/qbs/modules/cpp/windows-clang-cl.qbs
index e1f4ee425..9aa9d7395 100644
--- a/share/qbs/modules/cpp/windows-clang-cl.qbs
+++ b/share/qbs/modules/cpp/windows-clang-cl.qbs
@@ -28,15 +28,16 @@
**
****************************************************************************/
+import qbs.Host
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')
+ condition: Host.os().includes('windows') &&
+ qbs.targetOS.includes('windows') &&
+ qbs.toolchain && qbs.toolchain.includes('clang-cl')
priority: 100
Probes.ClangClBinaryProbe {
@@ -84,14 +85,17 @@ MsvcBaseModule {
linkerName: "lld-link.exe"
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+ systemIncludeFlag: "/imsvc"
+
validateFunc: {
+ var baseFunc = base;
return function() {
if (_skipAllChecks)
return;
var validator = new ModUtils.PropertyValidator("cpp");
validator.setRequiredProperty("vcvarsallPath", vcvarsallPath);
validator.validate();
- base();
+ baseFunc();
}
}
}
diff --git a/share/qbs/modules/cpp/windows-clang-mingw.qbs b/share/qbs/modules/cpp/windows-clang-mingw.qbs
index 10d56cc85..cfe6f2745 100644
--- a/share/qbs/modules/cpp/windows-clang-mingw.qbs
+++ b/share/qbs/modules/cpp/windows-clang-mingw.qbs
@@ -30,6 +30,7 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Utilities
import "msvc.js" as MSVC
@@ -37,8 +38,8 @@ import "msvc.js" as MSVC
import "setuprunenv.js" as SetupRunEnv
MingwBaseModule {
- condition: qbs.targetOS.contains("windows") &&
- qbs.toolchain && qbs.toolchain.contains("clang")
+ condition: qbs.targetOS.includes("windows") &&
+ qbs.toolchain && qbs.toolchain.includes("clang")
priority: 0
// llvm-as and llvm-objopy are not shipped with the official binaries on Windows at the
@@ -68,16 +69,16 @@ MingwBaseModule {
"llvm-rc" + compilerExtension)
setupBuildEnvironment: {
- if (product.qbs.hostOS.contains("windows") && product.qbs.sysroot) {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ if (Host.os().includes("windows") && product.qbs.sysroot) {
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.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);
+ if (Host.os().includes("windows") && product.qbs.sysroot) {
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), true);
v.prepend(FileInfo.joinPaths(product.qbs.sysroot, "bin"));
v.set();
SetupRunEnv.setupRunEnvironment(product, config);
diff --git a/share/qbs/modules/cpp/windows-mingw.qbs b/share/qbs/modules/cpp/windows-mingw.qbs
index 2a01d81a9..9ba4258c5 100644
--- a/share/qbs/modules/cpp/windows-mingw.qbs
+++ b/share/qbs/modules/cpp/windows-mingw.qbs
@@ -37,8 +37,8 @@ import 'cpp.js' as Cpp
import "setuprunenv.js" as SetupRunEnv
MingwBaseModule {
- condition: qbs.targetOS.contains("windows") &&
- qbs.toolchain && qbs.toolchain.contains("mingw")
+ condition: qbs.targetOS.includes("windows") &&
+ qbs.toolchain && qbs.toolchain.includes("mingw")
priority: 0
probeEnv: buildEnv
@@ -52,13 +52,13 @@ MingwBaseModule {
}
setupBuildEnvironment: {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), true);
v.prepend(product.cpp.toolchainInstallPath);
v.set();
}
setupRunEnvironment: {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), true);
v.prepend(product.cpp.toolchainInstallPath);
v.set();
SetupRunEnv.setupRunEnvironment(product, config);
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
index d188d53f3..9613800e5 100644
--- a/share/qbs/modules/cpp/windows-msvc-base.qbs
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -95,7 +95,7 @@ CppModule {
precompiledHeaderSuffix: ".pch"
imageFormat: "pe"
Properties {
- condition: product.multiplexByQbsProperties.contains("buildVariants")
+ condition: product.multiplexByQbsProperties.includes("buildVariants")
&& qbs.buildVariants && qbs.buildVariants.length > 1
&& qbs.buildVariant !== "release"
&& product.type.containsAny(["staticlibrary", "dynamiclibrary"])
@@ -320,12 +320,11 @@ CppModule {
outputFileTags: Cpp.assemblerOutputTags(false)
outputArtifacts: Cpp.assemblerOutputArtifacts(input)
prepare: {
- var args = ["/nologo", "/c",
- "/Fo" + FileInfo.toWindowsSeparators(output.filePath),
- FileInfo.toWindowsSeparators(input.filePath)];
+ var args = ["/nologo", "/c", "/Fo" + FileInfo.toWindowsSeparators(output.filePath)];
if (product.cpp.debugInformation)
args.push("/Zi");
args = args.concat(Cpp.collectMiscAssemblerArguments(input, "asm"));
+ args.push(FileInfo.toWindowsSeparators(input.filePath));
var cmd = new Command(product.cpp.assemblerPath, args);
cmd.description = "assembling " + input.fileName;
cmd.jobPool = "assembler";
diff --git a/share/qbs/modules/cpp/windows-msvc.qbs b/share/qbs/modules/cpp/windows-msvc.qbs
index 5e41c76fa..c30cec239 100644
--- a/share/qbs/modules/cpp/windows-msvc.qbs
+++ b/share/qbs/modules/cpp/windows-msvc.qbs
@@ -29,13 +29,14 @@
**
****************************************************************************/
+import qbs.Host
import qbs.Probes
import "windows-msvc-base.qbs" as MsvcBaseModule
MsvcBaseModule {
- condition: qbs.hostOS.contains('windows') &&
- qbs.targetOS.contains('windows') &&
- qbs.toolchain && qbs.toolchain.contains('msvc')
+ condition: Host.os().includes('windows') &&
+ qbs.targetOS.includes('windows') &&
+ qbs.toolchain && qbs.toolchain.includes('msvc')
priority: 50
Probes.ClBinaryProbe {
diff --git a/share/qbs/modules/dmg/DMGModule.qbs b/share/qbs/modules/dmg/DMGModule.qbs
index c5d097a0b..27a945033 100644
--- a/share/qbs/modules/dmg/DMGModule.qbs
+++ b/share/qbs/modules/dmg/DMGModule.qbs
@@ -31,15 +31,17 @@
import qbs.DarwinTools
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Process
+import qbs.Probes
import qbs.TextFile
import "dmg.js" as Dmg
Module {
Depends { name: "xcode"; required: false }
- condition: qbs.hostOS.contains("darwin") && qbs.targetOS.contains("darwin")
+ condition: Host.os().includes("darwin") && qbs.targetOS.includes("darwin")
property string volumeName: product.targetName
PropertyOptions {
@@ -72,6 +74,12 @@ Module {
property string sourceBase
+ Probes.BinaryProbe {
+ id: pythonProbe
+ names: ["python3"]
+ }
+ property string pythonExePath: pythonProbe.found ? pythonProbe.filePath : "python3"
+
readonly property string pythonPath: File.canonicalFilePath(FileInfo.joinPaths(path,
"..", "..",
"python"))
diff --git a/share/qbs/modules/dmg/dmg.js b/share/qbs/modules/dmg/dmg.js
index 4d972db9b..06fe7b906 100644
--- a/share/qbs/modules/dmg/dmg.js
+++ b/share/qbs/modules/dmg/dmg.js
@@ -57,7 +57,7 @@ function dmgbuildSettings(product, inputs) {
volumeIcon = volumeIcons[0].filePath;
}
- var licenseFileObjects = Array.prototype.map.call(inputs["dmg.license"], function (a) {
+ var licenseFileObjects = Array.prototype.map.call(inputs["dmg.license"] || [], function (a) {
return {
"dmg": {
"licenseLocale": localizationFromArtifact(a),
@@ -97,14 +97,14 @@ function dmgbuildSettings(product, inputs) {
}, {});
}
- var contentsArray = Array.prototype.map.call(inputs["dmg.input"], function (a) {
+ var contentsArray = Array.prototype.map.call(inputs["dmg.input"] || [], function (a) {
if (a.dmg.sourceBase && !a.filePath.startsWith(a.dmg.sourceBase)) {
throw new Error("Cannot install '" + a.filePath + "', " +
"because it doesn't start with the value of " +
"dmg.sourceBase '" + a.dmg.sourceBase + "'.");
}
- var isSymlink = a.fileTags.contains("dmg.input.symlink");
+ var isSymlink = a.fileTags.includes("dmg.input.symlink");
return {
"x": a.dmg.iconX,
"y": a.dmg.iconY,
@@ -114,7 +114,7 @@ function dmgbuildSettings(product, inputs) {
};
});
- Array.prototype.forEach.call(product.dmg.iconPositions, function (obj) {
+ Array.prototype.forEach.call(product.dmg.iconPositions || [], function (obj) {
var existingIndex = -1;
Array.prototype.forEach.call(contentsArray, function (contentsItem, i) {
if (contentsItem["name"] === obj["path"])
@@ -135,7 +135,7 @@ function dmgbuildSettings(product, inputs) {
}
});
- return {
+ var result = {
"title": product.dmg.volumeName,
"icon": !product.dmg.badgeVolumeIcon ? volumeIcon : undefined,
"badge-icon": product.dmg.badgeVolumeIcon ? volumeIcon : undefined,
@@ -154,13 +154,16 @@ function dmgbuildSettings(product, inputs) {
},
"format": product.dmg.format,
"compression-level": product.dmg.compressionLevel,
- "license": {
+ "contents": contentsArray
+ };
+ if (licenseFileObjects.length >= 0) {
+ result["license"] = {
"default-language": product.dmg.defaultLicenseLocale,
"licenses": reduceLicensesForKey(licenseFileObjects, "licenses"),
"buttons": reduceLicensesForKey(licenseFileObjects, "buttons")
- },
- "contents": contentsArray
- };
+ };
+ }
+ return result;
}
function prepareLicense(project, product, inputs, outputs, input, output) {
@@ -199,8 +202,10 @@ function prepareDmg(project, product, inputs, outputs, input, output) {
cmds.push(cmd);
// Create the actual DMG via dmgbuild
- cmd = new Command(FileInfo.joinPaths(product.qbs.libexecPath, "dmgbuild"),
- [product.dmg.volumeName,
+ cmd = new Command(product.dmg.pythonExePath,
+ ["-m",
+ "dmgbuild",
+ product.dmg.volumeName,
output.filePath,
"--no-hidpi", // qbs handles this by itself
"--settings", settingsJsonFilePath]);
diff --git a/share/qbs/modules/flatbuf/c/flatbuffers-c.qbs b/share/qbs/modules/flatbuf/c/flatbuffers-c.qbs
new file mode 100644
index 000000000..9f5b2b70c
--- /dev/null
+++ b/share/qbs/modules/flatbuf/c/flatbuffers-c.qbs
@@ -0,0 +1,61 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 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.FileInfo
+
+import "../flatbuffers.js" as Flatbuf
+import "../flatbuffersbase.qbs" as FlatbufBase
+
+FlatbufBase {
+ Depends { name: "cpp" }
+ Depends { name: "flatcc" }
+
+ compilerName: "flatcc"
+
+ _outputDir: FileInfo.joinPaths(product.buildDirectory, "flatbuf", "c")
+ _searchPaths: flatbuffers.hostBinDirs
+
+ cpp.systemIncludePaths: base.concat([_outputDir])
+
+ Rule {
+ inputs: ["flatbuf.input"]
+ outputFileTags: ["hpp"]
+ outputArtifacts: [Flatbuf.artifactC(input.flatbuf.c, input, "hpp", "_generated.h")]
+
+ prepare: {
+ return Flatbuf.doPrepareC(input.flatbuf.c, input);
+ }
+ }
+
+ validate: {
+ Flatbuf.validateCompiler(compilerName, compilerPath);
+ }
+}
diff --git a/share/qbs/modules/flatbuf/cpp/flatbuffers-cpp.qbs b/share/qbs/modules/flatbuf/cpp/flatbuffers-cpp.qbs
new file mode 100644
index 000000000..4614d4949
--- /dev/null
+++ b/share/qbs/modules/flatbuf/cpp/flatbuffers-cpp.qbs
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 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.FileInfo
+
+import "../flatbuffers.js" as Flatbuf
+import "../flatbuffersbase.qbs" as FlatbufBase
+
+FlatbufBase {
+ Depends { name: "cpp" }
+ Depends { name: "flatbuffers" }
+
+ property string filenameExtension: "h"
+ property string filenameSuffix: "_generated"
+ property string includePrefix // TODO: test
+ property bool keepPrefix: false
+
+ _outputDir: FileInfo.joinPaths(product.buildDirectory, "flatbuf", "cpp")
+ _searchPaths: flatbuffers.hostBinDirs
+
+ cpp.cxxLanguageVersion: "c++11"
+ cpp.systemIncludePaths: base.concat([_outputDir])
+
+ Rule {
+ inputs: ["flatbuf.input"]
+ outputFileTags: ["hpp"]
+ outputArtifacts: {
+ var module = input.flatbuf.cpp;
+ var fullSuffix = module.filenameSuffix + "." + module.filenameExtension;
+ return [ Flatbuf.artifact(module, input, "hpp", fullSuffix) ];
+ }
+
+ prepare: {
+ return Flatbuf.doPrepareCpp(input.flatbuf.cpp, input, output);
+ }
+ }
+
+ validate: {
+ Flatbuf.validateCompiler(compilerName, compilerPath);
+ }
+}
diff --git a/share/qbs/modules/flatbuf/flatbuffers.js b/share/qbs/modules/flatbuf/flatbuffers.js
new file mode 100644
index 000000000..24fd91168
--- /dev/null
+++ b/share/qbs/modules/flatbuf/flatbuffers.js
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 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.
+**
+****************************************************************************/
+
+var File = require("qbs.File");
+
+function validateCompiler(compilerName, compilerPath) {
+ if (!File.exists(compilerPath)) {
+ throw "Can't find '" + compilerName + "' binary. Please set the compilerPath property or "
+ + "make sure the compiler is found in PATH";
+ }
+}
+
+function getOutputDir(module, input) {
+ var outputDir = module._outputDir;
+ if (!module.keepPrefix)
+ return outputDir;
+ var importPaths = module.importPaths;
+ if (importPaths !== undefined && importPaths.length !== 0) {
+ var canonicalInput = File.canonicalFilePath(FileInfo.path(input.filePath));
+ for (var i = 0; i < importPaths.length; ++i) {
+ var path = File.canonicalFilePath(importPaths[i]);
+
+ if (canonicalInput.startsWith(path)) {
+ return outputDir + "/" + FileInfo.relativePath(path, canonicalInput);
+ }
+ }
+ }
+ return outputDir;
+}
+
+function artifactC(module, input, tag, suffix) {
+ var outputDir = module._outputDir;
+ return {
+ fileTags: [tag],
+ filePath: outputDir + "/" + FileInfo.baseName(input.fileName) + suffix,
+ cpp: { warningLevel: "none"}
+ };
+}
+
+function doPrepareC(module, input)
+{
+ var args = [];
+ args.push("-a") // write all
+ args.push("-o", input.flatbuf.c._outputDir) // output dir
+
+ var importPaths = module.importPaths;
+ importPaths.forEach(function(path) {
+ args.push("-I", path);
+ });
+
+ args.push(input.filePath);
+
+ var cmd = new Command(module.compilerPath, args);
+ cmd.workingDirectory = FileInfo.path(module._outputDir)
+ cmd.highlight = "codegen";
+ cmd.description = "generating C files for " + input.fileName;
+ return [cmd];
+}
+
+function artifact(module, input, tag, suffix) {
+ var outputDir = getOutputDir(module, input);
+ return {
+ fileTags: [tag],
+ filePath: outputDir + "/" + FileInfo.baseName(input.fileName) + suffix,
+ cpp: { warningLevel: "none" }
+ };
+}
+
+function doPrepareCpp(module, input, output)
+{
+ var outputDir = FileInfo.path(output.filePath);
+ var result = [];
+
+ var args = [];
+ args.push("--cpp")
+
+ var importPaths = module.importPaths;
+ importPaths.forEach(function(path) {
+ args.push("-I", path);
+ });
+
+ args.push("--filename-ext", module.filenameExtension);
+ args.push("--filename-suffix", module.filenameSuffix);
+
+ if (module.includePrefix)
+ args.push("--include-prefix", module.includePrefix);
+
+ if (module.keepPrefix)
+ args.push("--keep-prefix");
+
+ args.push(input.filePath);
+ var cmd = new Command(input.flatbuf.cpp.compilerPath, args);
+ cmd.workingDirectory = outputDir;
+ cmd.highlight = "codegen";
+ cmd.description = "generating C++ files for " + input.fileName;
+ result.push(cmd);
+
+ return result;
+}
diff --git a/share/qbs/modules/flatbuf/flatbuffersbase.qbs b/share/qbs/modules/flatbuf/flatbuffersbase.qbs
new file mode 100644
index 000000000..98eb2f344
--- /dev/null
+++ b/share/qbs/modules/flatbuf/flatbuffersbase.qbs
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2024 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.File
+import qbs.FileInfo
+import qbs.Probes
+
+import "flatbuffers.js" as HelperFunctions
+
+Module {
+ property string compilerName: "flatc"
+ property string compilerPath: compilerProbe.filePath
+
+ property pathList importPaths: []
+
+ property string _outputDir: FileInfo.joinPaths(product.buildDirectory, "flatbuf")
+
+ property stringList _searchPaths
+
+ FileTagger {
+ patterns: ["*.fbs"]
+ fileTags: ["flatbuf.input"];
+ }
+
+ Probes.BinaryProbe {
+ id: compilerProbe
+ names: [compilerName]
+ searchPaths: _searchPaths
+ }
+}
diff --git a/share/qbs/modules/freedesktop/FreeDesktop.qbs b/share/qbs/modules/freedesktop/FreeDesktop.qbs
index 5ff56a9a4..60722c674 100644
--- a/share/qbs/modules/freedesktop/FreeDesktop.qbs
+++ b/share/qbs/modules/freedesktop/FreeDesktop.qbs
@@ -33,22 +33,21 @@ import qbs.TextFile
import "freedesktop.js" as Fdo
Module {
- id: fdoModule
-
property string name: product.name
+ property string appName: name
property var desktopKeys
readonly property var defaultDesktopKeys: {
return {
'Type': 'Application',
- 'Name': product.freedesktop.name,
+ 'Name': product.freedesktop.appName,
'Exec': product.targetName,
'Terminal': 'false',
'Version': '1.1',
}
}
- property bool _fdoSupported: qbs.targetOS.contains("unix") && !qbs.targetOS.contains("darwin")
+ property bool _fdoSupported: qbs.targetOS.includes("unix") && !qbs.targetOS.includes("darwin")
additionalProductTypes: "freedesktop.desktopfile"
@@ -70,7 +69,7 @@ Module {
prepare: {
var cmd = new JavaScriptCommand();
- cmd.description = input.fileName + "->" + output.fileName;
+ cmd.description = "generating " + output.fileName + " from " + input.fileName;
cmd.highlight = "codegen";
cmd.sourceCode = function() {
var aggregateDesktopKeys = Fdo.parseDesktopFile(input.filePath);
@@ -96,14 +95,14 @@ Module {
}
Group {
- condition: fdoModule._fdoSupported
+ condition: product.freedesktop._fdoSupported
fileTagsFilter: [ "freedesktop.desktopfile" ]
qbs.install: true
qbs.installDir: "share/applications"
}
Group {
- condition: fdoModule._fdoSupported
+ condition: product.freedesktop._fdoSupported
fileTagsFilter: [ "freedesktop.appIcon" ]
qbs.install: true
qbs.installDir: "share/icons/hicolor/scalable/apps"
@@ -115,7 +114,7 @@ Module {
}
Group {
- condition: fdoModule._fdoSupported
+ condition: product.freedesktop._fdoSupported
fileTagsFilter: [ "freedesktop.appstream" ]
qbs.install: true
qbs.installDir: "share/metainfo"
diff --git a/share/qbs/modules/ib/IBModule.qbs b/share/qbs/modules/ib/IBModule.qbs
index 6af5e94e4..e6183e20c 100644
--- a/share/qbs/modules/ib/IBModule.qbs
+++ b/share/qbs/modules/ib/IBModule.qbs
@@ -31,6 +31,7 @@
import qbs.BundleTools
import qbs.DarwinTools
import qbs.File
+import qbs.Host
import qbs.FileInfo
import qbs.ModUtils
import qbs.Process
@@ -49,7 +50,7 @@ Module {
}
}
- condition: qbs.hostOS.contains("darwin") && qbs.targetOS.contains("darwin")
+ condition: Host.os().includes("darwin") && qbs.targetOS.includes("darwin")
property bool warnings: true
property bool errors: true
@@ -195,7 +196,7 @@ Module {
cmd.highlight = 'compiler';
// May not be strictly needed, but is set by some versions of Xcode
- if (input.fileTags.contains("storyboard"))
+ if (input.fileTags.includes("storyboard"))
cmd.environment.push("IBSC_MINIMUM_COMPATIBILITY_VERSION=" +
(product.moduleProperty("cpp", "minimumDarwinVersion") || ""));
diff --git a/share/qbs/modules/ib/ib.js b/share/qbs/modules/ib/ib.js
index ebb615e8e..d6873b261 100644
--- a/share/qbs/modules/ib/ib.js
+++ b/share/qbs/modules/ib/ib.js
@@ -116,7 +116,7 @@ function ibtooldArguments(product, inputs, input, outputs, overrideOutput) {
var outputFormat = ModUtils.moduleProperty(product, "outputFormat");
if (outputFormat) {
- if (!["binary1", "xml1", "human-readable-text"].contains(outputFormat))
+ if (!["binary1", "xml1", "human-readable-text"].includes(outputFormat))
throw("Invalid ibtoold output format: " + outputFormat + ". " +
"Must be in [binary1, xml1, human-readable-text].");
@@ -205,9 +205,9 @@ function ibtooldArguments(product, inputs, input, outputs, overrideOutput) {
function ibtoolFileTaggers(fileTags) {
var ext;
- if (fileTags.contains("nib") && !fileTags.contains("storyboard"))
+ if (fileTags.includes("nib") && !fileTags.includes("storyboard"))
ext = "nib";
- if (fileTags.contains("storyboard") && !fileTags.contains("nib"))
+ if (fileTags.includes("storyboard") && !fileTags.includes("nib"))
ext = "storyboard";
if (!ext)
@@ -223,9 +223,9 @@ function ibtoolFileTaggers(fileTags) {
function ibtoolCompiledDirSuffix(product, input) {
var suffix = input.completeBaseName;
- if (input.fileTags.contains("nib"))
+ if (input.fileTags.includes("nib"))
suffix += ModUtils.moduleProperty(product, "compiledNibSuffix");
- else if (input.fileTags.contains("storyboard"))
+ else if (input.fileTags.includes("storyboard"))
suffix += ModUtils.moduleProperty(product, "compiledStoryboardSuffix");
return suffix;
}
@@ -252,7 +252,7 @@ function ibtoolOutputArtifacts(product, inputs, input) {
var artifacts = tracker.artifacts(ibtoolBuildDirectory);
if (product.moduleProperty("ib", "ibtoolVersionMajor") >= 6) {
- var prefix = input.fileTags.contains("storyboard") ? "SB" : "";
+ var prefix = input.fileTags.includes("storyboard") ? "SB" : "";
var path = FileInfo.joinPaths(product.destinationDirectory, input.completeBaseName +
"-" + prefix + "PartialInfo.plist");
artifacts.push({ filePath: path, fileTags: ["partial_infoplist"] });
@@ -261,7 +261,7 @@ function ibtoolOutputArtifacts(product, inputs, input) {
// Let the output artifacts known the "main" output
// This can be either a file or directory so the artifact might already exist in the output list
for (var i = 0; i < artifacts.length; ++i) {
- if (artifacts[i].fileTags.contains("compiled_ibdoc"))
+ if (artifacts[i].fileTags.includes("compiled_ibdoc"))
artifacts[i].bundle = {
_bundleFilePath: artifacts[i].filePath.replace(ibtoolBuildDirectory, main)
};
@@ -296,7 +296,7 @@ function actoolOutputArtifacts(product, inputs) {
}
for (var i = 0; i < artifacts.length; ++i) {
- if (artifacts[i].fileTags.contains("compiled_assetcatalog")) {
+ if (artifacts[i].fileTags.includes("compiled_assetcatalog")) {
artifacts[i].bundle = {
_bundleFilePath: artifacts[i].filePath.replace(
product.buildDirectory + "/actool.dir",
diff --git a/share/qbs/modules/ico/ico.js b/share/qbs/modules/ico/ico.js
index a61d585ab..dc96eedf3 100644
--- a/share/qbs/modules/ico/ico.js
+++ b/share/qbs/modules/ico/ico.js
@@ -40,20 +40,20 @@ function prepareIconset(project, product, inputs, outputs, input, output) {
ico: {}
};
});
- inputs = {"png": inputs.filter(function (a) { return a.fileTags.contains("png"); })};
+ inputs = {"png": inputs.filter(function (a) { return a.fileTags.includes("png"); })};
input = undefined;
return prepare(project, product, inputs, outputs, input, output);
}
function prepare(project, product, inputs, outputs, input, output) {
var args = ["--create", "--output=" + output.filePath];
- if (output.fileTags.contains("ico")) {
+ if (output.fileTags.includes("ico")) {
args.push("--icon");
if (product.ico.alphaThreshold !== undefined)
args.push("--alpha-threshold=" + product.ico.alphaThreshold);
}
- var isCursor = output.fileTags.contains("cur");
+ var isCursor = output.fileTags.includes("cur");
if (isCursor)
args.push("--cursor");
diff --git a/share/qbs/modules/innosetup/InnoSetupModule.qbs b/share/qbs/modules/innosetup/InnoSetupModule.qbs
index 930d85a9a..9f1018ec4 100644
--- a/share/qbs/modules/innosetup/InnoSetupModule.qbs
+++ b/share/qbs/modules/innosetup/InnoSetupModule.qbs
@@ -33,7 +33,7 @@ import qbs.ModUtils
import qbs.Probes
Module {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
Probes.InnoSetupProbe {
id: innoSetupProbe
diff --git a/share/qbs/modules/java/JavaModule.qbs b/share/qbs/modules/java/JavaModule.qbs
index ceb29f36f..343b2f4ba 100644
--- a/share/qbs/modules/java/JavaModule.qbs
+++ b/share/qbs/modules/java/JavaModule.qbs
@@ -29,6 +29,7 @@
****************************************************************************/
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Probes
import qbs.Process
@@ -122,10 +123,10 @@ Module {
} else {
paths.push(FileInfo.joinPaths(jdkPath, "include"));
- var hostOS = qbs.hostOS.contains("windows") ? qbs.hostOS.concat(["win32"]) : qbs.hostOS;
+ var hostOS = Host.os().includes("windows") ? Host.os().concat(["win32"]) : Host.os();
var platforms = ["win32", "darwin", "linux", "bsd", "solaris"];
for (var i = 0; i < platforms.length; ++i) {
- if (hostOS.contains(platforms[i])) {
+ if (hostOS.includes(platforms[i])) {
// Corresponds to JDK_INCLUDE_SUBDIR in the JDK Makefiles
paths.push(FileInfo.joinPaths(jdkPath, "include", platforms[i]));
break;
@@ -140,7 +141,7 @@ Module {
property path classFilesDir: FileInfo.joinPaths(product.buildDirectory, "classes")
property path internalClassFilesDir: FileInfo.joinPaths(product.buildDirectory, ".classes")
- property bool isAppleJava: qbs.hostOS.contains("darwin")
+ property bool isAppleJava: Host.os().includes("darwin")
&& (compilerVersionMajor < 1
|| (compilerVersionMajor === 1 && compilerVersionMinor < 7))
@@ -253,7 +254,7 @@ Module {
prepare: {
var cmd = new Command(ModUtils.moduleProperty(product, "compilerFilePath"),
JavaUtils.javacArguments(product, inputs));
- cmd.description = "Compiling Java sources";
+ cmd.description = "compiling Java sources";
cmd.highlight = "compiler";
return [cmd];
}
diff --git a/share/qbs/modules/java/utils.js b/share/qbs/modules/java/utils.js
index 520511192..a59b8d41d 100644
--- a/share/qbs/modules/java/utils.js
+++ b/share/qbs/modules/java/utils.js
@@ -79,7 +79,7 @@ function findJdkPath(hostOS, arch, environmentPaths, searchPaths) {
return environmentPaths[i];
}
- if (hostOS.contains("windows")) {
+ if (hostOS.includes("windows")) {
var rootKey = jdkRootRegistryKey(useWow64Key(arch));
if (rootKey) {
var current = Utilities.getNativeSetting(rootKey, "CurrentVersion"); // 1.8 etc.
@@ -94,27 +94,55 @@ function findJdkPath(hostOS, arch, environmentPaths, searchPaths) {
return undefined;
}
- if (hostOS.contains("macos")) {
+ if (hostOS.includes("macos")) {
var p = new Process();
try {
// We filter by architecture here so that we'll get a compatible JVM for JNI use.
var args = [];
+ var canonicalArch;
if (arch) {
// Hardcoding apple/macosx/macho here is fine because we know we're on macOS
- args.push("--arch",
- Utilities.canonicalTargetArchitecture(arch, undefined,
- "apple", "macosx", "macho"));
+ canonicalArch = Utilities.canonicalTargetArchitecture(arch, undefined, "apple",
+ "macosx", "macho");
+ args.push("--arch", canonicalArch);
}
// --failfast doesn't print the default JVM if nothing matches the filter(s).
var status = p.exec("/usr/libexec/java_home", args.concat(["--failfast"]));
- return status === 0 ? p.readStdOut().trim() : undefined;
+ if (status === 0)
+ return p.readStdOut().trim();
+
+ // It has been obvserved that java_home fails for any architecture that is passed,
+ // so try without the filter and look up the JDK architecture manually.
+ if (!canonicalArch)
+ return undefined;
+
+ if (p.exec("/usr/libexec/java_home", ["--failfast"]) !== 0)
+ return undefined;
+ var jdkPath = p.readStdOut().trim();
+ var releaseFile = new TextFile(jdkPath + "/release", TextFile.ReadOnly);
+ var line;
+ while ((line = releaseFile.readLine())) {
+ if (!line.startsWith("OS_ARCH="))
+ continue;
+ var firstQuote = line.indexOf('"');
+ if (firstQuote === -1)
+ break;
+ var secondQuote = line.indexOf('"', firstQuote + 1);
+ if (secondQuote === -1)
+ break;
+ var archFromFile = line.substring(firstQuote + 1, secondQuote);
+ if (archFromFile !== canonicalArch)
+ break;
+ return jdkPath;
+ }
+ return undefined;
} finally {
p.close();
}
}
- if (hostOS.contains("unix")) {
+ if (hostOS.includes("unix")) {
var requiredTools = ["javac", "java", "jar"];
for (i = 0; i < searchPaths.length; ++i) {
function fullToolPath(tool) {
@@ -193,7 +221,7 @@ function javacArguments(product, inputs, overrides) {
classPaths.push(inputs["java.jar"][i].filePath);
var debugArg = product.moduleProperty("qbs", "buildVariant") === "debug"
? "-g" : "-g:none";
- var pathListSeparator = product.moduleProperty("qbs", "pathListSeparator");
+ var pathListSeparator = FileInfo.pathListSeparator();
var args = [
"-classpath", classPaths.join(pathListSeparator),
"-s", product.buildDirectory,
@@ -246,7 +274,7 @@ function helperFullyQualifiedNames(type) {
];
if (type === "java") {
return names.filter(function (name) {
- return !name.contains("$");
+ return !name.includes("$");
});
} else if (type === "class") {
return names;
@@ -312,7 +340,7 @@ function outputArtifacts(product, inputs) {
process.setWorkingDirectory(
FileInfo.joinPaths(ModUtils.moduleProperty(product, "internalClassFilesDir")));
- var sep = product.moduleProperty("qbs", "pathListSeparator");
+ var sep = FileInfo.pathListSeparator();
var toolsJarPath = ModUtils.moduleProperty(product, "toolsJarPath");
var javaArgs = [
"-classpath", process.workingDirectory() + (toolsJarPath ? (sep + toolsJarPath) : ""),
diff --git a/share/qbs/modules/nodejs/NodeJS.qbs b/share/qbs/modules/nodejs/NodeJS.qbs
index 7fd992fdb..412f9b8bb 100644
--- a/share/qbs/modules/nodejs/NodeJS.qbs
+++ b/share/qbs/modules/nodejs/NodeJS.qbs
@@ -31,6 +31,7 @@
import qbs.Environment
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Probes
@@ -84,13 +85,13 @@ Module {
"tmp", "nodejs.intermediate")
setupBuildEnvironment: {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, product.qbs.hostOS.contains("windows"));
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), Host.os().includes("windows"));
v.prepend(product.nodejs.toolchainInstallPath);
v.set();
}
setupRunEnvironment: {
- var v = new ModUtils.EnvironmentVariable("NODE_PATH", product.qbs.pathListSeparator, product.qbs.hostOS.contains("windows"));
+ var v = new ModUtils.EnvironmentVariable("NODE_PATH", FileInfo.pathListSeparator(), Host.os().includes("windows"));
v.prepend(FileInfo.path(Environment.getEnv("QBS_RUN_FILE_PATH")));
v.set();
}
@@ -118,7 +119,7 @@ Module {
outputArtifacts: {
var tags = ["nodejs_processed_js"];
- if (input.fileTags.contains("application_js") ||
+ if (input.fileTags.includes("application_js") ||
product.moduleProperty("nodejs", "applicationFile") === input.filePath)
tags.push("application");
diff --git a/share/qbs/modules/nsis/NSISModule.qbs b/share/qbs/modules/nsis/NSISModule.qbs
index 23d673880..11a5670b5 100644
--- a/share/qbs/modules/nsis/NSISModule.qbs
+++ b/share/qbs/modules/nsis/NSISModule.qbs
@@ -30,11 +30,12 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Utilities
Module {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
property path toolchainInstallPath: Utilities.getNativeSetting(registryKey)
@@ -89,7 +90,7 @@ Module {
// Private properties
property string registryKey: {
- if (!qbs.hostOS.contains("windows"))
+ if (!Host.os().includes("windows"))
return undefined;
var keys = [ "HKEY_LOCAL_MACHINE\\SOFTWARE\\NSIS", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\NSIS" ];
@@ -104,7 +105,7 @@ Module {
// Only *require* the toolchain install path on Windows
// On other (Unix-like) operating systems it'll probably be in the PATH
- if (qbs.targetOS.contains("windows"))
+ if (qbs.targetOS.includes("windows"))
validator.setRequiredProperty("toolchainInstallPath", toolchainInstallPath);
validator.setRequiredProperty("versionMajor", versionMajor);
@@ -158,7 +159,7 @@ Module {
var args = [];
// Prefix character for makensis options
- var opt = product.moduleProperty("qbs", "hostOS").contains("windows") ? "/" : "-";
+ var opt = product.moduleProperty("qbs", "hostOS").includes("windows") ? "/" : "-";
if (ModUtils.moduleProperty(product, "disableConfig")) {
args.push(opt + "NOCONFIG");
diff --git a/share/qbs/modules/pkgconfig/pkgconfig.qbs b/share/qbs/modules/pkgconfig/pkgconfig.qbs
index b436263e9..901e7e02e 100644
--- a/share/qbs/modules/pkgconfig/pkgconfig.qbs
+++ b/share/qbs/modules/pkgconfig/pkgconfig.qbs
@@ -47,7 +47,7 @@ Module {
}
property path sysroot: {
- if (qbs.targetOS.contains("macos"))
+ if (qbs.targetOS.includes("macos"))
return "";
return qbs.sysroot;
}
diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
index e1459658d..bd4a08557 100644
--- a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
+++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
@@ -6,27 +6,30 @@ import "../protobufbase.qbs" as ProtobufBase
import "../protobuf.js" as HelperFunctions
ProtobufBase {
- property string includePath: includeProbe.found ? includeProbe.path : undefined
- property string libraryPath: libraryProbe.found ? libraryProbe.path : undefined
-
property bool useGrpc: false
property bool _linkLibraries: true
+ readonly property bool _hasModules: protobuflib.present && (!useGrpc || grpcpp.present)
- property string grpcIncludePath: grpcIncludeProbe.found ? grpcIncludeProbe.path : undefined
- property string grpcLibraryPath: grpcLibraryProbe.found ? grpcLibraryProbe.path : undefined
+ property string _cxxLanguageVersion: "c++17"
- readonly property string _libraryName: {
- var libraryName;
- if (libraryProbe.found) {
- libraryName = FileInfo.baseName(libraryProbe.fileName);
- if (libraryName.startsWith("lib"))
- libraryName = libraryName.substring(3);
- }
- return libraryName;
- }
+ _searchPaths: protobuflib.present ? protobuflib.hostBinDirs : undefined
+ property stringList _grpcSearchPaths: grpcpp.present ? grpcpp.hostBinDirs : undefined
+
+ cpp.includePaths: outputDir
Depends { name: "cpp" }
+ Depends {
+ name: "protobuflib";
+ condition: _linkLibraries;
+ required: false
+ }
+ Depends {
+ name: "grpc++";
+ id: grpcpp
+ condition: _linkLibraries && useGrpc;
+ required: false
+ }
property path grpcPluginPath: grpcPluginProbe.filePath
@@ -34,43 +37,10 @@ ProtobufBase {
condition: useGrpc
id: grpcPluginProbe
names: "grpc_cpp_plugin"
+ searchPaths: _grpcSearchPaths
}
- cpp.libraryPaths: {
- if (!_linkLibraries)
- return [];
-
- var result = [];
- if (libraryProbe.found)
- result.push(libraryProbe.path);
- if (useGrpc && grpcLibraryProbe.found)
- result.push(grpcLibraryPath);
- return result;
- }
- cpp.dynamicLibraries: {
- if (!_linkLibraries)
- return [];
-
- var result = [];
- if (_libraryName)
- result.push(_libraryName)
- if (qbs.targetOS.contains("unix"))
- result.push("pthread");
- if (useGrpc)
- result.push("grpc++");
- return result;
- }
- cpp.includePaths: {
- if (!_linkLibraries)
- return [outputDir];
-
- var result = [outputDir];
- if (includeProbe.found)
- result.push(includePath);
- if (useGrpc && grpcIncludeProbe.found)
- result.push(grpcIncludePath);
- return result;
- }
+ cpp.cxxLanguageVersion: _cxxLanguageVersion
Rule {
inputs: ["protobuf.input", "protobuf.grpc"]
@@ -82,7 +52,7 @@ ProtobufBase {
".pb.h"),
HelperFunctions.cppArtifact(outputDir, input, "cpp", ".pb.cc")
];
- if (input.fileTags.contains("protobuf.grpc")) {
+ if (input.fileTags.includes("protobuf.grpc")) {
result.push(
HelperFunctions.cppArtifact(outputDir, input, ["hpp", "protobuf.hpp"],
".grpc.pb.h"),
@@ -95,7 +65,7 @@ ProtobufBase {
prepare: {
var result = HelperFunctions.doPrepare(
input.protobuf.cpp, product, input, outputs, "cpp");
- if (input.fileTags.contains("protobuf.grpc")) {
+ if (input.fileTags.includes("protobuf.grpc")) {
result = ModUtils.concatAll(result, HelperFunctions.doPrepare(
input.protobuf.cpp, product, input, outputs, "grpc",
"protoc-gen-grpc=" + input.protobuf.cpp.grpcPluginPath));
@@ -104,53 +74,16 @@ ProtobufBase {
}
}
- Probes.IncludeProbe {
- id: includeProbe
- names: "google/protobuf/message.h"
- platformSearchPaths: includePath ? [] : base
- searchPaths: includePath ? [includePath] : []
- }
-
- Probes.LibraryProbe {
- id: libraryProbe
- names: [
- "protobuf",
- "protobufd",
- ]
- platformSearchPaths: libraryPath ? [] : base
- searchPaths: libraryPath ? [libraryPath] : []
- }
-
- Probes.IncludeProbe {
- id: grpcIncludeProbe
- pathSuffixes: "grpc++"
- names: "grpc++.h"
- platformSearchPaths: grpcIncludePath ? [] : base
- searchPaths: grpcIncludePath ? [grpcIncludePath] : []
- }
-
- Probes.LibraryProbe {
- id: grpcLibraryProbe
- names: "grpc++"
- platformSearchPaths: grpcLibraryPath ? [] : base
- searchPaths: grpcLibraryPath ? [grpcLibraryPath] : []
- }
-
validate: {
HelperFunctions.validateCompiler(compilerName, compilerPath);
- if (_linkLibraries && !includeProbe.found)
- throw "Can't find cpp protobuf include files. Please set the includePath property.";
- if (_linkLibraries && !libraryProbe.found)
- throw "Can't find cpp protobuf library. Please set the libraryPath property.";
+ if (_linkLibraries && ! _hasModules) {
+ throw "Can't find cpp protobuf runtime. Make sure .pc files are present";
+ }
if (useGrpc) {
if (!File.exists(grpcPluginPath))
throw "Can't find grpc_cpp_plugin plugin. Please set the grpcPluginPath property.";
- if (_linkLibraries && !grpcIncludeProbe.found)
- throw "Can't find grpc++ include files. Please set the grpcIncludePath property.";
- if (_linkLibraries && !grpcLibraryProbe.found)
- throw "Can't find grpc++ library. Please set the grpcLibraryPath property.";
}
}
}
diff --git a/share/qbs/modules/protobuf/nanopb/nanopb.qbs b/share/qbs/modules/protobuf/nanopb/nanopb.qbs
index 898e230b6..ada7c20bb 100644
--- a/share/qbs/modules/protobuf/nanopb/nanopb.qbs
+++ b/share/qbs/modules/protobuf/nanopb/nanopb.qbs
@@ -41,6 +41,7 @@ ProtobufBase {
result.push(includePath);
return result;
}
+ cpp.cxxLanguageVersion: qbs.targetOS.contains("darwin") ? ["c++17"] : ["c++11"]
Rule {
inputs: ["protobuf.input"]
diff --git a/share/qbs/modules/protobuf/protobuf.js b/share/qbs/modules/protobuf/protobuf.js
index abc2c2c4d..60d6f48e4 100644
--- a/share/qbs/modules/protobuf/protobuf.js
+++ b/share/qbs/modules/protobuf/protobuf.js
@@ -75,6 +75,7 @@ function cppArtifact(outputDir, input, tags, suffix) {
filePath: FileInfo.joinPaths(outputDir, FileInfo.baseName(input.fileName) + suffix),
cpp: {
includePaths: [].concat(input.cpp.includePaths, outputDir),
+ defines: ["NDEBUG"],
warningLevel: "none",
}
};
diff --git a/share/qbs/modules/protobuf/protobufbase.qbs b/share/qbs/modules/protobuf/protobufbase.qbs
index e302d3758..e32ee30b9 100644
--- a/share/qbs/modules/protobuf/protobufbase.qbs
+++ b/share/qbs/modules/protobuf/protobufbase.qbs
@@ -6,6 +6,7 @@ import "protobuf.js" as HelperFunctions
Module {
property string compilerName: "protoc"
property string compilerPath: compilerProbe.filePath
+ property var _searchPaths
property pathList importPaths: []
@@ -19,5 +20,6 @@ Module {
Probes.BinaryProbe {
id: compilerProbe
names: [compilerName]
+ searchPaths: _searchPaths
}
}
diff --git a/share/qbs/modules/qbs/common.qbs b/share/qbs/modules/qbs/common.qbs
index 8ddfc582d..8b31092a9 100644
--- a/share/qbs/modules/qbs/common.qbs
+++ b/share/qbs/modules/qbs/common.qbs
@@ -53,10 +53,10 @@ Module {
readonly property string hostPlatform: undefined // set internally
readonly property stringList hostOS: Utilities.canonicalPlatform(hostPlatform)
property string hostOSVersion: {
- if (hostOS && hostOS.contains("macos")) {
+ if (hostOS && hostOS.includes("macos")) {
return Utilities.getNativeSetting("/System/Library/CoreServices/ServerVersion.plist", "ProductVersion") ||
Utilities.getNativeSetting("/System/Library/CoreServices/SystemVersion.plist", "ProductVersion");
- } else if (hostOS && hostOS.contains("windows")) {
+ } else if (hostOS && hostOS.includes("windows")) {
var version = Utilities.getNativeSetting(windowsRegistryKey, "CurrentVersion");
return version + "." + hostOSBuildVersion;
}
@@ -64,10 +64,10 @@ Module {
readonly property string hostArchitecture: undefined // set internally
property string hostOSBuildVersion: {
- if (hostOS.contains("macos")) {
+ if (hostOS.includes("macos")) {
return Utilities.getNativeSetting("/System/Library/CoreServices/ServerVersion.plist", "ProductBuildVersion") ||
Utilities.getNativeSetting("/System/Library/CoreServices/SystemVersion.plist", "ProductBuildVersion");
- } else if (hostOS.contains("windows")) {
+ } else if (hostOS.includes("windows")) {
return Utilities.getNativeSetting(windowsRegistryKey, "CurrentBuildNumber");
}
}
@@ -79,19 +79,19 @@ Module {
property string targetPlatform: hostPlatform
readonly property stringList targetOS: Utilities.canonicalPlatform(targetPlatform)
- property string pathListSeparator: hostOS.contains("windows") ? ";" : ":"
- property string pathSeparator: hostOS.contains("windows") ? "\\" : "/"
- property string nullDevice: hostOS.contains("windows") ? "NUL" : "/dev/null"
- property path shellPath: hostOS.contains("windows") ? windowsShellPath : "/bin/sh"
+ property string pathListSeparator: hostOS.includes("windows") ? ";" : ":"
+ property string pathSeparator: hostOS.includes("windows") ? "\\" : "/"
+ property string nullDevice: hostOS.includes("windows") ? "NUL" : "/dev/null"
+ property path shellPath: hostOS.includes("windows") ? windowsShellPath : "/bin/sh"
property string profile: project.profile
property string toolchainType: {
- if (targetOS.contains("windows"))
- return hostOS.contains("windows") ? "msvc" : "mingw";
- if (targetOS.contains("darwin"))
- return hostOS.contains("macos") ? "xcode" : "clang";
- if (targetOS.contains("freebsd"))
+ if (targetOS.includes("windows"))
+ return hostOS.includes("windows") ? "msvc" : "mingw";
+ if (targetOS.includes("darwin"))
+ return hostOS.includes("macos") ? "xcode" : "clang";
+ if (targetOS.includes("freebsd"))
return "clang";
- if (targetOS.contains("qnx"))
+ if (targetOS.includes("qnx"))
return "qcc";
if (targetOS.containsAny(["haiku", "vxworks", "unix"]))
return "gcc";
@@ -102,7 +102,7 @@ Module {
property path installSourceBase
property string installRoot: project.buildDirectory + "/install-root"
property string installDir
- property string installPrefix: qbs.targetOS.contains("unix") ? "/usr/local" : ""
+ property string installPrefix: targetOS.includes("unix") ? "/usr/local" : ""
property path sysroot
PropertyOptions {
@@ -122,12 +122,12 @@ Module {
validator.setRequiredProperty("hostOS", hostOS);
validator.setRequiredProperty("targetOS", targetOS);
validator.addCustomValidator("targetOS", targetOS, function (value) {
- if (!value || (value.contains("osx") && !value.contains("macos")))
+ if (!value || (value.includes("osx") && !value.includes("macos")))
return false;
return true;
}, "the value 'osx' has been replaced by 'macos'; use that instead and update "
+ "hostOS and targetOS condition checks in your project accordingly");
- if (hostOS && (hostOS.contains("windows") || hostOS.contains("macos"))) {
+ if (hostOS && (hostOS.includes("windows") || hostOS.includes("macos"))) {
validator.setRequiredProperty("hostOSVersion", hostOSVersion,
"could not detect host operating system version; " +
"verify that system files and registry keys have not " +
@@ -143,8 +143,9 @@ Module {
validator.addCustomValidator("architecture", architecture, function (value) {
return !architecture || architecture === Utilities.canonicalArchitecture(architecture);
- }, "'" + architecture + "' is invalid. You must use the canonical name '" +
- Utilities.canonicalArchitecture(architecture) + "'");
+ }, "'" + architecture + "' is invalid." + (architecture
+ ? " You must use the canonical name '" + Utilities.canonicalArchitecture(architecture)
+ : "") + "'");
validator.addCustomValidator("toolchain", toolchain, function (value) {
if (toolchain === undefined)
@@ -169,7 +170,7 @@ Module {
];
var canonical = Utilities.canonicalToolchain.apply(Utilities, value);
for (var i = 0; i < pairs.length; ++i) {
- if (canonical.contains(pairs[i][0]) && canonical.contains(pairs[i][1]))
+ if (canonical.includes(pairs[i][0]) && canonical.includes(pairs[i][1]))
return false;
}
return true;
@@ -182,14 +183,14 @@ Module {
property string windowsRegistryKey: "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows NT\\CurrentVersion"
property path windowsSystemRoot: FileInfo.fromWindowsSeparators(Utilities.getNativeSetting(windowsRegistryKey, "SystemRoot"))
property path windowsShellPath: FileInfo.fromWindowsSeparators(Environment.getEnv("COMSPEC")) || FileInfo.joinPaths(windowsSystemRoot, "System32", "cmd.exe")
- property string windowsPathVariable: hostOS.contains("windows") ? "PATH" : "WINEPATH"
+ property string windowsPathVariable: hostOS.includes("windows") ? "PATH" : "WINEPATH"
property var commonRunEnvironment: ({})
setupRunEnvironment: {
var env = product.qbs.commonRunEnvironment;
for (var i in env) {
var v = new ModUtils.EnvironmentVariable(i, product.qbs.pathListSeparator,
- product.qbs.hostOS.contains("windows"));
+ product.qbs.hostOS.includes("windows"));
v.value = env[i];
v.set();
}
diff --git a/share/qbs/modules/qnx/qnx.qbs b/share/qbs/modules/qnx/qnx.qbs
index 9cab5abb6..899b72441 100644
--- a/share/qbs/modules/qnx/qnx.qbs
+++ b/share/qbs/modules/qnx/qnx.qbs
@@ -31,6 +31,7 @@
import qbs.Environment
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Probes
import qbs.Utilities
@@ -39,7 +40,7 @@ Module {
Probes.PathProbe {
id: qnxSdkProbe
names: ["qnx700", "qnx660", "qnx650"]
- searchPaths: qbs.hostOS.contains("windows")
+ searchPaths: Host.os().includes("windows")
? [Environment.getEnv("USERPROFILE"), Environment.getEnv("SystemDrive")]
: [Environment.getEnv("HOME"), "/opt"]
}
@@ -77,11 +78,11 @@ Module {
property string hostArch: qnx7 ? "x86_64" : "x86"
property string hostOs: {
- if (qbs.hostOS.contains("linux"))
+ if (Host.os().includes("linux"))
return "linux";
- if (qbs.hostOS.contains("macos"))
+ if (Host.os().includes("macos"))
return "darwin";
- if (qbs.hostOS.contains("windows"))
+ if (Host.os().includes("windows"))
return qnx7 ? "win64" : "win32";
}
@@ -111,7 +112,7 @@ Module {
}
if (!hostOs) {
- throw ModUtils.ModuleError("Host operating system '" + qbs.hostOS
+ throw ModUtils.ModuleError("Host operating system '" + Host.os()
+ "' is not supported by the QNX SDK.");
} else if (!File.exists(hostDir)) {
throw ModUtils.ModuleError("Detected host tools operating system '" + hostOs
diff --git a/share/qbs/modules/typescript/TypeScriptModule.qbs b/share/qbs/modules/typescript/TypeScriptModule.qbs
index d8e61b17f..76df529c2 100644
--- a/share/qbs/modules/typescript/TypeScriptModule.qbs
+++ b/share/qbs/modules/typescript/TypeScriptModule.qbs
@@ -129,7 +129,7 @@ Module {
var preValidator = new ModUtils.PropertyValidator("nodejs");
preValidator.addCustomValidator("interpreterFileName", nodejs.interpreterFileName, function (value) {
- return value === "node" + (qbs.hostOS.contains("windows") ? ".exe" : "");
+ return value === "node" + FileInfo.executableSuffix();
}, interpreterMessage);
preValidator.addCustomValidator("interpreterFilePath", nodejs.interpreterFilePath, function (value) {
return value.endsWith(nodejs.interpreterFileName);
diff --git a/share/qbs/modules/typescript/typescript.js b/share/qbs/modules/typescript/typescript.js
index 858041b3d..199f486cf 100644
--- a/share/qbs/modules/typescript/typescript.js
+++ b/share/qbs/modules/typescript/typescript.js
@@ -132,7 +132,7 @@ function outputArtifacts(product, inputs) {
process.setEnv("NODE_PATH", [
ModUtils.moduleProperty(product, "toolchainInstallPath"),
product.moduleProperty("nodejs", "packageManagerRootPath")
- ].join(product.moduleProperty("qbs", "pathListSeparator")));
+ ].join(FileInfo.pathListSeparator()));
process.exec(product.moduleProperty("nodejs", "interpreterFilePath"),
[FileInfo.joinPaths(product.buildDirectory,
".io.qt.qbs.internal.typescript",
@@ -146,7 +146,7 @@ function outputArtifacts(product, inputs) {
var i, appIndex = -1;
if (product.moduleProperty("typescript", "singleFile")) {
for (i = 0; i < artifacts.length; ++i) {
- if (artifacts[i].fileTags.contains("compiled_typescript")) {
+ if (artifacts[i].fileTags.includes("compiled_typescript")) {
appIndex = i;
break;
}
@@ -169,7 +169,7 @@ function outputArtifacts(product, inputs) {
}
}
- if (appIndex === -1 || !artifacts[appIndex].fileTags.contains("compiled_typescript"))
+ if (appIndex === -1 || !artifacts[appIndex].fileTags.includes("compiled_typescript"))
throw "nodejs.applicationFile was set, but Qbs couldn't find the compiled " +
"JavaScript file corresponding to '" + applicationFile + "'";
diff --git a/share/qbs/modules/wix/WiXModule.qbs b/share/qbs/modules/wix/WiXModule.qbs
index ad8586da1..077f259f4 100644
--- a/share/qbs/modules/wix/WiXModule.qbs
+++ b/share/qbs/modules/wix/WiXModule.qbs
@@ -30,12 +30,13 @@
import qbs.File
import qbs.FileInfo
+import qbs.Host
import qbs.ModUtils
import qbs.Probes
import qbs.Utilities
Module {
- condition: qbs.targetOS.contains("windows")
+ condition: qbs.targetOS.includes("windows")
Probes.WiXProbe {
id: wixProbe
@@ -112,19 +113,19 @@ Module {
description: "the list of localizations to build the MSI for; leave undefined to build all localizations"
}
- property stringList extensions: product.type.contains("wixsetup") ? ["WixBalExtension"] : [] // default to WiX Standard Bootstrapper extension
+ property stringList extensions: product.type.includes("wixsetup") ? ["WixBalExtension"] : [] // default to WiX Standard Bootstrapper extension
// private properties
property string targetSuffix: {
- if (product.type.contains("msi")) {
+ if (product.type.includes("msi")) {
return windowsInstallerSuffix;
- } else if (product.type.contains("wixsetup")) {
+ } else if (product.type.includes("wixsetup")) {
return executableSuffix;
}
}
// MSI/MSM package validation only works natively on Windows
- property bool enablePackageValidation: qbs.hostOS.contains("windows")
+ property bool enablePackageValidation: Host.os().includes("windows")
property string executableSuffix: ".exe"
property string windowsInstallerSuffix: ".msi"
@@ -151,7 +152,7 @@ Module {
}
setupBuildEnvironment: {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, true);
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), true);
v.prepend(product.wix.toolchainInstallPath);
v.prepend(product.wix.toolchainInstallRoot);
v.set();
@@ -226,7 +227,7 @@ Module {
if (ModUtils.moduleProperty(input, "visualStudioCompatibility")) {
var toolchain = product.moduleProperty("qbs", "toolchain");
var toolchainInstallPath = product.moduleProperty("cpp", "toolchainInstallPath");
- if (toolchain && toolchain.contains("msvc") && toolchainInstallPath) {
+ if (toolchain && toolchain.includes("msvc") && toolchainInstallPath) {
var vcDir = toolchainInstallPath.replace(/[\\/]bin$/i, "");
var vcRootDir = vcDir.replace(/[\\/]VC$/i, "");
args.push("-dDevEnvDir=" + FileInfo.toWindowsSeparators(FileInfo.joinPaths(vcRootDir, 'Common7', 'IDE')));
@@ -334,12 +335,12 @@ Module {
multiplex: true
inputs: ["wixobj", "wxl"]
auxiliaryInputs: ["installable"]
- inputsFromDependencies: product.type.contains("wixsetup") ? ["msi"] : []
+ inputsFromDependencies: product.type.includes("wixsetup") ? ["msi"] : []
outputArtifacts: {
var artifacts = [];
- if (product.type.contains("wixsetup")) {
+ if (product.type.includes("wixsetup")) {
artifacts.push({
fileTags: ["wixsetup", "application"],
filePath: FileInfo.joinPaths(product.destinationDirectory,
@@ -349,7 +350,7 @@ Module {
});
}
- if (product.type.contains("msi")) {
+ if (product.type.includes("msi")) {
artifacts.push({
fileTags: ["msi"],
filePath: FileInfo.joinPaths(product.destinationDirectory,
@@ -375,9 +376,9 @@ Module {
prepare: {
var i;
var primaryOutput;
- if (product.type.contains("wixsetup")) {
+ if (product.type.includes("wixsetup")) {
primaryOutput = outputs.wixsetup[0];
- } else if (product.type.contains("msi")) {
+ } else if (product.type.includes("msi")) {
primaryOutput = outputs.msi[0];
} else {
throw("WiX: Unsupported product type '" + product.type + "'");
@@ -426,7 +427,7 @@ Module {
args.push(FileInfo.toWindowsSeparators(inputs.wxl[i].filePath));
}
- if (product.type.contains("msi")) {
+ if (product.type.includes("msi")) {
var cultures = ModUtils.moduleProperty(product, "cultures");
args.push("-cultures:"
+ (cultures && cultures.length > 0 ? cultures.join(";") : "null"));
diff --git a/share/qbs/modules/xcode/xcode.js b/share/qbs/modules/xcode/xcode.js
index 1060894d4..726974579 100644
--- a/share/qbs/modules/xcode/xcode.js
+++ b/share/qbs/modules/xcode/xcode.js
@@ -112,7 +112,7 @@ function sdkInfoList(sdksPath) {
if (!sdks[i].match(/[0-9]+/))
continue;
- if (sdks[i].startsWith("DriverKit"))
+ if (sdks[i].startsWith("DriverKit") || sdks[i].startsWith("AssetRuntime"))
continue;
var settingsPlist = FileInfo.joinPaths(sdksPath, sdks[i], "SDKSettings.plist");
@@ -202,18 +202,41 @@ function boolFromSdkOrPlatform(varName, sdkProps, platformProps, defaultValue) {
return defaultValue;
}
-function archsSpecsPath(version, targetOS, platformType, platformPath, devicePlatformPath) {
+function archsSpecsPath(version, targetOS, platformType, platformPath, devicePlatformPath,
+ developerPath) {
+ if (Utilities.versionCompare(version, "13.3") >= 0) {
+ var pluginsDir;
+ if (Utilities.versionCompare(version, "15.3") >= 0) {
+ pluginsDir = FileInfo.joinPaths(developerPath, "..",
+ "SharedFrameworks", "XCBuild.framework", "PlugIns", "XCBBuildService.bundle",
+ "Contents", "PlugIns");
+ } else if (Utilities.versionCompare(version, "14.3") >= 0) {
+ pluginsDir = FileInfo.joinPaths(developerPath, "Library", "Xcode", "Plug-ins");
+ } else {
+ pluginsDir = FileInfo.joinPaths(developerPath, "..", "PlugIns");
+ }
+ var baseDir = FileInfo.joinPaths(pluginsDir,
+ "XCBSpecifications.ideplugin", "Contents", "Resources");
+
+ var baseName = targetOS.includes("macos") ? "MacOSX Architectures"
+ : targetOS.includes("ios-simulator") ? "iOS Simulator"
+ : targetOS.includes("ios") ? "iOS Device"
+ : targetOS.includes("tvos-simulator") ? "tvOS Simulator"
+ : targetOS.includes("tvos") ? "tvOS Device"
+ : targetOS.includes("watchos-simulator") ? "watchOS Simulator" : "watchOS Device";
+ return FileInfo.joinPaths(baseDir, baseName + ".xcspec");
+ }
var _specsPluginBaseName;
if (Utilities.versionCompare(version, "12") >= 0) {
- if (targetOS.contains("macos"))
+ if (targetOS.includes("macos"))
_specsPluginBaseName = "OSX";
}
if (Utilities.versionCompare(version, "7") >= 0) {
- if (targetOS.contains("ios"))
+ if (targetOS.includes("ios"))
_specsPluginBaseName = "iOSPlatform";
- if (targetOS.contains("tvos"))
+ if (targetOS.includes("tvos"))
_specsPluginBaseName = "AppleTV";
- if (targetOS.contains("watchos"))
+ if (targetOS.includes("watchos"))
_specsPluginBaseName = "Watch";
}
@@ -224,8 +247,8 @@ function archsSpecsPath(version, targetOS, platformType, platformPath, devicePla
"Resources")
: FileInfo.joinPaths(platformPath, "Developer", "Library", "Xcode", "Specifications");
- var _archSpecsFileBaseName = targetOS.contains("ios")
- ? (targetOS.contains("ios-simulator") ? "iPhone Simulator " : "iPhoneOS")
+ var _archSpecsFileBaseName = targetOS.includes("ios")
+ ? (targetOS.includes("ios-simulator") ? "iPhone Simulator " : "iPhoneOS")
: DarwinTools.applePlatformDirectoryName(targetOS, platformType) + " ";
if (_specsPluginBaseName) {
diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs
index 6c0584c81..2c0cd001a 100644
--- a/share/qbs/modules/xcode/xcode.qbs
+++ b/share/qbs/modules/xcode/xcode.qbs
@@ -9,25 +9,23 @@ import qbs.PropertyList
import qbs.Utilities
Module {
- id: xcodeModule
-
Probes.XcodeLocationProbe {
id: xcodeLocationProbe
- condition: !xcodeModule.developerPath
+ condition: !developerPath
}
Probes.XcodeProbe {
id: xcodeProbe
- developerPath: xcodeModule.developerPath
- platformType: xcodeModule.platformType
- platformPath: xcodeModule.platformPath
- devicePlatformPath: xcodeModule.devicePlatformPath
- xcodebuildPath: xcodeModule.xcodebuildPath
- sdksPath: xcodeModule.sdksPath
+ developerPath: parent.developerPath
+ platformType: parent.platformType
+ platformPath: parent.platformPath
+ devicePlatformPath: parent.devicePlatformPath
+ xcodebuildPath: parent.xcodebuildPath
+ sdksPath: parent.sdksPath
}
- condition: qbs.targetOS.contains("darwin") &&
- qbs.toolchain && qbs.toolchain.contains("xcode")
+ condition: qbs.targetOS.includes("darwin") &&
+ qbs.toolchain && qbs.toolchain.includes("xcode")
version: xcodeProbe.xcodeVersion
@@ -134,6 +132,7 @@ Module {
readonly property var _sdkSettings: {
if (_availableSdks) {
+ // see 'sdk' property doc to understand why this loop is needed
for (var i in _availableSdks) {
if (_availableSdks[i]["Version"] === sdk)
return _availableSdks[i];
@@ -141,7 +140,7 @@ Module {
return _availableSdks[i];
}
- // Latest SDK available for the platform
+ // Latest SDK available for the platform (default case)
if (DarwinTools.applePlatformName(qbs.targetOS, platformType) === sdk)
return _latestSdk;
}
@@ -193,7 +192,7 @@ Module {
})
setupBuildEnvironment: {
- var v = new ModUtils.EnvironmentVariable("PATH", product.qbs.pathListSeparator, false);
+ var v = new ModUtils.EnvironmentVariable("PATH", FileInfo.pathListSeparator(), false);
v.prepend(product.xcode.platformPath + "/Developer/usr/bin");
v.prepend(product.xcode.developerPath + "/usr/bin");
v.set();