CMAKE中使用外部动态库
CMakeLists.txt使用外部共享库步骤如下:
准备:
- windows: 头文件、
.dll
文件、.a
或.lib
文件; - linux: 头文件、
.so
文件;
配置:
1. windows:
# CMakeLists.txt
target_include_directories(YourTarget PRIVATE /path/to/include)
target_link_libraries(YourTarget PRIVATE /path/to/lib/example.lib)
# 最后确保生成的exe能找到 dll
#法一,将 .dll 复制到exe 目录下
add_custom_command(TARGET jpbalance POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
"${QCUSTOMPLOT_LIB_DIR}/qcustomplotd2.dll"
$<TARGET_FILE_DIR:jpbalance>
)
#法二,让exe 自己查找.dll路径
# 如果需要在运行时自动找到动态库,可以设置 rpath
set_target_properties(jpbalance PROPERTIES INSTALL_RPATH "${QCUSTOMPLOT_LIB_DIR}")
windows 不能仅用
.dll
文件导入库。 链接器在编译时需要导入库(.lib文件)来解析符号。target_link_libraries
命令用于指定目标需要链接的库。共享库(
.so
文件)可以直接使用target_link_libraries
,因为链接器可以直接解析.so
文件中的符号。.so
文件本身包含了足够的信息,使得链接器能够生成正确的导入表。运行时,动态链接器加载共享库并解析符号。
2. Linux:
target_include_directories(YourTarget PRIVATE /path/to/include)
target_link_libraries(YourTarget PRIVATE /path/to/lib/example.so)
此外也可以对那些库文件进行封装后导入:
# 添加 QCustomPlot 动态库
set(QCUSTOMPLOT_LIB_DIR "${CMAKE_SOURCE_DIR}/third_party/qcustomplot/windows/debug")
add_library(QCUSTOMPLOTLIB SHARED IMPORTED) # add_library多用于项目内生成共享库,但这里使用的是它的导入功能。
set_target_properties(QCUSTOMPLOTLIB PROPERTIES
IMPORTED_LOCATION_DEBUG "${QCUSTOMPLOT_LIB_DIR}/exampled.dll"
IMPORTED_IMPLIB_DEBUG "${QCUSTOMPLOT_LIB_DIR}/libexampled.a"
IMPORTED_LOCATION_RELEASE "${QCUSTOMPLOT_LIB_DIR}/example.dll"
IMPORTED_IMPLIB_RELEASE "${QCUSTOMPLOT_LIB_DIR}/libexample.a"
)
target_include_directories(my_app PRIVATE ${QCUSTOMPLOT_LIB_DIR}/include)
target_link_libraries(my_app PRIVATE QCUSTOMPLOTLIB)
更为简便的方法是使用find_package
,这需要额外的配置:
准备:
- windows: 头文件、
.dll
文件、.a
或.lib
文件; - linux: 头文件、
.so
文件; Find<YourLibrary>.cmake
文件
# example.cmake
# - Find example library
#
# This module defines the following variables:
# EXAMPLE_INCLUDE_DIRS - Include directories for QCustomPlot
# EXAMPLE_LIBRARIES - Libraries to link against QCustomPlot
# 设置头文件路径
find_path(EXAMPLE_INCLUDE_DIR example.h
PATHS "${CMAKE_CURRENT_LIST_DIR}"
NO_DEFAULT_PATH
)
# 找库文件
find_library(EXAMPLE_LIBRARY
NAMES exampled
PATHS "${CMAKE_CURRENT_LIST_DIR}/windows/debug"
NO_DEFAULT_PATH
)
# 设置变量
set(EXAMPLE_INCLUDE_DIRS ${EXAMPLE_INCLUDE_DIR })
set(EXAMPLE_LIBRARIES ${EXAMPLE_LIBRARY})
# 使用FindPackageHandleStandardArgs处理查找结果
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Example DEFAULT_MSG EXAMPLE_INCLUDE_DIR EXAMPLE_LIBRARY)
# CMakeLists.txt
list(APPEND CMAKE_MODULE_PATH "path/to/example.cmake")
find_package(Example REQUIRED)
...
target_include_directories(YourTarget PRIVATE ${EXAMPLE_INCLUDE_DIRS })
target_link_libraries(YourTarget PRIVATE ${EXAMPLE_LIBRARIES })
# 后处理,复制.dll到.exe目录
...