Open Yuri6037 opened 2 years ago
I'm not convinced that it's cc-rs's domain/responsibility. To specify the dynamic linker that is. cc-rs merely compiles object modules, and linking is performed by rustc. One can wonder if cc-rs could [and then if it actually should] help steering rustc to target-specific linker, but as far as I can tell it doesn't interfere with this process. I would suggest treating musl as any other cross-compile target and specify musl-gcc
as designated linker. One way is to add following lines to your .cargo/config.toml:
[target.aarch64-unknown-linux-musl]
linker = "musl-gcc"
I think requiring users to specify this in .cargo/config.toml is not right. The problem clearly occurs when C++ code is linked. Rust is not responsible for linking C++ as is Cargo, cc is responsible for handling proper C++ linkage.
EDIT: You cannot rely on everyone customizing their config.toml every time they work on must based systems, this crate should just work no matter what target is used as long as the target supports C++.
EDIT2: If this is impossible at least consider showing an error message earlier in the build process to avoid generating broken unusable binaries.
I think requiring users to specify this in .cargo/config.toml is not right.
Yet it's the way it is. Try to cross-compile for any target and you'll see.
Rust is not responsible for linking C++ as is Cargo, cc is responsible for handling proper C++ linkage.
cc-rs does tell rustc to link with C++ run-time library, but doesn't tell which linker to use. The choice is rustc's. [Do note that I'm not in position to change anything, I merely describe the state of affairs.]
You cannot rely on everyone customizing their config.toml every time they work on must based systems, this crate should just work no matter what target is used as long as the target supports C++.
What defines a musl-based system? If there are systems where musl is the default (or only?) libc run-time, then the expectation would be that default cc
would link with it, as well as pick matching dynamic linker. If it's not the case, then can one call it musl-based? Questions are rather rhetorical... In sense that I don't expect answers, nor plan to engage in further discussion. Again, I'm just describing the way things are, and have no power to change anything.
If there are systems where musl is the default (or only?) libc run-time, then the expectation would be that default
cc
would link with it, as well as pick matching dynamic linker.
That's exactly what I meant, If musl is the only libc (which is the case on Postmarket OS aarch64) then cc should instruct rustc to use the proper linker instead of continuing with the default one and generate a broken binary which is the current state. If there are both libc and musl available let rustc choose what it prefers by default.
But that's not what I meant. I didn't mean that cc-rs crate would have to do anything special, but that the default linker used by rustc would "know" what to do without rustc doing anything special. In other words nobody would have to instruct anybody about anything on a musl-based system. Or maybe more specifically on a system that can actually be classified as musl-based.
Just in case, the misunderstanding arose from the fact that when I wrote "cc
" I referred to an actual command, a.k.a. default linker, while you interpreted it as "this crate." My fault, I should have been more clear.
But that's not what I meant. I didn't mean that cc-rs crate would have to do anything special, but that the default linker used by rustc would "know" what to do without rustc doing anything special. In other words nobody would have to instruct anybody about anything on a musl-based system. Or maybe more specifically on a system that can actually be classified as musl-based.
Just in case, the misunderstanding arose from the fact that when I wrote "
cc
" I referred to an actual command, a.k.a. default linker, while you interpreted it as "this crate." My fault, I should have been more clear.
If I get it right, that means you should open an issue on rustc...
If I get it right, that means you should open an issue on rustc...
It means that someone might choose to open an issue with rustc. Just in case, as implied above, I personally have no plans for doing anything beyond describing the way things are.
If I get it right, that means you should open an issue on rustc...
It means that someone might choose to open an issue with rustc. Just in case, as implied above, I personally have no plans for doing anything beyond describing the way things are.
So that means you're fine with the current state which is generating broken binaries...
EDIT: I just did it
I think this is definately a problem with the CC crate! On musl targets, rustc assumes static linking. The cc crate should provide a way to enable linking with the static build of the c++ library. On musl systems, a static build of the C++ library is already available under /usr/lib/libstdc++.a
, the cc crate should just allow linking with this library instead of forcing dynamic linking of the C++ library.
EDIT: Just hacked something together and I can conclude that cc crate can do something which is not hacky at all. Basically this crate can do similar than for Android:
println!("cargo:rustc-link-search=native=/usr/lib");
println!("cargo:rustc-link-lib=static=stdc++");
Once these 2 lines are manually emitted from the build script rustc no longer requests the wrong interpreter because the entire program gets linked statically.
The cc crate requests /lib/ld-linux-aarch64.so.1 as a program interpreter on musl targets when some c++ code is built. Instead the cc crate should request /lib/ld-musl-aarch64.so.1.