代码之家  ›  专栏  ›  技术社区  ›  Georg Schölly Crazy Developer

在qt creator中自动重建依赖项

  •  8
  • Georg Schölly Crazy Developer  · 技术社区  · 7 年前

    qt creator(4.6.1)让我抓狂。我的申请分为三部分:

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

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

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

    有什么设定可以改变吗?这是我的项目文件:

    TEMPLATE = subdirs
    
    SUBDIRS += \
        app \
        lib_mylib \
        tests
    
    app.depends = lib_mylib
    tests.depends = lib_mylib
    

    lib被构建为静态库:

    TEMPLATE = lib
    TARGET = mylib
    CONFIG += staticlib
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   Xplatforms    7 年前

    我使用了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
    

    将找到更多选项和标志 here

        2
  •  6
  •   Felix    6 年前

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

    一个可行的解决方案是:您可以使用 b.depends += a 就像你以前那样 CONFIG += ordered 添加 PRE_TARGETDEPS += ... b . (附带说明:不建议使用ordered,因为它会大大降低生成速度,通常被认为是不好的做法)

    DR: 需要这种特殊组合的原因是: app.depends = lib_mylib 在subdirs项目中,确保在启动构建应用程序之前始终构建库,并且 PRE_TARGETDEPS 确保应用程序在每次库更改时都在进行重建。


    详细说明:

    为了理解为什么这样做,我们需要了解qmake如何处理subdir。qmake是makefile生成器,这意味着它只创建makefile。所以所有的依赖排序都必须使用make prodives方法来完成。要了解发生了什么,首先我们必须了解make是如何工作的。

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

    some_target: dep1 dep2 dep3
        some_command
    

    意思是如果你想创造 some_target ,make将创建 dep1 , dep2 dep3 首先,在 未指定顺序 . 一旦三个都完成了, some_command 执行。

    但是,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 已经存在,不再创建。从那时起 TXT 没有改变,没有必要创建 hello2.txt 再一次。如果现在从外部更改 TXT 再次运行make, Helo2.TXT 将被重新创建,您将看到消息。

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

    lib_mylib: FORCE
        $(MAKE) lib_mylib/Makefile
    
    app: lib_mylib FORCE
        $(MAKE) app/Makefile
    

    如预期的那样,此代码将创建 lib_mylib 首先(阻塞,即 利比麦里布 只会在整个lib构建完成后完成),然后创建 app . 这个 FORCE 依赖性确保此命令始终运行,即使目标已存在。


    考虑到这些基础知识,我们现在可以重建qmake的情况。使用 b.取决于+=a 将生成如上所述的代码-这使舒尔能够按照正确的顺序构建所有依赖项,但没有其他依赖项!使用有序配置只会自动创建那些依赖规则,因此它们的工作方式没有逻辑上的区别。

    然而,这还不足以真正重建 应用程序 什么时候 利比麦里布 变化。它只能确保 利比麦里布 在make开始构建之前构建 应用程序 .

    为了重建 应用程序 我们使用 预目标部署 -这将向apps makefile中的make目标添加一个如前所示的依赖项

    app.exe: mylib.lib:
        #linker code
    

    这意味着每次 利比麦里布 变化, 应用程序 现在也重建了。但是,如果在不使用有序配置的情况下使用它,则可能会失败,因为make可能会首先尝试构建 应用程序 (因为lib没有改变,所以它什么也不做,或者如果lib不存在就会失败)并且在重建之后 利比麦里布 . 运行第二次将重建 应用程序 也一样-但那很不方便。

    所以,这就是我们需要把这两者结合起来的原因。我们需要控制不同makefile的执行顺序,并从另一个makefile引用创建的工件——这正是这些命令的作用。