rust-cross / rust-musl-cross

Docker images for compiling static Rust binaries using musl-cross
MIT License
617 stars 68 forks source link

armv7-musleabihf: `rodio`, `alsa-sys`, `pkg-config` issues #69

Closed vmenge closed 1 year ago

vmenge commented 1 year ago

Hi, first of all thanks for this repo, it's really useful :-)

As a small disclaimer I'm completely out of my depth when it comes to compiling Rust applications -- usually cargo build --release is the extent of my needs.

I've used the Dockerfile from this repo as the basis for a few apps I've built to run on ARMv7, but every time I have a dependency that uses pkg-config I end up having an issue. I'm currently trying to compile an app that plays an audio file a couple of times, using rodio for audio playback. rodio depends on alsa-sys, which in turns depends on the pkg-config crate as a build depenency.

When building the application I get the following error:

#6 64.36 error: failed to run custom build command for `alsa-sys v0.3.1`
#6 64.36 
#6 64.36 Caused by:
#6 64.36   process didn't exit successfully: `/home/rust/src/target/release/build/alsa-sys-b3fdfece193bda1f/build-script-build` (exit status: 101)
#6 64.36   --- stdout
#6 64.36   cargo:rerun-if-env-changed=ALSA_NO_PKG_CONFIG
#6 64.36   cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_armv7-unknown-linux-musleabihf
#6 64.36   cargo:rerun-if-env-changed=PKG_CONFIG_ALLOW_CROSS_armv7_unknown_linux_musleabihf

// ...

#6 64.36   --- stderr
#6 64.36   thread 'main' panicked at 'Could not run `"pkg-config" "--libs" "--cflags" "alsa"`
#6 64.36   The pkg-config command could not be found.
#6 64.36 
#6 64.36   Most likely, you need to install a pkg-config package for your OS.
#6 64.36   Try `apt install pkg-config`, or `yum install pkg-config`,
#6 64.36   or `pkg install pkg-config` depending on your distribution.
#6 64.36 
#6 64.36   If you've already installed it, ensure the pkg-config command is one of the
#6 64.36   directories in the PATH environment variable.

I can get around it by creating a Dockerfile and installing pkg-config, like so

FROM messense/rust-musl-cross:armv7-musleabihf
RUN apt update -y 
RUN apt install -y pkg-config
COPY . .
RUN cargo build --release

Then I still get an error with

#9 67.19   --- stderr
#9 67.19   thread 'main' panicked at '`"pkg-config" "--libs" "--cflags" "alsa"` did not exit successfully: exit status: 1
#9 67.19   error: could not find system library 'alsa' required by the 'alsa-sys' crate
#9 67.19 
#9 67.19   --- stderr
#9 67.19   Package alsa was not found in the pkg-config search path.
#9 67.19   Perhaps you should add the directory containing `alsa.pc'
#9 67.19   to the PKG_CONFIG_PATH environment variable

Well duh, I need to install Alsa, so I add librust-alsa-sys-dev to the apt install command on the Dockerfile.

But then I still have an issue because alsa.pc ends up being put at /usr/lib/x86_64-linux-gnu/pkgconfig, as opposed to any of the directories defined in the original Dockerfile ENVs (/usr/local/musl/lib/pkgconfig and /usr/local/musl/armv7-unknown-linux-musleabihf/lib/pkgconfig).

From here on I'm not sure how to proceed -- I've tried adding the directory as one of the pkg-config paths and I've also tried copying alsa.pc to the musleabihf pkgconfig folder, but this not only feels like the wrong thing, I still get errors with it. I would appreciate any pointers here as I'm sure my lack of knowledge on this is creating a lot more trouble than it should 🙏

Below is the application I'm trying to compile:

# Cargo.toml
[package]
name = "audio"
version = "0.1.0"
edition = "2021"

[dependencies]
rodio = "0.16.0"
// main.rs
use rodio::{Decoder, OutputStream, Sink, Source};
use std::{error::Error, fs::File, io::BufReader};

pub fn main() -> Result<(), Box<dyn Error>> {
    let (_stream, stream_handle) = OutputStream::try_default()?;
    let file = BufReader::new(File::open("coin.wav")?);
    let source = Decoder::new(file)?;
    let sink = Sink::try_new(&stream_handle).unwrap();
    let x = source.buffered();
    let y = x.clone();
    sink.append(x);
    sink.append(y);

    sink.play();

    Ok(())
}
messense commented 1 year ago

You can't just apt install librust-alsa-sys-dev and expect it to work since it will install a x86_64 version.

Perhaps you can try

dpkg --add-architecture armhf
apt update
apt install -y librust-alsa-sys-dev:armhf
messense commented 1 year ago

On second thought, I don't think install a system package for musl target will work because they are built for glibc. You need to compile it from source to target musl libc.

See also https://github.com/diwic/alsa-sys/issues/10