CMAKE使用find_package的config模式添加第三方库

概述

  • 本文将介绍 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使用较为方便,可以少写代码, 更方便
posted @ 2022-04-21 23:28  mohist  阅读(3746)  评论(2编辑  收藏  举报