簡體   English   中英

如何在 cmake 中使用 COMPONENTS 配置項目

[英]How to configure project with COMPONENTS in cmake

我想使用 cmake 創建一個項目項目,它的訪問方式與 Poco 使用的方式類似。 我發現使用 Poco 作為示例很擁擠且難以理解,因此我嘗試創建一個最小版本,沒有宏,以便我可以看到發生了什么。 我在這里為這個例子構建了一個存儲庫。

https://github.com/markeastwood82/nomnoms

這個,以及下面寫的內容,是我在閱讀/解決“現代 CMake”幾天后如何解決這個問題的最佳猜測,除了它不太有效。 本質上,我有一個包含fruitveg組件的庫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

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文件之外,我還根據下面@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處理REQUIREDQUIET[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM