开发者

Qmake project dependencies (linked libraries)

I have a project that links to a number of shared libraries.

Lets say project A depends on projects B and C

Ideally, I want to impose the following dependencies in my project file:

  1. Rebuild project A if either B or C has been rebuilt since last time project A was built
  2. Use the output for the relevant configuration (i.e. if building project A in debug mode, then use the debug versions of the libs for project B and C)

Does anyone know how I may explicitly express such dependencies in my开发者_开发技巧 project file?


After quite a bit of frustration with qmake, I have found what I think is the answer to your question. If not, then I have learned the way that I will use qmake until I find something better, because this is still a little bit ugly. I set up a demo project, this is my directory structure (files have extensions, folders do not):

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

We start with MyProj.pro as a subdirs project, which is the key to doing what you ask. Basically, instead of depending on other projects to specify debug/release and all sorts of other junk, you just set it on the one qmake file. It doesn't let you make only what you need, but it's the best solution I could come up with. Here are the contents:

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 is your typical shared object library:

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

myproj-app.pro is consumer application, where the little rebuild-when-needed trick is:

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

I hope this solves your problem, as I know it solved mine!

EDIT: I made a file specifically for building the dependencies for me, I store it in a sibling folder of each of my projects (child of the MyProj in the directory structure specified above) called dependencies.pri:

# 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}
}

So at the bottom of all the consuming applications, I can add the lines:

DEPENDENCY_LIBRARIES = myproj-core

include(../config/dependencies.pri)

This assumes that you are copying the libraries to some shared location and/or moving them around as needed, so my function might not work for you, but I figured I would add it to the solution.


I use the solution below. This works without the usage of an extra .pro file with subdir template.

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


  1. Check out this question: Force relink when building in QT Creator
  2. Try adding something similar to this code to your pro file:

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

Then you will have to specify the dependencies for each configuration:

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 
}


I had this problem when refactoring my project, after I moved in a new DLL (pqXDot) a reusable class (from pqGraphviz).

After adding a new DLL to my project, and adding the new DLL reference to others DLL and applications that needed it, I had in main .pro:

TEMPLATE = subdirs

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

and the rebuild caused a linker error, because pqGraphviz, the DLL being restructured, can't find pqXDot, the new DLL.

It turns out it's sufficient to reorder the SUBDIRS list, moving the required DLL before the dependent one:

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


For those that are interested into a template for your Qt/QML project, I have published one template on GitHub QmlAppTemplate.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