概述
- 本文将介绍 find_package 的 config添加依赖库
- module的模式先前已介绍过了, 详见 这里
- 本文演示环境: win11 + cmake 3.23
一个例子
- 这里以 libuv 库为例,
- config模式的文件名需要满足 XXX-config.cmake 或者 XXXConfig.cmake, 所以本例中为 libuv-config.cmake 或者 libuvConfig.cmake
- config.cmake文件中需要指定 头文件所在路径、库文件路径和可执行文件路径
- 范例目录结构, ext目录存放第三方库, src为源文件目录
.
│ CMakeLists.txt
│
├─ext
│ └─toolkits
│ ├─bin
│ │ ├─debug
│ │ │ libuv64D.dll
│ │ │
│ │ └─release
│ │ libuv64.dll
│ │
│ ├─cmake
│ │ libuv-config.cmake
│ │
│ ├─include
│ │ uv.h
│ │
│ └─lib
│ ├─debug
│ │ libuv64D.lib
│ │
│ └─release
│ libuv64.lib
│
└─src
main.cc
libuv-config.cmake 内容
# 方便下游使用
set(libuv_enbale ON)
if (libuv_enbale)
# 使用宏链接固定的属性
macro(_populate_libuv_target_properties TARGET_NAME Configuration LIB_LOCATION IMPLIB_LOCATION LIB_DIR BIN_DIR)
set_property(TARGET ${TARGET_NAME} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
# 指定动态库
set(imported_location "${BIN_DIR}/${LIB_LOCATION}")
set_target_properties(${TARGET_NAME} PROPERTIES "IMPORTED_LOCATION_${Configuration}" ${imported_location})
# 指定库文件
set(imported_implib "${LIB_DIR}/${IMPLIB_LOCATION}")
if(NOT "${IMPLIB_LOCATION}" STREQUAL "")
set_target_properties(${TARGET_NAME} PROPERTIES "IMPORTED_IMPLIB_${Configuration}" ${imported_implib} )
endif()
endmacro()
# ==========================================================
# 建库
# ==========================================================
add_library( libuv::uv SHARED IMPORTED)
# libuv的根目录:
set(libuv_root_dir ${third_lib_dir}/toolkits)
# ==========================================================
# 指定头文件
# ==========================================================
set_property(TARGET libuv::uv PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${libuv_root_dir}/include)
# 使用宏设定库属性
_populate_libuv_target_properties(libuv::uv DEBUG "libuv64D.dll" "libuv64D.lib" ${libuv_root_dir}/lib ${libuv_root_dir}/bin)
_populate_libuv_target_properties(libuv::uv RELEASE "libuv64.dll" "libuv64.lib" ${libuv_root_dir}/lib ${libuv_root_dir}/bin)
endif()
CMakeLists.txt中 引用 cmake文件
find_package
# 使用config模式, 需要指定config所在路径
set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${CMAKE_CURRENT_SOURCE_DIR}/ext/toolkits/cmake")
# 指定第三方库的路径, third_lib_dir 是 libuv-config.cmake中的变量, 用于表示第三方库的所在路径
# third_lib_dir 的赋值需要先于find_package执行
set(third_lib_dir ${CMAKE_CURRENT_SOURCE_DIR}/ext)
# 使用config模式查找第三方库
find_package(libuv REQUIRED)
链接第三方库
# 链接libuv库
if (libuv_enbale)
target_link_libraries(${PROJECT_NAME} PRIVATE libuv::uv)
endif()
完整CMakeLists.txt
cmake_minimum_required( VERSION 3.19)
project(cmake_demo_02)
# 使用config模式, 需要指定config所在路径
set(CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH};${CMAKE_CURRENT_SOURCE_DIR}/ext/toolkits/cmake")
# 指定第三方库的路径, third_lib_dir 是 libuv-config.cmake中的变量, 用于表示第三方库的所在路径
# third_lib_dir 的赋值需要先于find_package执行
set(third_lib_dir ${CMAKE_CURRENT_SOURCE_DIR}/ext)
# 使用config模式查找第三方库
find_package(libuv REQUIRED)
# 创建项目
add_executable(${PROJECT_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cc)
# 链接libuv库
if (libuv_enbale)
target_link_libraries(${PROJECT_NAME} PRIVATE libuv::uv)
endif()
总结
- 相对于module模式, config使用较为方便,可以少写代码, 更方便