[英]How to configure project with COMPONENTS in cmake
我想使用 cmake 創建一個項目項目,它的訪問方式與 Poco 使用的方式類似。 我發現使用 Poco 作為示例很擁擠且難以理解,因此我嘗試創建一個最小版本,沒有宏,以便我可以看到發生了什么。 我在這里為這個例子構建了一個存儲庫。
https://github.com/markeastwood82/nomnoms
這個,以及下面寫的內容,是我在閱讀/解決“現代 CMake”幾天后如何解決這個問題的最佳猜測,除了它不太有效。 本質上,我有一個包含fruit
和veg
組件的庫noms
,我希望從應用程序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
文件。 我不知道它應該包含什么,也不知道我應該把它放在哪里。 我也不確定在noms/<food-type>/CMakeLists.txt
中使用configure_file
的方法是否合適,因為在此處的示例中似乎noms/<food-type>/CMakeLists.txt
我的問題與此處提出的問題基本相同,目前未得到答復(已接受的答案不正確,正如我在該線程中所評論的那樣)。 實際上公平地說,由於該線程已有 6 年歷史,因此在撰寫本文時可能是正確的,但似乎沒有使用現在推薦的 xxx-config.cmake 方法。
請隨時提出我犯的任何錯誤,或者任何可以做得更好的事情。 謝謝
* 更新 *
除了上面更新的noms/CMakeLists.txt
文件之外,我還根據下面@Tsyvarev 的建議實現了以下noms/noms-config.cmake
文件......
foreach(component ${noms_FIND_COMPONENTS})
include(${CMAKE_CURRENT_LIST_DIR}/noms-${component}-config.cmake)
endforeach()
生成的代碼現在可以工作了,謝謝!
CMake 不會自動處理COMPONENTS
列表。 它將這個任務留給noms-config.cmake
腳本,當一個人發出命令時,它會被搜索和執行
find_package(noms COMPONENTS fruit veg)
從find_package文檔:
在配置模式下,
find_package
處理REQUIRED
、QUIET
和[version]
選項,但將其留給包配置文件以對包有意義的方式處理組件。
在此配置文件中,您可以從noms_FIND_COMPONENTS
變量中提取請求的組件列表(通過COMPONENTS
選項給find_package()
),並執行適當的操作。 例如:
noms-config.cmake :
foreach(component ${noms_FIND_COMPONENTS})
# For requested component, execute its "config" script
include(${CMAKE_CURRENT_LIST_DIR}/${component}-config.cmake)
endforeach()
這意味着,您將腳本noms-config.cmake
安裝到lib/cmake/noms
子目錄,靠近您已安裝在項目中的其他.cmake
腳本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.