2015-07-18 2 views
3

Я работаю над проектом, используя Rust на встроенном устройстве, где я пытаюсь написать функции в Rust, которые можно вызвать из C. Я скомпилирую проект без стандартной библиотеки, более или менее следуя этому руководству: Embedded Rust Right Now!Связывание ржавчины с C: неопределенные ссылки на функции '__aeabi'

Код моей ржавчины компилируется только в файлы .o, но у меня возникают проблемы при попытке связать файлы объектов C и Rust вместе с помощью arm-none- EABI-ЛД. Я получаю несколько ошибок, подобные этим:

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

Похоже, что пропущен в ABI. Я бы проверял, совместимы они или нужны обертки. Символы sems являются некоторыми специальными версиями libmcc 'memclr' (который является специальным вариантом' memset') и 'memcpy' – Olaf

+0

Как новичок в этом, не могли бы вы указать мне в направлении поиска этого? – Jambaman

+1

Это зависит от настроек ОС и ЦП и компилятора. Для ARM текущий PCS - это AAPCS и спецификации ABI (бесплатная загрузка), но gcc также позволяет некоторым другим. Это справедливо для C и некоторых других языков, но не имеет понятия о Rust. – Olaf

ответ

3

Проблема заключается в том, что LLVM, что ваш rustc (и, возможно, ваш cc) построен на ссылки компилятор встроенных команды или иногда Intrinsics, которые представляют собой небольшие вспомогательные процедуры, которые принимают на себя компилятор были оптимизированы для цели Платформа.

Обычно они поставляются вместе с компилятором, так что вы увидите много из commentary на «Чистом высказывании», почему бы вам не связаться с libgcc.a ». Это кажется бесполезным для проектов с белым металлом, и на самом деле это не сработает, потому что LLVM называет несколько разных встроенных, чем gcc.

Вы можете обеспечить реализацию этих подпрограмм, и настоящая голая металлическая ОС должна, вероятно, потратить около пяти минут на ее рассмотрение. Вы можете написать их в сборке или Руст:

// 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; 
} 

После того, как вы закончили мечтать, вы приступили к составлению llvm's compiler-rt (эквивалент libgcc.a) для вашей цели, и вы связать это.

До rustc и multirust увеличивают свою поддержку installing extra targets for cross-compilation, вы должны загрузить исходный код ржавчины и попытаться построить кросс-компилятор и библиотеки (включая compiler-rt) самостоятельно.

В настоящее время arm-none-eabi не поддерживается, а здание является грубым по списку причин, в том числе, что arm-none-eabi-gcc не свяжет исполняемый файл, на который настаивает Jemalloc Rust. Мое обходное решение - собрать исходные файлы с compiler-rt и построить и связать их по отдельности.

+0

Я собираюсь отметить это как принятый ответ, так как он объясняет, почему я столкнулся с проблемами. Определенно дайте мне знать, если вы придумаете полное решение! Благодарю. – Jambaman

+0

Неплохо, но я начинаю рвение/llvm/os. –

+0

Благодаря @Shepmaster для некоторых качественных изменений и поднятия бара. –