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

Bug: Linker Error When Using windows and mio (uses windows-sys) #2410

Closed
Nerixyz opened this issue Mar 30, 2023 · 5 comments · Fixed by #2412
Closed

Bug: Linker Error When Using windows and mio (uses windows-sys) #2410

Nerixyz opened this issue Mar 30, 2023 · 5 comments · Fixed by #2412
Labels
bug Something isn't working

Comments

@Nerixyz
Copy link
Contributor

Nerixyz commented Mar 30, 2023

Which crate is this about?

windows

Crate version

0.47

Summary

I'm trying to update windows to version 0.47. In my code, I used K32EnumProcesses (in 0.46 from kernel32.dll). This was removed in 0.47 and EnumProcesses was added. This function comes from psapi.dll. Using this on its own works fine. However, in the project I'm also using tokio which pulls in mio. Specifying mio in the Cargo.toml and compiling, results in a linker-error.

Toolchain version/configuration

Default host: i686-pc-windows-msvc
rustup home:  D:\Rust\rustup

installed toolchains
--------------------

stable-i686-pc-windows-gnu
stable-i686-pc-windows-msvc
stable-x86_64-pc-windows-gnu
stable-x86_64-pc-windows-msvc
nightly-2020-08-29-i686-pc-windows-msvc
nightly-2021-02-19-i686-pc-windows-msvc
nightly-2022-06-12-i686-pc-windows-msvc
nightly-2022-06-12-x86_64-pc-windows-msvc
nightly-i686-pc-windows-msvc
nightly-x86_64-pc-windows-msvc (default)
1.65-i686-pc-windows-msvc

active toolchain
----------------

nightly-x86_64-pc-windows-msvc (default)
rustc 1.70.0-nightly (2036fdd24 2023-03-27)

Note: I also tried to compile with stable (cargo +stable b).

Reproducible example

use std::mem;

use windows::{
    core::{Error as WinError, Result},
    Win32::System::ProcessStatus::EnumProcesses,
};

// some function that uses EnumProcesses
fn get_all_processes() -> Result<(Vec<u32>, u32)> {
    let mut buf = vec![0u32; 1024];
    let mut returned_bytes = 0;
    unsafe {
        if !EnumProcesses(
            buf.as_mut_ptr(),
            (mem::size_of::<u32>() * buf.len()) as u32,
            &mut returned_bytes,
        )
        .as_bool()
        {
            return Err(WinError::from_win32());
        }
    }
    Ok((buf, returned_bytes / (mem::size_of::<u32>() as u32)))
}

fn main() {
    dbg!(get_all_processes().unwrap());
}

Crate manifest

[package]
name = "example"
version = "0.1.0"
edition = "2021"

[dependencies]
windows = { version = "=0.47", features = ["Win32_Foundation", "Win32_System_ProcessStatus"] }
mio = "0.8.6"

Expected behavior

The binary should compile without any errors.

Actual behavior

Compiling results in a linker-error:

error: linking with `link.exe` failed: exit code: 1120
  |
  = note: "D:\\VisualStudio 2022\\VC\\Tools\\MSVC\\14.35.32215\\bin\\HostX64\\x86\\link.exe" "/NOLOGO" "/LARGEADDRESSAWARE" "/SAFESEH" "C:\\Users\\Johannes\\AppData\\Local\\Temp\\rustc60Hp4R\\symbols.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.10v1qk6gwxxitm6u.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.143gr5jzaqncoibx.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.173ry79el3r37uy4.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.19elwrcp46qq2bow.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.19okhzq4vss3h4iv.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.28b8bnb6lcgeswq6.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.2psi4w84g5ixa6kr.rcgu.o" 
