diff options
Diffstat (limited to 'share')
-rw-r--r-- | share/qbs/imports/qbs/PathTools/path-tools.js | 22 | ||||
-rw-r--r-- | share/qbs/imports/qbs/Probes/LibraryProbe.qbs | 22 | ||||
-rw-r--r-- | share/qbs/module-providers/conan.js | 239 | ||||
-rw-r--r-- | share/qbs/module-providers/conan.qbs | 12 | ||||
-rw-r--r-- | share/qbs/modules/capnproto/capnprotobase.qbs | 5 | ||||
-rw-r--r-- | share/qbs/modules/capnproto/cpp/capnprotocpp.qbs | 1 | ||||
-rw-r--r-- | share/qbs/modules/protobuf/cpp/protobufcpp.qbs | 4 | ||||
-rw-r--r-- | share/qbs/modules/protobuf/protobufbase.qbs | 2 |
8 files changed, 289 insertions, 18 deletions
diff --git a/share/qbs/imports/qbs/PathTools/path-tools.js b/share/qbs/imports/qbs/PathTools/path-tools.js index a857a7139..c928c33e4 100644 --- a/share/qbs/imports/qbs/PathTools/path-tools.js +++ b/share/qbs/imports/qbs/PathTools/path-tools.js @@ -232,3 +232,25 @@ function prependOrSetPath(path, pathList, separator) { return path; return path + separator + pathList; } + +function librarySuffixes(targetOS, types, forImport) { + if (targetOS.includes("windows")) { + if (forImport) + return [".lib"]; + return [].concat(types.includes("shared") ? [".dll"] : []); + } + if (targetOS.includes("darwin")) { + return [] + .concat(types.includes("shared") ? [".dylib"] : []) + .concat(types.includes("static") ? [".a"] : []); + } + return [] + .concat(types.includes("shared") ? [".so"] : []) + .concat(types.includes("static") ? [".a"] : []); +} + +function libraryNameFilter(targetOS) { + if (targetOS.contains("unix")) + return function(name) { return "lib" + name; } + return function(name) { return name; } +} diff --git a/share/qbs/imports/qbs/Probes/LibraryProbe.qbs b/share/qbs/imports/qbs/Probes/LibraryProbe.qbs index 7631eb441..d67a81372 100644 --- a/share/qbs/imports/qbs/Probes/LibraryProbe.qbs +++ b/share/qbs/imports/qbs/Probes/LibraryProbe.qbs @@ -28,15 +28,11 @@ ** ****************************************************************************/ +import qbs.PathTools + PathProbe { property string endianness - nameSuffixes: { - if (qbs.targetOS.contains("windows")) - return [".lib"]; - if (qbs.targetOS.contains("macos")) - return [".dylib", ".a"]; - return [".so", ".a"]; - } + nameSuffixes: PathTools.librarySuffixes(qbs.targetOS, ["shared", "static"], true) platformSearchPaths: { var result = []; if (qbs.targetOS.contains("unix")) { @@ -65,17 +61,7 @@ PathProbe { return result; } - nameFilter: { - if (qbs.targetOS.contains("unix")) { - return function(name) { - return "lib" + name; - } - } else { - return function(name) { - return name; - } - } - } + nameFilter: PathTools.libraryNameFilter(qbs.targetOS) platformEnvironmentPaths: { if (qbs.targetOS.contains("windows")) return [ "PATH" ]; diff --git a/share/qbs/module-providers/conan.js b/share/qbs/module-providers/conan.js new file mode 100644 index 000000000..a44af7eec --- /dev/null +++ b/share/qbs/module-providers/conan.js @@ -0,0 +1,239 @@ +/**************************************************************************** +** +** Copyright (C) 2024 Kai Dohmen +** 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$ +** +****************************************************************************/ + +var File = require("qbs.File"); +var FileInfo = require("qbs.FileInfo"); +var ModUtils = require("qbs.ModUtils"); +var PathProbe = require("../imports/qbs/Probes/path-probe.js") +var PathTools = require("qbs.PathTools"); +var TextFile = require("qbs.TextFile"); +var Utilities = require("qbs.Utilities"); + +const architectureMap = { + 'x86': 'x86', + 'x86_64': 'x86_64', + 'ppc32be': 'ppc', + 'ppc32': 'ppc', + 'ppc64le': 'ppc64', + 'ppc64': 'ppc64', + 'armv4': 'arm', + 'armv4i': 'arm', + 'armv5el': 'arm', + 'armv5hf': 'arm', + 'armv6': 'arm', + 'armv7': 'arm', + 'armv7hf': 'arm', + 'armv7s': 'arm', + 'armv7k': 'arm', + 'armv8': 'arm64', + 'armv8_32': 'arm64', + 'armv8.3': 'arm64', + 'sparc': 'sparc', + 'sparcv9': 'sparc64', + 'mips': 'mips', + 'mips64': 'mips64', + 'avr': 'avr', + 's390': 's390x', + 's390x': 's390x', + 'sh4le': 'sh' +} + +const platformMap = { + 'Windows': 'windows', + 'WindowsStore': 'windows', + 'WindowsCE': 'windows', + 'Linux': 'linux', + 'Macos': 'macos', + 'Android': 'android', + 'iOS': 'ios', + 'watchOS': 'watchos', + 'tvOS': 'tvos', + 'FreeBSD': 'freebsd', + 'SunOS': 'solaris', + 'AIX': 'aix', + 'Emscripten': undefined, + 'Arduino': 'none', + 'Neutrino': 'qnx', + 'baremetal': 'none', + 'VxWorks': 'vxworks', +} + +function findLibs(libnames, libdirs, libtypes, targetOS, forImport) { + var result = []; + if (libnames === null || libdirs === null) + return result; + libnames.forEach(function(libraryName) { + const suffixes = PathTools.librarySuffixes(targetOS, libtypes, forImport); + const lib = PathProbe.configure( + undefined, // selectors + [libraryName], + suffixes, + PathTools.libraryNameFilter(targetOS), + undefined, // candidateFilter + libdirs, // searchPaths + undefined, // pathSuffixes + [], // platformSearchPaths + undefined, // environmentPaths + undefined // platformEnvironmentPaths + ); + if (lib.found) + result.push(lib.files[0].filePath); + }); + return result; +} + +function getLibraryTypes(options) { + if (options !== undefined && options !== null) { + if (options.shared === undefined) + return ["shared", "static"]; + else if (options.shared === "True") + return ["shared"]; + else if (options.shared === "False") + return ["static"]; + } + return ["shared", "static"]; +} + +function configure(installDirectory, moduleName, outputBaseDir, jsonProbe) { + const moduleMapping = {"protobuflib": "protobuf"} + const realModuleName = moduleMapping[moduleName] || moduleName; + + const moduleFilePath = + FileInfo.joinPaths(installDirectory, "conan-qbs-deps", realModuleName + ".json") + if (!File.exists(moduleFilePath)) + return []; + + var reverseMapping = {} + for (var key in moduleMapping) + reverseMapping[moduleMapping[key]] = key + + console.info("Setting up Conan module '" + moduleName + "'"); + + var moduleFile = new TextFile(moduleFilePath, TextFile.ReadOnly); + const moduleInfo = JSON.parse(moduleFile.readAll()); + + const outputDir = FileInfo.joinPaths(outputBaseDir, "modules", moduleName.replace(".", "/")); + File.makePath(outputDir); + const outputFilePath = FileInfo.joinPaths(outputDir, "module.qbs"); + + const cppInfo = moduleInfo.cpp_info; + + var moduleContent = ""; + + // function write(data) { moduleContent = moduleContent + data } + function writeLine(data) { moduleContent = moduleContent + data + "\n"; } + + function writeProperty(propertyName, propertyValue) { + if (propertyValue === undefined || propertyValue === null) + propertyValue = []; + writeLine(" readonly property stringList " + propertyName + + ": " + ModUtils.toJSLiteral(propertyValue)); + } + function writeCppProperty(propertyName, propertyValue) { + writeProperty(propertyName, propertyValue); + // skip empty props for simplicity of the module file + if (propertyValue !== undefined && propertyValue != null && propertyValue.length !== 0) { + writeLine(" cpp." + propertyName + ": " + propertyName); + } + } + + writeLine("Module {"); + + writeLine(" version: " + ModUtils.toJSLiteral(moduleInfo.version)); + + const architecture = architectureMap[moduleInfo.settings.arch]; + const platform = platformMap[moduleInfo.settings.os]; + const targetOS = Utilities.canonicalPlatform(platform); + + writeLine(" readonly property string architecture: " + ModUtils.toJSLiteral(architecture)); + writeLine(" readonly property string platform: " + ModUtils.toJSLiteral(platform)); + writeLine(" condition: true"); + if (architecture !== undefined) { + writeLine(" && (!qbs.architecture || qbs.architecture === architecture)"); + } + if (platform !== undefined) { + if (["ios", "tvos", "watchos"].includes(platform)) { + writeLine(" && (qbs.targetPlatform === platform || qbs.targetPlatform === platform + \"-simulator\")"); + } else { + writeLine(" && qbs.targetPlatform === platform"); + } + } + + writeLine(" Depends { name: 'cpp' }"); + + moduleInfo.dependencies.forEach(function(dep) { + const realDepName = reverseMapping[dep.name] || dep.name; + writeLine(" Depends { name: " + ModUtils.toJSLiteral(realDepName) + + "; version: " + ModUtils.toJSLiteral(dep.version) + "}"); + }); + + writeLine(" readonly property stringList hostBinDirs: (" + ModUtils.toJSLiteral(moduleInfo.build_bindirs) + ")"); + // target bindirs + writeLine(" readonly property stringList binDirs: (" + ModUtils.toJSLiteral(cppInfo.bindirs) + ")"); + + // TODO: there's a weird issue with system include dirs with xcode-less clang - incorrect include order? + writeCppProperty("includePaths", cppInfo.includedirs); + writeCppProperty("frameworkPaths", cppInfo.frameworkdirs); + writeCppProperty("frameworks", cppInfo.frameworks); + writeCppProperty("defines", cppInfo.defines); + writeCppProperty("cFlags", cppInfo.cflags); + writeCppProperty("cxxFlags", cppInfo.cxxflags); + writeCppProperty("linkerFlags", (cppInfo.sharedlinkflags || []).concat(cppInfo.exelinkflags || [])); + + writeProperty("resources", cppInfo.resdirs); + + const isForImport = targetOS.includes("windows") + const libraryTypes = getLibraryTypes(moduleInfo.options); + libraryTypes.forEach(function(libraryType){ + const cppInfoLibs = cppInfo.libs === null ? [] : cppInfo.libs; + const libs = findLibs(cppInfoLibs, cppInfo.libdirs, libraryType, targetOS, isForImport) + .concat(cppInfo.system_libs === null ? [] : cppInfo.system_libs); + const property = libraryType === "shared" ? "dynamicLibraries" : "staticLibraries"; + writeCppProperty(property, libs); + }); + + writeLine("}"); + + var moduleFile = new TextFile(outputFilePath, TextFile.WriteOnly); + moduleFile.write(moduleContent); + moduleFile.close(); + + return ""; +} diff --git a/share/qbs/module-providers/conan.qbs b/share/qbs/module-providers/conan.qbs new file mode 100644 index 000000000..6391eeb65 --- /dev/null +++ b/share/qbs/module-providers/conan.qbs @@ -0,0 +1,12 @@ +import "conan.js" as ConanHelper + +ModuleProvider { + /* input */ + property path installDirectory + + isEager: false + + relativeSearchPaths: { + return ConanHelper.configure(installDirectory, moduleName, outputBaseDir); + } +} diff --git a/share/qbs/modules/capnproto/capnprotobase.qbs b/share/qbs/modules/capnproto/capnprotobase.qbs index 56d542770..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 @@ -42,14 +43,18 @@ Module { 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 bccfca192..83192b7de 100644 --- a/share/qbs/modules/capnproto/cpp/capnprotocpp.qbs +++ b/share/qbs/modules/capnproto/cpp/capnprotocpp.qbs @@ -40,6 +40,7 @@ CapnProtoBase { pluginName: "capnpc-c++" version: capnp.version + _searchPaths: capnp.hostBinDirs cpp.systemIncludePaths: outputDir cpp.cxxLanguageVersion: "c++14" diff --git a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs index b5dab2372..bd4a08557 100644 --- a/share/qbs/modules/protobuf/cpp/protobufcpp.qbs +++ b/share/qbs/modules/protobuf/cpp/protobufcpp.qbs @@ -13,6 +13,9 @@ ProtobufBase { property string _cxxLanguageVersion: "c++17" + _searchPaths: protobuflib.present ? protobuflib.hostBinDirs : undefined + property stringList _grpcSearchPaths: grpcpp.present ? grpcpp.hostBinDirs : undefined + cpp.includePaths: outputDir Depends { name: "cpp" } @@ -34,6 +37,7 @@ ProtobufBase { condition: useGrpc id: grpcPluginProbe names: "grpc_cpp_plugin" + searchPaths: _grpcSearchPaths } cpp.cxxLanguageVersion: _cxxLanguageVersion 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 } } |