【问题标题】:Qmake project dependencies (linked libraries)Qmake 项目依赖(链接库)
【发布时间】:2011-01-18 07:11:37
【问题描述】:

我有一个链接到多个共享库的项目。

假设项目 A 依赖于项目 B 和 C

理想情况下,我想在我的项目文件中强加以下依赖项:

  1. 如果自上次构建项目 A 以来已重建 B 或 C,则重建项目 A
  2. 将输出用于相关配置(即,如果在调试模式下构建项目 A,则使用项目 B 和 C 的调试版本的库)

有谁知道我如何在我的项目文件中明确表达这种依赖关系?

【问题讨论】:

    标签: qt qmake


    【解决方案1】:

    在对 qmake 感到相当沮丧之后,我找到了我认为是您问题的答案。如果没有,那么我已经学会了使用 qmake 的方式,直到找到更好的东西,因为这仍然有点难看。我建立了一个演示项目,这是我的目录结构(文件有扩展名,文件夹没有):

    MyProj
        MyProj.pro
        myproj-core
            myproj-core.pro
            globals.h
            MyProjCore.h
            MyProjCore.cpp
        myproj-app
            myproj-app.pro
            main.cpp
    

    我们从MyProj.pro 作为subdirs 项目开始,这是完成您所要求的事情的关键。基本上,您只需将其设置在一个 qmake 文件上,而不是依赖其他项目来指定调试/发布和各种其他垃圾。它不会让你只做你需要的东西,但它是我能想到的最好的解决方案。以下是内容:

    TEMPLATE = subdirs
    # Needed to ensure that things are built right, which you have to do yourself :(
    CONFIG += ordered
    
    # All the projects in your application are sub-projects of your solution
    SUBDIRS = myproj-core \
              myproj-app
    
    # Use .depends to specify that a project depends on another.
    myproj-app.depends = myproj-core
    

    myproj-core.pro 是您典型的共享对象库:

    QT -= gui
    TARGET = myproj-core
    TEMPLATE = lib
    DEFINES += MYPROJCORE_LIBRARY
    SOURCES += MyProjCore.cpp
    HEADERS += MyProjCore.h \
               globals.h
    

    myproj-app.pro 是消费者应用程序,需要时重建的小技巧是:

    QT       -= gui
    
    TARGET = myproj-app
    CONFIG   += console
    CONFIG   -= app_bundle
    
    TEMPLATE = app
    
    # Specify that we're lookin in myproj-core.  Realistically, this should be put
    # in some configuration file
    INCLUDEPATH += ../myproj-core
    # Link to the library generated by the project.  Could use variables or
    # something here to make it more bulletproof
    LIBS += ../myproj-core/libmyproj-core.so
    # Specify that we depend on the library (which, logically would be implicit from
    # the fact that we are linking to it)
    PRE_TARGETDEPS += ../myproj-core/libmyproj-core.so
    
    SOURCES += main.cpp
    

    我希望这能解决你的问题,因为我知道它解决了我的问题!

    编辑:我制作了一个专门为我构建依赖项的文件,我将它存储在我的每个项目的兄弟文件夹中(上面指定的目录结构中 MyProj 的子文件夹),名为 @ 987654329@:

    # On windows, a shared object is a .dll
    win32: SONAME=dll
    else:  SONAME=so
    
    # This function sets up the dependencies for libraries that are built with
    # this project.  Specify the libraries you need to depend on in the variable
    # DEPENDENCY_LIBRARIES and this will add
    for(dep, DEPENDENCY_LIBRARIES) {
        #message($$TARGET depends on $$dep ($${DESTDIR}/$${dep}.$${SONAME}))
        LIBS += $${DESTDIR}/lib$${dep}.$${SONAME}
        PRE_TARGETDEPS += $${DESTDIR}/lib$${dep}.$${SONAME}
    }
    

    所以在所有消费应用程序的底部,我可以添加以下行:

    DEPENDENCY_LIBRARIES = myproj-core
    
    include(../config/dependencies.pri)
    

    这假设您将库复制到某个共享位置和/或根据需要移动它们,所以我的功能可能不适合您,但我想我会将它添加到解决方案中。

    【讨论】:

    • 嗨,Travis,您能发布您项目的源文件吗?我相信有几个人会欣赏这一点并将项目用作他们的应用程序的模板。
    • 如果有源文件就好了。 :)
    • 您可以使用QMAKE_EXTENSION_SHLIB 而不是手动设置SONAME - 作为奖励,它也可以在Mac OS X 上运行(使用dylib 作为扩展名)。
    • @ashkulz:理论上是的,但在我的 Windows 系统上,QMAKE_EXTENSION_SHLIB 是空的。我不知道为什么。这可能会导致不良行为...
    • @TravisGockel 我认为CONFIG += ordered 在您的情况下不是必需的,因为您明确指定一个子项目依赖于另一个。
    【解决方案2】:

    我使用下面的解决方案。这无需使用带有子目录模板的额外 .pro 文件即可工作。

    TEMPLATE = app
    TARGET = MyApp
    PRE_TARGETDEPS = ../../libs/MyLib/MyLib.a
    INCLUDEPATH += ../../libs/MyLib/include 
    HEADERS += src/MyApp.h \
        ../../libs/MyLib/incude/MyLib.h
    SOURCES += src/MyApp.cpp
    LIBS += ../../libs/MyLib/MyLib.a
    
    MyLib.target = ../../libs/MyLib/MyLib.a
    MyLib.commands = cd ../../libs/MyLib && make
    MyLib.depends = ../../libs/MyLib/Makefile
    QMAKE_EXTRA_TARGETS += MyLib
    

    【讨论】:

    • 如果你的库不是一个 qmake 项目,那就太好了。谢谢!
    【解决方案3】:
    1. 看看这个问题:Force relink when building in QT Creator
    2. 尝试将与此代码类似的内容添加到您的 pro 文件中:

      CONFIG(debug, debug|release) {   
          DESTDIR = ../../../bin/debug  
          OBJECTS_DIR = ./debug  
      }  
      else {   
          DESTDIR = ../../../bin/release  
          OBJECTS_DIR = ./release  
      }
      

    然后您必须为每个配置指定依赖项:

    CONFIG(debug, debug|release) {   
        LIBS += -L../../../lib/debug \  
            -L../../../bin/debug \  
            -llib1 \  
            -llib2   
        PRE_TARGETDEPS += ../../../lib/debug/liblib1.a \  
            ../../../lib/debug/liblib2.a 
    else { 
        LIBS += -L../../../lib/release \
            -L../../../bin/release \
            -llib1 \  
            -llib2   
        PRE_TARGETDEPS += ../../../lib/release/liblib1.a \
            ../../../lib/release/liblib2.a 
    }
    

    【讨论】:

      【解决方案4】:

      在我将一个新的 DLL (pqXDot) 移入一个可重用的类(来自 pqGraphviz)之后,我在重构我的项目时遇到了这个问题。

      在我的项目中添加一个新的 DLL,并将新的 DLL 引用添加到其他需要它的 DLL 和应用程序后,我在 main .pro 中:

      TEMPLATE = subdirs
      
      SUBDIRS += \
          pqConsole \
          pqConsoleTest \
          pqSource \
          pqSourceTest \
          fdqueens \
          pqGraphviz \
          pqGraphvizTest \
          pqXDot
      

      并且重建导致链接器错误,因为正在重组的 DLL pqGraphviz 找不到新的 DLL pqXDot。

      事实证明,重新排序 SUBDIRS 列表就足够了,将所需的 DLL 移到依赖的 DLL 之前:

      SUBDIRS += \
          pqConsole \
          pqConsoleTest \
          pqSource \
          pqSourceTest \
          fdqueens \
          pqXDot \
          pqGraphviz \
          pqGraphvizTest
      

      【讨论】:

        【解决方案5】:

        对于那些对 Qt/QML 项目模板感兴趣的人,我在 GitHub QmlAppTemplate 上发布了一个模板。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-08-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-02
          • 1970-01-01
          • 2021-02-06
          相关资源
          最近更新 更多