"G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.2r3rqpigujbspeuv.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.2zw80lyx6zzorfjq.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.3e3tspw6xly2do2i.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.40bv0spe8ot0haw4.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.4d1y1uvd92h2wl5j.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.4jo4mj54y1i4i2w8.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.4oqyhim9mnscp3qe.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.4r8qjow4wa5sqwyc.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.5dx9ldipe9yc4ran.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.bs4r7o47zyg6ptb.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.gfqf7cso18zg8e4.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.tivyvndp2puectd.rcgu.o" 
"G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.y2hygd3u8g4z4aq.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.yrbt3eor9twn9bc.rcgu.o" "G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.4aq17lx8gt5wjefb.rcgu.o" "/LIBPATH:G:\\Dev\\cargo-test\\target\\debug\\deps" "/LIBPATH:D:\\Rust\\cargo\\registry\\src\\github.com-1285ae84e5963aae\\windows_i686_msvc-0.42.2\\lib" "/LIBPATH:D:\\Rust\\cargo\\registry\\src\\github.com-1285ae84e5963aae\\windows_i686_msvc-0.47.0\\lib" "/LIBPATH:D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib" "G:\\Dev\\cargo-test\\target\\debug\\deps\\libwindows-2f7d1b1e62caa374.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libstd-6bc3c267dccd1407.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libpanic_unwind-f3372e197f57c25b.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\librustc_demangle-ba86a3b40dfeb436.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libstd_detect-8067f3793b24ce83.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libhashbrown-66106553fb55aed5.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libminiz_oxide-279d438d7556a7e7.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libadler-347d8776c566f0eb.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\librustc_std_workspace_alloc-0d36d7c1d6ef43af.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libunwind-b03d01cf9bd87ee1.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libcfg_if-f82579346fbfb791.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\liblibc-9706fd397d3b79de.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\liballoc-551058c15bbc9ba9.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\librustc_std_workspace_core-f1a86f24101b242b.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libcore-799d8e84cd5e1cff.rlib" "D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib\\libcompiler_builtins-7c1c0e97cf8cda48.rlib" "windows.lib" "kernel32.lib" "advapi32.lib" "userenv.lib" "kernel32.lib" "ws2_32.lib" "bcrypt.lib" "msvcrt.lib" "legacy_stdio_definitions.lib" "/NXCOMPAT" "/LIBPATH:D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\i686-pc-windows-msvc\\lib" "/OUT:G:\\Dev\\cargo-test\\target\\debug\\deps\\cargo_test.exe" "/OPT:REF,NOICF" "/DEBUG" "/NATVIS:D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\etc\\intrinsic.natvis" 
"/NATVIS:D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\etc\\liballoc.natvis" "/NATVIS:D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\etc\\libcore.natvis" "/NATVIS:D:\\Rust\\rustup\\toolchains\\stable-i686-pc-windows-msvc\\lib\\rustlib\\etc\\libstd.natvis"
  = note: cargo_test.gfqf7cso18zg8e4.rcgu.o : error LNK2019: unresolved external symbol __imp__EnumProcesses@12 referenced in function __ZN7windows7Windows5Win326System13ProcessStatus13EnumProcesses17h6e2fa32296735387E
          G:\Dev\cargo-test\target\debug\deps\cargo_test.exe : fatal error LNK1120: 1 unresolved externals

Additional comments

I couldn't lower the problem down to a specific function from windows-sys that's used by mio.

@Nerixyz Nerixyz added the bug Something isn't working label Mar 30, 2023
@Nerixyz Nerixyz changed the title Bug: Linker Error When using windows and mio (uses windows-sys) Bug: Linker Error When Using windows and mio (uses windows-sys) Mar 30, 2023
@kennykerr
Copy link
Collaborator

On it - will get a fix out asap.

@kennykerr
Copy link
Collaborator

I can release a compatible version of windows-targets that would be version 0.42.3 and include imports for both the old and new functions. I would then yank 0.47.0 along with updating any crates that depend on 0.47.0 to use 0.42.3 instead.

https://crates.io/crates/windows-targets/versions

Then everyone is again compatible and we won't need another release of windows-sys.

How does that sound?

@Nerixyz
Copy link
Contributor Author

Nerixyz commented Mar 30, 2023

Sounds good! Not needing release for windows-sys is nice. This way the dependencies should just work without any work required for their maintainers.

@kennykerr
Copy link
Collaborator

Just a quick update.

I spent the last few hours digging into this issue, testing and debugging a few different scenarios including your repro - thanks! - and there are broadly two different issues here:

  • The Win32 metadata incorrectly yanked some functions, causing the lib files to omit those imports, causing linker issues. v46 yanked some functions - intentional? win32metadata#1496

  • This was the first major update to the windows-targets crate and highlighted a problem with the way that libs are versioned. This is actually the real cause of this particular issue. Even though your repro caused Cargo to download two different versions of windows-targets and include them both, the lib file names in both cases were the same so the linker, not knowing anything about semver, just picked one "randomly" based on path search order.

The Win32 metadata issue has now been resolved and we should have a fix trickling into windows-rs soon. If not, I can always merge the metadata on my end in the short term. This will avoid having to download and build different versions of windows-targets.

The solution to the larger issue I landed on is to embed the version number of the windows-targets crate in the name of the contained lib files. That way, the lib files will always be pinned to the particular version of windows-targets and even when you land up in a situation with multiple windows-targets crates in a single build, the names of the lib files won't collide.

The downside in the short term is that this does require some major surgery to the windows-targets crate and I'm reluctant to try and release a semver compatible update. I think I should instead yank the 0.47 crates and release a major new version (0.48) of all the crates. This will of course be compatible with the existing versions of windows-sys and windows since the lib names won't collide.

How does that sound?

@Nerixyz
Copy link
Contributor Author

Nerixyz commented Mar 30, 2023

That way, the lib files will always be pinned to the particular version of windows-targets and even when you land up in a situation with multiple windows-targets crates in a single build, the names of the lib files won't collide.

This is really important. I think it will be common for users to have at least a dependency on windows and windows-sys at the same time when more libraries adopt both crates.

This will of course be compatible with the existing versions of windows-sys and windows since the lib names won't collide.

How does that sound?

Sounds good! Especially since a release for windows-sys was requested in #2411.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants