У меня есть несколько приложений, которые будут использовать одну или несколько общих библиотек. Даже мои библиотеки могут зависеть друг от друга.
Вот дерево файлов:
Libaries/
Library1/
Library1.pro
Library1.cpp
Library1.h
Library2/
Library2.pro
Library2.cpp
Library2.h
Applications/
App1/
App1.pro
main.cpp
App2/
App2.pro
main.cpp
Приложение 1 зависит от библиотеки 1.
Приложение 2 зависит от Library1 и Library2.
Я хотел бы иметь возможность разрабатывать в Qt creator простым способом, когда я открываю Application1, у меня следующее поведение:
Это в основном то, что Visual Studio может делать годами, и для меня это такая базовая вещь, что я не понимаю, что я единственный, у кого есть эта проблема.
Есть ли у вас какие-либо подсказки, как это сделать? Я пробовал разные решения, основанные на SUBDIRS, но я никогда не доходил до всех 3 пунктов выше.
РЕДАКТИРОВАТЬ: Чтобы уточнить немного, я хотел бы иметь возможность сделать что-то вроде:
Application1.pro
include("Library1")
Application2.pro
include("Library1")
include("Library2")
И все работает автоматически. Я нашел решение, которое требует, чтобы файлы в библиотеках знали, что «родитель» делает, включая некоторые, что для меня не имеет смысла, библиотека не должна знать о программе, использующей ее.
Вы можете сделать проект, как это:
Мой проект:
project.pro
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
lib1 \
lib2 \
App
App.pro
QT += core
QT -= gui
include(../lib1/lib1.pri)
include(../lib2/lib2.pri)
TARGET = App
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = appSOURCES += main.cpp
main.cpp
#include <QCoreApplication>
#include "lib1.h"#include "lib2.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
Lib1 lib1();
return a.exec();
}
lib1.pro
QT -= gui
TARGET = lib1
TEMPLATE = lib
DEFINES += LIB1_LIBRARY
SOURCES += lib1.cpp
HEADERS += lib1.h\
lib1_global.h
DESTDIR = ../libs
unix {
target.path = /usr/lib
INSTALLS += target
}
OTHER_FILES += \
lib1.pri
lib1.pri
INCLUDEPATH += $$PWD/
LIBS += -L$$OUT_PWD/../libs/ -llib1
lib2.pro
QT -= gui
TARGET = lib2
TEMPLATE = lib
DEFINES += LIB2_LIBRARY
SOURCES += lib2.cpp
HEADERS += lib2.h\
lib1_global.h
DESTDIR = ../libs
unix {
target.path = /usr/lib
INSTALLS += target
}
OTHER_FILES += \
lib2.pri
lib2.pri
INCLUDEPATH += $$PWD/
LIBS += -L$$OUT_PWD/../libs/ -llib2
App1Solution.pro:
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
../../Libaries/Library1 \
../App1
Место рядом App1.pro
App2Solution.pro:
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS += \
../../Libaries/Library1 \
../../Libaries/Library2 \
../App2
Место рядом App2.pro
и помещает выходной файл .dll / .so в тот же каталог, что и Application1 .exe
Это должно быть сделано по-другому:
DESTDIR
из Library<i>
в зависимости от какой-то переменной.App<i>
профиль.Добавление к Том ответ, полезно иметь возможность ссылаться на заголовки библиотеки, используя квалифицированные префиксы — #include "lib1/lib1.h"
вместо #include "lib1.h"
, В противном случае практически невозможно использовать библиотеки, разработанные независимо, вы всегда будете сталкиваться с конфликтами заголовков.
Есть два способа сделать это.
Во-первых, вы можете добавить общую переменную к каждому файлу проекта верхнего уровня, которая указывает его глубину в дереве проекта, ссылаясь на корень дерева. Затем вы добавляете корень дерева в пути включения и зависимости.
ROOT = ..
include($$ROOT/lib1/lib1.pri)
include($$ROOT/lib2/lib2.pri)
INCLUDEPATH += $$ROOT
DEPENDPATH += $$ROOT
...
Таким образом, отдельные библиотечные проекты не должны указывать свои включения вообще.
В качестве альтернативы INCLUDEPATH
в каждой библиотеке должна быть указана одна папка вверх — не забудьте DEPENDPATH
!
ROOT = ..
INCLUDEPATH += $$PWD/$$ROOT
DEPENDPATH += $$PWD/$$ROOT
...
Тогда внутри main.cpp
Вы можете иметь разумно префиксные включения, которые не будут конфликтовать, даже если lib1
а также lib2
оба предоставляют один и тот же файл:
#include "lib1/easy.h"#include "lib2/easy.h"...