我有一个链接到许多共享库的项目。
假设项目 A 依赖于项目 B 和 C
理想情况下,我想在我的项目文件中强加以下依赖项:
- 如果自上次构建项目 A 以来已重建 B 或 C,则重建项目 A
- 使用相关配置的输出(即,如果在调试模式下构建项目 A,则使用项目 B 和 C 的调试版本的库)
有谁知道我如何在我的项目文件中明确表达这种依赖关系?
在对 qmake 感到相当沮丧之后,我找到了我认为是您问题的答案。如果没有,那么我已经学会了使用 qmake 的方式,直到找到更好的东西,因为这仍然有点难看。我建立了一个演示项目,这是我的目录结构(文件有扩展名,文件夹没有):
MyProj
MyProj.pro
myproj-core
myproj-core.pro
globals.h
MyProjCore.h
MyProjCore.cpp
myproj-app
myproj-app.pro
main.cpp
我们从MyProj.pro
一个subdirs
项目开始,这是完成您所要求的事情的关键。基本上,您只需将其设置在一个 qmake 文件上,而不是依赖其他项目来指定调试/发布和各种其他垃圾。它不会让你只做你需要的东西,但它是我能想到的最好的解决方案。以下是内容:
TEMPLATE = subdirs
# Needed to ensure that things are built right, which you have to do yourself :(
CONFIG += ordered
# All the projects in your application are sub-projects of your solution
SUBDIRS = myproj-core \
myproj-app
# Use .depends to specify that a project depends on another.
myproj-app.depends = myproj-core
myproj-core.pro
是您典型的共享对象库:
QT -= gui
TARGET = myproj-core
TEMPLATE = lib
DEFINES += MYPROJCORE_LIBRARY
SOURCES += MyProjCore.cpp
HEADERS += MyProjCore.h \
globals.h
myproj-app.pro
是消费者应用程序,需要时重建的小技巧是:
QT -= gui
TARGET = myproj-app
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
# Specify that we're lookin in myproj-core. Realistically, this should be put
# in some configuration file
INCLUDEPATH += ../myproj-core
# Link to the library generated by the project. Could use variables or
# something here to make it more bulletproof
LIBS += ../myproj-core/libmyproj-core.so
# Specify that we depend on the library (which, logically would be implicit from
# the fact that we are linking to it)
PRE_TARGETDEPS += ../myproj-core/libmyproj-core.so
SOURCES += main.cpp
我希望这可以解决您的问题,因为我知道它解决了我的问题!
编辑:我制作了一个专门为我构建依赖项的文件,我将它存储在我的每个项目的兄弟文件夹中(上面指定的目录结构中 MyProj 的子文件夹),名为dependencies.pri
:
# On windows, a shared object is a .dll
win32: SONAME=dll
else: SONAME=so
# This function sets up the dependencies for libraries that are built with
# this project. Specify the libraries you need to depend on in the variable
# DEPENDENCY_LIBRARIES and this will add
for(dep, DEPENDENCY_LIBRARIES) {
#message($$TARGET depends on $$dep ($${DESTDIR}/$${dep}.$${SONAME}))
LIBS += $${DESTDIR}/lib$${dep}.$${SONAME}
PRE_TARGETDEPS += $${DESTDIR}/lib$${dep}.$${SONAME}
}
所以在所有消费应用程序的底部,我可以添加以下行:
DEPENDENCY_LIBRARIES = myproj-core
include(../config/dependencies.pri)
这假设您将库复制到某个共享位置和/或根据需要移动它们,所以我的功能可能不适合您,但我想我会将它添加到解决方案中。
我使用下面的解决方案。这无需使用带有 subdir 模板的额外 .pro 文件即可工作。
TEMPLATE = app
TARGET = MyApp
PRE_TARGETDEPS = ../../libs/MyLib/MyLib.a
INCLUDEPATH += ../../libs/MyLib/include
HEADERS += src/MyApp.h \
../../libs/MyLib/incude/MyLib.h
SOURCES += src/MyApp.cpp
LIBS += ../../libs/MyLib/MyLib.a
MyLib.target = ../../libs/MyLib/MyLib.a
MyLib.commands = cd ../../libs/MyLib && make
MyLib.depends = ../../libs/MyLib/Makefile
QMAKE_EXTRA_TARGETS += MyLib
尝试将类似于此代码的内容添加到您的 pro 文件中:
CONFIG(debug, debug|release) {
DESTDIR = ../../../bin/debug
OBJECTS_DIR = ./debug
}
else {
DESTDIR = ../../../bin/release
OBJECTS_DIR = ./release
}
然后,您必须为每个配置指定依赖项:
CONFIG(debug, debug|release) {
LIBS += -L../../../lib/debug \
-L../../../bin/debug \
-llib1 \
-llib2
PRE_TARGETDEPS += ../../../lib/debug/liblib1.a \
../../../lib/debug/liblib2.a
else {
LIBS += -L../../../lib/release \
-L../../../bin/release \
-llib1 \
-llib2
PRE_TARGETDEPS += ../../../lib/release/liblib1.a \
../../../lib/release/liblib2.a
}
对于那些对 Qt/QML 项目模板感兴趣的人,我在 GitHub QmlAppTemplate上发布了一个模板。
在我搬入一个新的 DLL (pqXDot) 一个可重用的类(来自 pqGraphviz)之后,我在重构我的项目时遇到了这个问题。
在我的项目中添加一个新的 DLL,并将新的 DLL 引用添加到其他 DLL 和需要它的应用程序之后,我在 main .pro 中有:
TEMPLATE = subdirs
SUBDIRS += \
pqConsole \
pqConsoleTest \
pqSource \
pqSourceTest \
fdqueens \
pqGraphviz \
pqGraphvizTest \
pqXDot
并且重建导致链接器错误,因为正在重组的 DLL pqGraphviz 找不到新的 DLL pqXDot。
事实证明,重新排序 SUBDIRS 列表就足够了,将所需的 DLL 移到依赖的 DLL 之前:
SUBDIRS += \
pqConsole \
pqConsoleTest \
pqSource \
pqSourceTest \
fdqueens \
pqXDot \
pqGraphviz \
pqGraphvizTest