You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
cannot produce proc-macro when --target is set on musl host toolchain #7563
On a musl based linux system , cross compilation will fail when using proc-macro
Steps
1.Cargo.toml:
[package]
name = "demo"version = "0.1.0"edition = "2018"
[dependencies]
serde= { version = "1.0", features = ["derive"] }
2.src/main.rs:
fnmain(){}
$ RUSTFLAGS="-C target-feature=-crt-static" cargo build --target=wasm32-wasi
error: cannot produce proc-macro for `serde_derive v1.0.102` as the target `x86_64-unknown-linux-musl` does not support these crate types
The issue here is proc-macros are dylibs and Rust doesn't support linking dylibs to static CRT on targets other than Windows. Historically musl target links static CRT by default so one has to disable it with target-feature=-crt-static to get proc-macro. Binary will be build dynamically linked so it requires musl to be installed on the target to run (it loses portability).
Oh, I think I see. I've never been able to get rustc musl to work on any system. Do you know, is there any information on how to get it to work? Whatever I've tried, I get all sorts of errors (symbol not found, libgcc_s.so.1 not found, etc) just running rustc -V.
@ehuss you need musl compiler (musl-gcc) in the path to build for musl.
Whatever I've tried, I get all sorts of errors (symbol not found, libgcc_s.so.1 not found, etc) just running rustc -V.
You have probably installed musl host toolchain on glibc based linux, it's possible to run it there but sketchy. You'd have more luck running it on Alpine Linux or musl variant Void Linux.
Slightly offtopic but I want you to understand what is going on:
You can cross compile code from OP on linux-gnu to linux-musl or wasi just fine because proc macro runs on linux-gnu and get static binary.
Compiling it on linux-musl for any target won't work out of the box because user have to disable crt-static. I think it won't hurt for wasi but this prevents user from creating static binary on musl whenever proc-macros are involved.
I don't know how to fix it, generally proc-macros always have to be compiled dynamically for host assuming it supports dylibs. Probably this has to be fixed in rustc itself but I don't remember that code well enough to tell for sure.
You have probably installed musl host toolchain on glibc based linux, it's possible to run it there but sketchy. You'd have more luck running it on Alpine Linux or musl variant Void Linux.
I just tried with the latest nightly, with the same result. Any ideas what I'm missing? This is using rustup to install. Do I need to install a special package? Are there dependencies I need to install?
Just ran into this and want to make sure I'm understanding this correctly -- it sure seems like it's impossible to build a static binary (or at least the closest we can get to it on linux w/ musl) if you have any dependency that uses macros?
It seems like the only workaround is to dynamically link libgcc...
Maybe I wasn't clear about my misunderstanding -- it wasn't whether you needed musl installed or how to specifically to do it, but more about the fact if you choose to do use crt-static you must then the generated binary must at runtime be dynamically linked.
I'm going directly off what @mati865 said (reproduced below):
The issue here is proc-macros are dylibs and Rust doesn't support linking dylibs to static CRT on targets other than Windows. Historically musl target links static CRT by default so one has to disable it with target-feature=-crt-static to get proc-macro. Binary will be build dynamically linked so it requires musl to be installed on the target to run (it loses portability).
If I'm reading this correctly, then it means that at the moment Rust cannot generate the closest thing we have to a static binary on linux if the project being built uses macros.
[EDIT] - Just trying to make sure this is clear but I'm not trying to slight rust here, just want to make sure that I arrived at the right conclusion.
Compiling binary dynamically linked to musl on musl host (need RUSTFLAGS set) or binary statically linked to musl on glibc host will works.
This issue is about the fact that, when a crate use proc-macro, on a musl host
(1) we can't cross compile it for other targets
(2) we can't compile it statically linked to musl.
We can't do (1) because cargo set RUSTFLAGS to empty when compile proc-macro.
we can't do (2) because it will let proc-macro compile statically, which is wrong.
The problem is cargo don't have a concept about HOSTRUSTFLAGS that only apply to build script and proc-macro, but the behavior of crt-static is control by RUSTFLAGS.
However, RUSTFLAGS isn't a out of box solution. On every platform that have rustc built and runs, proc-macro is compiled dynamically, so the better solution is rustc don't check whether a target can compile proc-macro (as it always can), and compile it dynamically directly
Reacted by Victor Adossi ("vados"), Joshua Sleeper, Sunny Gonnabathula and Dan Aloni
I hit the same error message, and here's what worked for me to build a Rust Rocket app in a Dockerfile using Alpine and Rust nightly. I welcome feedback -- this is my first time trying Docker + Rust nightly + Alpine musl.
FROM alpine:latest as builder-system
RUN apk update
RUN apk add binutils build-base ca-certificates curl file g++ gcc libressl-dev make patch rust
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
RUN . ~/.cargo/env && rustup toolchain install nightly && rustup default nightly
RUN . ~/.cargo/env && rustup target add x86_64-unknown-linux-musl
WORKDIR /usr/src/demo_rust_rocket
COPY Cargo.toml Cargo.toml
RUN mkdir src/
RUN echo "fn main() {println!(\"if you see this, the build broke\")}" > src/main.rs
RUN . ~/.cargo/env && RUSTFLAGS="-C linker=musl-gcc -C target-feature=-crt-static" cargo build --release --target=x86_64-unknown-linux-musl
Activity
fix rust-lang#7563
ehuss commentedon Nov 13, 2019
AFAIK, rustc musl host fundamentally does not support proc-macros. Some more information may be found at rust-lang/rust#40174.
mati865 commentedon Nov 13, 2019
Musl target does support proc-macros.
The issue here is proc-macros are dylibs and Rust doesn't support linking dylibs to static CRT on targets other than Windows. Historically musl target links static CRT by default so one has to disable it with
target-feature=-crt-staticto get proc-macro. Binary will be build dynamically linked so it requires musl to be installed on the target to run (it loses portability).ehuss commentedon Nov 13, 2019
Oh, I think I see. I've never been able to get rustc musl to work on any system. Do you know, is there any information on how to get it to work? Whatever I've tried, I get all sorts of errors (symbol not found,
libgcc_s.so.1not found, etc) just runningrustc -V.mati865 commentedon Nov 13, 2019
@ehuss you need musl compiler (
musl-gcc) in the path to build for musl.You have probably installed musl host toolchain on glibc based linux, it's possible to run it there but sketchy. You'd have more luck running it on Alpine Linux or musl variant Void Linux.
Slightly offtopic but I want you to understand what is going on:
You can cross compile code from OP on linux-gnu to linux-musl or wasi just fine because proc macro runs on linux-gnu and get static binary.
Compiling it on linux-musl for any target won't work out of the box because user have to disable
crt-static. I think it won't hurt for wasi but this prevents user from creating static binary on musl whenever proc-macros are involved.I don't know how to fix it, generally proc-macros always have to be compiled dynamically for host assuming it supports dylibs. Probably this has to be fixed in rustc itself but I don't remember that code well enough to tell for sure.
ehuss commentedon Nov 13, 2019
On a fresh install of Alpine Linux, I get the exact same errors as other distros trying to run
rustcforstable-x86_64-unknown-linux-musl: https://gist.github.com/ehuss/57a81703bdfb4abcd64ddfbdc4d371c0I just tried with the latest nightly, with the same result. Any ideas what I'm missing? This is using rustup to install. Do I need to install a special package? Are there dependencies I need to install?
mati865 commentedon Nov 13, 2019
Maybe a bit overkill but installing
g++orbuild-baseshould give you everything you need.Using container in Docker/Podman is enough to try it BTW.
ehuss commentedon Nov 14, 2019
Ah, adding
g++did the trick, thanks!t3hmrman commentedon Feb 18, 2020
Just ran into this and want to make sure I'm understanding this correctly -- it sure seems like it's impossible to build a static binary (or at least the closest we can get to it on linux w/ musl) if you have any dependency that uses macros?
It seems like the only workaround is to dynamically link
libgcc...sfackler commentedon Feb 18, 2020
You don't need to use a MUSL host toolchain to target MUSL.
paulwang001 commentedon Feb 27, 2020
~/.cargo/config
[build]
rustflags = "-C target-feature=-crt-static"
OR
$>RUSTFLAGS="-C target-feature=-crt-static" cargo build
t3hmrman commentedon Feb 27, 2020
Thanks @paul-sedun/@sfackler
Maybe I wasn't clear about my misunderstanding -- it wasn't whether you needed musl installed or how to specifically to do it, but more about the fact if you choose to do use
crt-staticyou must then the generated binary must at runtime be dynamically linked.I'm going directly off what @mati865 said (reproduced below):
If I'm reading this correctly, then it means that at the moment Rust cannot generate the closest thing we have to a static binary on linux if the project being built uses macros.
[EDIT] - Just trying to make sure this is clear but I'm not trying to slight rust here, just want to make sure that I arrived at the right conclusion.
12101111 commentedon Feb 27, 2020
Compiling binary dynamically linked to musl on musl host (need RUSTFLAGS set) or binary statically linked to musl on glibc host will works.
This issue is about the fact that, when a crate use proc-macro, on a musl host
(1) we can't cross compile it for other targets
(2) we can't compile it statically linked to musl.
We can't do (1) because cargo set RUSTFLAGS to empty when compile
proc-macro.we can't do (2) because it will let
proc-macrocompile statically, which is wrong.The problem is cargo don't have a concept about
HOSTRUSTFLAGSthat only apply to build script andproc-macro, but the behavior ofcrt-staticis control by RUSTFLAGS.However, RUSTFLAGS isn't a out of box solution. On every platform that have rustc built and runs,
proc-macrois compiled dynamically, so the better solution is rustc don't check whether a target can compile proc-macro (as it always can), and compile it dynamically directlyt3hmrman commentedon Feb 27, 2020
Thank you for the explanation, I think I understand now!
Rollup merge of rust-lang#69519 - 12101111:remove-proc-macro-check, r…
Rollup merge of rust-lang#69519 - 12101111:remove-proc-macro-check, r…
Auto merge of #69519 - 12101111:remove-proc-macro-check, r=nagisa,smaeul
Auto merge of #69519 - 12101111:remove-proc-macro-check, r=nagisa
fix cannot produce pro-macro as the target x86_64-unknown-linux-musl …
joelparkerhenderson commentedon May 30, 2020
I hit the same error message, and here's what worked for me to build a Rust Rocket app in a Dockerfile using Alpine and Rust nightly. I welcome feedback -- this is my first time trying Docker + Rust nightly + Alpine musl.
sanmai-NL commentedon Nov 17, 2023
@joelparkerhenderson Any particular reason you set
linker=musl-gcc?joelparkerhenderson commentedon Nov 18, 2023
IIRC, I was attempting to stop dynamic linking related to release builds. IIRC, I was following rust-lang/rust#54243 and https://stackoverflow.com/questions/64737810/rust-building-a-statically-linked-binary-including-external-c-libraries