1

The windows crate, which provides Rust bindings to the Windows API, is split into a few internal crates, one of them being the windows-targets. This create is also split in a few internal crates, and these are loaded according to the target platform.

These platform-dependent crates don't seem to do much: they simply pass cargo:rustc-link-search=native={LIB_DIR} to the compiler.

Now looking at these LIB_DIR directories, they contain an already-compiled static library, one for each platform. Example: windows.0.48.0.lib file.

I couldn't find any documentation regarding this, but I suppose these static libraries are compiled from the C source files found in the baseline directory, which contain... a duplication of the Windows API function declarations in C. That's intriguing.

The Rust bindings themselves are written somewhere else, like here (GDI bindings).

Question: these compiled C static libraries seem to be a duplication of the API already available in Windows, so why are they necessary?

Paul Dempsey
  • 639
  • 3
  • 19
rodrigocfd
  • 6,450
  • 6
  • 34
  • 68
  • Do you mean "duplication" or "wrapper"? – tadman Apr 10 '23 at 16:50
  • @tadman I mean "duplication". The C code already exists in Windows, in theory we should need just the Rust bindings. – rodrigocfd Apr 10 '23 at 17:03
  • 1
    Those are **import** libraries. They contain the function names alongside the module name that exports those functions. The linker uses import libraries to build the import tables in the final executable image. – IInspectable Apr 10 '23 at 22:00
  • @IInspectable I know, but you don't need them. The bindings work perfectly fine just with the [Rust declarations](https://github.com/microsoft/windows-rs/blob/master/crates/libs/windows/src/Windows/Win32/Graphics/Gdi/mod.rs). Those import libs must be there for some other reason. – rodrigocfd Apr 10 '23 at 22:35
  • 1
    No, that's the reason why they are required. There are [many ways](https://github.com/microsoft/windows-rs/issues/1720#issuecomment-1485373474) a program can successfully link without an explicit dependency on `windows-targets` (see [this PR](https://github.com/Amanieu/parking_lot/pull/378) for more rationale), but that will eventually break. That is, until [`raw_dylib`](https://doc.rust-lang.org/beta/unstable-book/language-features/raw-dylib.html) becomes stable, at which point import libraries are no longer needed. – IInspectable Apr 11 '23 at 06:52
  • 1
    It seems like you don't quite understand the term *"import library"*. Those are libraries that strictly contain import information. There is no code in import libraries. The program you posted [here](https://github.com/microsoft/windows-rs/issues/2443) links as long as you have a Windows SDK installed, or some other build system managed to pull in the respective import libraries (Rust's Standard Library only needs a handful of imports). I guess you can make it fail if you build it on a Linux system. – IInspectable Apr 13 '23 at 17:53

1 Answers1

1

I got a response by asking directly the official windows crate maintainers:

While the GNU and MSVC toolchains often provide some import libs to support C++ development, those lib files are often incomplete, missing, or just plain wrong. This can lead to linker errors that are very difficult to diagnose. The windows-targets crate ensures that all functions defined by the windows and windows-sys crates can be linked without relying on implicit lib files distributed by the toolchain.

For anyone interested, further details can be seen here.

rodrigocfd
  • 6,450
  • 6
  • 34
  • 68