如何基于qmake创建可重用的库?

时间:2015-07-22 13:13:58

标签: c++ qt qt-creator qmake subdirs

我有多个应用程序将使用一个或多个公共库。甚至我的图书馆也可能相互依赖。

这是文件树:

Libaries/
   Library1/
       Library1.pro
       Library1.cpp
       Library1.h
   Library2/
       Library2.pro
       Library2.cpp
       Library2.h
Applications/
   App1/
       App1.pro
       main.cpp
   App2/
       App2.pro
       main.cpp

App1依赖于Library1。 App2依赖于Library1和Library2。

我希望能够以简单的方式在Qt创建者中开发,当我打开Application1时,我有以下行为:

  • Qt creator中提供的Application1代码
  • Qt creator中提供的Library1代码
  • 编译Application1会自动编译Library1并将输出.dll / .so文件放在与Application1 .exe相同的目录中。

这基本上是Visual Studio能够做多年的事情,对我来说这似乎是一件基本的事情,我不明白我是唯一一个遇到这个问题的人。

你对这个怎么做有任何线索吗?我尝试了基于SUBDIRS的不同解决方案,但我从未达到上述所有3点。

编辑:为了澄清一点,我希望能够做到这样的事情:

Application1.pro

include("Library1")

Application2.pro

include("Library1")
include("Library2")

自动完成所有工作。我找到了解决方案,它要求库中的文件知道什么是"父母"做一些包括,这对我来说是没有意义的,图书馆不应该知道使用它的程序。

3 个答案:

答案 0 :(得分:1)

<强> App1Solution.pro

TEMPLATE = subdirs
CONFIG += ordered

SUBDIRS += \
    ../../Libaries/Library1 \
    ../App1

靠近App1.pro

<强> App2Solution.pro

TEMPLATE = subdirs
CONFIG += ordered

SUBDIRS += \
    ../../Libaries/Library1 \
    ../../Libaries/Library2 \
    ../App2

靠近App2.pro

  

并将输出.dll / .so文件放在与Application1 .exe

相同的目录中

这应该有所不同:

  1. 您可以根据某个变量设置DESTDIR Library<i>
  2. 您可以将copy-lib命令添加到App<i>专业文件。

答案 1 :(得分:1)

您可以执行以下项目: MyProject的:

  • project.pro
    • 应用
      • App.pro
      • 的main.cpp
    • LIB1
      • lib1.pro
      • lib1.pri
      • lib1.h
      • lib1.cpp
    • LIB2
      • lib2.pro
      • lib2.pri
      • lib2.h
      • lib2.cpp

project.pro

TEMPLATE = subdirs
CONFIG += ordered

SUBDIRS += \
    lib1 \
    lib2 \
    App

App.pro

QT       += core

QT       -= gui

include(../lib1/lib1.pri)
include(../lib2/lib2.pri)

TARGET = App
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app


SOURCES += main.cpp

的main.cpp

#include <QCoreApplication>
#include "lib1.h"
#include "lib2.h"

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    Lib1 lib1();

    return a.exec();
}

lib1.pro

QT       -= gui

TARGET = lib1
TEMPLATE = lib

DEFINES += LIB1_LIBRARY

SOURCES += lib1.cpp

HEADERS += lib1.h\
        lib1_global.h

DESTDIR = ../libs

unix {
    target.path = /usr/lib
    INSTALLS += target
}

OTHER_FILES += \
    lib1.pri

lib1.pri

INCLUDEPATH += $$PWD/
LIBS += -L$$OUT_PWD/../libs/ -llib1

lib2.pro

QT       -= gui

TARGET = lib2
TEMPLATE = lib

DEFINES += LIB2_LIBRARY

SOURCES += lib2.cpp

HEADERS += lib2.h\
        lib1_global.h

DESTDIR = ../libs

unix {
    target.path = /usr/lib
    INSTALLS += target
}

OTHER_FILES += \
    lib2.pri

lib2.pri

INCLUDEPATH += $$PWD/
LIBS += -L$$OUT_PWD/../libs/ -llib2

答案 2 :(得分:1)

添加到Thom's answer,能够使用合格的前缀 - #include "lib1/lib1.h"而不是#include "lib1.h"来引用库标题是有利的。否则,使用独立开发的库几乎是不可能的,你总是会遇到标题冲突。

有两种方法可以实现这一目标。

首先,您可以通过引用树根向每个顶级项目文件添加一个公共变量,该文件在项目树中指示其深度。然后,将树根添加到include和depend路径。

App.pro

ROOT = ..
include($$ROOT/lib1/lib1.pri)
include($$ROOT/lib2/lib2.pri)

INCLUDEPATH += $$ROOT
DEPENDPATH += $$ROOT

...

这样,个别图书馆项目包括根本不必指定其包含。

或者,每个库中的INCLUDEPATH应指向一个文件夹 - 不要忘记DEPENDPATH

lib1.pri

ROOT = ..
INCLUDEPATH += $$PWD/$$ROOT
DEPENDPATH += $$PWD/$$ROOT

...

然后,在main.cpp内,即使lib1lib2都提供相同的文件,您也可以拥有明智的前缀包含且不会发生冲突:

的main.cpp

#include "lib1/easy.h"
#include "lib2/easy.h"
...