From acf8e4f4fcf14d6edf6fbb79ae2cfae1ce475baa Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 23 May 2013 11:48:18 +0200 Subject: support creation of OS X framework bundles To create a framework bundle, set your product type to "frameworkbundle". The bundle creation is similar to the "applicationbundle" product type. Task-number: QBS-274 Change-Id: I103feb59e141c463f66ebb45f08cea61dad5d880 Reviewed-by: Christian Kandeler Reviewed-by: Joerg Bornemann --- share/qbs/modules/cpp/DarwinGCC.qbs | 5 ++- share/qbs/modules/cpp/GenericGCC.qbs | 15 +++++---- share/qbs/modules/cpp/gcc.js | 28 ++++++++++++++-- share/qbs/modules/cpp/mac-gcc.qbs | 64 +++++++++++++++++++++++++++++------- 4 files changed, 88 insertions(+), 24 deletions(-) diff --git a/share/qbs/modules/cpp/DarwinGCC.qbs b/share/qbs/modules/cpp/DarwinGCC.qbs index e5b76003a..72dc0320e 100644 --- a/share/qbs/modules/cpp/DarwinGCC.qbs +++ b/share/qbs/modules/cpp/DarwinGCC.qbs @@ -1,6 +1,7 @@ import qbs 1.0 import '../utils.js' as ModUtils import 'darwin-tools.js' as Tools +import "gcc.js" as Gcc UnixGCC { condition: false @@ -49,9 +50,7 @@ UnixGCC { inputs: ["qbs"] Artifact { - fileName: product.targetName + ".app/" + - (product.moduleProperty("qbs", "targetOS") === "mac" ? "Contents/" : "") + - "Info.plist" + fileName: Gcc.bundleContentDirPath() + "/Info.plist" fileTags: ["infoplist"] } diff --git a/share/qbs/modules/cpp/GenericGCC.qbs b/share/qbs/modules/cpp/GenericGCC.qbs index b4ad2df6a..1fee23fdf 100644 --- a/share/qbs/modules/cpp/GenericGCC.qbs +++ b/share/qbs/modules/cpp/GenericGCC.qbs @@ -34,10 +34,11 @@ CppModule { id: dynamicLibraryLinker multiplex: true inputs: ["obj"] - usings: ['dynamiclibrary', 'staticlibrary'] + usings: ["dynamiclibrary", "staticlibrary", "frameworkbundle"] Artifact { - fileName: product.destinationDirectory + "/" + Gcc.dynamicLibraryFileName() + fileName: product.destinationDirectory + "/" + + (product.type.indexOf("frameworkbundle") === -1 ? Gcc.dynamicLibraryFileName() : Gcc.frameworkFilePath()) fileTags: ["dynamiclibrary"] cpp.transitiveSOs: { var result = [] @@ -145,7 +146,7 @@ CppModule { id: staticLibraryLinker multiplex: true inputs: ["obj"] - usings: ['dynamiclibrary', 'staticlibrary'] + usings: ["dynamiclibrary", "staticlibrary", "frameworkbundle"] Artifact { fileName: product.destinationDirectory + "/" + ModUtils.moduleProperty(product, "staticLibraryPrefix") @@ -189,7 +190,7 @@ CppModule { id: applicationLinker multiplex: true inputs: ["obj"] - usings: ['dynamiclibrary', 'staticlibrary'] + usings: ["dynamiclibrary", "staticlibrary", "frameworkbundle"] Artifact { fileName: product.destinationDirectory + "/" @@ -282,10 +283,10 @@ CppModule { } var frameworksI = frameworks; - for (i in inputs.framework) { - fileName = inputs.framework[i].fileName; + for (i in inputs.frameworkbundle) { + fileName = inputs.frameworkbundle[i].fileName; frameworkPaths.push(FileInfo.path(fileName)); - fileName = Gcc.removePrefixAndSuffix(FileInfo.fileName(fileName), dllPrefix, dllSuffix); + fileName = Gcc.removePrefixAndSuffix(FileInfo.fileName(fileName), "", ".framework"); frameworksI.push(fileName); } diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js index af61133dd..cbada4dda 100644 --- a/share/qbs/modules/cpp/gcc.js +++ b/share/qbs/modules/cpp/gcc.js @@ -162,6 +162,12 @@ function additionalCompilerAndLinkerFlags(product) { return args } +function majorVersion(version, defaultValue) +{ + var n = parseInt(product.version, 10); + return isNaN(n) ? defaultValue : n; +} + function dynamicLibraryFileName(version) { if (!version) @@ -177,12 +183,30 @@ function dynamicLibraryFileName(version) return fileName; } +function frameworkContentDirPath(version) +{ + return product.targetName + ".framework/Versions/" + (version || majorVersion(product.version, "1")); +} + +function bundleContentDirPath() +{ + if (product.type.indexOf("applicationbundle") !== -1) + return product.targetName + ".app/Contents"; + else + return frameworkContentDirPath() + "/Resources"; +} + +function frameworkFilePath() +{ + return frameworkContentDirPath() + "/" + product.targetName; +} + function soname() { var outputFileName = FileInfo.fileName(output.fileName); if (product.version) { - var major = parseInt(product.version, 10); - if (!isNaN(major)) { + var major = majorVersion(product.version); + if (major) { return outputFileName.substr(0, outputFileName.length - product.version.length) + major; } diff --git a/share/qbs/modules/cpp/mac-gcc.qbs b/share/qbs/modules/cpp/mac-gcc.qbs index 83f483c14..509d2bd6b 100644 --- a/share/qbs/modules/cpp/mac-gcc.qbs +++ b/share/qbs/modules/cpp/mac-gcc.qbs @@ -1,6 +1,7 @@ import qbs 1.0 import '../utils.js' as ModUtils import 'darwin-tools.js' as Tools +import "gcc.js" as Gcc DarwinGCC { condition: qbs.hostOS === 'mac' && qbs.targetOS === 'mac' && qbs.toolchain === 'gcc' @@ -8,19 +9,58 @@ DarwinGCC { defaultInfoPlist: { var baseName = String(product.targetName).substring(product.targetName.lastIndexOf('/') + 1); var baseNameRfc1034 = Tools.rfc1034(baseName); - var defaultVal = { - CFBundleName: baseName, - CFBundleIdentifier: "org.example." + baseNameRfc1034, - CFBundleInfoDictionaryVersion: "6.0", - CFBundleVersion: "1.0", // version of the app - CFBundleShortVersionString: "1.0", // user visible version of the app - CFBundleExecutable: baseName, - CFBundleDisplayName: baseName, - CFBundleIconFile: baseName + ".icns", - CFBundlePackageType: "APPL", - CFBundleSignature: "????", // legacy creator code in macOS Classic, can be ignored - CFBundleDevelopmentRegion: "en" // default localization + var defaultVal; + if (product.type.indexOf("applicationbundle") !== -1) { + defaultVal = { + CFBundleName: baseName, + CFBundleIdentifier: "org.example." + baseNameRfc1034, + CFBundleInfoDictionaryVersion: "6.0", + CFBundleVersion: "1.0", // version of the app + CFBundleShortVersionString: "1.0", // user visible version of the app + CFBundleExecutable: baseName, + CFBundleDisplayName: baseName, + CFBundleIconFile: baseName + ".icns", + CFBundlePackageType: "APPL", + CFBundleSignature: "????", // legacy creator code in macOS Classic, can be ignored + CFBundleDevelopmentRegion: "en" // default localization + } + } else if (product.type.indexOf("frameworkbundle") !== -1) { + defaultVal = { + CFBundleDisplayName: product.targetName, + CFBundleName: product.targetName, + CFBundleVersion: product.version || "1.0.0", + CFBundlePackageType: "FMWK", + CFBundleSignature: "????" + }; } return defaultVal } + + Rule { + multiplex: true + inputs: ["dynamiclibrary", "infoplist", "dsym"] + + Artifact { + fileName: product.targetName + ".framework" + fileTags: ["frameworkbundle"] + } + + prepare: { + var commands = []; + var cmd = new Command("ln", ["-s", Gcc.majorVersion(product.version, "1"), "Current"]); + cmd.workingDirectory = output.fileName + "/Versions"; + cmd.description = "creating framework " + product.targetName; + cmd.highlight = "codegen"; + commands.push(cmd); + + cmd = new Command("ln", ["-s", "Versions/Current/Resources", "Resources"]); + cmd.workingDirectory = output.fileName; + commands.push(cmd); + + cmd = new Command("ln", ["-s", "Versions/Current/" + product.targetName, product.targetName]); + cmd.workingDirectory = output.fileName; + commands.push(cmd); + return commands; + } + } } -- cgit v1.2.3