Skip to content
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

windows-sys without CRT? #1989

Closed
Zymlex opened this issue Aug 28, 2022 · 14 comments
Closed

windows-sys without CRT? #1989

Zymlex opened this issue Aug 28, 2022 · 14 comments

Comments

@Zymlex
Copy link

Zymlex commented Aug 28, 2022

As I see, windows-sys uses no_std, but still try to link with CRT.
Is it possible to use windows-sys without CRT?

upd: #1989 (comment)

@tim-weis
Copy link
Contributor

Could you provide a repro?

I'm not sure I'm seeing the same as you are, however, the (failed) imports I see aren't actually from the CRT, but rather the SEH infrastructure (__CxxFrameHandler3, _CxxThrowException). I don't know where those are getting pulled in (or the memsets further down).

This is the repro I'm using:

Cargo.toml

[package]
name = "nostd_windows-sys"
version = "0.0.0"
edition = "2021"

[dependencies.windows-sys]
version = "0.36.1"
features = [
    "Win32_Foundation",
    "Win32_System_Threading",
]

src/main.rs

#![no_std]
#![no_main]

use core::panic::PanicInfo;

use windows_sys::Win32::System::Threading::{GetCurrentProcess, TerminateProcess};

#[panic_handler]
fn panic_abort(_info: &PanicInfo) -> ! {
    unsafe {
        let h = GetCurrentProcess();
        TerminateProcess(h, 1);
    };
    unreachable!();
}

#[no_mangle]
pub extern "C" fn EntryPoint() -> u32 {
    0
}

.cargo/config.toml

[build]
rustflags = [
    "-C", "link-arg=/ENTRY:EntryPoint"
]

(Note: I don't know why the linker cannot find the entry point.)

@riverar
Copy link
Collaborator

riverar commented Aug 28, 2022

I'm seeing similar CRT functions getting referenced (__CxxFrameHandler3) as @Zymlex reported using @tim-weis's sample (after adding an empty eh_personality function and setting the subsystem):

...
 libcore-798bc7c2d986ac97.rlib(core-798bc7c2d986ac97.core.db87af78-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol memcpy referenced in function _ZN4core3num7flt2dec8strategy6dragon15format_shortest17h09419dd069410d1fE
 libcore-798bc7c2d986ac97.rlib(core-798bc7c2d986ac97.core.db87af78-cgu.0.rcgu.o) : error LNK2019: unresolved external symbol memcmp referenced in function _ZN63_$LT$core..ffi..c_str..CStr$u20$as$u20$core..cmp..PartialEq$GT$2eq17h66848a7c3b9113a9E
 libcore-798bc7c2d986ac97.rlib(core-798bc7c2d986ac97.core.db87af78-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol __CxxFrameHandler3
 libcore-798bc7c2d986ac97.rlib(core-798bc7c2d986ac97.core.db87af78-cgu.0.rcgu.o) : error LNK2001: unresolved external symbol _fltused

@ChrisDenton
Copy link
Collaborator

ChrisDenton commented Aug 28, 2022

Using panic=abort would be an option for removing panic handling. Although it may also need lto=true to remove all panic handling infrastructure.

Also compiler-builtins can provide mem* functions.

But I don't think any of this has anything to do with windows-sys.

@riverar
Copy link
Collaborator

riverar commented Aug 28, 2022

Using panic=abort would be an option for removing panic handling. Although it may also need lto=true to remove all panic handling infrastructure.

Also compiler-builtins can provide mem* functions.

Doesn't work for me.

@ChrisDenton
Copy link
Collaborator

Hm, this seems to have regressed in 1.60. For 1.59 and earlier the panic handling code is removed with panic=abort and lto.

@kennykerr
Copy link
Collaborator

The windows-sys crate only contains type and function declarations. There's no code, so I don't think this issue is specific to this crate.

@tim-weis
Copy link
Contributor

@ChrisDenton I used to have

[profile.release]
panic = 'abort'
lto = 'fat'

in Cargo.toml, but that didn't change anything. This is using 1.63, so this at least doesn't contradict your hypothesis. Still, as Kenny points out, I cannot think of any way that the windows-sys crate could even pull in any CRT dependencies.

Seems to be an issue with my repro, or @Zymlex's, or rustc.

@kennykerr
Copy link
Collaborator

Rafael pointed out that the windows-sys crate does provide Clone implemenetations that look like this:

impl ::core::clone::Clone for IO_COUNTERS {
    fn clone(&self) -> Self {
        *self
    }
}

This can result in the Rust compiler, or LLVM, injecting calls to functions or intrinsics like memcpy. So while the windows-sys crate does not have any explicit dependency on the CRT, it is likely that you cannot get away from it in practice if Rust itself has such a dependency.

@kennykerr
Copy link
Collaborator

Does this help? #1992

@Zymlex
Copy link
Author

Zymlex commented Aug 29, 2022

Minimal sample: https://github.com/Zymlex/TestCRTLinking

msvcrt.lib passed explicitly in linker:

Link args

"C:\\Program Files (x86)\\Microsoft Visual Studio\\2022\\BuildTools\\VC\\Tools\\MSVC\\14.33.31629\\bin\\HostX64\\x64\\link.exe" "/NOLOGO" "C:\\Temp\\rustcFQAfsD\\symbols.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.0.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.1.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.10.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.11.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.12.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.13.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.14.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.15.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.2.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.3.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.4.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.5.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.6.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.7.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.8.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.build_script_build.d23cf486-cgu.9.rcgu.o" "D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.526mukq0e2230mny.rcgu.o" "/LIBPATH:D:\\TestCRT\\target\\debug\\deps" "/LIBPATH:D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd-8423b2aaecc07cbd.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libpanic_unwind-140625d412b34ac2.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_demangle-6b3a560234908e6a.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libstd_detect-e813d6686824bdf5.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libhashbrown-f70691b8a0682d5c.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libminiz_oxide-c56fd5f6dd80139a.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libadler-07da6c35c286f881.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-3609338aefc74bee.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libunwind-75617f1352752ad2.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcfg_if-d095611f20a3926f.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liblibc-863480ba106f69c6.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\liballoc-b88f15a049f875f2.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\librustc_std_workspace_core-69892fa511d5a698.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcore-798bc7c2d986ac97.rlib" "D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib\\libcompiler_builtins-7738daf2e99ec4b2.rlib" "advapi32.lib" "userenv.lib" "kernel32.lib" "ws2_32.lib" "bcrypt.lib" "msvcrt.lib" "legacy_stdio_definitions.lib" "/NXCOMPAT" "/LIBPATH:D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\x86_64-pc-windows-msvc\\lib" "/OUT:D:\\TestCRT\\target\\debug\\build\\windows_x86_64_msvc-0573644fe28a5604\\build_script_build-0573644fe28a5604.exe" "/OPT:REF,NOICF" "/DEBUG" "/NATVIS:D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis" "/NATVIS:D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" "/NATVIS:D:\\Rust\\rustup\\toolchains\\nightly-x86_64-pc-windows-msvc\\lib\\rustlib\\etc\\libstd.natvis" "/NODEFAULTLIB" "/SUBSYSTEM:WINDOWS" "/ENTRY:main_entry_point" "/VERBOSE" "/WX"

@Zymlex
Copy link
Author

Zymlex commented Aug 29, 2022

This set is also of interest:

"advapi32.lib" "userenv.lib" "kernel32.lib" "ws2_32.lib" "bcrypt.lib" "msvcrt.lib" "legacy_stdio_definitions.lib"

@riverar
Copy link
Collaborator

riverar commented Aug 29, 2022

So, no_std is a toggle between std and core crates and relies on toolchains, crates, etc. all working together to realize the "no standard library" vision, which seems to be somewhat nebulously defined in my reading. It does not appear there is any work to be done on the windows-sys side, so I'm going to close this issue.

That said, I recognize that without a real working end-to-end example, this all feels like a sham. You might want to get the ball rolling on https://github.com/rust-lang/rust/issues.

Some issues to keep an eye on:

@riverar riverar closed this as not planned Won't fix, can't repro, duplicate, stale Aug 29, 2022
@Zymlex
Copy link
Author

Zymlex commented Aug 29, 2022

Managed to figure it out! Due to a bug, it is necessary to pass arguments through environment variables + cargo args:

RUSTFLAGS=-Clink-arg=/NODEFAULTLIB -Clink-arg=/SUBSYSTEM:WINDOWS -Clink-arg=/ENTRY:main_entry_point -Clink-arg=/VERBOSE -Clink-arg=/WX

cargo build --package test_crt -Zbuild-std=core --target x86_64-pc-windows-msvc --verbose

So I was able to build without CRT, Winsock and other...

@ChrisDenton
Copy link
Collaborator

ChrisDenton commented Aug 29, 2022

this all feels like a sham

I'm not really sure what you mean by that? I created some examples. The nostd crate is a normal no_std application using functions provided by the vcruntime, which is simple enough. It doesn't use the crt but the crt startup code is pretty minimal (and somewhat configurable) so I'm not sure that there's much reason to avoid it.

The nostd_novcrt crate is compiled without using vcruntime which, yes, requires some basic function definitions (mostly mem functions). Though using the platform functions (provided by vcruntime) would be better for performance (which is why Rust doesn't provide them by default) and indeed I'm not sure why anyone wouldn't want to use the platform implementation. I guess if they can hand write some better implementations or they have some kind of licensing concerns (in which case the msvc toolchain probably isn't a good idea for them).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants