查找库
查找路径
CMAKE_PREFIX_PATH
定义了查找 cmake
库的路径, 可以在编译时指定这个选项,
比如, 在使接非系统目录中安装的 Qt5.12 时, 可以写成:
cmake -DCMAKE_PREFIX_PATH=/path/to/qt5.12/cmake ..
find_package()
最常用的引入第三方库的方式就是使用 find_package()
命令:
find_package(Foo 2.0 REQUIRED)
...
target_link_libraries(Bar Foo::Foo ...)
cmake 项目本身提供了很多常用第三方库的查找脚本, 我们也可以自定义这类脚本. 将这些
脚本放在项目的 cmake
目录, 然后引入整个目录:
set(CMAKE_MODULE_PATH
${CMAKE_SOURCE_DIR}/cmake
${CMAKE_MODULE_PATH})
自定义查找模块
以查找 Foo
库为例, 提供一个基本的模板:
find_path(Foo_INCLUDE_DIR foo.h)
find_library(Foo_LIBRARY foo)
# 将这两个选项标记为高级选项, 让该库默认不在 cmake gui 工具中显示.
mark_as_advanced(Foo_INCLUDE_DIR Foo_LIBRARY)
# 用于提供 Foo_FOUND 变量, 也处理 QUITE/REQUIRED 等选项, 以及库的版本号.
# 比如: find_package(Foo 2.0 REQUIRED)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Foo
REQUIRED_VARS Foo_LIBRARY FOO_INCLUDE_DIR
)
# 添加一个自定义的 target
if(Foo_FOUND AND NOT TARGET Foo::Foo)
add_library(Foo::Foo UNKNOWN IMPORTED)
set_target_properties(Foo::Foo PROPERTIES
IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
IMPORTED_LOCATION "${Foo_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "${Foo_INCLUDE_DIR}"
)
endif()
依赖关系
如果引入的模块比较多的话,相互间的依赖关系就容易复杂,可以使用 cmake 自带的 命令来生成依赖关系图:
cmake --graphviz=foo.dot
生成的 dot
文件可以再转为一般的图片格式。
我们可以将这个步骤固化下来,形成一个 cmake 模块,比如就叫 GeneriteDeps.cmake
:
add_custom_target(generate_deps
COMMAND cmake --graphviz=deps.dot .
COMMAND dot -Tsvg -o deps.svg deps.dot
COMMAND setsid xdg-open deps.svg
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
这样可以在命令行生成:
cmake --build . --target generate_deps
但方便的是,可以直接在 IDE 里触发它。
比如,libuv
库的依赖图是这样的: