Параметры:
(Целью является Lego Mindstorm, использующий образ Linux от Ev3dev)
Конфигурация груза:
[package]
name = "ev3"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
jni = "0.19"
ev3dev-lang-rust = { version = "0.12.1", features=["screen"]}
jni_proc_macro= {path= "./jni_proc_macro"}
[lib]
crate-type= ["cdylib"]
[workspace]
members= ["jni_proc_macro"]
Конфигурация сборки:
[build]
target = "armv5te-unknown-linux-gnueabi"
[target.armv5te-unknown-linux-gnueabi]
linker = "rust-lld"
Ошибка сборки:
error: linking with `rust-lld` failed: exit code: 1
|
= note: {...}
= note: rust-lld: error: unable to find library -lgcc_s
rust-lld: error: unable to find library -lutil
rust-lld: error: unable to find library -lrt
rust-lld: error: unable to find library -lpthread
rust-lld: error: unable to find library -lm
rust-lld: error: unable to find library -ldl
rust-lld: error: unable to find library -lc
error: could not compile `ev3` due to previous error
Поскольку ошибка предполагает, что компоновщику не хватает библиотек. Я не нашел четкого решения, где я могу загрузить или предоставить эти зависимости.
Мой вопрос: есть ли другой способ успешно построить это или Б, как мне решить эти зависимости.
В результате должна получиться общая библиотека (.so) для linux и armv5te.
Я просто мельком взглянул на перекресток md. Они говорят, что поддерживают мою цель. Похоже, мне нужно сначала настроить докер. По вашему первому вопросу: я установил набор инструментов, используя rustup target add ... И версию musl, и версию gnu. Оба успешно компилируют staticlib. Musl не поддерживает динамические библиотеки, а gnu выдает указанную выше ошибку.
Да, вам нужно настроить докер; но это может быть проще, поскольку настройка цепочки инструментов вручную может быть головной болью в зависимости от вашей платформы. Это не так просто, как rustup install <triplet>, вам все еще нужен компоновщик armv5te-unknown-linux и библиотеки armv5te-unknown-linux, и вам нужно правильно указать на них (что упрощает кросс-контейнеризация, вы в значительной степени получаете vm вашей целевой машины со всеми этими битами и бобами, установленными и настроенными). Musl также должен поддерживать динамические библиотеки, если я правильно помню, это просто другая библиотека, связанная статически по умолчанию.
Тогда попробую докер. Я подумал, что не так уж сложно найти компоновщика и библиотеки для платформы. Но я ничего не могу найти. Musl, не поддерживающий динамические библиотеки, является проблемой реализации. На ржавом сайте про тулчейны написано, что «некоторые тулчейны жестко закодированы для статической компоновки», и armv5te musl — один из них. В любом случае статическое связывание gnu тоже работает, поэтому я предполагаю, что даже если бы musl поддерживал динамические библиотеки, у меня была бы та же проблема.
Я говорю, что musl статически скомпонован, но статически скомпонована только libc. Все цели musl статически связывают свои libc, цели gnu динамически связывают свои libc. Вы можете связать любые другие собственные динамические библиотеки C, от которых может зависеть ваш код, например openssl, в цели musl.
Я использовал кросс с докером, и это было очень просто. @MeetTitan большое спасибо за помощь. Вы хотите опубликовать это как ответ, или я напишу ответ, зачисляя вас на себя.
Вы должны написать ответ; задокументируйте шаги, которые вы предприняли, и то, что сработало для вас. Кому-то это поможет в поиске в Google, а я подниму вам настроение
Я столкнулся с другой проблемой. Docker-образ cross имеет glibc 2.28 и требует его при использовании динамической библиотеки. Моя цель поддерживает только 2.24. Я понятия не имею, как изменить образ докера, если возможно, вместо этого использовать glibc 2.24.
В этом случае я бы использовал цель musl и не беспокоился о glibc.
Как я упоминал выше, ржавчина armv5te linux musl не поддерживает так как цель. В противном случае я бы согласился на 100%.
(все делается в wsl/linux)
Установить крест на груз
cargo install cross --git https://github.com/cross-rs/cross
Установить докер Клонировать кросс-репозиторий Перейдите в папку докера Создайте новый файл с именем «Dockerfile.armv5te-unknown-linux-gnueabi-cross» Вставьте это в новый файл:
FROM ubuntu:16.04
ARG DEBIAN_FRONTEND=noninteractive
COPY common.sh lib.sh /
RUN /common.sh
COPY cmake.sh /
RUN /cmake.sh
COPY xargo.sh /
RUN /xargo.sh
RUN apt-get update && apt-get install --assume-yes --no-install-recommends \
g++-arm-linux-gnueabi \
crossbuild-essential-armel \
libc6-dev-armel-cross
COPY deny-debian-packages.sh /
RUN TARGET_ARCH=armel /deny-debian-packages.sh \
binutils \
binutils-arm-linux-gnueabi
# Qemu is disabled since we've changed the scripts to require newer Python versions.
#COPY qemu.sh /
#RUN /qemu.sh arm
COPY qemu-runner base-runner.sh /
ENV CROSS_TOOLCHAIN_PREFIX=arm-linux-gnueabi-
ENV CROSS_SYSROOT=/usr/arm-linux-gnueabi
ENV CARGO_TARGET_ARMV5TE_UNKNOWN_LINUX_GNUEABI_LINKER = "$CROSS_TOOLCHAIN_PREFIX"gcc \
CARGO_TARGET_ARMV5TE_UNKNOWN_LINUX_GNUEABI_RUNNER = "/qemu-runner arm" \
AR_armv5te_unknown_linux_gnueabi = "$CROSS_TOOLCHAIN_PREFIX"ar \
CC_armv5te_unknown_linux_gnueabi = "$CROSS_TOOLCHAIN_PREFIX"gcc \
CXX_armv5te_unknown_linux_gnueabi = "$CROSS_TOOLCHAIN_PREFIX"g++ \
BINDGEN_EXTRA_CLANG_ARGS_armv5te_unknown_linux_gnueabi = "--sysroot=$CROSS_SYSROOT" \
QEMU_LD_PREFIX = "$CROSS_SYSROOT" \
RUST_TEST_THREADS=1 \
PKG_CONFIG_PATH = "/usr/lib/arm-linux-gnueabi/pkgconfig/:${PKG_CONFIG_PATH}"
Убедитесь, что в проекте используются символы новой строки «LF». если нет это исправляет. Скомпилируйте пользовательскую сборку cross/docker с помощью следующей команды в корне клонированного репозитория:
cargo build-docker-image armv5te-unknown-linux-gnueabi-cross
Это создаст новый образ докера, который будет использоваться для компиляции кода ржавчины. Затем перейдите в целевую папку проекта и запустите:
export CROSS_TARGET_ARMV5TE_UNKNOWN_LINUX_GNUEABI_IMAGE=ghcr.io/cross-rs/armv5te-unknown-linux-gnueabi-cross:local
(Не закрывайте этот терминал) Теперь добавьте в файл Cargo.toml следующее:
[package.metadata.cross.build]
default-target = "armv5te-unknown-linux-gnueabi"
Теперь вы можете запустить:
cross build
Можно использовать многие опции груза, такие как «--release» (для получения дополнительной информации посмотрите на крестик в титрах)
Я рад, что ты разобрался! Я не думал, что для этого потребуется собственный контейнер докеров, но теперь вы знаете, как кросс-компилировать практически все что угодно.
Настроили ли вы цепочку инструментов целевой платформы? Если нет, то заглядывали ли вы в Cross?