Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

statically linking ALL deps for cross compiling [support a RISC-V + musl target] #73051

Closed
chaozju opened this issue Jun 6, 2020 · 5 comments
Labels
A-linkage Area: linking into static, shared libraries and binaries O-musl Target: The musl libc O-riscv Target: RISC-V architecture

Comments

@chaozju
Copy link

chaozju commented Jun 6, 2020

Hi I am working on cross compilation for wasmer to RISC-V.

I want to statically link all dependencies into 1 executable to avoid qemu issue like below.

Is there a way to globally configure cargo build or something else like -static flag for gcc?

[root@stage4 ~]# ls
ffi  wasmer
[root@stage4 ~]# file wasmer
wasmer: ELF 64-bit LSB shared object, UCB RISC-V, version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, with debug_info, not stripped
[root@stage4 ~]# ldd wasmer
        linux-vdso.so.1 (0x000000200001a000)
        libffi.so.8 => /lib64/lp64d/libffi.so.8 (0x000000200007b000)
        libstdc++.so.6 => /lib64/lp64d/libstdc++.so.6 (0x0000002000084000)
        libutil.so.1 => /lib64/lp64d/libutil.so.1 (0x00000020001f3000)
        libdl.so.2 => /lib64/lp64d/libdl.so.2 (0x00000020001f7000)
        librt.so.1 => /lib64/lp64d/librt.so.1 (0x00000020001fb000)
        libpthread.so.0 => /lib64/lp64d/libpthread.so.0 (0x0000002000202000)
        libgcc_s.so.1 => /lib64/lp64d/libgcc_s.so.1 (0x000000200021d000)
        libc.so.6 => /lib64/lp64d/libc.so.6 (0x0000002000231000)
        /lib/ld.so.1 => /lib/ld-linux-riscv64-lp64d.so.1 (0x0000002000000000)
        libm.so.6 => /lib64/lp64d/libm.so.6 (0x000000200033e000)
[root@stage4 ~]# ./wasmer
-bash: ./wasmer: No such file or directory
@petrochenkov
Copy link
Contributor

petrochenkov commented Jun 6, 2020

You need to pass -C target-feature="+crt-static" to the compiler, through RUSTFLAGS or rustflags in cargo config.
Then libc crate will switch linking of libc an related libraries to static.

Note, however, that not all Rust targets support +crt-static currently.
Glibc-based targets do not (#65447).

So you may have to use a musl libc based target.
Musl supports RISC-V, but looks like rustc doesn't have a built-in target for the combination musl + RISC-V, so you'l have to write a custom one by combining https://github.com/rust-lang/rust/blob/master/src/librustc_target/spec/riscv64gc_unknown_linux_gnu.rs and https://github.com/rust-lang/rust/blob/master/src/librustc_target/spec/x86_64_unknown_linux_musl.rs.

Actually, it would be great to add the riscv64gc_unknown_linux_musl target to rustc so it's always available, so feel free to make a pull request.

@petrochenkov petrochenkov changed the title statically linking ALL deps for cross compiling statically linking ALL deps for cross compiling [support a RISC-V + musl target] Jun 6, 2020
@jonas-schievink jonas-schievink added A-linkage Area: linking into static, shared libraries and binaries O-musl Target: The musl libc O-riscv Target: RISC-V architecture labels Jun 6, 2020
@chaozju
Copy link
Author

chaozju commented Jun 6, 2020

@petrochenkov Does it make sense to

  • cargo vendor all the deps locally
  • assign crate_type=staticlib to[lib] in Cargo.tomls in ./vendor/some_dep
  • modify deps in Cargo.tomls in my project into some_dep = { path = "../vendor/some_dep" some_flags = some_flags }
  • cargo build --some_flags

Cause I am not so sure about targetting _musl with riscv-gnu-toolchain which I use at present

@petrochenkov
Copy link
Contributor

petrochenkov commented Jun 6, 2020

@chaozju
I don't think you can change anything in the vendor directory, see https://doc.rust-lang.org/cargo/reference/overriding-dependencies.html for correct ways to override dependencies.

Anyway, it won't help in your case because Rust standard library will still pull libc dynamically unless you rebuild the standard library yourself.
If you do rebuild the standard library (https://doc.rust-lang.org/cargo/reference/unstable.html#build-std), you can override the libc crate and change #[link(name = "c")] to #[link(name = "c", kind = "static-nobundle")] as a workaround.
Then it will work with the glibc-based toolchain.

In other words, this is not a configuration readily supported by rustc, and I'd recommend to address further questions about workarounds to https://users.rust-lang.org if they appear.

Also, you'll need to talk to people maintaining wasmer to figure out how to make it pull other native libraries like libffi statically.

@chaozju
Copy link
Author

chaozju commented Jun 7, 2020

@petrochenkov Thanks a lot !
BTW I am wondering whether I can get a statically linked executable once fixing the libc issue? Does crate_type of vendored libs matter?

@Mark-Simulacrum
Copy link
Member

I'd recommend to address further questions about workarounds to https://users.rust-lang.org/ if they appear.

Closing -- questions generally should be directed to users or other forums rather than the issue tracker.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-linkage Area: linking into static, shared libraries and binaries O-musl Target: The musl libc O-riscv Target: RISC-V architecture
Projects
None yet
Development

No branches or pull requests

4 participants