Russian Qt Forum
Сентябрь 30, 2024, 06:35 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qbs не жрёт подпроекты  (Прочитано 5284 раз)
fisenkdima
Гость
« : Апрель 27, 2015, 16:10 »

Есть следующий проект в Qbs
Код:
import qbs
import "../StandartApp.qbs" as StandartApp
import "../StandartLib.qbs" as StandartLib

Project {
    StandartApp {
        name: "GUI"
        path: name + "/"
        Depends { name: "Qt"; submodules: ["core", "gui", "widgets"] }
        Depends { name: "SessionModule" }
    }

    StandartLib {
        name: "SessionModule"
        path: name + "/"
        Depends { name: "Qt"; submodules: ["core", "gui", "widgets"] }
    }
}
Здесь StandartApp определён так:
Код:
import qbs
import "StandartLib.qbs" as StandartLib

StandartLib {
    type: "application"
    Group {
        fileTagsFilter: product.type
        qbs.install: true
    }
}
А StandartLib так:
Код:
import qbs

CppApplication {
    type: "library"

    property string path : ""

    FileTagger {
        patterns: "*.cpp"
        fileTags: "cpp"
    }

    files: [path + '*.h', path + '*.cpp', path + '*.ui']

    Depends { name: "cpp" }
    cpp.cppFlags: "-std=c++11"
    //cpp.defines: ['__cplusplus 201103L']
}

Т.е. имеется приложение и либа.
Исходники расположены следующим образом:
./Game.qbs
./../StandartLib.qbs
./../StandartApp.qbs
./GUI/MainWindow.ui
./GUI/MainWindow.h
./GUI/MainWindow.cpp
./SessionModule/GameSession.h
./SessionModule/GameSession.cpp

Проблема состоит в следующем. На момент начала линковки приложения, в папке сборки есть единственный объектный файл MainWindow.cpp.o (это единственный класс приложения).
В то время как на деле там также должен находится ещё и файл GameSession.cpp.o (единственный класс либы), который используется в MainWindow.
Иными словами, либа не компилится. Очевидно, не распознается зависимость приложения от неё. В результате я получаю ошибки следующего характера:
Код:
undefined reference to `GameSession::interrupt()'
при попытке обратиться к методам класса из либы.

Что я сделал не так? (код ниже)

Приложение содержит окно MainWindow (наследник QMainWindow), которое является стартовым.
Код его .h-файла:
Код:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QWidget>

namespace Ui {
    class MainWindow;
}

class GameSession;

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private slots:
    void startNewGame();

private:
    Ui::MainWindow  *_ui;

    GameSession     *_gameSession;
};

#endif // MAINWINDOW_H
Код .cpp-файла:
Код:
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "../SessionModule/GameSession.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , _ui(new Ui::MainWindow)
    , _gameSession(nullptr)
{
    _ui->setupUi(this);
    connect(_ui->actionStart_new_game, SIGNAL(triggered()),
            this, SLOT());
}

MainWindow::~MainWindow()
{
    delete _ui;
}

void MainWindow::startNewGame()
{
    if (_gameSession) {
        _gameSession->interrupt();
        delete _gameSession;
        _gameSession = nullptr;
    }
    _gameSession = new GameSession();
    QWidget *gameSessionWidget = _gameSession->start();
}

Либа содержит класс GameSession
Его .h-файл:
Код:
#ifndef GAMESESSION_H
#define GAMESESSION_H

class QWidget;

class GameSession
{
public:
                    GameSession();
                    ~GameSession();
    QWidget*        start();
    void            interrupt();
};

#endif // GAMESESSION_H
Его .cpp-файл:
Код:
#include "GameSession.h"

#include <QWidget>

GameSession::GameSession()
{}

GameSession::~GameSession()
{}

QWidget* GameSession::start()
{
    return new QWidget();
}

void GameSession::interrupt()
{}
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #1 : Апрель 27, 2015, 20:12 »

Цитировать
...

StandartLib {
    type: "application"

...

CppApplication {
    type: "library"

...

huh?
Записан

ArchLinux x86_64 / Win10 64 bit
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #2 : Апрель 27, 2015, 22:51 »

В СтандартЛибе нет ни одного файла => ничего и не собирается

Далее:
Код:
    property string path : ""
Это может пересекаться со встроенным path'ом (да, есть такая пропертя у Project, насчет Product не уверен)

Код:
    FileTagger {
        patterns: "*.cpp"
        fileTags: "cpp"
    }
Не нужно

Код:
type: "library"
AFAIK, такого типа продукта нет (есть "staticlibrary" и "dynamiclibrary"). Или это алиас для "dynamiclibrary"?

Код:
files: [path + '*.h', path + '*.cpp', path + '*.ui']
Лучше просто "*.h" и тп. Подпапки лучше делать через Group и ее пропертю prefix.

Ну и разделите всё-таки апп и либ отдельно, без наследования друг от друга. Например, сделайте CppProduct без типа, но с зависимостью от "cpp" и установкой нужных флагов.

Upd: а не, в Апп файлы должны включаться из Либ. Тогда хз. Могу предположить, что оно ищет файлы не в той папке (а в "..")
Upd2: короче попробуйте файлы объявить в инстансах, а не в общем коде.
Upd3: всё-таки поставлю на type: "library"
« Последнее редактирование: Апрель 27, 2015, 23:10 от Авварон » Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #3 : Апрель 28, 2015, 01:08 »

Набросал рыбу https://github.com/ABBAPOH/qbsfish
Что не удалось сделать - завести общий файл для cpp продуктов - не компилит ничего, если вынести зависимость от cpp в продукт без типа.
Из багов - не работает install под маком - походу, сломали ребята в новых версиях
Записан
fisenkdima
Гость
« Ответ #4 : Апрель 28, 2015, 04:03 »

Код:
type: "library"
AFAIK, такого типа продукта нет (есть "staticlibrary" и "dynamiclibrary"). Или это алиас для "dynamiclibrary"?
<...>
Upd3: всё-таки поставлю на type: "library"

В яблочко. По-факту мне нужна была staticlibrary, выставил её и всё скомпилилось.
А наследование работает как положено (правда, у меня Linux Mint 17).

Код:
files: [path + '*.h', path + '*.cpp', path + '*.ui']

Да, у такого задания файлов есть минус. Не видит файлы в подпапках.
« Последнее редактирование: Апрель 28, 2015, 04:09 от Dalidul » Записан
fisenkdima
Гость
« Ответ #5 : Апрель 28, 2015, 04:04 »

Цитировать
...

StandartLib {
    type: "application"

...

CppApplication {
    type: "library"

...

huh?

Переменная перезаписывается. В чём проблема?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.046 секунд. Запросов: 23.