异构双核嵌入式开发中如何复制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
相关产品推荐
相关产品推荐

