QBS:在产品内部显式设置 qbs.profiles 导致构建失败
QBS: Explicitly setting qbs.profiles inside Products causing build to fail
我的用例是这样的:
我有一个静态库,我希望它可用于某些配置文件(例如 "gcc"、"arm-gcc"、"mips-gcc")。
我还有一个 link 到这个库的应用程序,但是这个应用程序应该只使用特定的配置文件构建(例如 "arm-gcc")。
为此,我正在修改 app-and-lib QBS 示例。
lib.qbs 文件:
import qbs 1.0
Product {
qbs.profiles: ["gcc", "arm-gcc", "mips-gcc"] //I added only this line
type: "staticlibrary"
name: "mylib"
files: [
"lib.cpp",
"lib.h",
]
Depends { name: 'cpp' }
cpp.defines: ['CRUCIAL_DEFINE']
Export {
Depends { name: "cpp" }
cpp.includePaths: [product.sourceDirectory]
}
}
app.qbs 文件:
import qbs 1.0
Product {
qbs.profiles: ["arm-gcc"] //I added only this line
type: "application"
consoleApplication: true
files : [ "main.cpp" ]
Depends { name: "cpp" }
Depends { name: "mylib" }
}
应用构建失败。 Qbs 错误地尝试 link 到库的 "gcc" 版本而不是 "arm-gcc" 版本,正如您在日志中看到的那样:
Build graph does not yet exist for configuration 'default'. Starting from scratch.
Resolving project for configuration default
Setting up build graph for configuration default
Building for configuration default
compiling lib.cpp [mylib {"profile":"gcc"}]
compiling lib.cpp [mylib {"profile":"arm-gcc"}]
compiling lib.cpp [mylib {"profile":"mips-gcc"}]
compiling main.cpp [app]
creating libmylib.a [mylib {"profile":"gcc"}]
creating libmylib.a [mylib {"profile":"mips-gcc"}]
creating libmylib.a [mylib {"profile":"arm-gcc"}]
linking app [app]
ERROR: /usr/bin/arm-linux-gnueabihf-g++ -o /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/app.7d104347/app /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/app.7d104347/3a52ce780950d4d9/main.cpp.o /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/mylib.eyJwcm9maWxlIjoiZ2NjIn0-.792f47ec/libmylib.a
ERROR: /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/mylib.eyJwcm9maWxlIjoiZ2NjIn0-.792f47ec/libmylib.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
ERROR: Process failed with exit code 1.
The following products could not be built for configuration default:
app
仅在app.qbs文件中选择一个 profile时,构建才会失败lib.qbs 文件。
选择两个或多个配置文件时 - 构建成功。
我的分析:
我认为这个问题与多路复用有关:
lib.qbs 包含多个配置文件。这会在构建库时打开多路复用,这反过来又会向构建目录名称 (moduleloader.cpp
) 添加额外的“multiplexConfigurationId
”。
app.lib 仅包含一个配置文件,因此未打开多路复用且构建目录名称未获得额外的字符串。
问题可以通过更改代码 (moduleloader.cpp
) 来解决,即使只有一个配置文件也可以打开多路复用,即使用以下补丁:
--- moduleloader.cpp 2018-10-24 16:17:43.633527397 +0300
+++ moduleloader.cpp.new 2018-10-24 16:18:27.541370544 +0300
@@ -872,7 +872,7 @@
= callWithTemporaryBaseModule<const MultiplexInfo>(dummyContext,
extractMultiplexInfoFromProduct);
- if (multiplexInfo.table.size() > 1)
+ if (multiplexInfo.table.size() > 0)
productItem->setProperty(StringConstants::multiplexedProperty(), VariantValue::trueValue());
VariantValuePtr productNameValue = VariantValue::create(productName);
@@ -891,7 +891,7 @@
const QString multiplexConfigurationId = multiplexInfo.toIdString(row);
const VariantValuePtr multiplexConfigurationIdValue
= VariantValue::create(multiplexConfigurationId);
- if (multiplexInfo.table.size() > 1 || aggregator) {
+ if (multiplexInfo.table.size() > 0 || aggregator) {
multiplexConfigurationIdValues.push_back(multiplexConfigurationIdValue);
item->setProperty(StringConstants::multiplexConfigurationIdProperty(),
multiplexConfigurationIdValue);
这适用于我的用例。我不知道从更广泛的角度来看是否有意义。
最后,问题:
这一切都有意义吗?
这是正常行为吗?
这个用例根本不受支持吗?
有没有更好的解决方案?
提前致谢。
是的,多路复用的默认行为是非多路复用产品依赖于依赖项的所有变体。通常,用户无法更改该行为,但应该可以。
然而,幸运的是,个人资料很特别:
Depends { name: "mylib"; profiles: "arm-gcc" }
这应该可以解决您的问题。
我的用例是这样的:
我有一个静态库,我希望它可用于某些配置文件(例如 "gcc"、"arm-gcc"、"mips-gcc")。
我还有一个 link 到这个库的应用程序,但是这个应用程序应该只使用特定的配置文件构建(例如 "arm-gcc")。
为此,我正在修改 app-and-lib QBS 示例。
lib.qbs 文件:
import qbs 1.0
Product {
qbs.profiles: ["gcc", "arm-gcc", "mips-gcc"] //I added only this line
type: "staticlibrary"
name: "mylib"
files: [
"lib.cpp",
"lib.h",
]
Depends { name: 'cpp' }
cpp.defines: ['CRUCIAL_DEFINE']
Export {
Depends { name: "cpp" }
cpp.includePaths: [product.sourceDirectory]
}
}
app.qbs 文件:
import qbs 1.0
Product {
qbs.profiles: ["arm-gcc"] //I added only this line
type: "application"
consoleApplication: true
files : [ "main.cpp" ]
Depends { name: "cpp" }
Depends { name: "mylib" }
}
应用构建失败。 Qbs 错误地尝试 link 到库的 "gcc" 版本而不是 "arm-gcc" 版本,正如您在日志中看到的那样:
Build graph does not yet exist for configuration 'default'. Starting from scratch.
Resolving project for configuration default
Setting up build graph for configuration default
Building for configuration default
compiling lib.cpp [mylib {"profile":"gcc"}]
compiling lib.cpp [mylib {"profile":"arm-gcc"}]
compiling lib.cpp [mylib {"profile":"mips-gcc"}]
compiling main.cpp [app]
creating libmylib.a [mylib {"profile":"gcc"}]
creating libmylib.a [mylib {"profile":"mips-gcc"}]
creating libmylib.a [mylib {"profile":"arm-gcc"}]
linking app [app]
ERROR: /usr/bin/arm-linux-gnueabihf-g++ -o /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/app.7d104347/app /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/app.7d104347/3a52ce780950d4d9/main.cpp.o /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/mylib.eyJwcm9maWxlIjoiZ2NjIn0-.792f47ec/libmylib.a
ERROR: /home/user/programs/qbs/usr/local/share/qbs/examples/app-and-lib/default/mylib.eyJwcm9maWxlIjoiZ2NjIn0-.792f47ec/libmylib.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
ERROR: Process failed with exit code 1.
The following products could not be built for configuration default:
app
仅在app.qbs文件中选择一个 profile时,构建才会失败lib.qbs 文件。
选择两个或多个配置文件时 - 构建成功。
我的分析:
我认为这个问题与多路复用有关:
lib.qbs 包含多个配置文件。这会在构建库时打开多路复用,这反过来又会向构建目录名称 (moduleloader.cpp
) 添加额外的“multiplexConfigurationId
”。
app.lib 仅包含一个配置文件,因此未打开多路复用且构建目录名称未获得额外的字符串。
问题可以通过更改代码 (moduleloader.cpp
) 来解决,即使只有一个配置文件也可以打开多路复用,即使用以下补丁:
--- moduleloader.cpp 2018-10-24 16:17:43.633527397 +0300
+++ moduleloader.cpp.new 2018-10-24 16:18:27.541370544 +0300
@@ -872,7 +872,7 @@
= callWithTemporaryBaseModule<const MultiplexInfo>(dummyContext,
extractMultiplexInfoFromProduct);
- if (multiplexInfo.table.size() > 1)
+ if (multiplexInfo.table.size() > 0)
productItem->setProperty(StringConstants::multiplexedProperty(), VariantValue::trueValue());
VariantValuePtr productNameValue = VariantValue::create(productName);
@@ -891,7 +891,7 @@
const QString multiplexConfigurationId = multiplexInfo.toIdString(row);
const VariantValuePtr multiplexConfigurationIdValue
= VariantValue::create(multiplexConfigurationId);
- if (multiplexInfo.table.size() > 1 || aggregator) {
+ if (multiplexInfo.table.size() > 0 || aggregator) {
multiplexConfigurationIdValues.push_back(multiplexConfigurationIdValue);
item->setProperty(StringConstants::multiplexConfigurationIdProperty(),
multiplexConfigurationIdValue);
这适用于我的用例。我不知道从更广泛的角度来看是否有意义。
最后,问题:
这一切都有意义吗?
这是正常行为吗?
这个用例根本不受支持吗?
有没有更好的解决方案?
提前致谢。
是的,多路复用的默认行为是非多路复用产品依赖于依赖项的所有变体。通常,用户无法更改该行为,但应该可以。 然而,幸运的是,个人资料很特别:
Depends { name: "mylib"; profiles: "arm-gcc" }
这应该可以解决您的问题。