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

shared_flag and static_flag don't work #594

Open
glandium opened this issue Apr 7, 2021 · 12 comments · May be fixed by #1444
Open

shared_flag and static_flag don't work #594

glandium opened this issue Apr 7, 2021 · 12 comments · May be fixed by #1444

Comments

@glandium
Copy link
Contributor

glandium commented Apr 7, 2021

The -shared and -static flags are linkage flags, and don't do anything when passed alongside -c.

Taking the example from shared_flag:

cc::Build::new()
    .file("src/foo.c")
    .shared_flag(true)
    .compile("libfoo.so");

What that does is:

cc $OTHER_FLAGS -shared -o foo.o -c src/foo.c
ar cq libfoo.so.a foo.o
ar s libfoo.so.a

The first command is strictly equivalent to cc $OTHER_FLAGS -o foo.o -c src/foo.c. So in practice, it makes no difference whether shared_flag was passed or not, and compile("libfoo.so") would make you think you'd end up with a dynamic library, but you don't.

@jerry73204
Copy link

Is the issue intended to be fixed?

@ssh352
Copy link

ssh352 commented Jun 1, 2023

how can I build dylib with cc crate?

@zhangzhuang15
Copy link

Same Problem.

@XuKeli8080174
Copy link

Same Problem too

@zhangzhuang15
Copy link

zhangzhuang15 commented Jan 2, 2024 via email

@sladg
Copy link

sladg commented Jan 22, 2024

Any solution to this one?

@NobodyXu
Copy link
Collaborator

This issue is due to cc always run ar, changing it should be possible.

cc @ChrisDenton @thomcc What's your thoughts on this?

@silvanshade
Copy link

Here's a workaround for this:

let out_dir = Path::new(std::env::var("OUT_DIR").unwrap());
let builder = cc::Build::new().file("src/foo.c");
let objects = builder.compile_intermediates();
builder
    .get_compiler()
    .to_command()
    .args(["-shared", "-o"])
    .arg(out_dir.join("libfoo.so"))
    .args(&objects)
    .status()
    .unwrap();

@Walter-Reactor
Copy link

Just following up here, this is doubly true on MSVC where the -shared flag actually triggers an error

@zhangzhuang15
Copy link

zhangzhuang15 commented Dec 17, 2024 via email

@westhide westhide linked a pull request Mar 30, 2025 that will close this issue
@madsmtm
Copy link
Collaborator

madsmtm commented Apr 4, 2025

Heads up: This is being discussed in #1444.

Personally, I'm against having this feature in cc-rs, since it's complex to support correctly (for example, you'd want cc-rs to use the same linker as rustc, but when using e.g. RUSTFLAGS=-Clinker=rust-lld, we'd have to know how to pass the correct flags to the linker. And e.g. for correctness on at least macOS, we'd need to pass -platform_version. Might be possible to work around by passing -fuse-ld=rust-lld to the compiler driver? But even then, how do we then avoid nonsensical things like cc -fuse-ld=cc? Should we instead invoke rustc as the linker? But what if the user doesn't have rustc in their PATH?).

I'd be more in favour of someone creating a separate crate like linker-rs, and implementing the desired capabilities there (since linking is mostly orthogonal to compiling).

@NobodyXu
Copy link
Collaborator

NobodyXu commented Apr 4, 2025

Well yeah, having a separate crate might be more reasonable, given that we already expose enough API for them to use cc to do compiler detection/etc

Like we can expose some APIs useful for link-rs/dynlib-rs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants