Я хочу создать проект проектов с использованием cmake, который доступен аналогично тому, который используется в Poco.Я считаю, что использование Poco в качестве примера переполнено и ему трудно следовать, поэтому я пытаюсь создать минимальную версию без макросов, чтобы я мог видеть, что происходит.Я создал репозиторий для этого примера здесь.
https://github.com/markeastwood82/nomnoms
Это, и то, что написано ниже, в настоящее время является моим лучшим предположением о том, как решить эту проблему после нескольких дней чтения /борется с "современным CMake", за исключением того, что он не совсем работает.По сути, у меня есть библиотека noms
с компонентами fruit
и veg
, которую я хочу динамически связать из приложения munch
.Я могу установить библиотеку noms
, но не могу найти ее с помощью munch
.Может кто-нибудь помочь мне собрать эту штуку?
Два проекта структурированы следующим образом:
noms
|---- CMakeLists.txt
+---- fruit
| |---- CMakeLists.txt
| |---- fruit-config.cmake.in
| +---- src
| | |----apple.cpp
| |
| +---- include/noms/fruit
| |----apple.h
|
+---- veg
|---- CMakeLists.txt
|---- veg-config.cmake.in
+---- src
| |---- asparagus.cpp
|
+---- include/noms/veg
|---- asparagus.h
munch
|---- CmakeLists.txt
+---- src
|---- main.cpp
Файл noms/CMakeLists.txt
содержит следующее.
cmake_minimum_required(VERSION 3.0)
set(project noms)
set(version 1.0.0)
project(${project})
add_subdirectory(fruit)
add_subdirectory(veg)
# UPDATE: implement advice from Tsyvarev
configure_file(${project}-config.cmake
"${CMAKE_BINARY_DIR}/${project}-config.cmake"
@ONLY
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_BINARY_DIR}/${project}-config-version.cmake"
VERSION ${version}
COMPATIBILITY AnyNewerVersion
)
install(
FILES
"${CMAKE_BINARY_DIR}/${project}-config.cmake"
DESTINATION lib/cmake/${project}
)
Файл noms/fruit/CMakeLists.txt
(и почти идентичный для noms/veg/CMakeLists.txt
) равен
set(component fruit)
add_library(${component} SHARED src/apple.cpp)
# namespaced alias
add_library(${project}::${component} ALIAS ${component})
target_include_directories(${component}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
install(TARGETS ${component} EXPORT ${component}-targets
COMPONENT ${component}
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
install(EXPORT ${component}-targets
FILE "${project}-${component}-targets.cmake"
NAMESPACE ${project}::
DESTINATION lib/cmake/${project}
COMPONENT ${component}
)
# This seems like a kludge, but it does place the file in the correct location
# on my machine (Ubuntu 18.04). Idea taken from Poco
configure_file("${component}-config.cmake.in"
"${CMAKE_BINARY_DIR}/${project}-${component}-config.cmake"
@ONLY
)
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_BINARY_DIR}/${project}-${component}-config-version.cmake"
VERSION ${version}
COMPATIBILITY AnyNewerVersion
)
install(
FILES
"${CMAKE_BINARY_DIR}/${project}-${component}-config.cmake"
"${CMAKE_BINARY_DIR}/${project}-${component}-config-version.cmake"
DESTINATION lib/cmake/${project}
COMPONENT ${component}
)
# DESTINATION will be automatically prefixed by ${CMAKE_INSTALL_PREFIX}
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include
COMPONENT ${component}
DESTINATION ${CMAKE_INSTALL_PREFIX}
)
Наконец, файл для noms/fruit/fruit-config.cmake.in
(и почти идентичный для noms/veg/veg-config.cmake
) равен
include(${CMAKE_CURRENT_LIST_DIR}/noms-fruit-config-version.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/noms-fruit-config-targets.cmake)
Для проекта munch
файл munch/CMakeLists.txt
просто
cmake_minimum_required(VERSION 3.0)
set(project munch)
find_package(noms REQUIRED COMPONENTS fruit)
add_executable(${project} src/main.cpp)
target_include_directories(${project}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:$include>
)
target_link_libraries(${project}
PUBLIC
noms::fruit
)
После установки noms
я пытаюсь собрать munch
, однако cmake не может найти noms-config.cmake
файл.Я не знаю, что это должно содержать, и где я должен действительно поместить это.Я также не уверен, что метод использования configure_file
в noms/<food-type>/CMakeLists.txt
является подходящим, учитывая, что это не требуется в приведенном здесь примере
https://github.com/boostcon/cppnow_presentations_2017/blob/master/05-19-2017_friday/effective_cmake__daniel_pfeifer__cppnow_05-19-2017.pdf
Мой вопроспо сути то же самое, что и здесь, который в настоящее время остается без ответа (принятый ответ неверен, как я прокомментировал в этой теме).На самом деле, чтобы быть справедливым, так как этому потоку 6 лет, он мог быть правильным на момент написания, но, похоже, не использует метод xxx-config.cmake, который сейчас рекомендуется.
Как экспортировать библиотеки с компонентами в CMAKE?
Пожалуйста, не стесняйтесь сообщать мне обо всех моих ошибках или о том, что можно сделать лучше.Спасибо
* ОБНОВЛЕНИЕ *
В дополнение к обновленному файлу noms/CMakeLists.txt
, приведенному выше, я реализовал следующий файл noms/noms-config.cmake
согласно совету @Tsyvarev ниже...
foreach(component ${noms_FIND_COMPONENTS})
include(${CMAKE_CURRENT_LIST_DIR}/noms-${component}-config.cmake)
endforeach()
Полученный код теперь работает, спасибо!