Я хочу передать строку версии в команде компиляции:
$ g++ -Wall -D VERSION="2013-12-03 02:15:21, commit cb060df" -o main main.cpp
Внутри моего кода у меня есть следующее:
#define TOSTR_(x) #x
#define STRINGIFY(x) TOSTR_(x)
#define VERSION_STR STRINGIFY(VERSION)
Это не работает, потому что VERSION
макрос содержит запятую, так что, похоже, я передаю два аргумента TOSTR()
(по-видимому, VERSION
макрос раскрывается только после его передачи STRINGIFY()
как один уникальный аргумент).
Следующий подход, который я нашел в Вот также не работает:
#define CONCAT(...) __VA_ARGS__
#define TOSTR_(x) #x
#define STRINGIFY(x) TOSTR_(CONCAT(x))
#define VERSION_STR STRINGIFY(VERSION)
потому что это выглядит так же, как
#define VERSIONSTR "CONCAT(2013-12-03 02:15:21, commit cb060df)"
то есть макрос CONCAT()
не расширяется.
Примечание 1: я бы предпочел не проходить С строка в командной строке, потому что строка версии фактически генерируется динамически и может содержать некоторые кавычки. Это означает, что просто писать g++ -D VERSION=\""$(GENERATED_STRING)"\"
вместо строкового аргумента не сработает.
Примечание 2: Я был бы очень рад, если бы кто-нибудь нашел способ сделать это без каких-либо макросов препроцессора.
Вы можете написать TOSTR_
макрос, принимающий переменные аргументы:
#define TOSTR_(x...) #x
#define STRINGIFY(x) TOSTR_(x)
#define VERSION_STR STRINGIFY(VERSION)
Этот код был протестирован и работает на Apple LLVM версии 5.0.
__VA_ARGS__ должен быть в каждом вызове:
#define _STRINGIZE(...) #__VA_ARGS__
#define STRINGIZE(...) _STRINGIZE(__VA_ARGS__)