У меня есть проект, написанный с использованием C++ и CMake с использованием Boost, который я пытаюсь сделать автономным бинарным/заголовочным пакетом, чтобы позволить другим людям связываться с моей работой. Для этого я использую установщики cmake. Тем не менее, я сталкиваюсь с проблемами с install(EXPORTS ...)
, когда моя библиотека обращается к внешней библиотеке. В частности, библиотеки Boost и местоположения каталога заголовков жестко закодированы в экспортированный файл, и я не могу понять, как заставить его работать лучше.Экспортный пакет CMake, который опирается на внешнюю библиотеку
Имейте пример. (Непроверенная, если это не ясно, что я могу разработать или исправить.)
CMakeLists.txt:
package(MyLibrary)
set(MyLibrary_VERSION 1.0)
find_component(BOOST 1.55.0 REQUIRED COMPONENTS serialization)
set(INSTALL_INCLUDE_DIR "C:/MyLibrary/include")
set(INSTALL_SRC_DIR "C:/MyLibrary/include")
set(INSTALL_BIN_DIR "C:/MyLibrary/bin")
set(INSTALL_LIB_DIR "C:/MyLibrary/lib")
set(INSTALL_CMAKE_DIR "C:/MyLibrary/cmake")
set(HEADERS myfile.hpp)
set(SOURCES myfile.cpp)
install(FILES ${HEADERS} DESTINATION ${INSTALL_INCLUDE_DIR} COMPONENT headers)
install(FILES ${SOURCES} DESTINATION ${INSTALL_SRC_DIR} COMPONENT sources)
add_library(MyLibrary STATIC
${HEADERS} ${SOURCES})
target_link_libraries(MyLibrary
${Boost_SERIALIZATION_LIBRARY})
target_include_directories(MyLibrary
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR};${Boost_INCLUDE_DIRS}>"
PUBLIC "$<INSTALL_INTERFACE:include;${Boost_INCLUDE_DIRS}>")
install(TARGETS MyLibrary EXPORT MyLibrary-depends
DESTINATION ${INSTALL_LIB_DIR} COMPONENT libraries)
configure_package_config_file(MyLibraryConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/MyLibraryConfig.cmake"
INSTALL_DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/MyLibraryConfigVersion.cmake"
VERSION ${MyLibrary_VERSION}
COMPATIBILITY AnyNewerVersion)
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/MyLibraryConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/MyLibraryConfigVersion.cmake"
DESTINATION "${INSTALL_CMAKE_DIR}")
install(EXPORT MyLibrary-depends
FILE MyLibrary-depends.cmake
DESTINATION "${INSTALL_CMAKE_DIR}")
MyLibraryConfig.cmake.in
@[email protected]
if (NOT MyLibrary_FOUND)
set(MyLibrary_FOUND 1)
find_package(Boost 1.55.0 COMPONENTS SERIALIZATION)
include(MyLibrary-depends.cmake)
# random directory stuff, etc.
endif()
Этот вопрос что MyProject-depends.cmake
заканчивается значением ${Boost_INCLUDE_DIRS}
и ${Boost_SERIALIZATION_LIBRARY}
, которые являются абсолютными путями и завинчивают переносимость установки.
Я попробовал несколько вещей, ни один из которых, кажется, исправить все мои проблемы.
target_include_directories
:
Я пытался уйти от $
, с надеждой, что MyProject-depends.cmake
бы подобрать значение переменной Boost_INCLUDE_DIRS
на включают времени:
target_include_directories(MyProject
PUBLIC "$<INSTALL_INTERFACE:include;\${Boost_INCLUDE_DIRS}>"
...)
Но, конечно же, INSTALL_INTERFACE
думает, что ${Boost_INCLUDE_DIRS}
- это относительный путь и префиксы его с {$_IMPORT_DIR}
, который разбивает все.
я могу канаву MyProject-depends.cmake
маршрут полностью, и добавить его в MyProjectConfig.cmake.in
:
CMakeLists.txt:
target_include_directories(MyProject
PUBLIC "$<INSTALL_INTERFACE:include>"
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR};${Boost_INCLUDE_DIRS>")
и MyProjectConfig.cmake.in:
include(MyProject-depends.cmake)
set_target_properties(MyProject
INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}")
Этот вариант кажется работать, но это боль.
target_link_libraries
:
У меня больше проблем с библиотекой ссылок.Я попробовал тот же трюк, перемещение материала в MyProjectConfig.cmake.in
файл для большего контроля, но
target_link_libraries(MyProject ${Boost_SERIALIZATION_LIBRARIES})
не работает на привозных библиотеках и
set_target_properties(MyProject INTERFACE_LINK_LIBRARIES ${Boost_SERIALIZATION_LIBRARY})
терпит неудачу, потому что ${Boost_SERIALIZATION_LIBRARY}
расширяется к чему-то вроде optimized;C:/boost/stage/lib/boost_serialization.lib;debug;C:/boost/stage/lib/boost_serialization.libd
и set_target_properties
не нравится ключевые слова.
Теперь я остался с какой-то переназначения с помощью
"$<$<CONFIG:DEBUG>:${Boost_SERIALIZATION_LIBRARY_DEBUG}>$;<$<CONFIG:RELEASE>:${Boost_SERIALIZATION_LIBRARY_RELEASE}>"
, но я также должен обнаружить ли не указана библиотека отладки ... что это выполнимо, но, кажется, как яка бритья мне.
Итак, мудрецы стека ... любые советы? Есть ли какой-то очевидный модуль или умный метод, который я пропускаю? (И спасибо за то, что весь путь через
также: документация CMake install(EXPORTS ...)
содержит полезную строку «Если целевая библиотека включена в экспорте, а цель, к которой он связывает не включали поведение не определенно.»Да, в принципе, я ищу обходные пути.