aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoerg Bornemann <joerg.bornemann@qt.io>2017-06-15 14:43:50 +0200
committerJoerg Bornemann <joerg.bornemann@qt.io>2017-06-16 19:39:51 +0000
commit0b112fa0b27f996fd71c5a0b63132b47b21d7b3e (patch)
tree02e2789c56fd3b3c2545bab7023ae662bbf9019c
parente16dd899d5d8329aaa83b77393e50e5feba247ca (diff)
Collect cpp.[weak]frameworks from library dependencies
When depending on a static library that needs a macOS framework, we should automatically link against that framework, like we do with other kinds of libraries. Task-number: QBS-1129 Change-Id: Ibe20d874b0baba5c78ef13ad6961b5812ecd8918 Reviewed-by: Jake Petroules <jake.petroules@qt.io>
-rw-r--r--share/qbs/modules/cpp/gcc.js27
-rw-r--r--tests/auto/api/testdata/static-lib-deps/d.cpp2
-rw-r--r--tests/auto/api/testdata/static-lib-deps/d.mm8
-rw-r--r--tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs6
4 files changed, 38 insertions, 5 deletions
diff --git a/share/qbs/modules/cpp/gcc.js b/share/qbs/modules/cpp/gcc.js
index 34e955abb..23d01d106 100644
--- a/share/qbs/modules/cpp/gcc.js
+++ b/share/qbs/modules/cpp/gcc.js
@@ -73,7 +73,7 @@ function useCompilerDriverLinker(product, inputs) {
return linker === product.cpp.compilerPath;
}
-function collectLibraryDependencies(product) {
+function collectLibraryDependencies(product, isDarwin) {
var publicDeps = {};
var objects = [];
var objectByFilePath = {};
@@ -119,6 +119,18 @@ function collectLibraryDependencies(product) {
ModUtils.sanitizedModuleProperty(obj, "cpp", "dynamicLibraries"));
for (var i = 0, len = externalLibs.length; i < len; ++i)
addObject({ direct: true, filePath: externalLibs[i] }, Array.prototype.push);
+ if (isDarwin) {
+ externalLibs = [].concat(
+ ModUtils.sanitizedModuleProperty(obj, "cpp", "frameworks"));
+ for (var i = 0, len = externalLibs.length; i < len; ++i)
+ addObject({ direct: true, filePath: externalLibs[i], framework: true },
+ Array.prototype.push);
+ externalLibs = [].concat(
+ ModUtils.sanitizedModuleProperty(obj, "cpp", "weakFrameworks"));
+ for (var i = 0, len = externalLibs.length; i < len; ++i)
+ addObject({ direct: true, filePath: externalLibs[i], framework: true,
+ symbolLinkMode: "weak" }, Array.prototype.push);
+ }
}
function traverse(dep, isBelowIndirectDynamicLib) {
@@ -168,7 +180,8 @@ function collectLibraryDependencies(product) {
if (obj.direct) {
result.libraries.push({ filePath: obj.filePath,
wholeArchive: obj.wholeArchive,
- symbolLinkMode: obj.symbolLinkMode });
+ symbolLinkMode: obj.symbolLinkMode,
+ framework: obj.framework });
} else {
var dirPath = FileInfo.path(obj.filePath);
if (!seenRPathLinkDirs.hasOwnProperty(dirPath)) {
@@ -220,12 +233,12 @@ function escapeLinkerFlags(product, inputs, linkerFlags) {
function linkerFlags(project, product, inputs, output, linkerPath) {
var libraryPaths = product.cpp.libraryPaths;
var distributionLibraryPaths = product.cpp.distributionLibraryPaths;
- var libraryDependencies = collectLibraryDependencies(product);
+ var isDarwin = product.qbs.targetOS.contains("darwin");
+ var libraryDependencies = collectLibraryDependencies(product, isDarwin);
var frameworks = product.cpp.frameworks;
var weakFrameworks = product.cpp.weakFrameworks;
var rpaths = (product.cpp.useRPaths !== false) ? product.cpp.rpaths : undefined;
var systemRunPaths = product.cpp.systemRunPaths || [];
- var isDarwin = product.qbs.targetOS.contains("darwin");
var i, args = additionalCompilerAndLinkerFlags(product);
if (output.fileTags.contains("dynamiclibrary")) {
@@ -413,12 +426,16 @@ function linkerFlags(project, product, inputs, output, linkerPath) {
var flags;
if (FileInfo.isAbsolutePath(lib) || lib.startsWith('@'))
flags = ["-" + symbolLinkMode + "_library", lib];
+ else if (dep.framework)
+ flags = ["-" + symbolLinkMode + "_framework", lib];
else
flags = ["-" + symbolLinkMode + "-l" + lib];
Array.prototype.push.apply(args, escapeLinkerFlags(product, inputs, flags));
} else if (FileInfo.isAbsolutePath(lib) || lib.startsWith('@')) {
- args.push(lib);
+ args.push(dep.framework ? PathTools.frameworkExecutablePath(lib) : lib);
+ } else if (dep.framework) {
+ args.push("-framework", lib);
} else {
args.push('-l' + lib);
}
diff --git a/tests/auto/api/testdata/static-lib-deps/d.cpp b/tests/auto/api/testdata/static-lib-deps/d.cpp
index 7c6812837..a7ecfd1ee 100644
--- a/tests/auto/api/testdata/static-lib-deps/d.cpp
+++ b/tests/auto/api/testdata/static-lib-deps/d.cpp
@@ -31,6 +31,7 @@
#elif defined(WITH_LEX_YACC)
extern "C" int yywrap(void);
extern "C" void yyerror(char const *s);
+extern void printGreeting();
#elif defined(WITH_SETUPAPI)
#include <windows.h>
#include <Setupapi.h>
@@ -50,6 +51,7 @@ int d()
#elif defined(WITH_LEX_YACC)
yywrap();
yyerror("no error");
+ printGreeting();
return 0;
#elif defined(WITH_SETUPAPI)
CABINET_INFO ci;
diff --git a/tests/auto/api/testdata/static-lib-deps/d.mm b/tests/auto/api/testdata/static-lib-deps/d.mm
new file mode 100644
index 000000000..5bf48966f
--- /dev/null
+++ b/tests/auto/api/testdata/static-lib-deps/d.mm
@@ -0,0 +1,8 @@
+#import <Foundation/Foundation.h>
+
+void printGreeting()
+{
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ NSLog (@"Hello darkness, my old friend!");
+ [pool drain];
+}
diff --git a/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs b/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs
index abb9dbf9d..c925d4d57 100644
--- a/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs
+++ b/tests/auto/api/testdata/static-lib-deps/static-lib-deps.qbs
@@ -45,6 +45,11 @@ Project {
"d.cpp",
]
+ Group {
+ condition: qbs.targetOS.contains("macos")
+ files: ["d.mm"]
+ }
+
Properties {
condition: qbs.targetOS.contains("windows")
cpp.defines: ["WITH_SETUPAPI"]
@@ -54,6 +59,7 @@ Project {
condition: qbs.targetOS.contains("macos")
cpp.defines: ["WITH_LEX_YACC"]
cpp.staticLibraries: ["l", "y"]
+ cpp.frameworks: ["Foundation"]
}
Properties {
condition: qbs.targetOS.contains("linux")