如何基于 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 时,我有以下行为:
- 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")
并且所有的工作都是自动进行的。我找到了解决方案,它要求库中的文件知道 "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
这应该是不同的:
- 根据某些变量,您可以设置
Library<i>
的 DESTDIR
。
- 您可以将 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
中,您可以明智地添加前缀,即使 lib1
和 lib2
都提供相同的文件也不会发生冲突:
main.cpp
#include "lib1/easy.h"
#include "lib2/easy.h"
...
我有多个应用程序将使用一个或多个公共库。甚至我的图书馆也可以相互依赖。
这是文件树:
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 时,我有以下行为:
- 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")
并且所有的工作都是自动进行的。我找到了解决方案,它要求库中的文件知道 "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
这应该是不同的:
- 根据某些变量,您可以设置
Library<i>
的DESTDIR
。 - 您可以将 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
中,您可以明智地添加前缀,即使 lib1
和 lib2
都提供相同的文件也不会发生冲突:
main.cpp
#include "lib1/easy.h"
#include "lib2/easy.h"
...