diff options
Diffstat (limited to 'share/qbs/modules/cpp/darwin.js')
-rw-r--r-- | share/qbs/modules/cpp/darwin.js | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/share/qbs/modules/cpp/darwin.js b/share/qbs/modules/cpp/darwin.js new file mode 100644 index 000000000..87f638831 --- /dev/null +++ b/share/qbs/modules/cpp/darwin.js @@ -0,0 +1,186 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qbs. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +var File = loadExtension("qbs.File"); +var FileInfo = loadExtension("qbs.FileInfo"); +var Gcc = require("./gcc.js"); +var ModUtils = loadExtension("qbs.ModUtils"); +var PathTools = loadExtension("qbs.PathTools"); + +function lipoOutputArtifacts(product, inputs, fileTag, debugSuffix) { + var buildVariants = []; + for (var i = 0; i < inputs[fileTag].length; ++i) { + var variant = inputs[fileTag][i].qbs.buildVariant; + var suffix = inputs[fileTag][i].cpp.variantSuffix; + if (!buildVariants.some(function (x) { return x.name === variant; })) + buildVariants.push({ name: variant, suffix: suffix }); + } + + var list = []; + + if (fileTag === "dynamiclibrary") { + Array.prototype.push.apply(list, buildVariants.map(function (variant) { + return { + filePath: product.destinationDirectory + "/.sosymbols/" + + PathTools.dynamicLibraryFilePath(product, variant.suffix), + fileTags: ["dynamiclibrary_copy"], + qbs: { buildVariant: variant.name, variantSuffix: variant.suffix }, + alwaysUpdated: false + }; + })); + } + + // Bundles should have a "normal" variant. In the case of frameworks, they cannot normally be + // linked to without a default variant unless a variant is specifically chosen at link time + // by passing the full path to the shared library executable instead of the -framework switch. + // Technically this doesn't affect qbs since qbs always uses full paths for internal + // dependencies but the "normal" variant is always the one that is linked to, since the + // alternative variants should only be chosen at runtime using the DYLD_IMAGE_SUFFIX variable. + // So for frameworks we'll create a symlink to the "default" variant as chosen by the user + // (we cannot do this automatically since the user must tell us which variant should be + // preferred, if there are multiple alternative variants). Applications are fine without a + // symlink but still need an explicitly chosen variant to set as the CFBundleExecutable so that + // Finder/LaunchServices can launch it normally but for simplicity we'll just use the symlink + // approach for all bundle types. + var defaultVariant; + if (!buildVariants.some(function (x) { return x.name === "release"; })) { + var defaultBuildVariant = product.qbs.defaultBuildVariant; + buildVariants.map(function (variant) { + if (variant.name === defaultBuildVariant) + defaultVariant = variant; + }); + if (!defaultVariant) { + throw new Error("qbs.defaultBuildVariant is '" + defaultBuildVariant + "', but this " + + "variant is not in the qbs.buildVariants list (" + + product.qbs.buildVariants.join(", ") + ")"); + } + + buildVariants.push({ + name: "release", + suffix: "", + isSymLink: true + }); + } + + Array.prototype.push.apply(list, buildVariants.map(function (variant) { + var tags = ["bundle.input"]; + if (variant.isSymLink) + tags.push("bundle.variant_symlink"); + else + tags.push(fileTag, "primary"); + + return { + filePath: FileInfo.joinPaths(product.destinationDirectory, + PathTools.linkerOutputFilePath(fileTag, product, + variant.suffix)), + fileTags: tags, + qbs: { + buildVariant: variant.name, + variantSuffix: variant.suffix, + _buildVariantFileName: variant.isSymLink && defaultVariant + ? FileInfo.fileName(PathTools.linkerOutputFilePath( + fileTag, product, + defaultVariant.suffix)) + : undefined + }, + bundle: { + _bundleFilePath: product.destinationDirectory + "/" + + PathTools.bundleExecutableFilePath(product, variant.suffix) + } + }; + })); + if (debugSuffix) + Array.prototype.push.apply(list, Gcc.debugInfoArtifacts(product, buildVariants, + debugSuffix)); + return list; +} + +function prepareLipo(project, product, inputs, outputs, input, output) { + var cmd; + var commands = []; + var allInputs = [].concat.apply([], Object.keys(inputs).map(function (tag) { + return ["application", "dynamiclibrary", "staticlibrary", "loadablemodule"].contains(tag) + ? inputs[tag] : []; + })); + + (outputs["bundle.variant_symlink"] || []).map(function (symlink) { + cmd = new Command("ln", ["-sfn", symlink.qbs._buildVariantFileName, symlink.filePath]); + cmd.silent = true; + commands.push(cmd); + }); + + for (var i = 0; i < outputs.primary.length; ++i) { + var vInputs = allInputs.filter(function (f) { + return f.qbs.buildVariant === outputs.primary[i].qbs.buildVariant + }).map(function (f) { + return f.filePath + }); + + if (vInputs.length > 1 || product.cpp.alwaysUseLipo) { + cmd = new Command(ModUtils.moduleProperty(product, "lipoPath"), + ["-create", "-output", outputs.primary[i].filePath].concat(vInputs)); + cmd.description = "lipo " + outputs.primary[i].fileName; + cmd.highlight = "linker"; + } else { + cmd = new JavaScriptCommand(); + cmd.src = vInputs[0]; + cmd.dst = outputs.primary[i].filePath; + cmd.sourceCode = function () { + File.copy(src, dst); + }; + cmd.silent = true; + } + + commands.push(cmd); + } + + var debugInfo = outputs.debuginfo_app || outputs.debuginfo_dll + || outputs.debuginfo_loadablemodule; + if (debugInfo) { + var dsymPath = debugInfo[0].filePath; + if (outputs.debuginfo_bundle && outputs.debuginfo_bundle[0]) + dsymPath = outputs.debuginfo_bundle[0].filePath; + var flags = ModUtils.moduleProperty(product, "dsymutilFlags") || []; + cmd = new Command(ModUtils.moduleProperty(product, "dsymutilPath"), flags.concat([ + "-o", dsymPath + ]).concat(outputs.primary.map(function (f) { return f.filePath; }))); + cmd.description = "generating dSYM for " + product.name; + commands.push(cmd); + } + + cmd = new Command(ModUtils.moduleProperty(product, "stripPath"), + ["-S", outputs.primary[0].filePath]); + cmd.silent = true; + commands.push(cmd); + if (outputs.dynamiclibrary_copy) + Array.prototype.push.apply(commands, Gcc.createSymbolCheckingCommands(product, outputs)); + return commands; +} + |