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

Why does windows-targets have compiled static libraries? #2443

Closed
rodrigocfd opened this issue Apr 13, 2023 · 9 comments
Closed

Why does windows-targets have compiled static libraries? #2443

rodrigocfd opened this issue Apr 13, 2023 · 9 comments
Labels
question Further information is requested

Comments

@rodrigocfd
Copy link

This issue is just a question.

The windows crate depends on windows-targets crate for linker support. And windows-targets depends on internal crates which vary according to the platform. These crates have compiled static libraries like this one, which are passed to the linker via cargo:rustc-link-search=native={LIB_DIR}.

Now I'm wondering:

  1. Why are those static libraries necessary?
  2. Do they contain only the compiled code from baseline folder?

I'm curious because the program below, with zero dependencies, works fine:

#[link(name = "user32")]
extern "system" {
	fn MessageBoxW(
		_: *mut std::ffi::c_void,
		_: *const u16,
		_: *const u16,
		_: u32,
	) -> i32;
}

fn main() {
	unsafe {
		MessageBoxW(
			std::ptr::null_mut(),
			"Text".encode_utf16()
				.chain(std::iter::once(0))
				.collect::<Vec<_>>()
				.as_ptr(),
			"Caption".encode_utf16()
				.chain(std::iter::once(0))
				.collect::<Vec<_>>()
				.as_ptr(),
			0,
		);
	}
}
@riverar
Copy link
Collaborator

riverar commented Apr 13, 2023

Hi @rodrigocfd, those are import libraries not static libraries.

The baseline folder is used to detect import library differences--it's less cumbersome than trying to diff a binary blob. See also #2132.

Closing as there's nothing actionable here but feel free to keep the discussion going/ask any follow up questions.

@riverar riverar closed this as not planned Won't fix, can't repro, duplicate, stale Apr 13, 2023
@riverar riverar added the question Further information is requested label Apr 13, 2023
@ChrisDenton
Copy link
Collaborator

To put it another way, your example has a dependency:

#[link(name = "user32")]

You're depending on the target specific import library "user32.lib". These libraries are usually managed by the Visual Studio or the Windows SDK installer. Rust is somewhat "smart" and will attempt to locate these kinds of dependencies for you.

Rather than having to find arbitrary import libraries from arbitrary SDK versions, the correct import libraries are distributed with windows-rs. This bundles all the required imports into one lib file for your target and makes sure there are no missing imports for your version of windows-rs. The windows-targets crate is just a way to manage using the correct library for the target.

@rodrigocfd
Copy link
Author

Thanks for the answers, guys.

Let me see if I got this right: if I'm using MSVC, when writing #[link(name = "user32")], I'm depending on the user32.lib provided by MSVC, which will be somewhat found by Cargo. Similarly, if I'm using GCC, I'm depending on the user32.lib provided by GCC.

So, windows-targets provides its own user32.lib, so I depend on no one else's.

Is that it?

@ChrisDenton
Copy link
Collaborator

Yep!

I should also mention a new feature coming soon is raw-dylib which will allow rust to generate the import libraries as needed instead of requiring pre-built ones.

@kennykerr
Copy link
Collaborator

And the windows-targets crate already supports raw-dylib. Using the windows_raw_dylib flag will avoid downloading and linking the import libs automatically.

@rodrigocfd
Copy link
Author

Now I'm wondering: why is it so bad to depend on the import libs provided by the toolchains? I mean, all those C and C++ programs are being built with them for decades.

Did you guys ever come across some situation where they didn't work as expected?

@riverar
Copy link
Collaborator

riverar commented Apr 14, 2023

One reason is that the crate provides access to APIs that may not have corresponding import libraries in the Windows SDK.

@kennykerr
Copy link
Collaborator

https://kennykerr.ca/rust-getting-started/understanding-windows-targets.html

@rodrigocfd
Copy link
Author

https://kennykerr.ca/rust-getting-started/understanding-windows-targets.html

This pretty much what I wanted to know.

@riverar, @ChrisDenton and @kennykerr, thank you very much.

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

No branches or pull requests

4 participants