Skip to content

Test linking and running no_std binaries #138904

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 11, 2025

Conversation

madsmtm
Copy link
Contributor

@madsmtm madsmtm commented Mar 24, 2025

I looked around, but it seems that we do not have a test that tests a #![no_std] + #![no_main] binary. So now I've added one. Motivated by discussion in this Zulip thread.

r? @tgross35

try-job: arm-android
try-job: armhf-gnu
try-job: dist-ohos
try-job: x86_64-mingw-1

@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 24, 2025
Comment on lines 13 to 31
// Need to link libSystem on Apple platforms, otherwise the linker fails with:
// > ld: dynamic executables or dylibs must link with libSystem.dylib
//
// With the new linker introduced in Xcode 15, the error is instead:
// > Undefined symbols: "dyld_stub_binder", referenced from: <initial-undefines>
//
// This _can_ be worked around by raising the deployment target with
// MACOSX_DEPLOYMENT_TARGET=13.0, though it's a bit hard to test that while
// still allowing the test suite to support running with older Xcode versions.
#[cfg_attr(target_vendor = "apple", link(name = "System"))]
extern "C" {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could just always link libSystem internally in rustc, but I'm not sure that's a good idea, since as noted, it is possible to create a fully no_std binary that doesn't link libSystem, it just requires the user to do some work.

Maybe better would be to document the limitation somewhere (where?)? Note that libc does the linking internally too (linking to libc.dylib also links to libSystem.dylib), so any code that does #![no_std] but uses libc works without this.

@folkertdev
Copy link
Contributor

For completeness, there is https://github.com./rust-lang/rust/blob/master/tests/run-make/thumb-none-qemu/example/src/main.rs so it's not completely untested, but coverage on more platforms is good of course.


//@ run-pass
//@ compile-flags: -Cpanic=abort
//@ ignore-wasm different `main` convention
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if we need to add more to the ignores here? Is something like ignore-embedded a thing, and would it make sense?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing run-pass already omits platforms that can't run standalone executables, cc @jieyouxu for a better answer.

Copy link
Member

@jieyouxu jieyouxu Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See

let proc_res = match &*self.config.target {
, I believe in the general case run-pass intentionally does not try to be "smart" and omit platforms that can't run standalone executables. Generally tests will need //@ ignore-cross-compile if they need to run the test binary (but that only runs on host).

@madsmtm
Copy link
Contributor Author

madsmtm commented Mar 24, 2025

For completeness, there is https://github.com./rust-lang/rust/blob/master/tests/run-make/thumb-none-qemu/example/src/main.rs so it's not completely untested, but coverage on more platforms is good of course.

Ah nice. Do you think I should try to merge this test with that?

@rust-log-analyzer

This comment has been minimized.

@folkertdev
Copy link
Contributor

folkertdev commented Mar 24, 2025

I don't think so, that test is very specifically for checking that the embedded ecosystem continues to work. It uses qemu to run on a simulated microcontroller. So instead additionally having this test for many more platforms in the ui tests seems independently useful.

@madsmtm madsmtm force-pushed the apple-test-no-std branch from e74978d to f9770e7 Compare March 24, 2025 22:22

// # Linux
//
// Linking `libc` is required by crt1.o, otherwise the linker fails with:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it would be fun to have a _start lib-less linux binary as well

@tgross35
Copy link
Contributor

tgross35 commented Apr 4, 2025

To have a no_main binary on Windows I believe you need mainCRTStartup as the entrypoint, plus a /subsystem linker arg and a handful of symbols need to be defined (https://nullprogram.com/blog/2023/02/15/ is a pretty good tutorial). I'm not sure if there is something that can be linked to make things "just work" with an unmangled main like MacOS and Linux, @ChrisDenton would likely know. We can still try this to see where it gets.

@bors try

Maybe it's worth adding a second test that links nothing, like Nora's suggestion? I'm not sure that is possible on MacOS but it is probably more interesting on Linux.

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 4, 2025
Test linking and running `no_std` binaries

I looked around, but it seems that we do not have a test that tests a `#![no_std]` + `#![no_main]` binary. So now I've added one. Motivated by discussion in [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/Provide.20.60__isPlatformVersionAtLeast.60.20in.20.60std.60.3F/with/507870028).

r? `@tgross35`

I haven't tested on Windows, so:
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2

And only tested lightly on Linux, so:
try-job: x86_64-linux

try-job: test-various
@bors

This comment was marked as outdated.

@rust-log-analyzer

This comment was marked as outdated.

@ChrisDenton
Copy link
Member

@tgross35 if you're using C main then it should just work, no extra steps needed, because you're using the C runtime.

@tgross35
Copy link
Contributor

tgross35 commented Apr 4, 2025

@bors try

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 4, 2025
Test linking and running `no_std` binaries

I looked around, but it seems that we do not have a test that tests a `#![no_std]` + `#![no_main]` binary. So now I've added one. Motivated by discussion in [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/Provide.20.60__isPlatformVersionAtLeast.60.20in.20.60std.60.3F/with/507870028).

r? `@tgross35`

I haven't tested on Windows, so:
try-job: x86_64-msvc-1
try-job: x86_64-msvc-2

And only tested lightly on Linux, so:
try-job: x86_64-gnu

try-job: test-various
@bors
Copy link
Collaborator

bors commented Apr 4, 2025

⌛ Trying commit f9770e7 with merge bb9c57a...

@bors
Copy link
Collaborator

bors commented Apr 4, 2025

☀️ Try build successful - checks-actions
Build commit: bb9c57a (bb9c57adf8785606340844eeae4898130594e2ff)

@tgross35
Copy link
Contributor

tgross35 commented Apr 8, 2025

LGTM but may as well try a couple of the more exotic targets before putting this into the queue. r=me with a pass.

@bors try

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 8, 2025
Test linking and running `no_std` binaries

I looked around, but it seems that we do not have a test that tests a `#![no_std]` + `#![no_main]` binary. So now I've added one. Motivated by discussion in [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/Provide.20.60__isPlatformVersionAtLeast.60.20in.20.60std.60.3F/with/507870028).

r? `@tgross35`

try-job: arm-android
try-job: armhf-gnu
try-job: dist-ohos
try-job: x86_64-mingw-1
@bors
Copy link
Collaborator

bors commented Apr 8, 2025

⌛ Trying commit f9770e7 with merge b40a57b...

@bors
Copy link
Collaborator

bors commented Apr 8, 2025

💥 Test timed out

@jieyouxu
Copy link
Member

jieyouxu commented Apr 8, 2025

@bors try

bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 8, 2025
Test linking and running `no_std` binaries

I looked around, but it seems that we do not have a test that tests a `#![no_std]` + `#![no_main]` binary. So now I've added one. Motivated by discussion in [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/Provide.20.60__isPlatformVersionAtLeast.60.20in.20.60std.60.3F/with/507870028).

r? `@tgross35`

try-job: arm-android
try-job: armhf-gnu
try-job: dist-ohos
try-job: x86_64-mingw-1
@bors
Copy link
Collaborator

bors commented Apr 8, 2025

⌛ Trying commit f9770e7 with merge 893fcd4...

@bors
Copy link
Collaborator

bors commented Apr 8, 2025

☀️ Try build successful - checks-actions
Build commit: 893fcd4 (893fcd4da31eb770555aa598b389e89901312482)

@tgross35
Copy link
Contributor

tgross35 commented Apr 8, 2025

@bors r+

@bors
Copy link
Collaborator

bors commented Apr 8, 2025

📌 Commit f9770e7 has been approved by tgross35

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Apr 8, 2025
Zalathar added a commit to Zalathar/rust that referenced this pull request Apr 10, 2025
Test linking and running `no_std` binaries

I looked around, but it seems that we do not have a test that tests a `#![no_std]` + `#![no_main]` binary. So now I've added one. Motivated by discussion in [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/Provide.20.60__isPlatformVersionAtLeast.60.20in.20.60std.60.3F/with/507870028).

r? `@tgross35`

try-job: arm-android
try-job: armhf-gnu
try-job: dist-ohos
try-job: x86_64-mingw-1
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 10, 2025
Rollup of 18 pull requests

Successful merges:

 - rust-lang#137412 (Ensure `swap_nonoverlapping` is really always untyped)
 - rust-lang#138167 (Small code improvement in rustdoc hidden stripper)
 - rust-lang#138605 (Clean up librustdoc::html::render to be better encapsulated)
 - rust-lang#138682 (Allow drivers to supply a list of extra symbols to intern)
 - rust-lang#138904 (Test linking and running `no_std` binaries)
 - rust-lang#139423 (Suppress missing field error when autoderef bottoms out in infer)
 - rust-lang#139449 (match ergonomics: replace `peel_off_references` with a recursive call)
 - rust-lang#139507 (compiletest: Trim whitespace from environment variable names)
 - rust-lang#139530 (Remove some dead or leftover code related to rustc-intrinsic abi removal)
 - rust-lang#139560 (fix title of offset_of_enum feature)
 - rust-lang#139563 (emit a better error message for using the macro incorrectly)
 - rust-lang#139568 (Don't use empty trait names)
 - rust-lang#139580 (Temporarily leave the review rotation)
 - rust-lang#139589 (saethlin is back from vacation)
 - rust-lang#139592 (rustdoc: Enable Markdown extensions when looking for doctests)
 - rust-lang#139599 (Tracking issue template: fine-grained information on style update status)
 - rust-lang#139600 (Update `compiler-builtins` to 0.1.153)
 - rust-lang#139606 (Update compiletest to Edition 2024)

r? `@ghost`
`@rustbot` modify labels: rollup
Zalathar added a commit to Zalathar/rust that referenced this pull request Apr 10, 2025
Test linking and running `no_std` binaries

I looked around, but it seems that we do not have a test that tests a `#![no_std]` + `#![no_main]` binary. So now I've added one. Motivated by discussion in [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/Provide.20.60__isPlatformVersionAtLeast.60.20in.20.60std.60.3F/with/507870028).

r? ``@tgross35``

try-job: arm-android
try-job: armhf-gnu
try-job: dist-ohos
try-job: x86_64-mingw-1
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 10, 2025
Rollup of 17 pull requests

Successful merges:

 - rust-lang#137412 (Ensure `swap_nonoverlapping` is really always untyped)
 - rust-lang#138167 (Small code improvement in rustdoc hidden stripper)
 - rust-lang#138605 (Clean up librustdoc::html::render to be better encapsulated)
 - rust-lang#138682 (Allow drivers to supply a list of extra symbols to intern)
 - rust-lang#138904 (Test linking and running `no_std` binaries)
 - rust-lang#139423 (Suppress missing field error when autoderef bottoms out in infer)
 - rust-lang#139449 (match ergonomics: replace `peel_off_references` with a recursive call)
 - rust-lang#139507 (compiletest: Trim whitespace from environment variable names)
 - rust-lang#139530 (Remove some dead or leftover code related to rustc-intrinsic abi removal)
 - rust-lang#139560 (fix title of offset_of_enum feature)
 - rust-lang#139563 (emit a better error message for using the macro incorrectly)
 - rust-lang#139568 (Don't use empty trait names)
 - rust-lang#139580 (Temporarily leave the review rotation)
 - rust-lang#139589 (saethlin is back from vacation)
 - rust-lang#139592 (rustdoc: Enable Markdown extensions when looking for doctests)
 - rust-lang#139599 (Tracking issue template: fine-grained information on style update status)
 - rust-lang#139600 (Update `compiler-builtins` to 0.1.153)

r? `@ghost`
`@rustbot` modify labels: rollup
bors added a commit to rust-lang-ci/rust that referenced this pull request Apr 11, 2025
Rollup of 12 pull requests

Successful merges:

 - rust-lang#137447 (add `core::intrinsics::simd::{simd_extract_dyn, simd_insert_dyn}`)
 - rust-lang#138182 (rustc_target: update x86_win64 to match the documented calling convention for f128)
 - rust-lang#138682 (Allow drivers to supply a list of extra symbols to intern)
 - rust-lang#138904 (Test linking and running `no_std` binaries)
 - rust-lang#138998 (Don't suggest the use of  `impl Trait` in closure parameter)
 - rust-lang#139447 (doc changes: debug assertions -> overflow checks)
 - rust-lang#139469 (Introduce a `//@ needs-crate-type` compiletest directive)
 - rust-lang#139564 (Deeply normalize obligations in `BestObligation` folder)
 - rust-lang#139574 (bootstrap: improve `channel` handling)
 - rust-lang#139600 (Update `compiler-builtins` to 0.1.153)
 - rust-lang#139641 (Allow parenthesis around inferred array lengths)
 - rust-lang#139654 (Improve `AssocItem::descr`.)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit 9a9a078 into rust-lang:master Apr 11, 2025
7 checks passed
@rustbot rustbot added this to the 1.88.0 milestone Apr 11, 2025
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Apr 11, 2025
Rollup merge of rust-lang#138904 - madsmtm:apple-test-no-std, r=tgross35

Test linking and running `no_std` binaries

I looked around, but it seems that we do not have a test that tests a `#![no_std]` + `#![no_main]` binary. So now I've added one. Motivated by discussion in [this Zulip thread](https://rust-lang.zulipchat.com/#narrow/channel/219381-t-libs/topic/Provide.20.60__isPlatformVersionAtLeast.60.20in.20.60std.60.3F/with/507870028).

r? ```@tgross35```

try-job: arm-android
try-job: armhf-gnu
try-job: dist-ohos
try-job: x86_64-mingw-1
@madsmtm madsmtm deleted the apple-test-no-std branch April 11, 2025 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. 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.

9 participants