Skip to content

simics-build-utils emits raw .dll link directives on Windows, breaking MSVC-host builds (LNK1107) #128

@Wenzel

Description

@Wenzel

Summary

simics_build_utils::emit_link_info() emits cargo:rustc-link-lib=dylib:+verbatim=<name>.dll for libsimics-common, libvtutils, and the bundled Python DLL on Windows. This works with the MinGW/GNU Rust target (MinGW's ld/lld can import directly from a PE DLL) but fails on the default x86_64-pc-windows-msvc host, because link.exe requires a proper import library (.lib).

Reproduction

Default Rust install on Windows (MSVC host), building any crate that depends on simics-build-utils — for example, TSFFS:

$env:SIMICS_BASE = "C:\...\Simics\simics-6.0.185"
cargo build --release       # defaults to x86_64-pc-windows-msvc

Result:

warning: Using Python environment for linking: PythonEnvironment { ...
          lib: C:\...\simics-6.0.185\win64\bin\python310.dll, ... }
error: linking with `link.exe` failed: exit code: 1107
  = note: ...\libsimics-common.dll : fatal error LNK1107:
          invalid or corrupt file: cannot read at 0x4F8

link.exe is being handed the raw DLL and chokes on the PE header where it expects a COFF archive.

Workaround: cargo build --release --target x86_64-pc-windows-gnu (requires MinGW-w64 installed). This is what TSFFS's docs recommend, but it should not be a requirement for consumers on a default Rust Windows install.

Root cause

In simics-build-utils/src/lib.rs, the #[cfg(windows)] branch of emit_link_info() resolves DLL filenames and emits them verbatim:

let libsimics_common = bin_dir.join(\"libsimics-common.dll\").canonicalize()?;
// ...
println!(\"cargo:rustc-link-lib=dylib:+verbatim={}\",
    libsimics_common.file_name()...);  // => libsimics-common.dll

+verbatim passes the string directly to the linker. MinGW accepts this; MSVC does not.

Similarly, simics_python_utils::PythonEnvironment::lib_filename() returns python310.dll for the bundled Python case (the banner shows lib: ...\bin\python310.dll), when MSVC needs python310.lib.

Proposed fix

Branch on target_env in the build script (not on host cfg(windows), since cross-compiles exist):

// Windows GNU: keep current behavior (link directly against DLL)
// Windows MSVC: emit import-library filenames
#[cfg(all(windows, target_env = \"msvc\"))]  // or examine CARGO_CFG_TARGET_ENV
{
    println!(\"cargo:rustc-link-lib=dylib:+verbatim=libsimics-common.lib\");
    println!(\"cargo:rustc-link-lib=dylib:+verbatim=libvtutils.lib\");
    println!(\"cargo:rustc-link-lib=dylib:+verbatim=python310.lib\");
}

On my Simics 6.0.185 install, libsimics-common.lib, libvtutils.lib, and python310.lib already exist in win64\bin alongside the DLLs, so no extra generation step is needed for this version. For installs where the .lib is missing, lib.exe /def: from a generated .def (via gendef or by dumping exports) is the standard workaround.

simics-python-utils needs a matching change so PythonEnvironment::lib_filename() returns the import lib name under MSVC.

Caveats (worth flagging, not blockers)

Simics's Windows DLLs ship alongside libgcc_s_seh-1.dll, libstdc++-6.dll, and libwinpthread-1.dll, indicating they were built with MinGW GCC. The linker fix above makes the build link, but runtime ABI compatibility for MSVC consumers depends on:

  • public Simics API being pure C (appears to be the case);
  • no C++ exceptions, longjmp, or TLS crossing the DLL boundary;
  • CRT consistency (both UCRT — probably fine).

Basic usage should work; edge cases may need validation. Happy to help test if a fix lands.

Environment

  • Windows 11
  • Rust 1.90.0, host `x86_64-pc-windows-msvc`
  • Simics 6.0.185 (bundled Python 3.10)
  • `simics-build-utils` 0.2.6, `simics-python-utils` 0.2.6
  • Consumer: tsffs 0.2.4

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions