Генерация исполняемого файла Rust из битового кода LLVM

Как я могу сгенерировать исполняемый файл приложения, написанного на Rust, который был скомпилирован в биткод LLVM-IR?

Если я попытаюсь скомпилировать файл .bc с помощью rustc, он скажет мне stream did not contain valid UTF-8, и я не могу понять, есть ли для этого конкретная опция в rustc.

В основном я хочу добиться этого: program.rs -> program.bc -> program. Где program — конечный исполняемый файл. Какие шаги я должен сделать, чтобы достичь этого?


person Leonardo Marques    schedule 24.05.2016    source источник
comment
rustc — это компилятор Rust, он не компилирует другие входные форматы. Почему бы не использовать LLVM llc или эквивалент, если у вас есть биткод?   -  person Shepmaster    schedule 24.05.2016
comment
Это было мое первоначальное предположение, но я не очень хорошо знаком с llc и нашел только это: -filetype — выберите тип файла (не все типы поддерживаются всеми целями): = asm — создайте файл сборки ('.s') =obj — Создать собственный объектный файл ('.o') =null — Ничего не создавать, для тестирования производительности. Ни один из них не показался мне тем, что я искал.   -  person Leonardo Marques    schedule 24.05.2016


Ответы (2)


Начиная с этого исходного кода:

fn main() {
    println!("Hello, world!");
}

Вы можете создать LLVM промежуточное представление (IR) или битовый код (BC):

# IR in hello.ll
rustc hello.rs --emit=llvm-ir
# BC in hello.bc
rustc hello.rs --emit=llvm-bc

Затем эти файлы могут быть обработаны LLVM для создания сборки или объектного файла:

# Assembly in hello.s
llc hello.bc
# Object in hello.o
llc hello.bc --filetype=obj

Затем вам нужно связать файлы для создания исполняемого файла. Для этого требуется привязка к стандартным библиотекам Rust. Путь зависит от платформы и версии:

cc -L/path/to/stage2/lib/rustlib/x86_64-apple-darwin/lib/ -lstd-f4a73f2c70e583e1 -o hello2 hello.o

Затем вы можете запустить программу:

DYLD_LIBRARY_PATH=/path/to/stage2/lib/rustlib/x86_64-apple-darwin/lib/ ./hello2

В этом ответе есть решения для macOS, но общие концепции должны распространяться на Linux и Windows. Реализация будет немного отличаться для Linux и, вероятно, сильно для Windows. Примечательно, что я использую DYLD_LIBRARY_PATH, так как я динамически связался со стандартной библиотекой Rust, которой нет в моем обычном пути поиска библиотек.

Обратите внимание, что файлы LLVM IR и BC не имеют самых сильных гарантий прямой/обратной совместимости. Это означает, что вам необходимо использовать версию llc, совместимую с используемой вами версией rustc. Для этого ответа я использовал llc, созданный моей локальной сборкой для разработки Rust:

% rustc --version --verbose
rustc 1.53.0 (53cb7b09b 2021-06-17)
binary: rustc
commit-hash: 53cb7b09b00cbea8754ffb78e7e3cb521cb8af4b
commit-date: 2021-06-17
host: x86_64-apple-darwin
release: 1.53.0
LLVM version: 12.0.1

% llc --version
LLVM (http://llvm.org/):
  LLVM version 12.0.1-rust-dev
  Optimized build.
  Default target: x86_64-apple-darwin20.5.0
  Host CPU: skylake

Смотрите также:

person Shepmaster    schedule 24.05.2016
comment
Для чего нужен DYLD_LIBRARY_PATH=/path/to/stage2/lib/rustlib/x86_64-apple-darwin/lib/? - person Leonardo Marques; 24.05.2016
comment
@LeonardoMarques Когда я связал объектные файлы со стандартной библиотекой, использовалось динамическое связывание. Поскольку стандартной библиотеки Rust нет в моем пути поиска библиотек по умолчанию, я должен сообщить динамическому компоновщику, где ее найти, во время выполнения программы. Вместо этого вы можете создать статический двоичный файл (что немного сложно для меня в OS X, поэтому я пропустил его), или если бы стандартная библиотека была в пути поиска, компоновщик времени выполнения знал бы, где ее найти. - person Shepmaster; 24.05.2016
comment
Разве -lstd-2f39a9bd не должен иметь расширение .dylib? Почему сложно создать статический двоичный файл? - person Leonardo Marques; 24.05.2016
comment
@LeonardoMarques именно так работает флаг -l. Он добавляет lib и добавляет .dylib (или .so, или что-то еще, что подходит для платформы). - person Shepmaster; 24.05.2016
comment
Почему сложно создать статический двоичный файл? (Я также работаю над MacOSX) - person Leonardo Marques; 24.05.2016
comment
@LeonardoMarques Apple не поддерживает статически связанные двоичные файлы в Mac OS X. См. также Создание статической сборки Mac OS X C. В Stack Overflow подробно описаны многие из этих деталей. :-) - person Shepmaster; 24.05.2016
comment
@Shepmaster Я получаю сообщение об ошибке, когда пытаюсь воспроизвести ваши команды (llc hello.bc). llc: error: llc: hello.bc: error: Unknown attribute kind (61) (Producer: 'LLVM11.0.0-rust-1.49.0-stable' Reader: 'LLVM 7.1.0') - person rambi; 14.07.2021
comment
@rambi, как указано в сообщении об ошибке, LLVM 7.1.0 не может прочитать данные из LLVM 11.0.0. Вам нужно будет сопоставить версии. - person Shepmaster; 14.07.2021
comment
Благодарность ! Я видел этот полезный пост: stackoverflow.com/questions/15836430/ - person rambi; 14.07.2021

Это не очевидно, так как документация LLVM очень неясна, но clang скомпилирует как файлы LLVM IR («.ll»), так и файлы битового кода («.bc»), и свяжет их с вашими системными библиотеками. .

В Linux с Rust 1.9:

clang -dynamic-linker /usr/local/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-d16b8f0e.so  hello.ll -o hello
person Peter Caven    schedule 26.05.2016