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
答案 0 :(得分:4)
我知道这有点晚了,但是我想给出一个更广泛的答案,为什么会发生这种情况以及其他解决方案到底有什么帮助。
一个可行的解决方案是:您可以像以前一样使用b.depends += a
或CONFIG += 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_target
,dep1
和dep2
。完成所有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_mylib
。 app
依赖关系可确保即使目标已经存在,该命令也始终运行。
有了这些基本知识,我们现在可以重建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
对于我相当小而短的项目,它对我有用。