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

Cargo does not relink after linked-against library changes #12502

Closed
zopsicle opened this issue Aug 15, 2023 · 3 comments
Closed

Cargo does not relink after linked-against library changes #12502

zopsicle opened this issue Aug 15, 2023 · 3 comments
Labels
C-bug Category: bug S-triage Status: This issue is waiting on initial triage.

Comments

@zopsicle
Copy link

zopsicle commented Aug 15, 2023

Problem

Normally, when a file the crate depends on is changed, Cargo rebuilds the crate. This works when the file is imported as a module or include{,_str,_bytes}!d, but not when it is linked against using a link attribute. This results in frustration when working on a project where Rust is used in conjunction with other programming languages.

Steps

$ cat Cargo.toml
[package]
name = "c"
version = "0.0.0"
edition = "2021"

$ cat src/lib.rs
#[link(name = "a")]
extern
{
    fn f();
}

#[test]
fn t() { unsafe { f() } }

$ cat a.c
void f() {}

$ gcc -c -o a.o a.c

$ ar crs liba.a a.o

$ RUSTFLAGS='-L native=.' cargo test

$ echo 'void f() { abort(); }' > a.c

$ gcc -c -o a.o a.c

$ ar crs liba.a a.o

$ RUSTFLAGS='-L native=.' cargo test  # should abort, but succeeds

$ rm -rf target

$ RUSTFLAGS='-L native=.' cargo test  # aborts as expected

Possible Solution(s)

For each executable, test, and benchmark, keep track of the libraries it links against. When the modification date of any library exceeds that of the artifact, relink it.

Notes

Adding the +bundle modifier to the link attribute makes no difference.

Version

cargo 1.73.0-nightly (d78bbf4bd 2023-08-03)
release: 1.73.0-nightly
commit-hash: d78bbf4bde3c6b95caca7512f537c6f9721426ff
commit-date: 2023-08-03
host: x86_64-unknown-linux-gnu
libgit2: 1.6.4 (sys:0.17.2 vendored)
libcurl: 8.2.1-DEV (sys:0.4.65+curl-8.2.1 vendored ssl:OpenSSL/1.1.1u)
ssl: OpenSSL 1.1.1u  30 May 2023
os: NixOS 23.5.0 [64-bit]
@zopsicle zopsicle added C-bug Category: bug S-triage Status: This issue is waiting on initial triage. labels Aug 15, 2023
@ehuss
Copy link
Contributor

ehuss commented Aug 15, 2023

Thanks for the report! Unfortunately there isn't anything that cargo can do here. It doesn't know anything about linking or which libraries were used when passed via attributes.

As a workaround, if it is possible in your circumstance, to use a build script which can pass cargo:rerun-if-changed to tell cargo to track changes in the static library. That will require knowing the path to the library.

I'm going to close as a duplicate of rust-lang/rust#58393 and rust-lang/rust#57717. The fix for this will need to be done in rustc. However, in this case I'm not sure that is even possible because rustc depends on the system linker to find libraries, and so rustc wouldn't know where they are located.

@ehuss ehuss closed this as not planned Won't fix, can't repro, duplicate, stale Aug 15, 2023
@zopsicle
Copy link
Author

Thanks for the response. Does cargo:rerun-if-changed cause the crate to be rebuilt in addition to rerunning the build script? That would explain why I've never seen this problem when using the cc crate.

@weihanglo
Copy link
Member

Does cargo:rerun-if-changed cause the crate to be rebuilt in addition to rerunning the build script

Yes. When anything a crate depending on recompiles, the crate itself needs to recompile. And a crate does depend on its own build script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: bug S-triage Status: This issue is waiting on initial triage.
Projects
None yet
Development

No branches or pull requests

3 participants