CMake 将来自不同 CMakeLists.txt 的对象附加到一个库中
CMake append objects from different CMakeLists.txt into one library
我想从多个子目录中的对象创建一个库,每个子目录都包含自己的 CMakeLists.txt 使用 OBJECT 库技巧来拥有具有不同编译选项的多个目标。
文件如下:
project_dir
|--- subdir1
| |--- src1.c
| |--- CMakeLists.txt
|--- subdir2
| |--- src2.c
| |--- CMakeLists.txt
|--- CMakeLists.txt
全部内容CMakeLists.txt
// project_dir/CMakeLists.txt
// what to put here? to make one single library (mainLib)
// project_dir/subdir1/CMakeLists.txt
add_library(lib11 OBJECT src1.c)
set_target_properties(lib11 PROPERTIES COMPILE_FLAGS "some-flags11")
add_library(lib12 OBJECT src1.c)
set_target_properties(lib12 PROPERTIES COMPILE_FLAGS "some-flags12")
// here I would like to add lib11:objects and lib12:objects to mainLib
// how should it be done?
// project_dir/subdir2/CMakeLists.txt
// *** similar to subdir1 but with src2.c that creates lib21 and lib22
// here I would like to add lib21:objects and lib22:objects to mainLib
// how should it be done?
能独立做平台吗?谢谢。
编辑:
基于CMake: how create a single shared library from all static libraries of subprojects?,我可以将cmake文件改成下面这样,但还是没有解决我的问题。
// project_dir/subdir1/CMakeLists.txt
add_library(lib11 OBJECT src1.c)
set_target_properties(lib11 PROPERTIES COMPILE_FLAGS "some-flags11")
add_library(lib12 OBJECT src1.c)
set_target_properties(lib12 PROPERTIES COMPILE_FLAGS "some-flags12")
add_library(lib1 STATIC $<TARGET_OBJECTS:lib11> $<TARGET_OBJECTS:lib12>)
// Above add_library cannot be OBJECT which would fix my problem.
// how to append the lib1 (lib11 and lib12) to mainLib?
编辑:
更新我的 post,尝试按照答案中的建议链接接口库。
add_library(lib11 OBJECT test1/sub1/src1.c)
set_target_properties(lib11 PROPERTIES COMPILE_FLAGS "-DF1")
add_library(lib12 OBJECT test1/sub1/src1.c)
set_target_properties(lib12 PROPERTIES COMPILE_FLAGS "-DF2")
add_library(lib1 INTERFACE)
target_sources(lib1 INTERFACE $<TARGET_OBJECTS:lib11>)
target_sources(lib1 INTERFACE $<TARGET_OBJECTS:lib12>)
add_library(lib21 OBJECT test1/sub2/src2.c)
set_target_properties(lib21 PROPERTIES COMPILE_FLAGS "-DF1")
add_library(lib22 OBJECT test1/sub2/src2.c)
set_target_properties(lib22 PROPERTIES COMPILE_FLAGS "-DF2")
add_library(lib2 INTERFACE)
target_sources(lib2 INTERFACE $<TARGET_OBJECTS:lib21>)
target_sources(lib2 INTERFACE $<TARGET_OBJECTS:lib22>)
add_library(PARENT INTERFACE)
target_link_libraries(PARENT INTERFACE lib1)
target_link_libraries(PARENT INTERFACE lib2)
add_library(CORE OBJECT src.c)
add_library(GPARENT STATIC $<TARGET_OBJECTS:CORE>)
target_link_libraries(GPARENT INTERFACE PARENT)
几个OBJECT库可以合并到一个INTERFACE库中:
# Create lib1 OBJECT library with some sources, compile flags and so.
add_library(lib1 OBJECT ...)
# Create lib2 OBJECT library with some sources, compile flags and so.
add_library(lib2 OBJECT ...)
# Create INTERFACE library..
add_library(libs INTERFACE)
# .. which combines OBJECT libraries
target_sources(libs INTERFACE $<TARGET_OBJECTS:lib1> $<TARGET_OBJECTS:lib2>)
生成的库可以与标准一起使用 target_link_libraries
:
add_library(mainLib <some-source>)
target_link_libraries(mainLib libs)
可以进一步组合 INTERFACE 库:
# Create libs_another INTERFACE library like 'libs' one
add_library(libs_another INTERFACE)
..
# Combine 'libs' and 'libs_another' together
add_library(upper_level_libs INTERFACE)
target_link_libraries(upper_level_libs INTERFACE libs libs_another)
结果库的 "chain" 可以是任意长度。
虽然这种组合 OBJECT 库的方式看起来很老套,但实际上是 CMake documentation 允许的:
Although object libraries may not be named directly in calls to the target_link_libraries()
command, they can be "linked" indirectly by using an Interface Library whose INTERFACE_SOURCES target property is set to name $<TARGET_OBJECTS:objlib>
.
我只是使用 set
和 PARENT_SCOPE
从所有地方收集对象。
root CMakeLists.txt:
set(OBJECTS)
add_subdirectory(lib1)
add_subdirectory(lib2)
add_library(lib STATIC ${OBJECTS})
CMakeLists.txt 在子目录中:
add_subdirectory(lib11)
add_library(${PROJECT_NAME} OBJECT src1.c)
list(APPEND OBJECTS $<TARGET_OBJECTS:${PROJECT_NAME}>)
set(OBJECTS ${OBJECTS} PARENT_SCOPE)
我想从多个子目录中的对象创建一个库,每个子目录都包含自己的 CMakeLists.txt 使用 OBJECT 库技巧来拥有具有不同编译选项的多个目标。
文件如下:
project_dir
|--- subdir1
| |--- src1.c
| |--- CMakeLists.txt
|--- subdir2
| |--- src2.c
| |--- CMakeLists.txt
|--- CMakeLists.txt
全部内容CMakeLists.txt
// project_dir/CMakeLists.txt
// what to put here? to make one single library (mainLib)
// project_dir/subdir1/CMakeLists.txt
add_library(lib11 OBJECT src1.c)
set_target_properties(lib11 PROPERTIES COMPILE_FLAGS "some-flags11")
add_library(lib12 OBJECT src1.c)
set_target_properties(lib12 PROPERTIES COMPILE_FLAGS "some-flags12")
// here I would like to add lib11:objects and lib12:objects to mainLib
// how should it be done?
// project_dir/subdir2/CMakeLists.txt
// *** similar to subdir1 but with src2.c that creates lib21 and lib22
// here I would like to add lib21:objects and lib22:objects to mainLib
// how should it be done?
能独立做平台吗?谢谢。
编辑: 基于CMake: how create a single shared library from all static libraries of subprojects?,我可以将cmake文件改成下面这样,但还是没有解决我的问题。
// project_dir/subdir1/CMakeLists.txt
add_library(lib11 OBJECT src1.c)
set_target_properties(lib11 PROPERTIES COMPILE_FLAGS "some-flags11")
add_library(lib12 OBJECT src1.c)
set_target_properties(lib12 PROPERTIES COMPILE_FLAGS "some-flags12")
add_library(lib1 STATIC $<TARGET_OBJECTS:lib11> $<TARGET_OBJECTS:lib12>)
// Above add_library cannot be OBJECT which would fix my problem.
// how to append the lib1 (lib11 and lib12) to mainLib?
编辑: 更新我的 post,尝试按照答案中的建议链接接口库。
add_library(lib11 OBJECT test1/sub1/src1.c)
set_target_properties(lib11 PROPERTIES COMPILE_FLAGS "-DF1")
add_library(lib12 OBJECT test1/sub1/src1.c)
set_target_properties(lib12 PROPERTIES COMPILE_FLAGS "-DF2")
add_library(lib1 INTERFACE)
target_sources(lib1 INTERFACE $<TARGET_OBJECTS:lib11>)
target_sources(lib1 INTERFACE $<TARGET_OBJECTS:lib12>)
add_library(lib21 OBJECT test1/sub2/src2.c)
set_target_properties(lib21 PROPERTIES COMPILE_FLAGS "-DF1")
add_library(lib22 OBJECT test1/sub2/src2.c)
set_target_properties(lib22 PROPERTIES COMPILE_FLAGS "-DF2")
add_library(lib2 INTERFACE)
target_sources(lib2 INTERFACE $<TARGET_OBJECTS:lib21>)
target_sources(lib2 INTERFACE $<TARGET_OBJECTS:lib22>)
add_library(PARENT INTERFACE)
target_link_libraries(PARENT INTERFACE lib1)
target_link_libraries(PARENT INTERFACE lib2)
add_library(CORE OBJECT src.c)
add_library(GPARENT STATIC $<TARGET_OBJECTS:CORE>)
target_link_libraries(GPARENT INTERFACE PARENT)
几个OBJECT库可以合并到一个INTERFACE库中:
# Create lib1 OBJECT library with some sources, compile flags and so.
add_library(lib1 OBJECT ...)
# Create lib2 OBJECT library with some sources, compile flags and so.
add_library(lib2 OBJECT ...)
# Create INTERFACE library..
add_library(libs INTERFACE)
# .. which combines OBJECT libraries
target_sources(libs INTERFACE $<TARGET_OBJECTS:lib1> $<TARGET_OBJECTS:lib2>)
生成的库可以与标准一起使用 target_link_libraries
:
add_library(mainLib <some-source>)
target_link_libraries(mainLib libs)
可以进一步组合 INTERFACE 库:
# Create libs_another INTERFACE library like 'libs' one
add_library(libs_another INTERFACE)
..
# Combine 'libs' and 'libs_another' together
add_library(upper_level_libs INTERFACE)
target_link_libraries(upper_level_libs INTERFACE libs libs_another)
结果库的 "chain" 可以是任意长度。
虽然这种组合 OBJECT 库的方式看起来很老套,但实际上是 CMake documentation 允许的:
Although object libraries may not be named directly in calls to the
target_link_libraries()
command, they can be "linked" indirectly by using an Interface Library whose INTERFACE_SOURCES target property is set to name$<TARGET_OBJECTS:objlib>
.
我只是使用 set
和 PARENT_SCOPE
从所有地方收集对象。
root CMakeLists.txt:
set(OBJECTS)
add_subdirectory(lib1)
add_subdirectory(lib2)
add_library(lib STATIC ${OBJECTS})
CMakeLists.txt 在子目录中:
add_subdirectory(lib11)
add_library(${PROJECT_NAME} OBJECT src1.c)
list(APPEND OBJECTS $<TARGET_OBJECTS:${PROJECT_NAME}>)
set(OBJECTS ${OBJECTS} PARENT_SCOPE)