Skip to content

fix: cross-compiling to *-pc-windows-* from a non-Windows host - #132

Open
Alexigbokwe wants to merge 2 commits into
zmwangx:masterfrom
chuks-programming-language:fix/windows-cross-compile
Open

Alexigbokwe wants to merge 2 commits into
zmwangx:masterfrom
chuks-programming-language:fix/windows-cross-compile

Conversation

@Alexigbokwe

Copy link
Copy Markdown

Two bugs prevent cross-compiling the vendored FFmpeg (the build feature) to a Windows target from a non-Windows host (e.g. Linux → x86_64-pc-windows-gnu, as CI images do for official builds).

1. --target-os=windows is not a valid FFmpeg OS

get_ffmpeg_target_os() returns Rust's CARGO_CFG_TARGET_OS verbatim, which is "windows". FFmpeg's configure has no windows OS and aborts:

configure stdout: Unknown OS 'windows'.
called `Result::unwrap()` on an `Err` value: Custom { kind: Other, error: "configure failed " }

FFmpeg expects mingw32/mingw64 (GNU) or win32/win64 (MSVC). This PR maps the windows target to the right name from CARGO_CFG_TARGET_ENV + pointer width.

2. --enable-pthreads is gated by a build-script #[cfg], which resolves for the HOST

#[cfg(not(target_env = "msvc"))]
{ configure.arg("--enable-pthreads"); }

A build script's #[cfg(...)] is evaluated for the host, not the target being built. Cross-compiling from a non-MSVC host (Linux) therefore always adds --enable-pthreads, even when targeting Windows — where MinGW has no pthread library by default, so configure fails:

ERROR: pthreads requested but not found

Windows uses native w32threads. This PR gates the flag on the target via CARGO_CFG_TARGET_{ENV,OS} env vars (the correct way to branch on the target inside a build script), skipping --enable-pthreads for any Windows target; FFmpeg then auto-selects w32threads.

Result

With both fixes, cross-compiling from Linux with the MinGW-w64 toolchain (--cross-prefix=x86_64-w64-mingw32-, posix-threads variant) configures and builds FFmpeg cleanly for x86_64-pc-windows-gnu, producing a working, self-contained cdylib.

Note (not in this PR)

There is a further cross-bindgen wrinkle: with the Windows target, the hwcontext_wrapper.h D3D11VA/D3D12VA blocks pull in Windows SDK headers (windows.h intrinsics / a missing d3d12sdklayers.h). I worked around it downstream by disabling those blocks, but a proper upstream fix (e.g. gating the D3D blocks on non-cross, or completing the guard suppression) is better decided by maintainers — happy to follow up separately.

FFmpeg's configure rejects --target-os=windows (Unknown OS 'windows'); it needs
mingw32/mingw64 for GNU or win32/win64 for MSVC. Derive the right name from
TARGET_ENV + pointer width so cross-compiling to *-pc-windows-* works.
A build script's #[cfg] resolves for the HOST, so #[cfg(not(target_env=msvc))]
wrongly forced --enable-pthreads when cross-compiling Linux -> Windows, which
then failed ('pthreads requested but not found', no pthread lib on MinGW).
Windows uses native w32threads; gate on CARGO_CFG_TARGET_{ENV,OS}.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant