Я не знаю ни одного способа сделать то, что вы хотите сделать напрямую, с помощью флага, используя один из часто используемых линкеров.В общем, если вы хотите связать определение такого объекта с вашей программой, вам нужно будет предоставить объектный файл, содержащий подходящее определение символа.
Вероятно, самый простой способ получить это - простовызовите компилятор, чтобы скомпилировать определение вашей переменной с контентом, передаваемым из макроса, определенного через командную строку, как уже предлагалось в других ответах.Если вы хотите избежать создания временных исходных файлов, gcc также может получать входные данные прямо из stdin:
echo "const char git_commit[] = GIT_COMMIT;" | gcc -DGIT_COMMIT=\"asdf\" -c -o git_commit.obj -xc++ -
И в своем коде вы просто объявляете его как
extern const char git_commit[];
Примечание: I 'м, используя const char git_commit[]
вместо const char* git_commit
.Таким образом, git_commit
будет непосредственно массивом подходящего размера, инициализированным для хранения содержимого хэша коммита.const char* git_commit
, с другой стороны, создаст объект глобального указателя, инициализированный для хранения адреса отдельного строкового литерального объекта, что означает, что вы вводите ненужную косвенность.Не то, чтобы здесь это действительно имело значение, но это также ничего не стоит, чтобы пропустить неэффективность, какой бы маленькой она ни была ...
Также была бы утилита objcopy
, которую можно использовать для переноса.произвольный двоичный контент в объектном файле, см., например, здесь Как мне вставить содержимое двоичного файла в исполняемый файл на Mac OS X? Может даже оказаться возможным передать ввод в objcopy напрямую через stdinтакже.Наконец, вы можете также написать свой собственный инструмент, который напрямую записывает объектный файл, содержащий подходящее определение символа.Однако учтите, что в конце дня вы пытаетесь создать объектный файл, который можно связать с другими объектными файлами, составляющими вашу программу.Простое использование того же компилятора, который вы используете для компиляции остальной части кода, возможно, самый надежный способ сделать это.С другими решениями вам всегда нужно будет вручную убедиться, что объектные файлы совместимы с точки зрения целевой архитектуры, структуры памяти,…