且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

当您需要指定 CMAKE_MODULE_PATH 时,find_package() 有什么用?

更新时间:2023-12-04 07:57:58

Command find_package 有两种模式:Module 模式和 Config 模式.你正试图当您确实需要 Config 模式时,请使用 Module 模式.

Command find_package has two modes: Module mode and Config mode. You are trying to use Module mode when you actually need Config mode.

查找项目中的.cmake文件.像这样:

Find<package>.cmake file located within your project. Something like this:

CMakeLists.txt
cmake/FindFoo.cmake
cmake/FindBoo.cmake

CMakeLists.txt 内容:

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(Foo REQUIRED) # FOO_INCLUDE_DIR, FOO_LIBRARIES
find_package(Boo REQUIRED) # BOO_INCLUDE_DIR, BOO_LIBRARIES

include_directories("${FOO_INCLUDE_DIR}")
include_directories("${BOO_INCLUDE_DIR}")
add_executable(Bar Bar.hpp Bar.cpp)
target_link_libraries(Bar ${FOO_LIBRARIES} ${BOO_LIBRARIES})

请注意,CMAKE_MODULE_PATH 具有高优先级,当您需要重写标准Find.cmake 文件时可能会很有用.

Note that CMAKE_MODULE_PATH has high priority and may be usefull when you need to rewrite standard Find<package>.cmake file.

Config.cmake 文件位于外部并由 install 生成其他项目的命令(例如Foo).

<package>Config.cmake file located outside and produced by install command of other project (Foo for example).

foo 库:

> cat CMakeLists.txt 
cmake_minimum_required(VERSION 2.8)
project(Foo)

add_library(foo Foo.hpp Foo.cpp)
install(FILES Foo.hpp DESTINATION include)
install(TARGETS foo DESTINATION lib)
install(FILES FooConfig.cmake DESTINATION lib/cmake/Foo)

配置文件的简化版:

> cat FooConfig.cmake 
add_library(foo STATIC IMPORTED)
find_library(FOO_LIBRARY_PATH foo HINTS "${CMAKE_CURRENT_LIST_DIR}/../../")
set_target_properties(foo PROPERTIES IMPORTED_LOCATION "${FOO_LIBRARY_PATH}")

默认项目安装在CMAKE_INSTALL_PREFIX目录:

> cmake -H. -B_builds
> cmake --build _builds --target install
-- Install configuration: ""
-- Installing: /usr/local/include/Foo.hpp
-- Installing: /usr/local/lib/libfoo.a
-- Installing: /usr/local/lib/cmake/Foo/FooConfig.cmake

配置模式(使用)

使用 find_package(... CONFIG)FooConfig.cmake 包含在导入的目标 foo 中:

Config mode (use)

Use find_package(... CONFIG) to include FooConfig.cmake with imported target foo:

> cat CMakeLists.txt 
cmake_minimum_required(VERSION 2.8)
project(Boo)

# import library target `foo`
find_package(Foo CONFIG REQUIRED)

add_executable(boo Boo.cpp Boo.hpp)
target_link_libraries(boo foo)
> cmake -H. -B_builds -DCMAKE_VERBOSE_MAKEFILE=ON
> cmake --build _builds
Linking CXX executable Boo
/usr/bin/c++ ... -o Boo /usr/local/lib/libfoo.a

请注意,导入的目标高度可配置.请参阅我的答案.

Note that imported target is highly configurable. See my answer.

更新