Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Qt Creator中自动重建依赖项_Qt_Compilation_Dependencies_Qt Creator - Fatal编程技术网

在Qt Creator中自动重建依赖项

在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 =

Qt Creator(4.6.1)快把我逼疯了。我的应用程序分为三部分:

  • 应用程序
  • 图书馆
  • 单元测试应用程序
当我在库中更改文件并重建应用程序时,编译器不会重新编译库,而是链接到库的旧版本

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

是否有一个设置来改变这一点?这是我的项目文件:

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