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

How to create re-usable libraries based on qmake?

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

这是文件树:

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 Creator 中进行开发,当我打开 Application1 时,我有以下行为:

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

你知道如何做到这一点吗?我尝试了基于SUBDIRS的不同解决方案,但我从未达到上述所有3点。

编辑:为了澄清一点,我希望能够做类似的事情:

Application1.pro

include("Library1")

Application2.pro

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

并且所有的工作都是自动进行的。我找到了解决方案,它要求库中的文件知道 "parent" 正在做什么,其中包含一些内容,这对我来说是无意义的,库不应该知道使用它的程序。

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

and puts the output .dll/.so file in the same directory than Application1 .exe

这应该是不同的:

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

你可以做这样一个项目: 我的项目:

  • 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

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

有两种方法可以实现。

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

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"
...