交叉编译 ALSA crate 到 armv7。

huangapple go评论125阅读模式
英文:

Cross compiling alsa crate for armv7

问题

我正在尝试为amrv7-unknown-linux-gnueabihf交叉编译基于alsa创建的Rust二进制文件。

对于交叉编译,我正在使用Cross和自定义的Dockerfile来获取所需的依赖项。

我遵循了这篇帖子中的说明,通过添加以下.cargo/config.toml文件:

但这导致了以下错误,pkg-config抱怨找不到alsa库:

你对如何修复这个错误有任何线索吗?

我尝试过以下方法:

  1. 如此描述添加了特性标志"alsa-backend"。
  2. 像同一帖子中描述的那样定制了.cargo/config.toml
  3. 查看了所有与在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:

  1. Adding the feature flag "alsa-backend" as described here
  2. Custom .cargo/config.toml as described in the same post
  3. 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 by root

  • --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.

huangapple
  • 本文由 发表于 2023年6月6日 02:35:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/76409150.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定