在Qt Creator中自动重建依赖项

时间:2018-06-12 11:01:59

标签: qt compilation dependencies qt-creator

Qt Creator(4.6.1)让我疯了。我的申请分为3部分:

  • 应用
  • 图书馆
  • 单元测试应用

当我更改库中的文件并重建应用程序时,编译器不会重新编译库,而是链接到旧版本的库。

此外,当我更改库,重新编译它然后编译应用程序时,不会进行任何编译,因为它使用缓存的应用程序。

是否有更改设置?这是我的项目文件:

TEMPLATE = subdirs

SUBDIRS += \
    app \
    lib_mylib \
    tests

app.depends = lib_mylib
tests.depends = lib_mylib

lib构建为静态库:

TEMPLATE = lib
TARGET = mylib
CONFIG += staticlib

3 个答案:

答案 0 :(得分:4)

我知道这有点晚了,但是我想给出一个更广泛的答案,为什么会发生这种情况以及其他解决方案到底有什么帮助。

一个可行的解决方案是:您可以像以前一样使用b.depends += aCONFIG += ordered 并将添加到PRE_TARGETDEPS += ...b。 (旁注:不建议您订购,因为它会大大降低您的构建速度,通常被认为是不好的做法)

TL; DR:之所以需要这种特殊组合,是因为:subdirs项目中的app.depends = lib_mylib确保在开始构建应用程序之前始终构建库,而{ {1}}确保应用程序实际上在每次库更改时都在重建。


详细说明:

要了解其工作原理,我们需要了解qmake如何处理子目录。 qmake是一个Makefile生成器,这意味着它将仅创建makefile。因此,必须使用make prodives方法完成所有依赖项排序。要了解发生了什么,我们必须首先了解make的工作原理。

在make中,依赖关系相对简单:

PRE_TARGETDEPS

表示如果要创建some_target: dep1 dep2 dep3 some_command ,make将首先以未指定的顺序创建some_targetdep1dep2。完成所有3个步骤后,将执行dep3

但是,make会对文件进行优化。考虑以下内容:

some_command

运行make将创建两个文件并打印两个消息。第二次运行将无济于事。原因是make跟踪已创建的文件和文件更改。由于hello.txt: echo "creating hello" echo "hello" > hello.txt hello2.txt: hello.txt echo "creating hello2" echo "hello2" > hello2.txt 已经存在,因此不会再次创建。并且由于hello.txt尚未更改,因此无需再次创建hello.txt。如果现在从外部更改hello2.txt的内容并再次运行make,将重新创建hello.txt并看到消息。

现在有了subdirs项目,这变得有些复杂,因为我们现在需要多个不同的makefile之间的依赖关系!这通常通过递归make调用来解决。对于您的示例,qmake创建以下代码(简化):

hello2.txt

此代码将按预期方式首先创建lib_mylib: FORCE $(MAKE) lib_mylib/Makefile app: lib_mylib FORCE $(MAKE) app/Makefile (阻塞,即lib_mylib仅在整个lib构建完成后才能完成),然后再创建lib_mylibapp依赖关系可确保即使目标已经存在,该命令也始终运行。


有了这些基本知识,我们现在可以重建qmake的情况。使用FORCE将生成如上所述的代码-确保所有依赖项均以正确的顺序构建,但除此之外没有其他!使用有序配置将简单地自动创建那些依赖规则,因此它们的工作方式没有逻辑差异。

但是,当b.depends += a更改时,这还不足以实际重建app。它仅确保在make开始构建lib_mylib之前已构建lib_mylib

为了重建app,我们使用app-这将向应用程序makefile中的make目标添加如前所示的依赖项

PRE_TARGETDEPS

这意味着每次app.exe: mylib.lib: #linker code 更改时,lib_mylib现在也会重新构建。但是,在没有有序配置的情况下使用它可能会失败,因为make可能会首先尝试构建app(由于lib尚未更改,它无能为力,或者如果lib不存在,则失败)。重建app。第二次运行也会重建lib_mylib-但这很不方便。

所以,这就是为什么我们需要将两者结合在一起。我们需要控制执行不同makefile文件的顺序,并引用另一个makefile文件中创建的工件,而这正是这些命令的作用。

答案 1 :(得分:3)

我使用了CONFIG + = ordered,DEPENDPATH和PRE_TARGETDEPS来解决同样的问题。它适用于Linux和MSVC的胜利。试试吧。

在您的项目专业文件中添加:

CONFIG += ordered

P.S。:应首先列出您的lib。喜欢:

SUBDIRS += \
    lib \
    app \
    tests
你的exe .pro文件中的

用正确的路径添加它:

DEPENDPATH += $$PWD/../lib
PRE_TARGETDEPS += $$OUT_PWD/../lib/liblib.a

可以找到更多选项和标记here

答案 2 :(得分:1)

不管我尝试过的冗长且易于理解的解释

TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
    dynamiclib \
    staticlib \
    testlibs

对于我相当小而短的项目,它对我有用。