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

Improve error message when attempting to use a crate that was created as a staticlib instead of an rlib. #14416

Closed
ahmedcharles opened this issue May 25, 2014 · 10 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.

Comments

@ahmedcharles
Copy link
Contributor

If a crate is created as a staticlib, which is for linking against C programs, the error message that is gotten when trying to use that create from Rust is:

foo.rs:3:1: 3:26 error: can't find crate for `bar`
foo.rs:3 extern crate bar;
            ^~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

It would be better if the error message were:

foo.rs:3:1: 3:26 error: found staticlib `bar` instead of rlib `bar`, please compile using --crate-type rlib instead.
foo.rs:3 extern crate bar;
            ^~~~~~~~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

Or something similarly useful.

Thanks.

@emberian
Copy link
Member

I can mentor this.

@kaseyc
Copy link
Contributor

kaseyc commented Jun 2, 2014

What would working on this entail?

@nebffa
Copy link

nebffa commented Jun 8, 2014

Hey I'd like to work on this issue - it looks like we'll need to work on the linker. I'm reading up on it to work out what might need changing.

@emberian
Copy link
Member

emberian commented Jun 8, 2014

The linker doesn't need to be modified. The error message today comes out of src/librustc/metadata/loader.rs:133. It just needs to be smarter about looking at the candidates it did find, and what was requested to link against, rather than just saying "not found".

@nebffa
Copy link

nebffa commented Jun 9, 2014

Cool - this could be done in one of two places in src/librustc/metadata/loader.rs:

  1. fn crate_matches
  2. fn find_library_crate

I think it would be better suited in crate_matches since some rejection of crates already happens in here, whereas find_library_crate doesn't do that

@nebffa
Copy link

nebffa commented Jun 15, 2014

Hey @cmr, I've been trying to do some work on this - I'm having trouble finding where exactly the path gets searched to find possible crates. Any idea where it might be?

FileSearch.search in loader.rs seems to just search for .so and .rlib libraries, but not .a (static libraries).

Also the speed of compilation is a bit of a bottleneck :p

@JIghtuse
Copy link
Contributor

Can I fix this? I found a place where loader looks for candidates for crates. Relevant code looks like this:

let (hash, rlib) = if file.starts_with(rlib_prefix.as_slice()) &&
        file.ends_with(".rlib") {
    (file.slice(rlib_prefix.len(), file.len() - ".rlib".len()),
     true)
} else if dypair.map_or(false, |(_, suffix)| {
    file.starts_with(dylib_prefix.get_ref().as_slice()) &&
    file.ends_with(suffix)
}) {
    let (_, suffix) = dypair.unwrap();
    let dylib_prefix = dylib_prefix.get_ref().as_slice();
    (file.slice(dylib_prefix.len(), file.len() - suffix.len()),
     false)
} else {
    return FileDoesntMatch
};

So, we can add our warning message to the last else clause. We need to be careful though. I've discovered with RUST_LOG that rustc first looks for all files in its path (isn't it ineffective on directories with many files?). Then the loader does what showed above: tries to match filename to rlib or dypair. By comparing crate name with "lib{crate_name}.a" we can catch mentioned in the issue case. We probably should to check for .so files too?

@JIghtuse
Copy link
Contributor

We need to be even more careful. I've used span_err(), but it aborts compilation immedieately. Changed to sess.span_warn()

JIghtuse added a commit to JIghtuse/rust that referenced this issue Oct 11, 2014
Now loader suggests to set crate type explicitly if it founds file with
name similar to crate name, but different extension.

This commit adds warning if loader found static library instead of rlib
or dylib. It fixes issue rust-lang#14416.
@JIghtuse
Copy link
Contributor

Example output:

$ rustc foo.rs   
foo.rs:1:1: 1:18 warning: found staticlib `bar` instead of rlib `bar`, please compile using --crate-type rlib instead.
foo.rs:1 extern crate bar;
         ^~~~~~~~~~~~~~~~~
foo.rs:1:1: 1:18 error: can't find crate for `bar`
foo.rs:1 extern crate bar;
         ^~~~~~~~~~~~~~~~~
error: aborting due to previous error

bors added a commit that referenced this issue Feb 7, 2015
…crichton

Add special error for this case and help message `please recompile this crate using --crate-type lib`, also list found candidates.

See issue #14416

r? @alexcrichton
@Potpourri
Copy link
Contributor

Fixed in #21978

@jdm jdm closed this as completed Feb 7, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants