You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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})

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:53:22