CMake configure_file не включен в статическую библиотеку

#c #build #cmake

#c #сборка #cmake

Вопрос:

Структура каталогов выглядит следующим образом:

 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.h libbench_main.a

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

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

Итак, ожидаемый результат, насколько я понимаю, заключается в том, что если я затем сделаю nm с libbench_main.a после его создания я должен увидеть 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})
...
 

Верно? Итак, я настраиваю файл, и после запуска cmake -GNinja .. я project/build получаю это:

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

Все, как и ожидалось. Однако, когда я запускаю ninja bench/libbench_main.a project/build и фактически создаю это, ошибок нет, но nm -ing project/build/bench/libbench_main.a показывает, что символа там нет. Я понятия не имею, как такой простой набор команд может не включить его — в CMake очень ясно, что он предназначен для добавления. build Я должен добавить, что это с чистым каталогом, так что это не будет проблемой.

Это на Ubuntu, если это имеет какое-либо значение, с CMake версии 3.12.

Комментарии:

1. #define BAR 0 является директивой препроцессора C и как таковой не определяет никакого символа. Вам необходимо явно использовать это определение. Например: const extern bool bar(BAR); в вашем *.cc файле

2. @Ptaq666 — Может быть, это было бы лучше дать в качестве ответа? И, кроме того, изменится project/bench/foo.h.in ли использование переменной, подобной bool bar = @BAR@; работе, при условии, что я изменил CMake? Это было бы хорошей идеей?

Ответ №1:

#define BAR 0 является директивой препроцессора C и как таковой не определяет никакого символа. Вам необходимо явно использовать это определение. Например: const extern bool bar(BAR); в вашем bench_main.cc . Он также может быть определен непосредственно в foo.h.in , как bool bar = @BAR@; если бы вы изменили свою строку на CMakeLists.txt set(BAR false) (в нижнем регистре false). Просто помните об ODR при работе с глобальными переменными.

Также нет необходимости включать ваш заголовок в add_library(bench_main STATIC bench_main.cc)