Skip to content

Inject the hermit crate if necessary#154130

Open
mkroening wants to merge 1 commit intorust-lang:mainfrom
hermit-os:inject-hermit
Open

Inject the hermit crate if necessary#154130
mkroening wants to merge 1 commit intorust-lang:mainfrom
hermit-os:inject-hermit

Conversation

@mkroening
Copy link
Contributor

This PR makes rustc always link against the hermit crate on Hermit if the crate is present.

For Hermit, the static library OS (libhermit.a) is compiled in the hermit crate's build script and then linked against. Users just add hermit to the application's Cargo.toml. This causes Cargo to call rustc with --extern hermit=$PATH_TO_libhermit-hash.rlib. Unless users also specify extern crate hermit, though, rustc calls the linker without libhermit.rlib, which is intended:

--extern merely makes the crate a candidate for being linked; it does not actually link it unless it’s actively used.

Command-line Arguments - The rustc book

This PR makes sure that rustc links against the hermit crate if some libhermit-hash.rlib file is being supplied. From the outside, this is similar to replacing --extern hermit with --extern force:hermit but also supports crate renaming. Internally, the crate mechanism works similarly to the one that is used for compiler builtins, forced externs, the profiler runtime, the allocator crate, and the panic runtime. This allows users to avoid modifying their Rust applications to use Hermit. Putting the crate into the Cargo.toml is sufficient.

This approach is very similar to what we do in our GCC cross compiler (hermit-os/gcc/gcc/config/i386/hermit.h#L5): we put -lhermit into LIB_SPEC to ensure that each Hermit application links against libhermit.a. This PR applies the same approach to rustc but has to account for the hash in libhermit-hash.rlib and accounts for the possibility of users renaming the hermit crate.

An alternative for a more general approach to avoid adding more target-specific code to rustc-metadate could be stabilizing --extern force (#111302) and making this available for dependencies. Then, the hermit crate could enable extern force in its Cargo.toml, which would ensure it is linked even if unused. This would likely take a while, though, and I am not sure if we have the resources to put significant effort into such a more general approach. Meanwhile, this small patch might be bearable.

On Hermit, the OS is included in the `hermit` crate. This commit makes
sure we link against the possibly renamed `hermit` crate if it is
provided even if there is no explicit `extern hermit`.

This is similar to replacing `--extern hermit` with `--extern force:hermit`.
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Mar 20, 2026
@rustbot
Copy link
Collaborator

rustbot commented Mar 20, 2026

r? @petrochenkov

rustbot has assigned @petrochenkov.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 69 candidates
  • Random selection from 14 candidates

@petrochenkov
Copy link
Contributor

Individual targets certainly shouldn't require special casing like this from the compiler.

Stabilizing force in some form would be a good long term solution, yes.
In the meantime if a library needs to be linked even if nothing from it is used in source code, it has to document that extern crate lib_name as _; needs to be used. There are other libraries that need it, not just hermit.

If the hermit library is so ubiquitous on the hermit targets if pretty much anything links it, then it could also potentially become a dependency of libstd.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 20, 2026
@bjorn3
Copy link
Member

bjorn3 commented Mar 20, 2026

I agree with @petrochenkov. This is not something that should be done in the crate loader. Having the standard library depend on the hermit library would be a much better solution. If that is not an option as you want to allow users to use a newer version of Hermit than was available when the standard library got compiled, then having users add use hermit as _; (or extern crate hermit;) to their application would be the best option that doesn't add a special case to rustc.

As for stabilizing --extern force, I'm not aware of any blockers other than ensuring it has proper documentation. AFAICT the actual implementation of it is quite simple without any known issues.

@mkroening
Copy link
Contributor Author

Thanks for the swift responses!

Currently (for the past seven years), we tell users to put extern crate hermit into their applications for them to use Hermit. This PR was an attempt to make that not necessary, but I understand that doing it the GCC way is not desirable for rustc.

For the Hermit OS, the hermit crate is almost ubiquitous. Every application has to depend on it, since it includes the operating system. Making std depend on hermit is not feasible, not only because of the version, but also because the users will want to adjust the features of the OS through Cargo features, resulting in highly specialized unikernel images.

There are other libraries that need it, not just hermit.

In that case it might be useful to introduce an option to the Cargo.toml that allows dependencies to specify that Cargo force linking against them using --extern force.

Such a thing would likely not require an RFC, right? Instead, I should open an issue on Cargo's issue tracker for this feature request, right?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants