Вмъкване на крайния изход в изходния файл преди компилация

Имам C++ проект, който случайно се съхранява в базар репо. Този проект също използва низ #define'd, за да покаже номера на версията си. Някой току-що попита дали можем просто да свържем този показан номер на версия с номера на ревизията на bzr repo.

И така, в псевдо-C, псевдо-баш, нещо като:

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

Или нещо такова. Как бихте могли да отговорите на този въпрос? Makefile изпълнява ли скрипт, който вмъква резултата от тази команда в съответния изходен файл? Има ли макро решение за това? и т.н.

Отворен съм за всички и всички умни решения, тъй като черпя образована празна информация за това. =D


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, вероятно същият в повечето други). От рамките на makefile, както посочи musasabi, синтаксисът е малко по-различен: $(shell bzr revno),

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