forked from rust-lang/rust
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#109421 - mhammerly:extern-force-option, r=pet…
…rochenkov Add `force` option for `--extern` flag When `--extern force:foo=libfoo.so` is passed to `rustc` and `foo` is not actually used in the crate, ~inject an `extern crate foo;` statement into the AST~ force it to be resolved anyway in `CrateLoader::postprocess()`. This allows you to, for instance, inject a `#[panic_handler]` implementation into a `#![no_std]` crate without modifying its source so that it can be built as a `dylib`. It may also be useful for `#![panic_runtime]` or `#[global_allocator]`/`#![default_lib_allocator]` implementations. My work previously involved integrating Rust into an existing C/C++ codebase which was built with Buck and shipped on, among other platforms, Android. When targeting Android, Buck builds all "native" code with shared linkage* so it can be loaded from Java/Kotlin. My project was not itself `#![no_std]`, but many of our dependencies were, and they would fail to build with shared linkage due to a lack of a panic handler. With this change, that project can add the new `force` option to the `std` dependency it already explicitly provides to every crate to solve this problem. *This is an oversimplification - Buck has a couple features for aggregating dependencies into larger shared libraries, but none that I think sustainably solve this problem. ~The AST injection happens after macro expansion around where we similarly inject a test harness and proc-macro harness. The resolver's list of actually-used extern flags is populated during macro expansion, and if any of our `--extern` arguments have the `force` option and weren't already used, we inject an `extern crate` statement for them. The injection logic was added in `rustc_builtin_macros` as that's where similar injections for tests, proc-macros, and std/core already live.~ (New contributor - grateful for feedback and guidance!)
- Loading branch information
Showing
7 changed files
with
78 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,7 @@ where | |
is_private_dep: false, | ||
add_prelude: true, | ||
nounused_dep: false, | ||
force: false, | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
#![feature(lang_items)] | ||
#![no_std] | ||
|
||
// Since `rustc` generally passes `-nodefaultlibs` to the linker, | ||
// Rust programs link necessary system libraries via `#[link()]` | ||
// attributes in the `libc` crate. `libc` is a dependency of `std`, | ||
// but as we are `#![no_std]`, we need to include it manually. | ||
#![feature(rustc_private)] | ||
extern crate libc; | ||
|
||
#[panic_handler] | ||
pub fn begin_panic_handler(_info: &core::panic::PanicInfo<'_>) -> ! { | ||
loop {} | ||
} | ||
|
||
#[lang = "eh_personality"] | ||
extern "C" fn eh_personality() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// check-pass | ||
// ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header) | ||
// aux-crate:force:panic_handler=panic_handler.rs | ||
// compile-flags: -Zunstable-options --crate-type dylib | ||
// edition:2018 | ||
|
||
#![no_std] | ||
|
||
fn foo() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
// aux-crate:panic_handler=panic_handler.rs | ||
// ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header) | ||
// compile_flags: -Zunstable-options --crate-type dylib | ||
// error-pattern: `#[panic_handler]` function required, but not found | ||
// dont-check-compiler-stderr | ||
// edition: 2018 | ||
|
||
#![no_std] | ||
|
||
fn foo() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// check-pass | ||
// ignore-cross-compile (needs dylibs and compiletest doesn't have a more specific header) | ||
// aux-crate:force:panic_handler=panic_handler.rs | ||
// compile-flags: -Zunstable-options --crate-type dylib | ||
// edition:2018 | ||
|
||
#![no_std] | ||
|
||
extern crate panic_handler; | ||
|
||
fn foo() {} |