I'm targeting aarch64-unknown-linux-gnu and building openssl-sys with the vendored feature enabled. If have an cross toolchain installed, so I can specify target.linker = aarch64-linux-gnu-gcc and it successfully builds. I'm wondering why I don't need to also specify the compiler/archiver as well. Does setting linker imply that rustc should use the associated toolchain of said linker?
They either make or find you a static library, which isn't really a library, but a bunch of unlinked object files.
Or you emit a "please link to this later" directive for dynamic libraries, which have already been linked long before you even installed them on your system.
Cargo doesn't support building and linking Rust dependencies as dylibs (as opposed to the internal rlib format for staticlaly-linked Rust dependencies), and doesn't have features for managing install paths of dylibs, so there isn't really a viable third option for building dylibs on the fly for the current Rust build.
Static libraries are not linked by the sys crates, by definition. They're not a binary. They're an ar archive, which is like a .zip file of .o files before linking. There is nothing linker-specific about the ar files.
Static libraries are an unfinished product that is later fed to to the linker along with all other object files and other static libraries to produce the final Rust program or dylib. That happens only after sys crates finish running.
Interesting, maybe I'm using the wrong terminology. I thought that when I depend on openssl-sys, with the vendored features, that that enabled the openssl-src feature which adds a dependency that literally contains the openssl source code, builds that, and statically links it into my Rust binary.
There is a chance that OpenSSL's build glue looks for the standard target-prefixed cross compiler on your PATH, which could be what's making it "just work".
And all of that vendored openssl build literally does not touch the linker at any point. It uses the compiler, archiver, but no linker.
Dynamic libraries are made by compiling and linking, and static libraries are made by compiling and NOT linking. That's the primary difference between them. If you use a linker on a static library, it's not going to be a static library any more.
Another way to think about it is that linker can be run only once, as the final step in making a binary. If you're building a Rust executable, this means the one and only invocation of the linker happened when Rust/Cargo created the executable, and nowhere earlier in the process of building dependencies.
I see what you're saying. The build fails at the very last step due to the linker not knowing how to assemble the final binary for the target platform (?). As for actually producing assembly, the openssl build crate likely looks for the cross toolchain in my path.
After uninstalling the cross toolchain, cargo was still able to compile all the crates, including openssl-sys, which makes me thing that it is just using clangs inherent cross compiling capabilities? It still failed the final link step, obviously.