Как связать интерфейс со статической библиотекой с CMake
То, что я хочу, - это основная библиотека, основанная на интерфейсе (в будущем их будет больше). Этот интерфейс должен использоваться другими библиотеками, такими как lib1 и lib2. Идея состоит в том, чтобы создать lib1 и lib2 как статические, а затем связать их с mainLib, которая должна быть общей библиотекой.
Для этого примера давайте представим, что я использую только lib1, потому что процесс будет таким же для lib2.
Моя проблема в том, что я не знаю, как правильно связать библиотеки. Сначала мне нужно связать интерфейсную библиотеку с lib1, чтобы она стала новой статической библиотекой, а эту нужно связать с общей библиотекой mainlib.
Я пытаюсь сделать проект со следующей структурой:
mainLib
|-------> CMakeLists.txt
|-------> include
| |----> mainlib.h
|-------> src
| |----> mainlib.cpp
|
|-------> interface
| |----> CMakeLists.txt
| |----> include
| |----> interface.hpp
| |----> src
| |----> interface.cpp
| |----> lib1
| |----> CMakeLists.txt
| |----> include
| |----> lib1.hpp
| |----> src
| |----> lib1.cpp
| |----> lib2
| |----> CMakeLists.txt
| |----> include
| |----> lib2.hpp
| |----> src
| |----> lib2.cpp
Вот версия кода, которую я использую в своих cmakelists:
mainLib
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/interface ${CMAKE_CURRENT_BINARY_DIR}/interface)
set(EXPORTABLE_HEADERS include/mainlib.hpp)
set(SOURCES src/mainlib.cpp)
set(HEADERS ${EXPORTABLE_HEADERS})
add_library(${PROJECT_NAME} SHARED ${SOURCES} ${HEADERS} $<TARGET_OBJECTS:lib1>)
target_include_directories(${PROJECT_NAME}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
INTERFACE $<INSTALL_INTERFACE:include>)
set_target_properties(${PROJECT_NAME} PROPERTIES PUBLIC_HEADER "${EXPORTABLE_HEADERS}")
install(TARGETS ${PROJECT_NAME} EXPORT ${PRODUCT_TARGET}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
PUBLIC_HEADER DESTINATION include/${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} lib1)
install(DIRECTORY interface/include/
DESTINATION "include/${PROJECT_NAME}/interface")
install(DIRECTORY interface/lib1/include/
DESTINATION "include/${PROJECT_NAME}/interface/lib1")
интерфейс
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/lib1 ${CMAKE_CURRENT_BINARY_DIR}/lib1)
add_library(${PROJECT_NAME} INTERFACE)
target_include_directories(${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
install(TARGETS ${PROJECT_NAME} EXPORT ${PRODUCT_TARGET})
lib1
set(EXPORTABLE_HEADERS include/lib1.hpp)
set(SOURCES src/lib1.cpp)
set(HEADERS ${EXPORTABLE_HEADERS})
add_library(${PROJECT_NAME} OBJECT ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME}
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE $<TARGET_PROPERTY:interface,INTERFACE_INCLUDE_DIRECTORIES>)
install(TARGETS ${PROJECT_NAME} EXPORT ${PRODUCT_TARGET})
target_link_libraries(${PROJECT_NAME} INTERFACE interface)
Итак, мне нужно установить все заголовки в соответствии с определенным ${PRODUCT_TARGET}. Но мне нужно сделать это, следуя той же структуре проекта. Прямо сейчас все hpp установлены в одной папке (${PRODUCT_TARGET}).
Интерфейс не связан с моим lib1, потому что ему нужен целевой "интерфейс", которого нет в наборе экспорта, и я не знаю, как его решить, потому что я не могу установить свойства установки в интерфейсе из-за много ошибок.
Однажды lib1 включает интерфейс. Я хочу связать это с mainlib. Я просто делаю с ним target_link_libraries, но я не уверен, что это правильный способ связывания общего доступа со статическими библиотеками.
РЕДАКТИРОВАТЬ: я могу создать разделяемую библиотеку с этим кодом, но когда я пытаюсь использовать его, и я включаю lib.hpp, он не может найти заголовки интерфейса. Я действительно не знаю, где проблема...
Все советы приветствуются.