QBS: явная установка файла qbs.profiles в продуктах, вызывающих сбой сборки - PullRequest
0 голосов
/ 24 октября 2018

Мой вариант использования такой:

У меня есть статическая библиотека, которую я хочу использовать для некоторых профилей (например, "gcc", "arm-gcc", "mips-gcc").

У меня также есть приложение, которое ссылается на эту библиотеку, но эти приложения должны собираться только с использованием определенного профиля (например, «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 ошибочно пытается связаться с версией библиотеки "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, и этот профиль не должен быть первым профилем в строке qbs.profiles в файле lib.qbs.

При выборе двух или более профилей - сборка завершается успешно.

Мой анализ:

Я думаю, что эта проблема связана с мультиплексированием:

lib.qbs содержит более одного профиля.Это включает мультиплексирование при сборке библиотеки, что, в свою очередь, добавляет дополнительный 'multiplexConfigurationId' к имени каталога сборки (moduleloader.cpp).

В 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);

Это сработало для моего варианта использования.Я не знаю, имеет ли это смысл в более широком представлении.

Наконец, вопросы:

Имеет ли это смысл?

Это нормальное поведение?

Этот вариант использования просто не поддерживается?

Есть ли лучшее решение?

Заранее спасибо.

1 Ответ

0 голосов
/ 24 октября 2018

Да, поведение по умолчанию с мультиплексированием заключается в том, что немультиплексированный продукт зависит от всех вариантов зависимости.В общем, пользователь не может изменить это поведение, но должен быть.Однако, к счастью для вас, профили являются специальными:

Depends { name: "mylib"; profiles: "arm-gcc" }

Это должно решить вашу проблему.

...