Dynamic linking in Alpine

I am having some problems dynamically linking so-files to my Rust application when building in an Alpine container. The following is just an example; it is not because I actually want to use Jansson in my Rust application.

main.rs

extern "C" {
    pub fn jansson_version_str() -> *const ::std::os::raw::c_char;
}

fn main() {
    unsafe {
        let version = jansson_version_str();
        println!("Jansson version: {:?}", ::std::ffi::CStr::from_ptr(version));
    }
}

In build.rs, I tell cargo to link against libjansson.so

fn main() {
    println!("cargo:rustc-link-search=/usr/lib");
    println!("cargo:rustc-link-lib=jansson");
}

When doing the above on my archlinux, it works fine, but for some reason it fails in an Alpine docker container.

I start the container, install jansson, and checks that the so-file is available:

docker run --rm -it -v $PWD:/work -w /work rust:1-alpine3.19

apk update
apk add jansson-dev

/work # ls -l /usr/lib/libjansson*
lrwxrwxrwx    1 root     root            20 Jan 20 13:00 /usr/lib/libjansson.so -> libjansson.so.4.14.0
lrwxrwxrwx    1 root     root            20 Jan 12 19:55 /usr/lib/libjansson.so.4 -> libjansson.so.4.14.0
-rwxr-xr-x    1 root     root         50976 May 18  2023 /usr/lib/libjansson.so.4.14.0

Finally, I try building, which fails with the message cannot find -ljansson: No such file or directory:

/work # cargo build
   Compiling so-test-rust v0.1.0 (/work)
error: linking with `cc` failed: exit status: 1
  |
  = note: LC_ALL="C" PATH="/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/bin:/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/bin/self-contained:/usr/local/cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" VSLANG="1033" "cc" "-m64" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/rcrt1.o" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crti.o" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtbeginS.o" "/tmp/rustc7HWCHq/symbols.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.1bffrc8nhwf77szl.rcgu.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.23nbsmq4tuxibi32.rcgu.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.2654qpf4w4fmqucg.rcgu.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.2zg50jxdfqrxenmm.rcgu.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.3njtmt8yx7u3u2r2.rcgu.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.4i6xk5201m06fb5l.rcgu.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.4oszaam2kc7po2x3.rcgu.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.a7zw2me4z5anht5.rcgu.o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66.43g73hunsz74kgme.rcgu.o" "-Wl,--as-needed" "-L" "/work/target/debug/deps" "-L" "/usr/lib" "-L" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib" "-Wl,-Bstatic" "-ljansson" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libstd-11c02606063fb1b5.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libpanic_unwind-527b1ade0207850b.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libobject-5c6479882291983e.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libmemchr-b30d7598b031e855.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libaddr2line-7bdd9f1650697dee.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libgimli-af6e6b96893335a7.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_demangle-61a774fd0ca56cef.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libstd_detect-0bdaa2154e535182.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libhashbrown-40daaa64e7b3ff16.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_std_workspace_alloc-51b0c25ea806d020.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libminiz_oxide-503b1c30e4fe986c.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libadler-0dfa15d5b98a6f2c.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libunwind-7e3d215879e752d5.rlib" "-lunwind" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libcfg_if-f91de774775af47a.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/liblibc-a172c9da7a8c39aa.rlib" "-lc" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/liballoc-05ed26095d7bae0a.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/librustc_std_workspace_core-940bcdced839ada6.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libcore-ece58c607aadf4ad.rlib" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/libcompiler_builtins-cfd03998b63f49b3.rlib" "-Wl,-Bdynamic" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-nostartfiles" "-L" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib" "-L" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained" "-o" "/work/target/debug/deps/so_test_rust-30fc2b54f6024e66" "-Wl,--gc-sections" "-static-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtendS.o" "/usr/local/rustup/toolchains/1.75.0-x86_64-unknown-linux-musl/lib/rustlib/x86_64-unknown-linux-musl/lib/self-contained/crtn.o"
  = note: /usr/lib/gcc/x86_64-alpine-linux-musl/13.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: cannot find -ljansson: No such file or directory
          collect2: error: ld returned 1 exit status


error: could not compile `so-test-rust` (bin "so-test-rust") due to previous error

Any ideas about what happens here?

It is looking for static files to link.
Try using RUSTFLAGS='-C target-feature=-crt-static'

Or change docker image. This Reddit - Dive into anything hints that something different is being used.

Official rustup rustc for musl target is static by default.
Alpine's default rustc has altered target to be dynamic.

Thanks a lot for the input! That was helpful.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.