У меня есть структура, которая зависит от нескольких сторонних библиотек. Я хотел бы легко поделиться своей картой. Например, пользователю нужны только мои включения и добавление моей библиотеки, чтобы использовать мою фреймворк, а не все зависимости.
Я использую CMake для создания моих библиотек, но я все еще пытаюсь понять, как это работает.
Иерархия проекта
test
├── CMakeLists.txt
├── libA
│ ├── CMakeLists.txt
│ ├── libA.cpp
│ ├── libA.hpp
├── libB
│ ├── CMakeLists.txt
│ ├── libB.cpp
│ ├── libB.hpp
└── test
├── CMakeLists.txt
└── main.cpp
LibB зависит от libA, и я хотел бы добавить только libB, чтобы проект работал.
Содержимое основного CMakeLists.txt находится в тесте/:
cmake_minimum_required (VERSION 2.8.11)
project (C CXX)
include(CheckCXXCompilerFlag)
add_subdirectory("libA")
add_subdirectory("libB")
add_subdirectory("test")
Содержимое основного CMakeLists.txt, расположенного в test/libA:
cmake_minimum_required (VERSION 2.8.11)
project (A CXX)
include(CheckCXXCompilerFlag)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14")
file(GLOB SOURCES "*.cpp")
add_library(A STATIC ${SOURCES})
Содержимое основного CMakeLists.txt, расположенного в test/libB:
cmake_minimum_required (VERSION 2.8.11)
project (B CXX)
include(CheckCXXCompilerFlag)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14")
set(CMAKE_EXE_LINKER_FLAGS ${CMAKE_EXE_LINKER_FLAGS} "-static")
include_directories("../libA")
link_directories("../libA")
file(GLOB SOURCES "*.cpp")
add_library(B STATIC ${SOURCES})
target_link_libraries(B A)
Содержимое основного CMakeLists.txt, находящегося в тесте/тесте:
cmake_minimum_required (VERSION 2.8.11)
project (C CXX)
include(CheckCXXCompilerFlag)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++14")
include_directories(../libA)
include_directories(../libB)
link_directories(../build/libB)
link_directories(../build/libA)
add_executable(C main.cpp)
target_link_libraries(C B)
Если я запускаю основной CMake, все работает отлично, автономный файл хорошо сгенерирован. Но если я хочу создать только exe, перейдя в test/test и запустив "cmake. && make", у меня есть неопределенная ссылка на addL (int, int). Чтобы сделать это, я должен добавить target_link_libraries (CA) в конец CMakeLists. Это нормально? Можно ли добавить только основную библиотеку без ее зависимостей?
Вызов команды
target_link_libraries(C B)
имеют разные значения в ваших случаях использования.
В "все" прецедент "B" (ранее) определяется как цель CMake, поэтому CMake знает расположение библиотеки (в этом случае не используются link_directories
) и автоматически распространяет все зависимости библиотеки "B" к исполняемому ", C".
В случае использования "только для теста" нет цели CMake с именем "B", поэтому она просто преобразуется в вариант компоновщика -lB
. Linker ищет соответствующий файл библиотеки в каталогах ссылок (в этом случае необходимы link_directories
). Но информация о зависимостях "B" теряется, поэтому автоматическая привязка к A не выполняется.
Ваш проект может предоставить отдельный сценарий CMake, который может быть включен пользователем вашей библиотеки. Сценарий должен определять все необходимые зависимости. Обычными типами таких скриптов являются FindXXX.cmake
и XXXConfig.cmake
, которые могут быть включены с помощью команды find_package (XXX).