Использовать значение из макроса C / C ++ в CMake - PullRequest
2 голосов
/ 06 апреля 2019

Какой самый простой способ получить значение макроса C / C ++ в переменную CMake?

Учитывая, что я проверяю библиотеку libfoo с заголовком foo.h. Я знаю, foo.h содержит макрос #define FOO_VERSION_MAJOR <version>, где версия - целое или строковое значение. Чтобы извлечь основную версию найденной библиотеки, я хочу использовать значение из этого макроса.

В качестве бонуса, если макрос не найден, это может означать, что версия старше, чем конкретная версия, представляющая макрос версии.

Ответы [ 2 ]

2 голосов
/ 08 апреля 2019

С try_compile и правильной прагмой можно вывести значение макроса препроцессора во время компиляции.CMake может проанализировать вывод для получения желаемого значения.

Фрагмент CMake:

try_compile(result "${CMAKE_BINARY_DIR}"
  SOURCES "${CMAKE_SOURCE_DIR}/foo-version.cpp"
  OUTPUT_VARIABLE fooversion)
string(REGEX MATCH ": [0-9]+" fooversionshort "${fooversion}")
string(REGEX MATCH "[0-9]+" FooMajorVersion "${fooversionshort}")

foo-version.cpp:

#include "foo.h"

/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#pragma message(VALUE(FOO_MAJOR_VERSION))

int main()
{
    return 0;
}

Good:

  • Фактическое значение из переменной, которое может быть вычислено.

Плохо:

  • Вывод макросов поддерживается только некоторыми новыми компиляторами.
  • Анализ выходных данных может прерваться для непроверенных компиляторов, поскольку формат изменяется от версии компилятора к версии компилятора.
  • Вид сложного кода, подробного кода, который трудно читать.
2 голосов
/ 06 апреля 2019

Я бы пошел с file(READ ...), чтобы прочитать заголовок, а затем string(REGEX ...), чтобы извлечь желаемое определение.

Пример кода:

file(READ "foo.h" header)
string(REGEX MATCH "#define FOO_MAJOR_VERSION [0-9]+" macrodef "${header}")
string(REGEX MATCH "[0-9]+" FooMajorVersion "${macrodef}")
...