如何让FetchContent引入的依赖编译为位置无关库?
解决FetchContent引入fmt库时无法设置PIC的问题
错误原因
你在add_subdirectory执行前就尝试修改fmt::fmt目标的属性,此时该目标还未被CMake创建,因此触发找不到目标的错误。
解决方法
方法一:利用fmt自带的PIC控制选项
fmt库原生提供了FMT_PICCMake选项,专门用于启用位置无关代码编译。在add_subdirectory前设置该选项即可:
FetchContent_Declare( fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG e69e5f977d458f2650bb346dadf2ad30c5320281 # 10.2.1 ) FetchContent_GetProperties(fmt) if(NOT fmt_POPULATED) message(STATUS "Fetching fmt...") FetchContent_Populate(fmt) set(FMT_INSTALL ON CACHE INTERNAL "Request installation of the library dependency") set(FMT_PIC ON CACHE INTERNAL "Build fmt with position-independent code") add_subdirectory(${fmt_SOURCE_DIR} ${fmt_BINARY_DIR}) endif()
方法二:延迟设置目标属性到add_subdirectory之后
将set_property语句移至add_subdirectory之后,此时fmt::fmt目标已被创建,可正常修改属性:
FetchContent_Declare( fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG e69e5f977d458f2650bb346dadf2ad30c5320281 # 10.2.1 ) FetchContent_GetProperties(fmt) if(NOT fmt_POPULATED) message(STATUS "Fetching fmt...") FetchContent_Populate(fmt) set(FMT_INSTALL ON CACHE INTERNAL "Request installation of the library dependency") add_subdirectory(${fmt_SOURCE_DIR} ${fmt_BINARY_DIR}) set_property(TARGET fmt::fmt PROPERTY POSITION_INDEPENDENT_CODE ON) endif()
方法三:用FetchContent_MakeAvailable简化流程(CMake 3.14+)
FetchContent_MakeAvailable会自动完成Populate和add_subdirectory操作,可在之后直接设置目标属性:
FetchContent_Declare( fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG e69e5f977d458f2650bb346dadf2ad30c5320281 # 10.2.1 ) # 若需启用FMT_INSTALL,提前设置缓存变量 set(FMT_INSTALL ON CACHE INTERNAL "") FetchContent_MakeAvailable(fmt) set_property(TARGET fmt::fmt PROPERTY POSITION_INDEPENDENT_CODE ON)
备选方案:全局启用PIC
如果你的项目所有目标都需要位置无关代码,可全局设置CMAKE_POSITION_INDEPENDENT_CODE,这样fmt库会自动继承该属性:
# 放在项目最开头或FetchContent配置前 set(CMAKE_POSITION_INDEPENDENT_CODE ON) # 后续的FetchContent配置 FetchContent_Declare( fmt GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_TAG e69e5f977d458f2650bb346dadf2ad30c5320281 # 10.2.1 ) # ... 其余配置
内容的提问来源于stack exchange,提问作者Michał Fita
相关产品推荐
相关产品推荐

