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.qbs32
-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/qbs/qbsexporter.js34
-rw-r--r--share/qbs/modules/Sanitizers/address/asan.qbs3
-rw-r--r--share/qbs/modules/bundle/BundleModule.qbs91
-rw-r--r--share/qbs/modules/bundle/bundle.js19
-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/codesign/apple.qbs2
-rw-r--r--share/qbs/modules/codesign/codesign.js90
-rw-r--r--share/qbs/modules/cpp/GenericGCC.qbs6
-rw-r--r--share/qbs/modules/cpp/cpp.js10
-rw-r--r--share/qbs/modules/cpp/gcc.js20
-rw-r--r--share/qbs/modules/cpp/msvc.js45
-rw-r--r--share/qbs/modules/cpp/windows-clang-cl.qbs2
-rw-r--r--share/qbs/modules/cpp/windows-msvc-base.qbs5
-rw-r--r--share/qbs/modules/dmg/DMGModule.qbs7
-rw-r--r--share/qbs/modules/dmg/dmg.js19
-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/java/utils.js36
-rw-r--r--share/qbs/modules/protobuf/cpp/protobufcpp.qbs114
-rw-r--r--share/qbs/modules/protobuf/nanopb/nanopb.qbs1
-rw-r--r--share/qbs/modules/protobuf/protobufbase.qbs2
-rw-r--r--share/qbs/modules/qbs/common.qbs2
-rw-r--r--share/qbs/modules/xcode/xcode.js17
-rw-r--r--share/qbs/modules/xcode/xcode.qbs19
31 files changed, 993 insertions, 295 deletions
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index d663a01e4..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
}
@@ -263,7 +263,7 @@ Module {
property bool customManifestProcessing: false
Group {
- condition: !Android.sdk.customManifestProcessing
+ condition: !product.Android.sdk.customManifestProcessing
fileTagsFilter: "android.manifest_processed"
fileTags: "android.manifest_final"
}
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/qbs/qbsexporter.js b/share/qbs/modules/Exporter/qbs/qbsexporter.js
index f09dd2d0c..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)
{
@@ -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) + ", "
diff --git a/share/qbs/modules/Sanitizers/address/asan.qbs b/share/qbs/modules/Sanitizers/address/asan.qbs
index 9ae6f285e..9d8f5b97e 100644
--- a/share/qbs/modules/Sanitizers/address/asan.qbs
+++ b/share/qbs/modules/Sanitizers/address/asan.qbs
@@ -64,7 +64,8 @@ Module {
flags.push("-fsanitize-address-use-after-scope");
if (detectUseAfterReturn) {
if (qbs.toolchain.includes("llvm")) {
- if (Utilities.versionCompare(cpp.compilerVersion, "13") >= 0)
+ 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");
diff --git a/share/qbs/modules/bundle/BundleModule.qbs b/share/qbs/modules/bundle/BundleModule.qbs
index 0d8452a7e..f640fd55f 100644
--- a/share/qbs/modules/bundle/BundleModule.qbs
+++ b/share/qbs/modules/bundle/BundleModule.qbs
@@ -193,6 +193,11 @@ Module {
property string _productTypeIdentifier: Bundle.productTypeIdentifier(product.type)
property stringList _productTypeIdentifierChain: bundleSettingsProbe.productTypeIdentifierChain
+ 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: ({
@@ -281,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"),
@@ -290,7 +295,7 @@ Module {
bundle: {
_bundleFilePath: FileInfo.joinPaths(
product.destinationDirectory,
- ModUtils.moduleProperty(product, "infoPlistPath")),
+ product.bundle.infoPlistPath),
}
});
}
@@ -301,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;
@@ -343,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];
@@ -480,11 +486,11 @@ Module {
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;
@@ -535,9 +541,9 @@ 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.includes("application")
@@ -552,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"]
});
}
@@ -573,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"]
});
}
@@ -606,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({
@@ -617,7 +622,7 @@ 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 };
@@ -634,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")
@@ -652,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);
@@ -699,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) {
@@ -733,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) {
@@ -747,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) {
@@ -761,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) {
@@ -772,17 +777,17 @@ Module {
if (cmd.sources && cmd.sources.length)
commands.push(cmd);
- if (product.moduleProperty("qbs", "hostOS").includes("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").includes("macos")) {
+ && product.qbs.targetOS.includes("macos")) {
var bundlePath = FileInfo.joinPaths(
product.destinationDirectory, product.bundle.bundleName);
- cmd = new Command(ModUtils.moduleProperty(product, "lsregisterPath"),
+ cmd = new Command(product.bundle.lsregisterPath,
["-f", bundlePath]);
- cmd.description = "registering " + ModUtils.moduleProperty(product, "bundleName");
+ 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 ec0e30054..cf765f7be 100644
--- a/share/qbs/modules/bundle/bundle.js
+++ b/share/qbs/modules/bundle/bundle.js
@@ -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"));
@@ -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/codesign/apple.qbs b/share/qbs/modules/codesign/apple.qbs
index 72384a06a..0d1335d92 100644
--- a/share/qbs/modules/codesign/apple.qbs
+++ b/share/qbs/modules/codesign/apple.qbs
@@ -181,7 +181,7 @@ CodeSignModule {
}
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 903d16f80..482225ea2 100644
--- a/share/qbs/modules/codesign/codesign.js
+++ b/share/qbs/modules/codesign/codesign.js
@@ -280,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 “"
@@ -310,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/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs
index 22a98ad57..f84028940 100644
--- a/share/qbs/modules/cpp/GenericGCC.qbs
+++ b/share/qbs/modules/cpp/GenericGCC.qbs
@@ -170,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."
}
@@ -216,7 +216,7 @@ CppModule {
linkerScriptFlag: "-T"
readonly property bool shouldCreateSymlinks: {
- return createSymlinks && internalVersion && ["macho", "elf"].includes(cpp.imageFormat);
+ return createSymlinks && internalVersion && ["macho", "elf"].includes(imageFormat);
}
readonly property bool shouldSignArtifacts: codesign._canSignArtifacts
@@ -252,7 +252,7 @@ CppModule {
property var buildEnv: {
var env = {};
if (qbs.toolchain.includes("mingw"))
- env.PATH = [toolchainInstallPath]; // For libwinpthread etc
+ env.PATH = toolchainInstallPath; // For libwinpthread etc
return env;
}
diff --git a/share/qbs/modules/cpp/cpp.js b/share/qbs/modules/cpp/cpp.js
index a13504013..9f907580a 100644
--- a/share/qbs/modules/cpp/cpp.js
+++ b/share/qbs/modules/cpp/cpp.js
@@ -327,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) {
@@ -338,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/gcc.js b/share/qbs/modules/cpp/gcc.js
index 747c6c9ee..90f8fc933 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -78,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"
@@ -170,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) {
@@ -193,6 +196,7 @@ function collectLibraryDependencies(product, isDarwin) {
publicDeps[dep.name] = true;
} else {
addArtifactFilePaths(dep, tagForLinkingAgainstSharedLib, addPrivateFilePath);
+ privateDeps[dep.name] = true;
}
}
}
@@ -204,7 +208,6 @@ function collectLibraryDependencies(product, isDarwin) {
product.dependencies.forEach(traverseDirectDependency);
addExternalLibs(product);
- var seenRPathLinkDirs = {};
var result = { libraries: [], rpath_link: [] };
objects.forEach(
function (obj) {
@@ -215,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;
@@ -377,6 +377,9 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
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];
@@ -403,8 +406,8 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
// 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));
@@ -474,7 +477,10 @@ function linkerFlags(project, product, inputs, outputs, primaryOutput, linkerPat
if (isDarwin && 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)
diff --git a/share/qbs/modules/cpp/msvc.js b/share/qbs/modules/cpp/msvc.js
index 8be4bff24..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.includes("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,20 +92,20 @@ 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.includes("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.includes("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 Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30138.0") >= 0
- || (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 13);
+ return (input.qbs.toolchain.includes("clang-cl") && input.cpp.compilerVersionMajor >= 13)
+ || Utilities.versionCompare(input.cpp.compilerVersion, "19.29.30138.0") >= 0;
}
function supportsExternalIncludesOption(input) {
@@ -124,10 +124,9 @@ function addCxxLanguageVersionFlag(input, args) {
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.includes("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;
@@ -250,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) {
@@ -371,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) {
diff --git a/share/qbs/modules/cpp/windows-clang-cl.qbs b/share/qbs/modules/cpp/windows-clang-cl.qbs
index 32abb572a..9aa9d7395 100644
--- a/share/qbs/modules/cpp/windows-clang-cl.qbs
+++ b/share/qbs/modules/cpp/windows-clang-cl.qbs
@@ -85,6 +85,8 @@ MsvcBaseModule {
linkerName: "lld-link.exe"
linkerPath: FileInfo.joinPaths(toolchainInstallPath, linkerName)
+ systemIncludeFlag: "/imsvc"
+
validateFunc: {
var baseFunc = base;
return function() {
diff --git a/share/qbs/modules/cpp/windows-msvc-base.qbs b/share/qbs/modules/cpp/windows-msvc-base.qbs
index 1a2c338db..9613800e5 100644
--- a/share/qbs/modules/cpp/windows-msvc-base.qbs
+++ b/share/qbs/modules/cpp/windows-msvc-base.qbs
@@ -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/dmg/DMGModule.qbs b/share/qbs/modules/dmg/DMGModule.qbs
index 59161b1db..27a945033 100644
--- a/share/qbs/modules/dmg/DMGModule.qbs
+++ b/share/qbs/modules/dmg/DMGModule.qbs
@@ -34,6 +34,7 @@ import qbs.FileInfo
import qbs.Host
import qbs.ModUtils
import qbs.Process
+import qbs.Probes
import qbs.TextFile
import "dmg.js" as Dmg
@@ -73,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 7d50d95f3..06fe7b906 100644
--- a/share/qbs/modules/dmg/dmg.js
+++ b/share/qbs/modules/dmg/dmg.js
@@ -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/java/utils.js b/share/qbs/modules/java/utils.js
index 9ee5932dc..a59b8d41d 100644
--- a/share/qbs/modules/java/utils.js
+++ b/share/qbs/modules/java/utils.js
@@ -99,16 +99,44 @@ function findJdkPath(hostOS, arch, environmentPaths, searchPaths) {
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();
}
diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
index ae218a0c2..bd4a08557 100644
--- a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
+++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs
@@ -6,40 +6,29 @@ 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
- property stringList _extraGrpcLibs: []
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;
- enableFallback: false
+ required: false
}
Depends {
- name: "grpcpp";
+ name: "grpc++";
+ id: grpcpp
condition: _linkLibraries && useGrpc;
- required: false;
- enableFallback: false
+ required: false
}
property path grpcPluginPath: grpcPluginProbe.filePath
@@ -48,45 +37,10 @@ ProtobufBase {
condition: useGrpc
id: grpcPluginProbe
names: "grpc_cpp_plugin"
+ searchPaths: _grpcSearchPaths
}
- cpp.libraryPaths: {
- if (!_linkLibraries || _hasModules)
- return [];
-
- var result = [];
- if (libraryProbe.found)
- result.push(libraryProbe.path);
- if (useGrpc && grpcLibraryProbe.found)
- result.push(grpcLibraryPath);
- return result;
- }
- cpp.dynamicLibraries: {
- if (!_linkLibraries || _hasModules)
- return [];
-
- var result = [];
- if (_libraryName)
- result.push(_libraryName)
- if (qbs.targetOS.includes("unix"))
- result.push("pthread");
- if (useGrpc) {
- result = result.concat(_extraGrpcLibs);
- result.push("grpc++");
- }
- return result;
- }
- cpp.includePaths: {
- if (!_linkLibraries || _hasModules)
- 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"]
@@ -120,56 +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 (_hasModules)
- return;
-
- 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/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 7723c6050..8b31092a9 100644
--- a/share/qbs/modules/qbs/common.qbs
+++ b/share/qbs/modules/qbs/common.qbs
@@ -102,7 +102,7 @@ Module {
property path installSourceBase
property string installRoot: project.buildDirectory + "/install-root"
property string installDir
- property string installPrefix: qbs.targetOS.includes("unix") ? "/usr/local" : ""
+ property string installPrefix: targetOS.includes("unix") ? "/usr/local" : ""
property path sysroot
PropertyOptions {
diff --git a/share/qbs/modules/xcode/xcode.js b/share/qbs/modules/xcode/xcode.js
index 15afddb95..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");
@@ -205,8 +205,19 @@ function boolFromSdkOrPlatform(varName, sdkProps, platformProps, defaultValue) {
function archsSpecsPath(version, targetOS, platformType, platformPath, devicePlatformPath,
developerPath) {
if (Utilities.versionCompare(version, "13.3") >= 0) {
- var baseDir = FileInfo.joinPaths(developerPath, "..",
- "PlugIns/XCBSpecifications.ideplugin/Contents/Resources");
+ 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"
diff --git a/share/qbs/modules/xcode/xcode.qbs b/share/qbs/modules/xcode/xcode.qbs
index 941b8d395..2c0cd001a 100644
--- a/share/qbs/modules/xcode/xcode.qbs
+++ b/share/qbs/modules/xcode/xcode.qbs
@@ -9,21 +9,19 @@ 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.includes("darwin") &&
@@ -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;
}