Вставить строку во время ссылки - PullRequest
0 голосов
/ 10 мая 2019

Я хочу определить внешний глобальный символ (const char*), используемый программой. Добавьте символ во время связывания с заданным значением. Это полезно, например, для фиксации хэша или времени сборки.

Я нашел --defsym, который делает что-то еще. Линкер Go поддерживает эту функцию с помощью опции -X. (Да, я знаю, строки Go управляются, но я говорю о простых старых строках c с нулевым символом в конце)

Например:

extern const char *git_commit;

int main(int argc, char *argv[]) {
    puts(git_commit);
    return 0;
}
gcc main.o -Wl<something here that adds git_commit and set it to '84e5...'>

Мне известны подход config.h и создание объектных файлов, содержащих эти строки . Но его 2019 года знают. Такая простая задача должна быть легкой.

Изменить более точный вопрос Есть ли эквивалентная опция в gcc / binutils для опции Go 101er -X.

Ответы [ 4 ]

4 голосов
/ 10 мая 2019

Существует изменение, чтобы сделать это во время компиляции / предварительной обработки, рассмотрим это:

#include <stdio.h>

const char * git_commit = GIT_COMMIT;

int main(int argc, char ** argv) {
        puts(git_commit);
        return 0;
}

и в командной строке:

gcc -o test test.c -DGIT_COMMIT="\"This is a test\""

при условии, что выиспользуете компилятор GCC.

1 голос
/ 10 мая 2019

В одну сторону:

echo "char const* git_commit = \"$(git rev-parse HEAD)\";" > git_commit.c
gcc -c -o git_commit.o git_commit.c
gcc -o main main.o git_commit.o

Когда вы реализуете это в make-файле, вам может потребоваться воссоздать git_commit.c только при изменении ревизии, чтобы она не связывалась с ним при каждом вызове make.

0 голосов
/ 10 мая 2019

Вы можете встроить его в файл ресурса, например:

GitInfoHTML               HTML                    "GitInfo.html"

Это будет помещено в исполняемый файл компоновщиком (в время ссылки ) и затем может быть загружено.

Для получения дополнительной информации см .: https://docs.microsoft.com/en-us/cpp/windows/resource-files-visual-studio?view=vs-2019

0 голосов
/ 10 мая 2019

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

Вероятно, самый простой способ получить это - простовызовите компилятор, чтобы скомпилировать определение вашей переменной с контентом, передаваемым из макроса, определенного через командную строку, как уже предлагалось в других ответах.Если вы хотите избежать создания временных исходных файлов, 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также.Наконец, вы можете также написать свой собственный инструмент, который напрямую записывает объектный файл, содержащий подходящее определение символа.Однако учтите, что в конце дня вы пытаетесь создать объектный файл, который можно связать с другими объектными файлами, составляющими вашу программу.Простое использование того же компилятора, который вы используете для компиляции остальной части кода, возможно, самый надежный способ сделать это.С другими решениями вам всегда нужно будет вручную убедиться, что объектные файлы совместимы с точки зрения целевой архитектуры, структуры памяти,…

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...