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

异构双核嵌入式开发中如何复制CMake目标?

异构双核场景下复制CMake库目标的解决方案

CMake本身没有内置的copy_target函数,但可以通过自定义函数或对象库的方式实现目标复制,满足异构双核不同编译选项的需求。

方法一:自定义copy_target函数复制目标属性

通过自定义函数提取原目标的核心属性,创建新目标并复制这些属性,再分别设置编译选项。

自定义函数实现

function(copy_target src_target dst_target)
  # 获取原目标类型
  get_target_property(SRC_TARGET_TYPE ${src_target} TYPE)
  # 获取原目标的源文件、包含目录、编译定义、链接依赖
  get_target_property(SRC_SOURCES ${src_target} SOURCES)
  get_target_property(SRC_INCLUDE_DIRS ${src_target} INCLUDE_DIRECTORIES)
  get_target_property(SRC_COMPILE_DEFS ${src_target} COMPILE_DEFINITIONS)
  get_target_property(SRC_LINK_LIBS ${src_target} LINK_LIBRARIES)

  # 根据原目标类型创建新目标
  if(SRC_TARGET_TYPE STREQUAL "STATIC_LIBRARY")
    add_library(${dst_target} STATIC ${SRC_SOURCES})
  elseif(SRC_TARGET_TYPE STREQUAL "SHARED_LIBRARY")
    add_library(${dst_target} SHARED ${SRC_SOURCES})
  else()
    message(FATAL_ERROR "不支持的目标类型: ${SRC_TARGET_TYPE}")
  endif()

  # 复制原目标的属性
  if(SRC_INCLUDE_DIRS)
    target_include_directories(${dst_target} PRIVATE ${SRC_INCLUDE_DIRS})
  endif()
  if(SRC_COMPILE_DEFS)
    target_compile_definitions(${dst_target} PRIVATE ${SRC_COMPILE_DEFS})
  endif()
  if(SRC_LINK_LIBS)
    target_link_libraries(${dst_target} PRIVATE ${SRC_LINK_LIBS})
  endif()
endfunction()

实际使用示例

add_executable(core0 ${CORE0_SRCS})
add_executable(core1 ${CORE1_SRCS})

add_subdirectory(mylib) # 生成静态库目标mylib
copy_target(mylib mylib1) # 复制生成mylib1

# 为两个库分别设置异构核心的编译选项
target_compile_options(mylib PRIVATE ${CORE0_FLAGS})
target_compile_options(mylib1 PRIVATE ${CORE1_FLAGS})

# 链接到各自的核心可执行文件
target_link_libraries(core0 mylib)
target_link_libraries(core1 mylib1)

方法二:使用对象库(Object Libraries)

先编译源文件为对象库(仅生成目标文件,不打包成库),再基于同一对象库生成两个不同的库目标,避免重复编译源文件,提升效率。

实现示例

在mylib目录的CMakeLists.txt中,将原静态库改为对象库:

add_library(mylib_objects OBJECT ${MYLIB_SRCS})
# 设置公共属性(如包含目录、编译定义)
target_include_directories(mylib_objects PUBLIC ${MYLIB_INCLUDE_DIR})
target_compile_definitions(mylib_objects PUBLIC ${MYLIB_DEFINITIONS})

回到主项目的CMakeLists.txt:

add_executable(core0 ${CORE0_SRCS})
add_executable(core1 ${CORE1_SRCS})

add_subdirectory(mylib) # 引入对象库mylib_objects

# 基于对象库生成两个不同的静态库
add_library(mylib STATIC $<TARGET_OBJECTS:mylib_objects>)
add_library(mylib1 STATIC $<TARGET_OBJECTS:mylib_objects>)

# 设置各自的编译选项
target_compile_options(mylib PRIVATE ${CORE0_FLAGS})
target_compile_options(mylib1 PRIVATE ${CORE1_FLAGS})

# 链接到对应核心的可执行文件
target_link_libraries(core0 mylib)
target_link_libraries(core1 mylib1)

关键注意事项

  • 自定义函数可根据需求扩展,比如复制INTERFACE类型的属性(如INTERFACE_INCLUDE_DIRECTORIES),适配更复杂的目标依赖。
  • 编译选项建议使用PRIVATE关键字,避免将核心专属的编译选项传递给其他依赖目标。
  • 对象库方式仅编译一次源文件,适合源文件较多的场景,能显著减少编译时间。

内容的提问来源于stack exchange,提问作者Logiase

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 06:22:41