【问题标题】:How to create layered project structure in c++ using qmake如何使用 qmake 在 C++ 中创建分层项目结构
【发布时间】:2016-04-19 08:47:43
【问题描述】:

在使用 MinGW、C++11、Qt 5 和 qmake 的 windows 下,我有以下项目结构:

/my-project
   my-project.pro
   /my-app
      my-app.pro
      main.cpp
   /module-a
      module-a.pro
      modulea.h
      modulea.cpp
   /module-b
      module-b.pro
      moduleb.h
      moduleb.cpp

模块之间的依赖关系应该是这样的:

my-app ==> module-a ==> module-b

我想要实现的是 my-app 使用 module-a,module-a 使用 module-b,而 my-app 对 module-b 一无所知。模块-a 仅通过其实现引用模块-b(模块-b 的#include 位于模块-a 的.cpp 中)。

我尝试通过在 qmake 中将 module-a 和 module-b 配置为静态库来实现这一点。不幸的是,在编译时我收到链接器错误,提示“未定义对 ModuleB::doSmthB() 的引用”

我理解这个链接问题的原因,我的问题是是否有可能实现类似于提议的分层结构的东西?

来源:

我的项目.pro:

TEMPLATE = subdirs
SUBDIRS += module-b
SUBDIRS += module-a
SUBDIRS += my-app
my-app.depends = module-a
module-a.depends = module-b

my-app.pro:

QT += widgets
TARGET = my-app
TEMPLATE = app
CONFIG += c++11
SOURCES += *.cpp
win32 {
    INCLUDEPATH += $$clean_path($$PWD/../module-a)
    DEPENDPATH += $$clean_path($$PWD/../module-a)
    LIBS += $$clean_path($$OUT_PWD/../module-a/debug/libmodule-a.a)
    PRE_TARGETDEPS += $$clean_path($$OUT_PWD/../module-a/debug/libmodule-a.a)
}

main.cpp:

#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>

#include "modulea.h"

int main(int argc, char *args[])
{
    QApplication app(argc, args);
    QGraphicsView view;
    QGraphicsScene *scene = new QGraphicsScene(0, 0, 300, 300, &view);
    ModuleA moduleA;
    scene->addText(QString::number(moduleA.doSmthA())); // undefined reference to ModuleB::doSmthB()
    view.setScene(scene);
    view.show();
    return app.exec();
}

模块-a.pro:

QT -= core gui
TARGET = module-a
TEMPLATE = lib
CONFIG += staticlib
CONFIG += c++11
HEADERS += *.h
SOURCES += *.cpp
win32 {
    INCLUDEPATH += $$clean_path($$PWD/../module-b)
    DEPENDPATH += $$clean_path($$PWD/../module-b)
    LIBS += $$clean_path($$OUT_PWD/../module-b/debug/libmodule-b.a)
    PRE_TARGETDEPS += $$clean_path($$OUT_PWD/../module-b/debug/libmodule-b.a)
}

modulea.h:

#ifndef MODULEA_H
#define MODULEA_H

struct ModuleA
{
    int doSmthA();
};

#endif // MODULEA_H

modulea.cpp:

#include "modulea.h"
#include "moduleb.h"

int ModuleA::doSmthA() {
    ModuleB other;
    return other.doSmthB();
}

模块-b.pro:

QT -= core gui
TARGET = module-b
TEMPLATE = lib
CONFIG += staticlib
CONFIG += c++11
HEADERS += *.h
SOURCES += *.cpp

模块b.h:

#ifndef MODULEB_H
#define MODULEB_H

struct ModuleB
{
    int doSmthB();
};

#endif // MODULEB_H

moduleb.cpp:

#include "moduleb.h"

int ModuleB::doSmthB() {
    return 12345;
}

【问题讨论】:

    标签: c++ qt qmake modularity project-structure


    【解决方案1】:

    要修复我的示例,需要进行以下更改:

    1) 将CONFIG += create_prl 添加到所有应用程序直接依赖项的.pro 文件中(在我的情况下为module-a)。像这样修改所有模块不会有什么坏处。

    这里的解释: http://doc.qt.io/qt-5/qmake-advanced-usage.html#library-dependencies

    2) 在主 .pro(在我的示例中为 my-project.pro)中,应用程序 (SUBDIRS += my-app) 的子目录声明必须放在应用程序的直接依赖项之后(SUBDIRS += module-a 之后)。

    我在这里找到的第二点的提示:https://stackoverflow.com/a/1417859/6223445

    3) LIBS 属性必须使用 -L-l 选项定义(至少在 windows 下),例如而不是:

    LIBS += $$clean_path($$OUT_PWD/../module-a/debug/libmodule-a.a)
    

    使用以下:

    LIBS += -L$$clean_path($$OUT_PWD/../module-a/debug/) -lmodule-a
    

    固定解决方案如下所示(仅限修改后的文件):

    我的项目.pro:

    TEMPLATE = subdirs
    SUBDIRS += module-b
    SUBDIRS += module-a
    SUBDIRS += my-app
    my-app.depends = module-a
    module-a.depends = module-b
    

    my-app.pro:

    QT += widgets
    TARGET = my-app
    TEMPLATE = app
    CONFIG += c++11
    SOURCES += *.cpp
    win32 {
        INCLUDEPATH += $$clean_path($$PWD/../module-a)
        DEPENDPATH += $$clean_path($$PWD/../module-a)
        LIBS += -L$$clean_path($$OUT_PWD/../module-a/debug/) -lmodule-a
        PRE_TARGETDEPS += $$clean_path($$OUT_PWD/../module-a/debug/libmodule-a.a)
    }
    

    模块-a.pro:

    QT -= core gui
    TARGET = module-a
    TEMPLATE = lib
    CONFIG += staticlib
    CONFIG += c++11
    CONFIG += create_prl
    HEADERS += *.h
    SOURCES += *.cpp
    win32 {
        INCLUDEPATH += $$clean_path($$PWD/../module-b)
        DEPENDPATH += $$clean_path($$PWD/../module-b)
        LIBS += -L$$clean_path($$OUT_PWD/../module-b/debug/) -lmodule-b
        PRE_TARGETDEPS += $$clean_path($$OUT_PWD/../module-b/debug/libmodule-b.a)
    }
    

    【讨论】:

      猜你喜欢
      • 2014-11-25
      • 1970-01-01
      • 2014-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多