CMake configure_file 未包含在静态库中

Posted

技术标签:

【中文标题】CMake configure_file 未包含在静态库中【英文标题】:CMake configure_file not being included in static library 【发布时间】:2019-04-18 12:09:52 【问题描述】:

目录结构如下:

project
   | ...
   | CMakeLists.txt
   | - build/
         | - bench/
               | libbench_main.a  // static library containing symbols
               | foo.h
   | - bench/
         | - bench_main.cc
         | - CMakeLists.txt
         | - foo.h.in

我想在include foo.hinclude foo.hlibbench_main.a

// project/bench/bench_main.cc
#include "foo.h"
...

// project/bench/foo.h.in
#cmakedefine01 BAR

因此,据我所知,如果我在构建 libbench_main.a 后执行nm,我应该会看到BAR 符号。

就 CMake 而言,CMake 对我来说似乎也很简单:

// project/bench/CMakeLists.txt
...
set(BAR FALSE)
configure_file(foo.h.in foo.h @ONLY)
add_library(bench_main STATIC bench_main.cc foo.h)
target_include_directories(bench_main PRIVATE $CMAKE_CURRENT_BINARY_DIR)
...

对吗?所以我配置了文件,在project/build 中运行cmake -GNinja .. 后,我得到了这个:

// project/build/bench/foo.h
#define BAR 0

一切都如预期的那样。但是,当我在project/build 中运行ninja bench/libbench_main.a 并实际构建它时,没有错误,但nm-ing project/build/bench/libbench_main.a 显示该符号不存在。我知道这么简单的命令集怎么可能无法包含它 - 在 CMake 中非常清楚地表明它是要添加的。这是一个干净的build 目录,我应该添加,所以这不会是问题。

这是在 Ubuntu 上,如果这有什么不同的话,使用 CMake 版本 3.12。

【问题讨论】:

#define BAR 0 是 C 预处理器指令,因此不定义任何符号。您需要明确使用此定义。例如:const extern bool bar(BAR); 在您的 *.cc 文件中 @Ptaq666 - 也许作为答案会更好?顺便说一句,假设我更改了 CMake,是否可以将 project/bench/foo.h.in 更改为使用 bool bar = @BAR@; 之类的变量?这是个好主意吗? 【参考方案1】:

#define BAR 0 是 C 预处理器指令,因此不定义任何符号。您需要明确使用此定义。例如:const extern bool bar(BAR); 在您的bench_main.cc 中。如果您将CMakeLists.txt 中的行更改为set(BAR false)(小写错误),它也可以直接在foo.h.in 中定义为bool bar = @BAR@;。使用全局变量时,请记住 ODR。

也没有必要在add_library(bench_main STATIC bench_main.cc) 中包含您的标题

【讨论】:

以上是关于CMake configure_file 未包含在静态库中的主要内容,如果未能解决你的问题,请参考以下文章

cmake configure_file 评价

cmake学习之-configure_file

cmake基础教程(42)configure_file动态生成头文件

cmake基础教程(42)configure_file动态生成头文件

CMake configure_file没有源代码构建

复制文件并将它们包含在 CPack 存档中