Есть пара вещей, о которых вы должны знать.Наиболее важно то, что версия LLVM, которую rustc использует по умолчанию, если вы получаете ее из rustup или диспетчера пакетов дистрибутивов, является / не / актуальной версией LLVM и может фактически не быть совместимой с битовым кодом с конкретной версией llvm.Мы решили эту проблему в моем проекте, создав ржавчину из источника с флагом --llvm-root
для настройки.Затем вы можете использовать rustup toolchain link
, чтобы связать ваш встроенный rustc с пользовательским набором инструментов rustup.
Во-вторых, вы можете сделать файлы rustr emit .rlib, содержащие битовый код llvm вместо машинного кода, если вы используете хотя бы rustc 1.34 ипередать флаг -C linker-plugin-lto в rustc.Я также написал следующий скрипт, который может распаковать файл rlib, содержащий объектный код, и упаковать его обратно в файл rlib, содержащий битовый код llvm, если вышеуказанный подход не работает для вас.
#!/bin/bash
dir="$(mktemp -d)"
trap "rm -rf $dir" INT TERM EXIT
archive=$(realpath -m $1)
cd "$dir"
ar x "$archive"
rm ./*.rcgu.o
for file in *.bc.z; do
len=`od -An -t u4 -j 15 -N4 $file`
blen=`od -An -t u8 -j $((len+19)) -N8 $file`
tail -c+$((len+28)) $file | head -c $blen > $file.bc.gz
printf "\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\x00" |cat - $file.bc.gz |gzip -dc > ${file%.bc.z}.o
done
rm *.bc.z
rm *.gz
rm "$archive"
llvm-ar rs "${archive}" ./*
После того, как вы получитеRlib-файлы, вы можете использовать любой инструмент llvm toolchain для них так же, как и для .a-файла, содержащего битовый код llvm.
С точки зрения выполнения окончательной ссылки, следует помнить несколько вещей.,Во-первых, rustc автоматически генерирует символы __rust_alloc
, __rust_alloc_zeroed
, __rust_dealloc
и __rust_realloc
и указывает на них либо __rg_alloc
(и аналогичные __rg_
символы соответственно), что является реализацией GlobalAlloc, которая использует jemalloc bydefault или __rdl_alloc
(и аналогичные __rdl_
символы соответственно), который является системным распределителем, работающим на libc malloc.Вам придется реализовать эти символы самостоятельно, если вы не используете rustc для окончательной ссылки.
Во-вторых, libstd и libcore зависят от некоторых других библиотек, с которыми вам также, вероятно, придется ссылаться.В зависимости от того, какой сегмент стандартной библиотеки вы используете, вы можете обнаружить, что требуются разные наборы библиотек, поэтому я не могу помочь вам без конкретного сообщения об ошибке, но я могу вам сказать, что список библиотек, которые мое приложениев итоге потребовалось было, по порядку: std, core, alloc, unwind, compiler_builtins, panic_abort, backtrace_sys, rustc_demangle
.Если вы используете panic = unwind, вам, очевидно, придется использовать это вместо этого.Если вы обнаружите, что у вас все еще отсутствуют символы, я бы предложил использовать nm, чтобы найти библиотеку, содержащую отсутствующий символ, и выяснить, где он находится в порядке компоновщика с методом проб и ошибок.
Надеюсь, это поможет, поскольку ямы потратили немало усилий на разработку решения именно этой проблемы (хотя и не в целях кросс-компиляции).