Search code examples
rustrust-cargo

rustc -L command not finding crate


I am just starting to use rust. I have installed rust with cargo and subsequently installed some packages, so that now ~/.cargo/registry/cache/github.com-1ecc6299db9ec823 folder has many crates:

aho-corasick-0.5.3.crate   env_logger-0.4.3.crate    open-1.2.2.crate           regex-0.1.80.crate            textwrap-0.11.0.crate
aho-corasick-0.6.10.crate  gcc-0.3.55.crate          rand-0.3.23.crate          regex-0.2.11.crate            thread-id-2.0.0.crate
aho-corasick-0.7.3.crate   getrandom-0.1.2.crate     rand-0.4.6.crate           regex-1.1.6.crate             thread_local-0.2.7.crate
ansi_term-0.11.0.crate     hoedown-6.0.0.crate       rand-0.6.5.crate           regex-syntax-0.3.9.crate      thread_local-0.3.6.crate
atty-0.2.11.crate          itertools-0.5.10.crate    rand_chacha-0.1.1.crate    regex-syntax-0.5.6.crate      time-0.1.42.crate
autocfg-0.1.2.crate        kernel32-sys-0.2.2.crate  rand_core-0.3.1.crate      regex-syntax-0.6.6.crate      toml-0.2.1.crate
bitflags-0.5.0.crate       lazy_static-0.2.11.crate  rand_core-0.4.0.crate      rustc-serialize-0.3.24.crate  ucd-util-0.1.3.crate
bitflags-1.0.4.crate       lazy_static-1.3.0.crate   rand_hc-0.1.0.crate        rustc_version-0.1.7.crate     unicode-width-0.1.5.crate
cargo-script-0.2.8.crate   libc-0.2.51.crate         rand_isaac-0.1.1.crate     semver-0.1.20.crate           utf8-ranges-0.1.3.crate
cfg-if-0.1.7.crate         log-0.3.9.crate           rand_jitter-0.1.3.crate    semver-0.5.1.crate            utf8-ranges-1.0.2.crate
chan-0.1.23.crate          log-0.4.6.crate           rand_os-0.1.3.crate        semver-parser-0.6.2.crate     vec_map-0.8.1.crate
clap-2.33.0.crate          memchr-0.1.11.crate       rand_pcg-0.1.2.crate       shaman-0.1.0.crate            winapi-0.2.8.crate
either-1.5.2.crate         memchr-2.2.0.crate        rand_xorshift-0.1.1.crate  strsim-0.8.0.crate            winapi-build-0.1.1.crate

I now want to use rustc command with -L option for a simple source file from here:

extern crate regex;
use regex::Regex;
fn main() {
    let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
    println!("Did our date match? {}", re.is_match("2014-01-01"));
}

However, this fails with following error:

$ rustc -L ~/.cargo/registry/cache/github.com-1ecc6299db9ec823 hellomain.rs 
error[E0463]: can't find crate for `regex`
 --> hellomain.rs:4:1
  |
4 | extern crate regex;
  | ^^^^^^^^^^^^^^^^^^^ can't find crate

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.

Why is rustc not finding crate and how can this be corrected? Thanks for your help.

Edit: same error occurs even if I specify the crate file name:

$ rustc -L ~/.cargo/registry/cache/github.com-1ecc6299db9ec823/regex-1.1.6.crate hellomain.rs
error[E0463]: can't find crate for `regex`
 --> hellomain.rs:4:1
  |
4 | extern crate regex;
  | ^^^^^^^^^^^^^^^^^^^ can't find crate

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.

Solution

  • The .crate files you are trying to link to are not compiled binary artifacts. The format is (as far as I know) just a .gz of the crate's source code. It is the output format of cargo package. Also the -L flag typically is for library directories and -l is used for particular libraries to link (though you'll see below that rustc uses --extern for Rust dependencies).

    In order to use the regex crate it must first be built. However as of now, it requires two other crates, regex_syntax and regex_automata, which need to be built first. Each one requires a rustc call separately, building off of each other, until you can finally build your executable.

    Here are all those commands (using ./deps as build cache):

    rustc --out-dir ./deps --crate-type lib --emit=metadata,link --crate-name regex_syntax --edition=2021 ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-syntax-0.8.4/src/lib.rs
    rustc --out-dir ./deps --crate-type lib --emit=metadata,link --crate-name regex_automata --edition=2021 ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-automata-0.4.7/src/lib.rs --cfg 'feature="alloc"' --cfg 'feature="meta"' --cfg 'feature="nfa-pikevm"' --cfg 'feature="nfa-thompson"' --cfg 'feature="syntax"' -L dependency=./deps --extern regex_syntax=./deps/libregex_syntax.rmeta
    rustc --out-dir ./deps --crate-type lib --emit=metadata,link --crate-name regex --edition=2021 ~/.cargo/registry/src/index.crates.io-6f17d22bba15001f/regex-1.10.5/src/lib.rs -L dependency=./deps --extern regex_automata=./deps/libregex_automata.rmeta --extern regex_syntax=./deps/libregex_syntax.rmeta
    rustc --out-dir ./deps --crate-type bin --emit=link --crate-name mycrate --edition=2021 src/main.rs -L dependency=./deps --extern regex=./deps/libregex.rlib
    

    This actually doesn't successfully run your code since I didn't include the 17 feature flags that the regex crate enables by default.

    Running rustc commands manually like this assumes the sources are already available somewhere like in ~/.cargo/registry. This also doesn't specify optimization flags or codegen options. This neglects generating debug info. This also doesn't handle conflicts if two versions of the same crate both need to be built and linked. This also requires you to understand and propagate feature unification yourself. This also neglects all the environment variables that are passed by cargo during the compilation which some crates depend on.

    This obviously gets more complicated as you depend on more crates and worse if there are build scripts. You can use cargo build -vv to see the normally generated commands. Just use cargo.