Usage of `extern crate`?

Hello guys! I'm currently trying to understand the usage of extern crate.
The rust-reference rust-reference says:

An extern crate declaration specifies a dependency on an external crate. (...)

So is it like adding a new dependency by adding it to Cargo.toml? What are its usages? If I understood it correctly, it just brings the given crate into our current scope, so we can write use theCrate::stuff; for example.

Also according to this Stack Overflow and ticked answer it looks like that it should be used to access the dependency-crates in the former versions of rust.

TL;DR

What are the usages for extern crate? Since it looks like an alternative way of adding depencies with less options.

1 Like

extern crate was necessary in the 2015 edition to actually use a dependency you declared in Cargo.toml. Since the 2018 edition crates will implicitly be loaded at the first reference. Using extern crate is thus not necessary anymore in (almost) all cases and is advised against.

8 Likes

And to expand on this one in particular: no, it's not. You still unconditionally need to add dependencies to Cargo.toml.

I read that elsewhere some time ago. Out of curiosity, what are those cases?

It's still necessary to use extern crate when linking to crates which are not pulled in as Cargo dependencies, but are provided by the toolchain itself, such as proc_macro.

2 Likes

extern crate proc_macro; is not need needed anymore (I don't remember since when). I think Cargo injects it or something. It is required for alloc, and I think also for test.

4 Likes

Also, sometimes you might want/need to rename some crate like :

extern crate core as std;

Which will affect every module in the project.

4 Likes

Think of extern crate as a declaration inside your code that tells the compiler you want to link to another crate so you can use its functionality, kinda like the -l argument for clang or gcc. Whereas the [dependencies] section in Cargo.toml will orchestrate the downloading and building of your dependencies[1].

Most of the time what your crate needs to link with can be inferred from your Cargo.toml, so in the 2018 edition it was decided to make this extern crate implicit to reduce the boilerplate needed to use a dependency and match intuition ("I've already added foo to my Cargo.toml so why do I also need to write extern crate foo at the top of my lib.rs?").

However, some crates aren't present in your Cargo.toml because they are distributed with the Rust toolchain instead of being downloaded from crates.io. Some examples of these are the std, alloc, core, and proc_macro crates, although extern crate std will be injected automatically with the prelude. You can also do extern crate rustc to use the Rust compiler as a library, but that requires a #![feature(rustc_private)] because the compiler's internals are perma-unstable.


  1. This isn't 100% true and I'm hand waving a bit, but the analogy should help build intuition anyway. ↩ī¸Ž

10 Likes

Thank you for the detail explanation!

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.