复制编译/链接设置从项目在CMake对象库?



我的情况与添加对象文件依赖关系类似:

…我需要一些对象文件,它们是同一库的一部分,要在其他文件之前编译。

不要试图声明对象文件之间的依赖关系。如果存在有依赖项的文件,使用add_library将它们分离到一个单独的库中,然后使用add_dependencies和target_link_libraries声明该依赖项。这样做没有额外的成本。特别是,考虑一下对象库。

我试图在我的原始项目中实现这一点,在那里我正在使用一个巨大的CMakeLists.txt文件,其中包括&链接器路径可以有条件地插入或删除,我失败了。实际上,CMakeLists.txt文件看起来像这样简化:

project(MY_PROGRAM C CXX ASM)
set(MY_PROGRAM_sources
main.c
file_one.c
file_two.c
)
add_executable(MY_PROGRAM ${MY_PROGRAM_sources})
target_include_directories(MY_PROGRAM PRIVATE
${CUSTOM_PATH}/src/custom/include
...
)
add_compile_options(-Wall
-Wno-format
...
)

target_link_libraries(MY_PROGRAM
somelib1
somelib2
)

使用Unix Makefiles可以很好地构建。

现在,我试着像这样提取file_one和file_two对象:

project(MY_PROGRAM C CXX ASM)
set(MY_PROGRAM_sources
main.c
#file_one.c
#file_two.c
$<TARGET_OBJECTS:SEPFILE_OBJS>
)
add_library(SEPFILE_OBJS OBJECT
file_one.c
file_two.c
)
add_executable(MY_PROGRAM ${MY_PROGRAM_sources})
target_include_directories(MY_PROGRAM PRIVATE
${CUSTOM_PATH}/src/custom/include
...
)
add_compile_options(-Wall
-Wno-format
...
)

target_link_libraries(MY_PROGRAM
somelib1
somelib2
)

cmake在这里通过得很好,但是当我点击make时,一旦file_one.c开始编译,就会出现中断:

...
[  9%] Building C object CMakeFiles/SEPFILE_OBJS.dir/file_one.c.obj
In file included from C:/tmp/file_one.c:14:
C:/tmp/file_one.h:19:10: fatal error: ExoticHeader.h: No such file or directory
19 | #include <ExoticHeader.h>

显然,SEPFILE_OBJS库没有从MY_PROGRAM可执行文件中继承include库或其他编译/链接器设置。

我可能会重复所有的target_*行为SEPFILE_OBJS -但这看起来相当难以管理,加上我原来的CMakeLists.txt是巨大的,我想避免这种工作。

所以有一种方法说CMake "保持相同的编译和链接器设置为MY_PROGRAM的可执行文件,也为对象库SEPFILE_OBJS"?

我会反过来做。我将首先定义一个库部分,包括file_one.cfile_two.c,然后是一个主可执行部分,它将链接到这个库目标。

对于目录结构,我还将遵循以下内容(理想情况下,我会将源文件放在src目录中):

/ MY_PROGRAM
|- include
|   - MY_PROGRAM
|       |- file_one.h
|       - fine_two.h
|- file_one.c
|- file_two.c
|- main.c
- CMakeLists.txt
  1. 把你的头文件放在include/${PROJECT_NAME}文件夹中,并设置一个include_dir变量指向它。
set(include_dir ${PROJECT_SOURCE_DIR}/include/${PROJECT_NAME})
  1. 定义库和应用程序源列表:
set(lib_sources
"${CMAKE_CURRENT_SOURCE_DIR}/file_one.c"
"${CMAKE_CURRENT_SOURCE_DIR}/file_two.c"
)
set(app_sources
"${CMAKE_CURRENT_SOURCE_DIR}/main.cpp"
)
  1. Library部分。定义一个lib_MY_PROGRAM目标,并为它设置包含目录、编译选项和链接库。注意,最好使用target_...特定的命令,而不是更通用的命令,例如add_compile_options:
add_library(lib_${PROJECT_NAME} ${lib_sources})
target_include_directories(lib_${PROJECT_NAME} PUBLIC
"$<BUILD_INTERFACE:${include_dir}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
target_include_directories(lib_${PROJECT_NAME} SYSTEM PUBLIC
${CUSTOM_PATH}/src/custom/include
)
target_compile_options(lib_${PROJECT_NAME} PRIVATE
-Wall
-Wno-format
)
target_link_libraries(lib_${PROJECT_NAME} PRIVATE
somelib1
somelib2
)
  1. 主二进制段:
add_executable(${PROJECT_NAME} ${app_sources})
target_include_directories(${PROJECT_NAME} PUBLIC
"$<BUILD_INTERFACE:${include_dir}>"
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
)
target_compile_options(lib_${PROJECT_NAME} PRIVATE
-Wall
-Wno-format
)
target_link_libraries(${PROJECT_NAME} PRIVATE lib_${PROJECT_NAME})

相关内容

  • 没有找到相关文章

最新更新