Skip to content

--print native-static-libs of a staticlib crate does not print libraries linked in via #[link] attribute or -l parameters #111643

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

Closed
sdroege opened this issue May 16, 2023 · 4 comments · Fixed by #111675
Labels
A-linkage Area: linking into static, shared libraries and binaries C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@sdroege
Copy link
Contributor

sdroege commented May 16, 2023

This is with Rust 1.69 but was probably always the case.

Example:

lib.rs

#[no_mangle]
pub extern "C" fn my_staticlib_add(left: i32, right: i32) -> i32 {
    // Obviously makes no sense but...
    unsafe {
        g_free(std::ptr::null_mut());
    }
    left + right
}

#[link(name = "glib-2.0")]
extern "C" {
    fn g_free(p: *mut ());
}

Compiling with

$ rustc --crate-type staticlib --print native-static-libs --edition=2018 --crate-name staticlib --emit link -o libstaticlib.a lib.rs

prints

note: Link against the following native artifacts when linking against this static library. The order and any duplication can be significant on some platforms.

note: native-static-libs: -lgcc_s -lutil -lrt -lpthread -lm -ldl -lc

Similarly when providing -lglib-2.0 nothing changes. I didn't really follow how rustc collects the libraries but I think it's via the native_libraries query in compiler/rustc_middle/src/query/mod.rs which claims

    /// Look up all native libraries this crate depends on.
    /// These are assembled from the following places:
    /// - `extern` blocks (depending on their `link` attributes)
    /// - the `libs` (`-l`) option

so this should be included AFAIU. Also the rationale of native-static-libs was to provide all libraries needed to link to the resulting staticlib, which is not the case in the above example.


CC @kornelski who originally implemented this feature.

@GuillaumeGomez GuillaumeGomez added A-linkage Area: linking into static, shared libraries and binaries T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. C-bug Category: This is a bug. labels May 16, 2023
@Urgau
Copy link
Member

Urgau commented May 16, 2023

It works as expected if the #[link] attribute is used in a dependencies.

It seems to me that the link_staticlib function,

fn link_staticlib<'a>(
sess: &'a Session,
archive_builder_builder: &dyn ArchiveBuilderBuilder,
codegen_results: &CodegenResults,
out_filename: &Path,
tempdir: &MaybeTempDir,
) -> Result<(), ErrorGuaranteed> {

is forgetting to add the current native libs.

Doing something like this correctly adds -lglib-2.0 to the output (even when passed via the command line) but I don't know if it's the right thing to do (cc @petrochenkov).

all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries);

@bjorn3
Copy link
Member

bjorn3 commented May 16, 2023

Yeah, I think adding all_native_libs.extend_from_slice(&codegen_results.crate_info.used_libraries); is the correct fix. That adds the same information as codegen_results.crate_info.native_libraries does for dependencies.

@kornelski
Copy link
Contributor

Beware that --print native-static-libs is rather quirky. Originally Rust printed lines during build with information which link flags need to be added to use the static library it builds, and --print native-static-libs is a blunt way of redirecting these "warnings". I don't know whether omission of #[link] is a bug or the old warnings just weren't meant to print them.

@bjorn3
Copy link
Member

bjorn3 commented May 16, 2023

I can't imagine it to be a deliberate omission as --print native-static-libs is the only way to know how to correctly link any arbitrary staticlib afaik.

Urgau added a commit to Urgau/rust that referenced this issue May 17, 2023
@bors bors closed this as completed in 1b67f8b May 21, 2023
oli-obk pushed a commit to oli-obk/miri that referenced this issue May 23, 2023
…r=bjorn3

Fix local libs not included when printing native static libs

This PR fixes rust-lang/rust#111643 by adding the local used libs to the printed `--print=native-static-libs` output.

It seems that `--print=native-static-libs` doesn't have any test, so I added one. It's very simple and doesn't even tries to compile the result to a binary as I don't know how to handle external library linking in CI. (Note that https://github.com/rust-lang/rust/blob/master/tests/run-make/staticlib-dylib-linkage/Makefile does compile to a binary)

r? `@bjorn3`
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 C-bug Category: This is a bug. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants