使用CMAKE静态链接外部库Xerces的正确惯用方法是什么
CMake静态导入XercesC的规范实现方式
首先要明确:find_package 本身支持优先查找静态库,只需要在调用前调整查找优先级参数即可,不需要硬编码路径,也符合CMake官方推荐的配置惯例。
具体实现步骤
- 调用
find_package前临时修改CMAKE_FIND_LIBRARY_SUFFIXES的优先级,让静态库后缀(.a)排在动态库(.so/.dll)前面,注意要先保存原有值,查找完成后恢复,避免影响后续其他库的查找逻辑。 - 正常使用
find_package导入XercesC的官方目标,直接链接即可,不需要手动创建IMPORTED目标。
对应代码示例:
# 保存原有的库查找后缀优先级 set(ORIGINAL_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) # 调整优先级,优先查找静态库 if(WIN32) set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .dll) else() set(CMAKE_FIND_LIBRARY_SUFFIXES .a .so) endif() # 查找XercesC,此时会优先匹配静态库 find_package(XercesC 3.2.0 REQUIRED) # 恢复原来的查找后缀配置,避免影响后续其他库的查找 set(CMAKE_FIND_LIBRARY_SUFFIXES ${ORIGINAL_CMAKE_FIND_LIBRARY_SUFFIXES}) # 正常链接官方导入目标即可,此时链接的就是静态库 add_library(MyLib STATIC <files...>) target_link_libraries(MyLib PRIVATE XercesC::XercesC)
补充说明
- 如果构建环境中XercesC静态库没有安装在系统默认路径,可以在调用
find_package前通过CMAKE_PREFIX_PATH变量指定XercesC的安装根目录,比如set(CMAKE_PREFIX_PATH "/path/to/your/xercesc/install" ${CMAKE_PREFIX_PATH}),完全不需要硬编码库的完整路径。 - 如果需要全局强制所有库都优先静态链接,可以直接在CMake命令行调用时传入参数:
cmake .. -DCMAKE_FIND_LIBRARY_SUFFIXES=".a;.so",不需要修改CMakeLists.txt代码。 - 部分库的官方Config包可能会明确强制使用动态库,遇到这类情况才需要手动创建IMPORTED目标,此时可以配合
find_library来查找静态库路径,避免硬编码:
find_library(XERCESC_STATIC_LIB NAMES xerces-c libxerces-c PATHS /usr/lib/x86_64-linux-gnu PATH_SUFFIXES lib) if(NOT XERCESC_STATIC_LIB) message(FATAL_ERROR "XercesC static library not found") endif() add_library(xercesc STATIC IMPORTED) set_target_properties(xercesc PROPERTIES IMPORTED_LOCATION ${XERCESC_STATIC_LIB} INTERFACE_INCLUDE_DIRECTORIES /usr/include )
这种写法相比直接硬编码路径要灵活很多,也符合CMake的配置逻辑。
内容的提问来源于stack exchange,提问作者Dale
相关产品推荐
相关产品推荐

