GitHub - tombruijn/rust-elixir-linking-issue-example-project: Test project to create a Rust staticlib, install it as a Erlang NIF in an Elixir project. Will fail for the musl target on Rust 1.21.0 and newer. (original) (raw)
Rust staticlib linking with Elixir issue example app
Usage
./build_and_test
<Rust version>
: The Rust version is the version of the Rust language to test against. It will automatically install it.
This testing tool will follow the process described in "Build and test process details" below. Afterwards it will open a shell in which the user can do additional debugging, such as:
./bin/elixir_app stop # Stop application that's currently running ./bin/elixir_app foreground # Run application in foreground cat lib/elixir_package-0.0.1/install.log # Print install log file with error (if present)
Examples
./build_and_test 1.20.0
Works, creates a build and complains about a missing install.log file, which is fine
./build_and_test 1.21.0
Fails, starts app but prints the error listed below
./build_and_test 1.29.1
Fails, unrelated error that's already fixed in the latest nightly
./build_and_test nightly-2018-10-08
Fails, starts app but prints the error listed below
Unexpected error
This error occurs when linking a staticlib with the x86_64-unknown-linux-musl
target to an Elixir app.
Error loading NIF (host triple: x86_64-pc-linux-musl)
Error: Failed to load NIF library: 'Error loading shared library libgcc_s.so.1: No such file or directory (needed by /app/lib/elixir_package-0.0.1/priv/elixir_package_extension.so)'
Testing
Requirements
Requirements for running this project on a macOS host machine, see "Build and test process details". This project is not optimized for a Linux host machine, but will run the same.
Build and test process details
The following steps describe the automated process this project performs. No manual steps required.
- Build extension
- Create a virtual machine (controlled through Vagrant) that will act as the build environment.
* You will be prompted for your password the first time to mount a NFS volume on the virtual machine.
* Install Docker on this build machine. - With cross, cross compile the extension to musl.
* This cannot be done if the host is macOS, which is why we're running this through the virtual build machine.
- Create a virtual machine (controlled through Vagrant) that will act as the build environment.
- Install the extension as an Erlang NIF
- Move built extension to Elixir package (
elixir_app/elixir_package/c_src
) - Start a Docker image build process that compiles the Elixir app.
* Start the first stage that compiles the app. - Make an app release with distillery.
* Compile the Elixir app.
* Install the Erlang NIF.
* Package the release as a zip.
- Move built extension to Elixir package (
- Run the app.
- Create a second stage for the release in which the app is run. This is a slimmer version of the Docker image than the build stage. This does not include the compilation dependencies from the first stage.
* Copy and extract the zip file from the first stage. - Run the Elixir app release (including the NIF).
- The error will be printed as the
install.log
file is read.
* If this file is not present it will warn it cannot be found. Which is good.
- Create a second stage for the release in which the app is run. This is a slimmer version of the Docker image than the build stage. This does not include the compilation dependencies from the first stage.
Clean up
Note: This testing process will create a new Docker image per build. Be sure to clean them after you're done testing.
docker rmi alpine-elixir-build-test:build