2014-12-17 2 views
2

У меня есть проект, написанный с использованием 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 ...) содержит полезную строку «Если целевая библиотека включена в экспорте, а цель, к которой он связывает не включали поведение не определенно.»Да, в принципе, я ищу обходные пути.

ответ

0

Я закончил с последним target_link_libraries ответом, канавами встроенной в структуру импорта полностью и написание модуля CMake переназначить

optimized;C:/boost/stage/lib/boost_serialization.lib;debug;C:/boost/stage/lib/boost_serialization.libd 

в

$<$<CONFIG:DEBUG>:${Boost_SERIALIZATION_LIBRARY_DEBUG}>$;<$<CONFIG:RELEASE>:${Boost_SERIALIZATION_LIBRARY_RELEASE}> 

Не совсем красиво, но это было лучшее, что я мог придумать. Такие дела.