web-dev-qa-db-fra.com

Dépendances du projet Qmake (bibliothèques liées)

J'ai un projet qui relie à un certain nombre de bibliothèques partagées.

Disons que le projet A dépend des projets B et C

Idéalement, je souhaite imposer les dépendances suivantes dans mon fichier de projet:

  1. Reconstruire le projet A si B ou C a été reconstruit depuis la dernière construction du projet A
  2. Utilisez la sortie pour la configuration appropriée (c'est-à-dire si vous générez le projet A en mode débogage, puis utilisez les versions de débogage des bibliothèques pour les projets B et C)

Est-ce que quelqu'un sait comment exprimer explicitement de telles dépendances dans mon fichier de projet?

44
Stick it to THE MAN

Après un peu de frustration avec qmake, j'ai trouvé ce que je pense être la réponse à votre question. Sinon, j'ai appris comment utiliser qmake jusqu'à ce que je trouve quelque chose de mieux, car c'est encore un peu moche. J'ai mis en place un projet de démonstration, voici ma structure de répertoires (les fichiers ont des extensions, les dossiers non):

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

Nous commençons par MyProj.pro en tant que projet subdirs, qui est la clé pour faire ce que vous demandez. Fondamentalement, au lieu de dépendre d'autres projets pour spécifier le débogage/la libération et toutes sortes d'autres indésirables, vous le définissez simplement sur le fichier qmake. Cela ne vous permet pas de créer uniquement ce dont vous avez besoin, mais c'est la meilleure solution que j'ai pu trouver. Voici le contenu:

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 est votre bibliothèque d'objets partagés typique:

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

myproj-app.pro est une application grand public, où la petite astuce de reconstruction en cas de besoin est:

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

J'espère que cela résout votre problème, car je sais qu'il a résolu le mien!

EDIT : J'ai fait un fichier spécialement pour construire les dépendances pour moi, je le stocke dans un dossier frère de chacun de mes projets (enfant du MyProj dans le structure de répertoires spécifiée ci-dessus) appelée 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}
}

Donc, au bas de toutes les applications consommatrices, je peux ajouter les lignes:

DEPENDENCY_LIBRARIES = myproj-core

include(../config/dependencies.pri)

Cela suppose que vous copiez les bibliothèques vers un emplacement partagé et/ou les déplacez selon les besoins, donc ma fonction pourrait ne pas fonctionner pour vous, mais j'ai pensé que je l'ajouterais à la solution.

59
Travis Gockel

J'utilise la solution ci-dessous. Cela fonctionne sans l'utilisation d'un fichier .pro supplémentaire avec un modèle de sous-répertoire.

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
8
Jeroen
  1. Consultez cette question: Forcer la reconnexion lors de la construction dans QT Creator
  2. Essayez d'ajouter quelque chose de similaire à ce code dans votre fichier pro:

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

Ensuite, vous devrez spécifier les dépendances pour chaque 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 
}
5
rpg

J'ai eu ce problème lors de la refactorisation de mon projet, après avoir déplacé dans une nouvelle DLL (pqXDot) une classe réutilisable (de pqGraphviz).

Après avoir ajouté une nouvelle DLL à mon projet et ajouté la nouvelle DLL référence à d'autres DLL et applications qui en avaient besoin) , J'avais en principal .pro:

TEMPLATE = subdirs

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

et la reconstruction a provoqué une erreur de l'éditeur de liens, car pqGraphviz, la DLL en cours de restructuration, ne trouve pas pqXDot, la nouvelle DLL.

Il s'avère qu'il suffit de réorganiser la liste des SUBDIRS, en déplaçant la DLL avant la dépendante):

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

Pour ceux qui sont intéressés par un modèle pour votre projet Qt/QML, j'ai publié un modèle sur GitHub QmlAppTemplate .

1
lucab0ni