Static linking of libwinpthread-1.dll with mingw-w64-i686-gcc

# Static Linking Failure: Unwanted libwinpthread-1.dll Dependency in MinGW-w64 Rust Plug-in

## Summary
- Compiling a Windows plug-in (.dll) combining Rust (`staticlib`) and C code resulted in an unwanted runtime dependency on `libwinpthread-1.dll`
- Target environment: 32-bit Windows (i686) using mingw-w64-i686-gcc
- Rust `windows-gnu` toolchain hardwired to POSIX threading required runtime dependency resolution
- General linker flags (`-static`, `-Wl,-Bstatic`) failed to eliminate the dependency due to plugin constraints

## Root Cause
- MinGW-w64 POSIX thread implementation (`libwinpthread`) defaults to dynamic linking
- Rust's `windows-gnu` toolchain exclusively uses POSIX threads (no Win32 thread alternative)
- Mixed linking requirements:
  * Host application dependencies require dynamic linking for compatibility
  * Static-linking pthread would disrupt runtime binding to host's CRT
- MSYS2 mingw-w64-i686 toolchain lacks Win32 thread support, forcing POSIX threading

## Why This Happens in Real Systems
- Cross-platform toolchains (Windows/Linux) prioritize POSIX compliance over Windows-native threading
- Dependency chains inherit defaults from compiler distributions (MSYS2/Rustup ship POSIX-threaded GCC)
- Static linking isn't granular enough for mixed-scenario plugin architectures
- Compiler vendors optimize for executables over plug-in constraints

## Real-World Impact
- Plug-in fails to load if `libwinpthread-1.dll` is missing from user's PATH
- DLL conflicts when multiple versions exist (MSYS2 vs Rustup)
- Plug-in crashes due to thread-model incompatibility between incompatible pthread implementations
- Broken installations requiring non-standard DLL redistribution
- Host application stability compromised by runtime binding conflicts

## Example or Code
```makefile
# Failed approach using non-specific static linking flags
RUST_STATICLIB := target/i686-pc-windows-gnu/release/mylib.a
all: plugin.dll

plugin.dll: glue.o $(RUST_STATICLIB)
    gcc -shared glue.o $(RUST_STATICLIB) -o $@ -static -lpthread  # Doesn't work

# Working solution using explicit static threading libraries
plugin.dll: glue.o $(RUST_STATICLIB)
    gcc -shared glue.o $(RUST_STATICLIB) -o $@ \
        -Wl,-Bstatic -l:libpthread.a -l:libstdc++.a -l:libgcc.a \
        -Wl,-Bdynamic -lmingw32 -luser32 -lkernel32

How Senior Engineers Fix It

  1. Precisely isolate pthread dependency via static-only linking
  2. Explicitly reference static library file (-l:libpthread.a)
  3. Include static runtime dependencies (libgcc.a, libstdc++.a)
  4. Manually restore dynamic linking for system libraries (-Wl,-Bdynamic)
  5. Use dependency walkers (Dependency Walker) to validate binary imports
  6. Avoid blanket -static to prevent incompatible static CRT binding
  7. Verify linker order: Static threading libs before switch to dynamic mode

Why Juniors Miss It

  • Assume -static unconditionally eliminates dependencies
  • Confuse plugin linking constraints with executable linking rules
  • Unaware of MinGW threading variants (POSIX vs Win32)
  • Overlook Rust toolchain enforcement of POSIX threading
  • Miss implicit compiler/runtime library dependencies
  • Skip binary validation steps (dependency checking)
  • Focus on build success over runtime deployment context