gyscos / zstd-rs

A rust binding for the zstd compression library.
MIT License
501 stars 104 forks source link

Error cross-compiling from M1 MacOS to Linux #229

Open JarredAllen opened 1 year ago

JarredAllen commented 1 year ago

I'm trying to build this crate as part of a project I'm working on. All the other rust crates build fine when cross-compiling (I need to target aarch64-unknown-linux-musl), but attempting to use this crate fails at building zstd-sys with a very long error message (>1800 lines, err.log), containing many repetitions of #error Unsupported architecture and #error architecture not supported from various .c and .h files being built.

This error is specific to cross-compiling, I can build on my M1 Mac targeting itself, or my Linux box targeting itself and those builds work fine. It's only when I attempt to cross-compile that I get issues. I also get the same error building the train example in this repo (which is what I did to generate the error I attached above).

Judging by the output I'm seeing, I suspect the compilation process is pulling in headers for MacOS instead of the correct headers for targeting Linux. However, I don't see any options in this crate that control where those headers come from, and I don't have these issues with building any other rust crates when I cross-compile, so I suspect it's specific to the headers being pulled in here. How can I control what headers it includes, to fix this error?

I'm able to build the zstd submodule by just running make, but I don't know how to ask make to cross-compile its build when running manually (I'm not very experienced with C/C++, so my ability to diagnose issues on that side is limited).

NobodyXu commented 1 year ago

I am able to cross-compile zstd to aarch64-unknown-linux-{musl, gnu} using cargo-zigbuild in cargo-binstall.

Just use pip3 install cargo-zigbuild (which will also install zig for you) then cargo zigbuild.

DoumanAsh commented 1 year ago

This crate doesn't use proper build procedure of zstd and instead relies on cc by supplying files in build.rs

You will need to setup environment to tell it how to do cross-compilation https://github.com/rust-lang/cc-rs#external-configuration-via-environment-variables

Proper way would be to probably use zstd's Cmake file and modify build script to use it instead of direct compilation

NobodyXu commented 1 year ago

Perhaps zstd could use crate cmake to utilize the Cmake manifest file?

DoumanAsh commented 1 year ago

yeah, cmake crate has code for handling target architecture of darwin targets https://github.com/rust-lang/cmake-rs/blob/3ddc3d505ef38ebec54b999110f9dd10b4465252/src/lib.rs#L664-L670

so switching to cmake would solve it for cross compilation users, at least in most common cases https://github.com/facebook/zstd/tree/63779c798237346c2b245c546c40b72a5a5913fe/build

Note that only make is official and third party integrations are provided by community