Связывание Rust с C: неопределенная ссылка на функции __aeabi
Я работаю над проектом, использующим Rust на встроенном устройстве, где я пытаюсь написать функции на Rust, которые можно вызывать из C. Я компилирую проект без стандартной библиотеки, более или менее следуя этому руководству: Embedded Rust Right Сейчас!
Мой код Rust прекрасно компилируется в файлы.o, но у меня возникают проблемы при попытке связать вместе объектные файлы C и Rust, используя arm-none-eabi-ld. Я получаю несколько ошибок, подобных этим:
rustfunc.o: In function `func':
rustfunc.0.rs:(.text.hash+0x18): undefined reference to `__aeabi_memclr8'
...
/rust/src/libcore/slice.rs:1446: undefined reference to `__aeabi_memcpy'
/rust/src/libcore/fmt/num.rs:196: undefined reference to `__aeabi_memclr4'
Больше всего меня озадачивает то, что, хотя я просто связываю объектные файлы, ошибки ссылаются как на мой код Rust, так и на код из libcore.
Кто-нибудь знает, что означают эти ошибки и почему компоновщик не может решить эти проблемы? Спасибо!
1 ответ
Проблема в том, что LLVM, который ваш rustc
(и, возможно, ваш cc
), ссылается на встроенные компиляторы или иногда на встроенные функции, которые представляют собой небольшие вспомогательные процедуры, которые, как предполагает компилятор, будут оптимизированы для целевой платформы.
Обычно они поставляются с компилятором, поэтому вы увидите много комментариев в сети, говорящих: "Почему бы вам не связаться с libgcc.a
Msgstr "Это кажется бесполезным для голых проектов и на самом деле не сработает, потому что LLVM вызывает немного другие встроенные функции, чем gcc.
Вы можете предоставить реализации для этих подпрограмм, и настоящая голая операционная система, вероятно, должна потратить около пяти минут на ее обдумывание. Вы можете написать их в сборке или Rust:
// Use this at your peril
#[no_mangle]
pub unsafe extern fn __aeabi_memclr4(s: *mut u8, n: usize) -> *mut u8 {
let mut i = 0;
while i < n {
*s.offset(i as isize) = 0u8;
i += 1;
}
return s;
}
После того, как вы закончили мечтать, вы приступили к компиляции llvmcompiler-rt
(эквивалентно libgcc.a) для вашей цели, и вы связываете это.
До тех пор rustc
а также multirust
Чтобы увеличить поддержку установки дополнительных целей для кросс-компиляции, вам нужно скачать исходный код Rust и попытаться собрать кросс-компилятор и библиотеки (включая compiler-rt
) сам.
В настоящее время arm-none-eabi
не является поддерживаемой целью, и построение является грубым по ряду причин, в том числе arm-none-eabi-gcc
не будет связывать исполняемый файл, на котором настаивает jemalloc Руста. Мой обходной путь - собрать исходные файлы с compiler-rt
и построить и связать их по отдельности.