英文:
Cross compiling alsa crate for armv7
问题
我正在尝试为amrv7-unknown-linux-gnueabihf
交叉编译基于alsa创建的Rust二进制文件。
对于交叉编译,我正在使用Cross和自定义的Dockerfile来获取所需的依赖项。
我遵循了这篇帖子中的说明,通过添加以下.cargo/config.toml
文件:
但这导致了以下错误,pkg-config
抱怨找不到alsa库:
你对如何修复这个错误有任何线索吗?
我尝试过以下方法:
- 如此描述添加了特性标志"alsa-backend"。
- 像同一帖子中描述的那样定制了
.cargo/config.toml
。 - 查看了所有与在armv7上交叉编译alsa相关的stackoverflow帖子,但我没有找到任何有用的回复,即使这些帖子有回复。
英文:
I'm trying to cross-compile for amrv7-unknown-linux-gnueabihf
a rust binary based on the alsa crate.
For the cross-compilation, I'm using Cross with a custom Dockerfile to have the required dependencies:
FROM ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:0.2.5
RUN dpkg --add-architecture armhf && \
apt-get update && \
apt-get install -y --no-install-recommends \
libasound2-dev:armhf \
libudev-dev:armhf \
pkg-config:armhf
RUN apt-get autoremove -y && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*
COPY .cargo/config.toml /root/.cargo/config.toml
I followed the instruction from this post about cross compiling for arm, by adding the following .cargo/config.toml
file:
[build]
[target.arm-unknown-linux-gnueabihf.libasound]
linker = "arm-linux-gnueabihf-gcc"
rustc-link-lib = ["libasound"]
rustc-link-search = ["/usr/lib/arm-linux-gnueabihf"]
But this leads to the following error, with pkg-config
complaining about not finding the alsa library:
➜ alsa-cross git:(master) ✗ cross build --target armv7-unknown-linux-gnueabihf --features "alsa-backend" -v
+ cargo metadata --format-version 1 --filter-platform armv7-unknown-linux-gnueabihf --features alsa-backend
+ rustc --print sysroot
+ rustup toolchain list
+ rustup target list --toolchain stable-x86_64-unknown-linux-gnu
+ rustup component list --toolchain stable-x86_64-unknown-linux-gnu
+ /usr/bin/docker
+ "/gitrepos/alsa-cross" /usr/bin/docker build --label 'org.cross-rs.for-cross-target=armv7-unknown-linux-gnueabihf' --label 'org.cross-rs.workspace_root=/gitrepos/alsa-cross' --tag cross-custom-alsa-cross:armv7-unknown-linux-gnueabihf-7235a --build-arg 'CROSS_DEB_ARCH=armhf' --build-arg 'CROSS_BASE_IMAGE=ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:0.2.5' --file ./Dockerfile /gitrepos/alsa-cross
Sending build context to Docker daemon 30.33MB
Step 1/6 : FROM ghcr.io/cross-rs/armv7-unknown-linux-gnueabihf:0.2.5
---> 32cf786140f9
Step 2/6 : RUN dpkg --add-architecture armhf && apt-get update && apt-get install -y --no-install-recommends libasound2-dev:armhf libudev-dev:armhf pkg-config:armhf
---> Using cache
---> 8288951e6f23
Step 3/6 : RUN apt-get autoremove -y && apt-get clean && rm -rf /var/lib/apt/lists/*
---> Using cache
---> e0ba37616482
Step 4/6 : COPY .cargo/config.toml /root/.cargo/config.toml
---> Using cache
---> 68d32d3aa8f2
Step 5/6 : LABEL org.cross-rs.for-cross-target=armv7-unknown-linux-gnueabihf
---> Using cache
---> 42924a9ff180
Step 6/6 : LABEL org.cross-rs.workspace_root=/gitrepos/alsa-cross
---> Using cache
---> 98094b203092
[Warning] One or more build-args [CROSS_DEB_ARCH CROSS_BASE_IMAGE] were not consumed
Successfully built 98094b203092
Successfully tagged cross-custom-alsa-cross:armv7-unknown-linux-gnueabihf-7235a
+ /usr/bin/docker run --userns host -e 'PKG_CONFIG_ALLOW_CROSS=1' -e 'XARGO_HOME=/xargo' -e 'CARGO_HOME=/cargo' -e 'CARGO_TARGET_DIR=/target' -e 'CROSS_RUNNER=' -e TERM -e 'USER=florian' --rm --user 1000:1000 -v /home/florian/.xargo:/xargo:z -v /home/florian/.cargo:/cargo:z -v /cargo/bin -v /gitrepos/alsa-cross:/project:z -v /home/florian/.rustup/toolchains/stable-x86_64-unknown-linux-gnu:/rust:z,ro -v /gitrepos/alsa-cross/target:/target:z -w /project -i -t cross-custom-alsa-cross:armv7-unknown-linux-gnueabihf-7235a sh -c 'PATH=$PATH:/rust/bin cargo build --target armv7-unknown-linux-gnueabihf --features alsa-backend -v'
Fresh pkg-config v0.3.27
Fresh libc v0.2.145
Fresh bitflags v1.3.2
Fresh cfg-if v1.0.0
Compiling alsa-sys v0.3.1
Fresh nix v0.24.3
Running `/target/debug/build/alsa-sys-5b7e484eb5de5d94/build-script-build`
error: failed to run custom build command for `alsa-sys v0.3.1`
Caused by:
process didn't exit successfully: `/target/debug/build/alsa-sys-5b7e484eb5de5d94/build-script-build` (exit status: 101)
--- stdout
cargo:rerun-if-env-changed=ALSA_NO_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_armv7-unknown-linux-gnueabihf
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_armv7_unknown_linux_gnueabihf
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS
cargo:rerun-if-env-changed=PKG_CONFIG_armv7-unknown-linux-gnueabihf
cargo:rerun-if-env-changed=PKG_CONFIG_armv7_unknown_linux_gnueabihf
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG
cargo:rerun-if-env-changed=PKG_CONFIG
cargo:rerun-if-env-changed=ALSA_STATIC
cargo:rerun-if-env-changed=ALSA_DYNAMIC
cargo:rerun-if-env-changed=PKG_CONFIG_ALL_STATIC
cargo:rerun-if-env-changed=PKG_CONFIG_ALL_DYNAMIC
cargo:rerun-if-env-changed=PKG_CONFIG_PATH_armv7-unknown-linux-gnueabihf
cargo:rerun-if-env-changed=PKG_CONFIG_PATH_armv7_unknown_linux_gnueabihf
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_PATH
cargo:rerun-if-env-changed=PKG_CONFIG_PATH
cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_armv7-unknown-linux-gnueabihf
cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR_armv7_unknown_linux_gnueabihf
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_LIBDIR
cargo:rerun-if-env-changed=PKG_CONFIG_LIBDIR
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_armv7-unknown-linux-gnueabihf
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR_armv7_unknown_linux_gnueabihf
cargo:rerun-if-env-changed=TARGET_PKG_CONFIG_SYSROOT_DIR
cargo:rerun-if-env-changed=PKG_CONFIG_SYSROOT_DIR
--- stderr
thread 'main' panicked at '`PKG_CONFIG_ALLOW_SYSTEM_CFLAGS="1" PKG_CONFIG_ALLOW_SYSTEM_LIBS="1" PKG_CONFIG_PATH="/usr/lib/arm-linux-gnueabihf/pkgconfig/:" "pkg-config" "--libs" "--cflags" "alsa"` did not exit successfully: exit status: 2
error: could not find system library 'alsa' required by the 'alsa-sys' crate
--- stderr
/usr/bin/pkg-config: 1: /usr/bin/pkg-config: Syntax error: word unexpected (expecting ")")
', /cargo/registry/src/index.crates.io-6f17d22bba15001f/alsa-sys-0.3.1/build.rs:13:18
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
+ rustup component list --toolchain stable-x86_64-unknown-linux-gnu
Do you have any lead about how to fix this error ?
I have tried the following:
- Adding the feature flag "alsa-backend" as described here
- Custom
.cargo/config.toml
as described in the same post - Look at all the stackoverflow posts related to cross compiling alsa to armv7, but I didn't find any useful responses, when the post had responses at all.
答案1
得分: 1
我确信使用cross
有一种方法,但我个人未能成功实现。
然而,我通过直接使用cargo的交叉编译功能来实现了这一点。
创建以下Dockerfile
:
ARG DEBIAN_VERSION="11.7"
FROM debian:${DEBIAN_VERSION}
# 安装目标编译目标
RUN dpkg --add-architecture armhf
# 添加交叉编译器和依赖项
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --yes \
curl git crossbuild-essential-armhf pkg-config \
libasound2-dev:armhf \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# 在全局范围内安装Rust
ENV RUSTUP_HOME=/opt/rust
ENV CARGO_HOME=/opt/rust
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path
ENV PATH="/opt/rust/bin:${PATH}"
# 添加交叉编译目标并设置为默认值
RUN rustup target add armv7-unknown-linux-gnueabihf
ENV CARGO_BUILD_TARGET=armv7-unknown-linux-gnueabihf
# 为交叉编译配置Rust链接器
ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=/usr/bin/arm-linux-gnueabihf-gcc
# 为交叉编译配置pkg-config
ENV PKG_CONFIG_ALLOW_CROSS=1/
ENV PKG_CONFIG_PATH_armv7_unknown_linux_gnueabihf=/usr/lib/arm-linux-gnueabihf/pkgconfig/
# 将工作目录设置为/src,我们将在其中挂载项目
WORKDIR /src
构建Docker容器(我在这里命名为armv7_cross
):
docker build -t armv7_cross .
然后,在您的项目目录内,您可以执行:
docker run -v $PWD:/src --user $(id -u):$(id -g) --rm -ti armv7_cross cargo build
这应该像正常情况下一样构建,并且您应该在target/armv7-unknown-linux-gnueabihf
中获取输出。
关于docker run
标志的解释:
-v $PWD:/src
- 将当前目录挂载到docker容器中的/src
目录--user $(id -u):$(id -g)
- 配置用户和组ID,否则所有构建输出将由root
所有--rm
- 构建后销毁docker容器-ti
- 交互式终端模式,以获取一些漂亮的颜色armv7_cross
- Docker镜像的名称cargo build
- 在容器内执行的命令。
请注意,我们已经在我们的Docker容器中将armv7-unknown-linux-gnueabihf
设置为默认目标,因此不需要提供--target
标志。
英文:
I'm sure there is a way with cross
, but I personally didn't manage to achieve it.
I did, however, achieve this by using the cross-building functionality of cargo directly.
Create the following Dockerfile
:
ARG DEBIAN_VERSION="11.7"
FROM debian:${DEBIAN_VERSION}
# Install target compilation targets
RUN dpkg --add-architecture armhf
# Add cross compilers and dependencies
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --yes \
curl git crossbuild-essential-armhf pkg-config \
libasound2-dev:armhf \
&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Install Rust system-wide
ENV RUSTUP_HOME=/opt/rust
ENV CARGO_HOME=/opt/rust
ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y --no-modify-path
ENV PATH="/opt/rust/bin:${PATH}"
# Add cross compilation target and set as default
RUN rustup target add armv7-unknown-linux-gnueabihf
ENV CARGO_BUILD_TARGET=armv7-unknown-linux-gnueabihf
# Configure Rust linkers for cross compilation
ENV CARGO_TARGET_ARMV7_UNKNOWN_LINUX_GNUEABIHF_LINKER=/usr/bin/arm-linux-gnueabihf-gcc
# Configure pkg-config for cross compilation
ENV PKG_CONFIG_ALLOW_CROSS=1/
ENV PKG_CONFIG_PATH_armv7_unknown_linux_gnueabihf=/usr/lib/arm-linux-gnueabihf/pkgconfig/
# Set the working directory to /src, where we will mount our project
WORKDIR /src
Build the docker container (I named it armv7_cross
here):
docker build -t armv7_cross .
Then, inside of your project directory, you can do:
docker run -v $PWD:/src --user $(id -u):$(id -g) --rm -ti armv7_cross cargo build
This should build like normally, and you should get our output at target/armv7-unknown-linux-gnueabihf
.
Explanation of the docker run
flags:
-
-v $PWD:/src
- Mounts the current directory to/src
in your docker container -
--user $(id -u):$(id -g)
- Configures user and group id, otherwise all your build outputs would be owned byroot
-
--rm
- Destroys the docker container again after building -
-ti
- Interactive terminal mode, to get some pretty colors -
armv7_cross
- The name of the docker image -
cargo build
- The command that gets executed inside of the container.Note we already set
armv7-unknown-linux-gnueabihf
as the default target inside our docker container, so we don't need to supply a--target
flag.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论