使用qmake的subdir结构避免重复的对象文件

Avoid duplicate object files using subdir structure with qmake

本文关键字:对象 文件 qmake subdir 结构 使用      更新时间:2023-10-16

我有一个游戏,有两个独立的项目用于应用程序本身和测试。我正在以源代码构建所有项目。以下是我的项目结构的缩短版本:

game
game.pro
app
app.pro
Entity.h
Entity.cpp
Entity.o
moc_Entity.cpp
moc_Entity.o
tests
layer
layer.pro
Entity.o (duplicated)
moc_Entity.cpp (duplicated)
moc_Entity.o (duplicated)
tst_Layer.cpp

app.pro:

QT += core gui
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
}
TARGET = cotw-clone
TEMPLATE = app
MOC_DIR = .moc
OBJECTS_DIR = .obj
HEADERS += MainWindow.h 
Map.h 
Tile.h 
Character.h 
Layer.h 
NewGameDialog.h 
GameController.h 
Stair.h 
Random.h 
MapGenerator.h 
TileData.h 
Statistics.h 
StatisticsDialog.h 
StatisticWidget.h 
Range.h 
Level.h 
RandomMapGenerator.h 
AiController.h 
MonsterJournalWidget.h 
InventoryDialog.h 
PathSearch.h 
PathNode.h 
Path.h 
Geometry.h 
EntityDatabase.h 
EntityData.h 
Entity.h 
CharacterData.h 
EntityMetadata.h
SOURCES +=
MainWindow.cpp 
Map.cpp 
Tile.cpp 
Character.cpp 
Layer.cpp 
NewGameDialog.cpp 
GameController.cpp 
Stair.cpp 
TileData.cpp 
Statistics.cpp 
StatisticsDialog.cpp 
StatisticWidget.cpp 
Level.cpp 
RandomMapGenerator.cpp 
AiController.cpp 
MonsterJournalWidget.cpp 
InventoryDialog.cpp 
PathSearch.cpp 
PathNode.cpp 
Path.cpp 
EntityDatabase.cpp 
EntityData.cpp 
Entity.cpp 
CharacterData.cpp 
main.cpp
FORMS += MainWindow.ui 
NewGameDialog.ui 
StatisticsDialog.ui 
StatisticWidget.ui 
MonsterJournalWidget.ui 
InventoryDialog.ui
RESOURCES += 
icons/icons.qrc 
tiles/tiles.qrc
RESOURCES += 
entities/entities.qrc

我的问题是,所有的tests项目都使用app项目中的类,这意味着它们正在编译所有这些类,即使它们在构建app时已经编译过了。以layer测试项目为例:

layer.pro:

QT += testlib
QT -= gui
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
}
TARGET = tst_LayerTest
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += tst_LayerTest.cpp
DEFINES += SRCDIR=\"$$PWD/\"
HEADERS += "../../app/Entity.h"
SOURCES += "../../app/Entity.cpp"

那么,我如何将qmake指向已经在app中生成的.o(以及qrc_.moc等)文件呢?是否有一些qmake变量用于此目的,或者我的项目结构是否存在根本缺陷?

您可以在qmake.pro文件中使用通配符,以避免维护所有文件名的列表。

例如,

SOURCES += *.cpp

每次运行qmake时,模式*.cpp都会扩展到与该模式匹配的当前文件列表中。

如果有要排除的特定文件名,也可以使用-=删除文件名。

例如:

SOURCES += *.cpp
SOURCES -= main.cpp

编辑

我在前面的回答中几乎建议您引入一个库,使用qt的lib模板来包含您的公共代码。

然后你的构建结构会是这样的——假设你可以四处移动文件,从app/到lib/:

game
game.pro
app
app.pro
main.cpp
lib
lib.pro
Entity.h
Entity.cpp
Entity.o
moc_Entity.cpp
moc_Entity.o
tests
layer
layer.pro
tst_Layer.cpp

你可以在Qt网站上的"建立图书馆"中找到一些关于图书馆项目的信息

如果出于某种原因,你不能四处移动文件,那么你可以为库引入一个新目录,并让它从应用程序目录中提取源文件——但这肯定更麻烦,也更令人困惑:

game
game.pro
app
app.pro - builds only main.o
main.cpp
Entity.h
Entity.cpp
moc_Entity.cpp
lib
lib.pro
Entity.o
moc_Entity.o
tests
layer
layer.pro
tst_Layer.cpp

编辑2

您遇到的一个问题是将对象文件放入LIBS变量中,该变量定义了代码将链接到的库。所以这就是为什么你会在这些文件中出现错误的原因。

尝试将这些LIBS的用途改为OBJECTS,这样可能会奏效。

如果没有,请阅读这篇帖子,它提出了几乎相同的问题。

特别是,参见ChrisW67在"2012年5月13日,10:14"中的答案,该答案开头;

尝试:

OBJECTS+=f1.of2.of3.of3.o

尽管我认为,如果你有来源应用程序直接或通过图书馆是一个更好的选择。