Я хочу, чтобы clang компилировал мой C/C++
код в LLVM
байт-код, а не в двоичный исполняемый файл. Как я могу этого достичь? И если я получу LLVM
байт-код, как я могу взять его для дальнейшей компиляции в двоичный исполняемый файл.
По сути, я хочу добавить свой собственный код в LLVM
байт-код перед компиляцией в двоичный исполняемый файл.
Ответы:
Учитывая некоторый файл C / C ++
foo.c
:Создает
foo.ll
файл IR LLVM.-emit-llvm
Вариант также может быть передан в компилятор переднего конца непосредственно, а не водитель с помощью-cc1
:Производит
foo.ll
с ИК.-cc1
добавляет несколько интересных вариантов, как-ast-print
. Проверьте-cc1 --help
для более подробной информации.Чтобы скомпилировать LLVM IR далее для сборки, используйте
llc
инструмент:Производит
foo.s
со сборкой (в зависимости от архитектуры машины, на которой вы его запускаете).llc
является одним из инструментов LLVM - вот его документация .источник
использование
источник
.o
должен ссылаться на двоичные объектные файлы,.s
на файлы сборки и что-то еще (по соглашению.ll
) на IR-файлы LLVM. В противном случае легко запутаться. Clang / LLVM теперь не имеет своего собственного компоновщика для бинарных объектов (хотя один находится в разработке). Линкер LLVMllvm-ld
просто объединяет несколько файлов IR в один.bc
используется; Кроме того, имейте в виду, что онllvm-ld
может выступать в качестве внешнего интерфейса для системного инструментария, т.е. мой предыдущий ответ с использованиемllvm-ld -native
должен работать, как и ожидалось ....foo.bc
это файл битового кода LLVMclang -emit-llvm -o test.bc -c test.c && file test.bc: test.bc: LLVM IR bitcode
.Если у вас есть несколько исходных файлов, вы, вероятно, на самом деле хотите использовать оптимизацию по ссылочному времени для вывода одного файла битового кода для всей программы. Другие ответы приведут к тому, что вы получите файл с битовым кодом для каждого исходного файла.
Вместо этого вы хотите скомпилировать с оптимизацией времени соединения
и для последнего шага связывания добавьте аргумент -Wl, -plugin-opt = Кроме того-emit-llvm
Это дает вам как скомпилированную программу, так и соответствующий ей битовый код (program.bc). Затем вы можете изменить program.bc любым удобным вам способом и перекомпилировать измененную программу в любое время, выполнив
хотя имейте в виду, что на этом шаге необходимо снова включить все необходимые флаги компоновщика (для внешних библиотек и т. д.).
Обратите внимание, что вам нужно использовать золотой компоновщик, чтобы это работало. Если вы хотите заставить clang использовать определенный компоновщик, создайте символическую ссылку на этот компоновщик с именем «ld» в специальной директории с именем «fakebin» где-нибудь на вашем компьютере и добавьте параметр
к любым шагам связывания выше.
источник
Если у вас есть несколько файлов и вы не хотите вводить каждый файл, я бы порекомендовал вам выполнить следующие простые шаги (я использую,
clang-3.8
но вы можете использовать любую другую версию):создать все
.ll
файлысвязать их в один
(Необязательно) Оптимизируйте свой код (возможно, анализ псевдонимов)
Создать сборку (создает
optimised.s
файл)Создать исполняемый файл (по имени
a.out
)источник
-S
опцию (в шаге 2), я указываю, что я хотел бы произвести вывод в LLVM IR. По сути, поместите все файлы * .ll в один. Я делаю это, чтобы убедиться, что оптимизация действительно меняет код, то естьsingle.ll
иoptimised.ll
теперь должна выглядеть по-другому (с точки зрения кода), и вы также можете показать отчет, чтобы увидеть, есть ли какая-либо разница.-basicaaa
неправильный флаг,-basicaa
должен использоваться вместоВы читали
clang
документацию ? Вы, наверное, ищете-emit-llvm
.источник