Как передать CMAKE_SOURCE_DIR CMake в исходные файлы C++?
В своей программе на C++ я используюдля вывода журнала. Напечатанный путь в настоящее время является абсолютным. Проект создан с помощью CMake. Я хочу сократитьstd::source_location
путь согласно переменной CMake.
Как я могу получить доступCMAKE_SOURCE_DIR
в моем коде на C++?
Я пытался:
add_compile_definitions("-DSOURCE_ROOT=\"${CMAKE_SOURCE_DIR}\"")
Но получил:
error: macro names must be identifiers
У меня установлен CMake 3.22.1, иcmake_minimum_required(VERSION 3.19)
в моем CMakeLists.txt. Я тестировал GCC в Ubuntu, но у меня есть необоснованное подозрение, что я буду наблюдать то же самое в MSVC и clang в Windows.
2 ответа
Общий подход, который вы используетеadd_compile_definitions
работает. Одна из причин, почему это не работает, заключается в том, что вы добавляете префикс-D
вручную, который CMake добавит за вас (его включать не нужно). Другая часть заключается в том, что вам не нужно заключать значение определения в кавычки. CMake автоматически добавит кавычки вокруг значения, если они ему понадобятся (например, если оно содержит пробелы). Итак, вы можете просто сделатьadd_compile_definitions("SOURCE_ROOT=${CMAKE_SOURCE_DIR}")
(или используйтеtarget_compile_definitions
в случае необходимости).
отПримечаниеadd_compile_definition
документы :
Новое в версии 3.26: любой ведущий -D в элементе будет удален.
поэтому я не смог воспроизвести вашу проблему (на момент написания этой статьи у меня изначально была установлена версия 3.26)
Есть и другие способы сделать то, что вы ищете. Вы можете использовать CMake для создания заголовка, содержащего определение макроса, что, я полагаю, может иметь то преимущество, что для установок, если кто-то хочет использовать установку, и макрос должен быть доступен в установленных заголовках, тогда это не будет зависеть от любой механизм, специфичный для CMake. Для этого вы можете использоватьconfigure_file
команда. На самом деле это часть самого первого шага руководства по CMake . Создайте входной файл с включенными охранниками и#define VAR ${CMAKE_SOURCE_DIR}
(или любую другую переменную, которую вы хотите), а затем настройте этот файл. Обычно сгенерированные файлы помещаются где-то вCMAKE_CURRENT_BINARY_DIR
(или какой-либо другой двоичный каталог, напримерPROJECT_BINARY_DIR
илиCMAKE_BINARY_DIR
). Затем добавьте соответствующий каталог включения, используяadd_include_directory
илиinclude_directories
илиtarget_include_directories
.
Обратите внимание, что существуют и другие связанные переменные.CMAKE_SOURCE_DIR
что вам действительно может быть интересно использовать вместо этого, исходя из ваших реальных потребностей:PROJECT_SOURCE_DIR
,CMAKE_CURRENT_SOURCE_DIR
,CMAKE_CURRENT_LIST_DIR
.
Если вы хотите отладить эти вещи, вы можете использовать нестандартный (но поддерживаемый в GCC, Clang и MSVC)#pragma message ...
pragma для печати определения макроса или, если ваш генератор поддерживает это, файл compile_commands.json .
Простой способ:
add_compile_definitions("SOURCE_ROOT=${CMAKE_SOURCE_DIR}")
И тогда вы бы сделали:
#define STRING(x) #x
#define XSTRING(x) STRING(x)
std::cout << XSTRING(SOURCE_ROOT) << '\n';