如何在CMake中创建并使用部分链接目标文件(VxWorks内核模块开发)
针对VxWorks内核模块的CMake部分链接目标文件构建方案
问题背景
我正在为VxWorks开发内核模块,构建流程需遵循以下步骤:
- 编译源文件
- 对编译生成的目标文件进行部分链接(使用
-r标志),生成单个目标文件 - 对该部分链接目标文件运行自定义脚本,生成
created_by_script.c文件 - 编译
created_by_script.c文件,并与之前生成的部分链接目标文件链接
当前使用CMake 3.25.2,希望避免手动编写链接命令(防止降低可读性),但尝试的方案遇到以下问题:
尝试的代码
add_executable(${TARGET_NAME} all_sources.cpp) set_target_properties(${TARGET_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TARGET_TEMP_DIR}" SUFFIX ".o" ENABLE_EXPORTS TRUE ) # ... 此处添加运行脚本的自定义目标 ... add_executable(${FINAL_TARGET} created_by_script.c $<TARGET_FILE:${TARGET_NAME}> ) target_link_libraries(${FINAL_TARGET} ${TARGET_NAME} ) add_dependencies(${FINAL_TARGET} ${TARGET})
遇到的问题
- 链接可执行文件时无法将生成的目标文件纳入源文件列表
- 使用生成器表达式
$<TARGET_FILE:${TARGET_NAME}>时配置阶段报错,因文件尚未生成,需两次构建才能正常运行
解决方案
方法1:OBJECT库+自定义命令(无需升级CMake)
利用OBJECT库管理编译后的目标文件,通过自定义命令执行部分链接,全程依赖CMake自动管理:
# 1. 将源文件编译为OBJECT库(仅编译,不执行链接) add_library(${OBJ_LIB_NAME} OBJECT all_sources.cpp) # 2. 指定部分链接后目标文件的输出路径 set(PARTIAL_LINKED_O "${TARGET_TEMP_DIR}/partial_linked.o") # 3. 执行部分链接:用编译器驱动调用ld -r,避免直接写ld命令 add_custom_command( OUTPUT ${PARTIAL_LINKED_O} COMMAND ${CMAKE_CXX_COMPILER} -r $<TARGET_OBJECTS:${OBJ_LIB_NAME}> -o ${PARTIAL_LINKED_O} DEPENDS ${OBJ_LIB_NAME} COMMENT "Performing partial link to create ${PARTIAL_LINKED_O}" ) # 4. 运行自定义脚本生成created_by_script.c add_custom_command( OUTPUT created_by_script.c COMMAND ${YOUR_SCRIPT_PATH} ${PARTIAL_LINKED_O} DEPENDS ${PARTIAL_LINKED_O} COMMENT "Running script to generate created_by_script.c" ) # 5. 构建最终可执行文件 add_executable(${FINAL_TARGET} created_by_script.c ${PARTIAL_LINKED_O} ) # 根据需求添加VxWorks依赖库 target_link_libraries(${FINAL_TARGET} PRIVATE ${VXWORKS_REQUIRED_LIBS})
方法2:升级至CMake 3.29+使用LINK_LIBRARY属性
CMake 3.29新增LINK_LIBRARY属性,可直接为静态库指定部分链接标志,语法更简洁:
# 1. 编译源文件为OBJECT库 add_library(${OBJ_LIB_NAME} OBJECT all_sources.cpp) # 2. 创建部分链接的静态库(本质是生成单个.o文件) add_library(${PARTIAL_LIB_NAME} STATIC) target_sources(${PARTIAL_LIB_NAME} PRIVATE $<TARGET_OBJECTS:${OBJ_LIB_NAME}>) set_target_properties(${PARTIAL_LIB_NAME} PROPERTIES LINK_LIBRARY "-r" # 指定部分链接标志 SUFFIX ".o" # 输出文件后缀改为.o ) # 3. 运行脚本生成created_by_script.c add_custom_command( OUTPUT created_by_script.c COMMAND ${YOUR_SCRIPT_PATH} $<TARGET_FILE:${PARTIAL_LIB_NAME}> DEPENDS ${PARTIAL_LIB_NAME} COMMENT "Generating created_by_script.c" ) # 4. 构建最终可执行 add_executable(${FINAL_TARGET} created_by_script.c $<TARGET_FILE:${PARTIAL_LIB_NAME}> ) target_link_libraries(${FINAL_TARGET} PRIVATE ${VXWORKS_REQUIRED_LIBS})
核心优势
- 两种方案均无需手动维护源文件列表,依赖关系由CMake自动处理,一次构建即可完成
- 方法1兼容现有CMake 3.25.2版本,方法2利用新版本特性进一步简化语法,提升可读性
内容的提问来源于stack exchange,提问作者Kecajjo
相关产品推荐
相关产品推荐

