在Qt Creator中自动重建依赖项
Qt Creator(4.6.1)快把我逼疯了。我的应用程序分为三部分:在Qt Creator中自动重建依赖项,qt,compilation,dependencies,qt-creator,Qt,Compilation,Dependencies,Qt Creator,Qt Creator(4.6.1)快把我逼疯了。我的应用程序分为三部分: 应用程序 图书馆 单元测试应用程序 当我在库中更改文件并重建应用程序时,编译器不会重新编译库,而是链接到库的旧版本 另外,当我更改库,重新编译它,然后编译应用程序时,不会进行编译,因为它使用缓存的应用程序 是否有一个设置来改变这一点?这是我的项目文件: TEMPLATE = subdirs SUBDIRS += \ app \ lib_mylib \ tests app.depends =
- 应用程序
- 图书馆
- 单元测试应用程序
TEMPLATE = subdirs
SUBDIRS += \
app \
lib_mylib \
tests
app.depends = lib_mylib
tests.depends = lib_mylib
该库构建为静态库:
TEMPLATE = lib
TARGET = mylib
CONFIG += staticlib
我使用CONFIG+=ordered、DEPENDPATH和PRE_TARGETDEPS来解决相同的问题。它在linux和MSVC上对我有效。试试看 在project pro文件中添加:
CONFIG += ordered
附言:你的lib应该列在第一位。比如:
SUBDIRS += \
lib \
app \
tests
在exe.pro文件中,使用正确的路径添加此文件:
DEPENDPATH += $$PWD/../lib
PRE_TARGETDEPS += $$OUT_PWD/../lib/liblib.a
更多的选项和标志将被找到我知道现在有点晚了,但我想给出一个更广泛的答案,解释为什么会发生这种情况,以及其他解决方案到底有什么帮助 一个有效的解决方案是:像以前一样使用
b.dependens+=A
,或者CONFIG+=ordered
和将PRE_TARGETDEPS+=…
添加到b
。(旁注:不建议使用ordered,因为它会大大降低构建速度,通常被认为是不好的做法)
TL;DR:需要这种特殊组合的原因:SubDRS项目中的app.dependens=lib_mylib
确保在开始构建应用程序之前始终构建库,而PRE_TARGETDEPS
确保每次库发生更改时,应用程序实际上都在重建
详细解释: 为了理解为什么这样做,我们需要了解qmake如何处理子对象。qmake是一个Makefile生成器,这意味着它将只创建Makefile。因此,所有依赖项排序都必须使用make-prodives方法来完成。要了解发生了什么,我们首先必须了解make是如何工作的 在make中,依赖关系相对简单:
some_target: dep1 dep2 dep3
some_command
这意味着,如果要创建某个_目标
,make将首先以未指定的顺序创建dep1
、dep2
和dep3
。完成所有3项后,将执行某个_命令
但是,make将针对文件对此进行优化。考虑到以下几点:
hello.txt:
echo "creating hello"
echo "hello" > hello.txt
hello2.txt: hello.txt
echo "creating hello2"
echo "hello2" > hello2.txt
运行make将创建这两个文件并打印这两条消息。第二次运行它将毫无用处。这里的原因是make跟踪已经创建的文件和文件更改。由于hello.txt
已经存在,因此不会再次创建它。由于hello.txt
没有改变,因此不需要再次创建hello2.txt
。如果您现在从外部更改了hello.txt
的内容并再次运行make,hello2.txt
将被重新创建,您将看到消息
现在,对于subdirs项目,这变得有点复杂,因为我们现在需要多个不同的makefile之间的依赖关系!这通常通过递归make调用来解决。对于您的示例,qmake创建以下代码(简化):
正如预期的那样,此代码将首先创建lib_mylib
(阻塞,即lib_mylib
仅在构建整个lib后完成),然后创建app
。FORCE
从属关系确保始终运行此命令,即使目标已存在
有了这些基础知识,我们现在可以重新构建qmake发生了什么。使用
b.dependens+=a
将生成如上所述的代码-这使舒尔能够以正确的顺序构建所有依赖项,而不是其他任何依赖项!使用有序配置只会自动创建这些依赖规则,因此它们的工作方式在逻辑上没有区别
然而,这还不足以在lib_mylib
发生更改时实际重建app
。它只确保在make开始构建应用程序之前构建lib_mylib
为了重建app
,我们使用了PRE_TARGETDEPS
——这将向apps makefile中的make目标添加一个依赖项,如前所示
app.exe: mylib.lib:
#linker code
这意味着每次lib_mylib
更改时,app
现在也会重新生成。但是,在没有有序配置的情况下使用此配置可能会失败,因为make可能会首先尝试构建app
(它要么什么都不做,因为lib没有更改,要么如果lib不存在,它将失败),然后重新构建lib\u mylib
。运行make第二次将重建应用程序
,但这相当不方便
所以,这就是为什么我们需要将两者结合起来。我们需要控制不同的makefile的执行顺序,并引用来自另一个makefile的已创建工件,而这正是这些命令所做的。不管我尝试过的冗长且易懂的解释如何
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
dynamiclib \
staticlib \
testlibs
对于我的小而短的项目,它对我很有效。不需要
CONFIG+=ordered
,它不会改变任何东西-它只会减慢构建速度(基本上与基于顺序的自动依赖项是一样的)。然而,DEPENDPATH
和PRE_TARGETDEPS
应该可以工作。PRE_TARGETDEPS
是使其工作的关键。非常感谢。据我所知,DEPENDPATH
对于Qt5不再是必需的。您使用的是什么操作系统?我经常在linux上使用这样的结构,从未经历过这样的问题problem@Felix:Windows 7和MSVC那么它可能与jom/nmake有关-您可以尝试在生成配置中禁用jom,但这将显著降低生成速度
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
dynamiclib \
staticlib \
testlibs