使用外部附加头文件构建 cmake 对象库

Posted

技术标签:

【中文标题】使用外部附加头文件构建 cmake 对象库【英文标题】:cmake object library build with external aditional header file 【发布时间】:2020-09-14 09:24:47 【问题描述】:

我想在一个 cmake 对象库 mylib 中构建一个测试可执行文件。这只是一个简单的测试设置。该库包括一个源代码a.c 和一个标头a.h。问题是 cmake 对象库还需要一个额外的配置头文件a_config.h。我没有找到使用附加标头和对象库构建可执行文件的解决方案。 所以我把例子推送到了github:https://github.com/mgiaco/mylib/blob/master/verify/CMakeLists.txt

文件夹结构:

 mylib
     build
     include
       a.h
     src
       a.c
     verify
       source
         a_config.h
         mylib_test.c
         CMakeList.txt   // one
     CMakeList.txt       // two

CMakeList.txt(一)

list (APPEND verify_HEADER $CMAKE_CURRENT_SOURCE_DIR/source)
message("mylib")
list (APPEND verify_SOURCE $CMAKE_CURRENT_SOURCE_DIR/source/mylib_test.c)

add_executable(verify_exe $verify_SOURCE $verify_HEADER)
target_include_directories(verify_exe PUBLIC $verify_HEADER)
target_link_libraries(verify_exe $<TARGET_OBJECTS:mylib_obj>)

CMakeList.txt(二)

cmake_minimum_required(VERSION 3.13)
message("verify")
project(mylib VERSION 1.0.0)

add_library($PROJECT_NAME_obj OBJECT $CMAKE_CURRENT_SOURCE_DIR/src/a.c)

target_include_directories($PROJECT_NAME_obj
    PUBLIC 
        $<BUILD_INTERFACE:$CMAKE_CURRENT_SOURCE_DIR/include>
)
    
add_subdirectory(verify)

运行和错误

C:\workdir\io\mylib\build (master)
λ cmake.exe -DCMAKE_SH="CMAKE_SH-NOTFOUND" -G"MinGW Makefiles" ..
verify
mylib
-- Configuring done
-- Generating done
-- Build files have been written to: C:/workdir/io/mylib/build

C:\workdir\io\mylib\build (master)
λ mingw32-make.exe
[ 33%] Building C object CMakeFiles/mylib_obj.dir/src/a.c.obj
C:\workdir\io\mylib\src\a.c:10:10: fatal error: a_config.h: No such file or directory
 #include "a_config.h"
          ^~~~~~~~~~~~
compilation terminated.
mingw32-make[2]: *** [CMakeFiles\mylib_obj.dir\build.make:63: CMakeFiles/mylib_obj.dir/src/a.c.obj] Error 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:95: CMakeFiles/mylib_obj.dir/all] Error 2
mingw32-make: *** [Makefile:83: all] Error 2

我在这里做错了什么?

谢谢 数学家

【问题讨论】:

那么你想如何编译源文件src/a.c 没有 a_config.h?你认为编译器应该做什么? 我不想在没有配置的情况下编译src/a.c。因此,我想构建一个对象库 - 我教过这在 cmake 中可以使用对象库 to build a object library 不,你没有。你说你不想build。对象库是对象的集合,对象是编译后的源代码。对象库不是这里的解决方案。 还有其他方法可以实现我想要的吗? add_library 为 INTERFACE IMPORTED 左右? 【参考方案1】:

您不想构建源代码,那么创建库不是解决方案 - 库是 编译 源代码的集合。通常我会做一个允许用户轻松添加库的功能:

# mylib/CMakeList.txt

# 'a' as in the library named 'a', not as an article but as a name
set(_add_a_library_source_dir $CMAKE_CURRENT_LIST_DIR)
function(add_a_library name)
   add_library($name $ARGN $_add_a_library_source_dir/src/a.c)
   taget_include_directories($name
       PUBLIC 
           $<BUILD_INTERFACE:$_add_a_library_source_dir/include>
    )
endfunction()

然后图书馆的用户可以这样做:

# mylib/verify/CMakeLists.txt

add_a_library(verify_a_library OBJECT)
# add path to a_config.h to a library
target_include_directories(verify_a_library $CMAKE_CURRENT_SOURCE_DIR)

add_executable(verify_exe $sources)
target_link_libraries(verify_exe verify_a_library)

即使他们需要多个版本。

注意:如果你的cmake足够新,就不用$&lt;TARGET_OBJECTS,直接链接对象库即可。

【讨论】:

以上是关于使用外部附加头文件构建 cmake 对象库的主要内容,如果未能解决你的问题,请参考以下文章

如何在 CMakeLists 中包含库头文件

Android Studio外部本机构建预编译头

[An Introduction to GCC 学习笔记] 06 链接外部库头文件

QtCreator里添加外部第三库头文件路径的方法(.pro文件)

我不能在 C++ 上使用 fmt 库头文件

Android 安装包优化使用 lib7zr.so 动态库处理压缩文件 ( 拷贝 lib7zr.so 动态库头文件到 Android 工程中 | 配置 CMakeLists.txt 构建脚本 )(代码