Как передать 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';
Другие вопросы по тегам