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

How to create re-usable libraries based on qmake?

本文关键字:何基于 qmake 创建      更新时间:2023-10-16

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

下面是文件树:

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时,我有以下行为:

  • Application1代码可在Qt creator
  • libary1代码可在Qt creator
  • Compiling Application1自动编译Library1,并把输出。dll/。
  • 与Application1 .exe在同一目录下。

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

你知道怎么做吗?我尝试了基于SUBDIRS的不同解决方案,但我从来没有达到以上3点。

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

Application1.pro

include("Library1")

Application2.pro

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

并全部自动工作。我找到了解决方案,要求库中的文件知道什么是"父"做一些包括,这对我来说是毫无意义的,库不应该知道使用它的程序。

你可以这样做一个项目: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

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/。与Application1 .exe在同一目录下的文件

这个应该是不同的:

  1. 您可以根据某些变量设置DESTDIRLibrary<i>
  2. 你可以添加copy-lib命令到App<i> pro-file。

加上Thom的回答,能够使用限定前缀引用库头是有利的- #include "lib1/lib1.h"而不是#include "lib1.h"。否则,几乎不可能使用独立开发的库,您总是会遇到头冲突。

有两种方法可以做到这一点。

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

App.pro

ROOT = ..
include($$ROOT/lib1/lib1.pri)
include($$ROOT/lib2/lib2.pri)
INCLUDEPATH += $$ROOT
DEPENDPATH += $$ROOT
...

这样,单个库项目的include就完全不需要指定它们的include。

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

lib1.pri

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

然后,在main.cpp中,即使lib1lib2都提供相同的文件,也可以有合理的前缀包含,不会冲突:

main.cpp

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