I'm new to Rust and I'm having trouble understanding what extern crate foo does. I work mainly in C, maybe someone has a C analogy? When is it necessary to write that line?
As I understand, use would be kind of like an #include, but instead of including files it brings modules or functions into scope (? - not 100% sure).
Alright, makes sense. I was wondering why I couldn't find that statement in The Book. I guess I've only seen it in examples in the documentation of old, unmaintained crates.
Unfortunately it's not 100% gone yet, e.g. for working with optionally-std-using crates you still need it for extern crate alloc; and extern crate std;, and proc-macros need extern crate proc_macro;. But definitely for newcomers it shouldn't be necessary.
Aha! So that's where I've seen it! I'm an embedded developer and I've seen extern crate foo lines in the Embedded book and other tutorials/examples, e.g. in here.
Can someone explain then when is it needed? If that statement is needed often in the embedded development world, then I guess I should know what it is for and why is it needed.
It's needed for alloc and std because there's no way to add them as dependencies in your Cargo.toml. So you'll see a lot of crates that optionally support allocation doing something like
This says that by default this crate doesn't need std or alloc and has only one function available, foo; but, if you activate the alloc feature it will additionally depend on the alloc crate shipped with the compiler and provide the function bar using types from it.
The extern crate panic_halt; in that example is actually another case altogether, panic_halt's public API is a #[panic_handler] function. How #[panic_handler] and some other "weak dependencies" of core/alloc are linked together is a bit weird, and in order to make sure it is linked in you need to use either extern crate panic_halt; or use panic_halt as _; so that rustc won't just skip the crate as an unused dependency.
This is the most common case you'll see in embedded Rust, in my experience: a crate that does its work simply by being linked into the program, because it provides a special piece of data like an interrupt vector table, or a special function like a panic hook. Such a crate is never "used" by the code, so you need to extern crate it to instruct the toolchain to include it during linking.
This can also come up if you're writing very minimal embedded applications using e.g. cortex_m_rt. If you don't actually use anything from the crate, but want to have a valid interrupt vector table, you may have to extern crate it.
There is also this section in the Rust by Example "book". Would I be able to write a use statement instead of the extern crate one, as long as I declared the dependency in Cargo.toml?