#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)