Вставка вывода терминала в исходный файл перед компиляцией

У меня есть проект C++, который хранится в репозитории Bazaar. Этот проект также использует строку #define для отображения номера версии. Кто-то только что спросил, можем ли мы просто связать отображаемый номер версии с номером версии репозитория bzr.

Итак, в псевдо-C псевдо-bash что-то вроде:

#define VERSION_STRING "revision $(bzr revno)"
//...
cout << "Starting " << VERSION_STRING;

Или так. Как вы могли бы ответить на этот вопрос? Запускает ли makefile сценарий, который вставляет вывод этой команды в соответствующий исходный файл? Есть ли макрорешение для этого? И т.д?

Я открыт для любых и всех умных решений, так как я ничего не понимаю в этом. = Д


person musasabi    schedule 15.12.2015    source источник
comment
Вы можете определить макросы с флагом компилятора -D для g++ и clang++: g++ -DVERSION_STRING="revision $(bzr revno)" file.cpp -c -o file.o   -  person BoBTFish    schedule 15.12.2015
comment
Ах, идеально. Будет ли это иметь прецедент над макросом, определенным в источнике с таким же именем? Причина, по которой я спрашиваю, заключается в том, что я полагаю, что должен включить #define VERISON_STRING "000" на случай, если встроенный bash выйдет из строя при вызове g++.   -  person musasabi    schedule 15.12.2015
comment
Развернуто в полный ответ.   -  person BoBTFish    schedule 15.12.2015
comment
Это сработало для вас?   -  person BoBTFish    schedule 16.12.2015
comment
Это произошло! ...Однако оказывается, что структура проекта делает это решение нежизнеспособным. Увы. Но вы точно ответили, так что баллы точно получите. знак равно   -  person musasabi    schedule 16.12.2015


Ответы (1)


Компилятор будет иметь флаг для внешнего определения значения макроса. Для g++ и clang++ это -D:

g++ -DVERSION_STRING="revision $(bzr revno)" file.cpp -c -o file.o

Чтобы получить это в файле в виде строки, вы можете добавить в определение дополнительные кавычки:

g++ -DVERSION_STRING="\"revision $(bzr revno)"\" file.cpp -c -o file.o

или вам нужно знать, как преобразовать это значение в файл, что требует небольшой магии:

#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)

Тогда у вас также может быть значение по умолчанию. Я бы порекомендовал, чтобы компилятор установил другую переменную для той, которую вы используете внутри, это помогает отслеживать:

#include <iostream>

#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)

#ifdef VERSION
#define VERSION_STRING STRINGIFY(VERSION)
#else
#define VERSION_STRING "0.0.0"
#endif

int main()
{
    std::cout << VERSION_STRING << '\n';
}

приводит к:

$ g++ -DVERSION="1.0.0" SO.cpp
$ ./a.out 
1.0.0
$ g++ SO.cpp
$ ./a.out 
0.0.0

Обратите внимание, что $(bzr revno) — это синтаксис для запуска bzr revno и подстановки его вывода в оболочку (синтаксис bash, вероятно, такой же, как и в большинстве других). Как заметил Мусасаби, внутри make-файла синтаксис немного отличается: $(shell bzr revno),

person BoBTFish    schedule 15.12.2015
comment
Единственное изменение заключалось в том, что мне нужно было использовать $(shell bzr revno) в make-файле. знак равно - person musasabi; 16.12.2015