Nano Hash - криптовалюты, майнинг, программирование

Как я могу скомпилировать программу Rust с пользовательским llc?

У меня есть собственный бэкенд LLVM, и я хотел бы кросс-компилировать Rust для этого пользовательского (nostd) таргета. Я хотел бы скомпилировать программы Rust в два этапа:

  1. Использование rustc для генерации LLVM IR.
  2. Используйте мои собственные opt и llc для преобразования LLVM IR в машинный код.

Я пытался использовать cargo rustc -- --emit=llvm-ir. Я получаю .ll файлов, а затем использую llc для получения .o файлов. Затем таким же образом я перекрестно компилирую libcore. Когда я пытаюсь связать все объекты вместе, он говорит мне о неопределенной ссылке. Я использовал ту же фиксацию libcore и rustc. Это кажется проблемой с версиями LLVM, но я не уверен.

22.10.2018

  • Можете ли вы подробно рассказать о неопределенных ссылках, которые вы получаете? 22.10.2018
  • Этот вопрос является пограничным для SO; слишком мало конкретных деталей, например, какие ссылки не определены. Но я догадываюсь, каким будет ответ. LLVM допускает некоторую степень независимости от целей, но не требует, чтобы каждый интерфейс был на 100% переносим на новые цели. Когда внешний интерфейс менее чем на 100% переносим, ​​вы часто будете видеть неопределенные ссылки для каждого случая зависимости от платформы. Что-то легко поправимо, что-то очень и очень сложно. 22.10.2018
  • @rodrigo Технически это _ZN4core9panicking5panic17he3feabc16d430735E (ожидается в моем проекте) и _ZN4core9panicking5panic17ha8afdce0157d83a3E (предусмотрено в libcore). Отличается только хеш-часть, поэтому я подозреваю, что это какая-то проблема с версиями. 22.10.2018
  • О, однажды у меня была похожая проблема, и я решил ее с помощью -C panic=abort или [profile] panic = 'abort' в Cargo.toml. Может быть, это помогает, хотя я не знаю, почему это не удается в первую очередь. 22.10.2018

Ответы:


1

Есть пара вещей, о которых вы должны знать. Что наиболее важно, версия LLVM, которую rustc использует по умолчанию, если вы получаете ее от rustup или диспетчера пакетов дистрибутива, не является/ не/ фактическим выпуском LLVM и может фактически быть несовместима по битовому коду с конкретным выпуском llvm. Мы решили эту проблему в моем проекте, собрав rust из исходников с флагом --llvm-root для настройки. Затем вы можете использовать rustup toolchain link, чтобы связать ваш собранный rustc с пользовательской цепочкой инструментов rustup.

Во-вторых, вы можете заставить rustc создавать файлы .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 так же, как и с файлом .a, содержащим битовый код llvm.

Что касается выполнения последней ссылки, следует помнить о нескольких вещах. Во-первых, rustc автоматически генерирует символы __rust_alloc, __rust_alloc_zeroed, __rust_dealloc и __rust_realloc и указывает их либо на __rg_alloc (и аналогичные символы __rg_ соответственно), что является реализацией GlobalAlloc, использующей jemalloc по умолчанию, либо на __rdl_alloc (и аналогичные символы __rdl_ соответственно). который является системным распределителем на базе libc malloc. Вам придется реализовать эти символы самостоятельно, если вы не используете rustc для создания окончательной ссылки.

Во-вторых, libstd и libcore зависят от некоторых других библиотек, с которыми вам, вероятно, также придется связываться. В зависимости от того, какой сегмент стандартной библиотеки вы используете, вы можете обнаружить, что требуются разные наборы библиотек, поэтому я не могу вам помочь без конкретного сообщения об ошибке, но я могу сказать вам, что список библиотек, которые мое приложение в итоге потребовалось, по порядку: std, core, alloc, unwind, compiler_builtins, panic_abort, backtrace_sys, rustc_demangle. Если вы используете panic=unwind, вам, очевидно, придется использовать его вместо этого. Если вы обнаружите, что у вас все еще есть отсутствующие символы, я бы предложил использовать nm для поиска библиотеки, содержащей отсутствующий символ, и выяснить, где он находится в порядке компоновщика методом проб и ошибок.

Надеюсь, это поможет, так как я потратил немало усилий на разработку решения именно этой проблемы (хотя и не для целей кросс-компиляции).

31.05.2019
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..