Skip to content

Don't link gomp on MSVC (openmp-runtime-comp)#144

Merged
jkawamoto merged 1 commit into
jkawamoto:mainfrom
timo9378:fix-msvc-gomp-link
Jul 18, 2026
Merged

Don't link gomp on MSVC (openmp-runtime-comp)#144
jkawamoto merged 1 commit into
jkawamoto:mainfrom
timo9378:fix-msvc-gomp-link

Conversation

@timo9378

Copy link
Copy Markdown
Contributor

Hi, thanks for these bindings. While looking into the Windows hang from #64 I found the
openmp-runtime-comp feature can't link on MSVC, which is a small fix.

openmp-runtime-comp unconditionally links gomp, which is GNU's OpenMP runtime and
doesn't exist on the MSVC toolchain. Building with the feature on
x86_64-pc-windows-msvc fails:

LINK : fatal error LNK1181: cannot open input file 'gomp.lib'

MSVC doesn't need an explicit link here: /openmp emits a /DEFAULTLIB:VCOMP
directive into every object, so its runtime is pulled in automatically. So the fix is
to skip the gomp link on MSVC only. Every other toolchain, including windows-gnu
(MinGW uses GCC and has no such directive), still links it as before. This applies to
both the source-build path (build_ctranslate2) and the system-feature path
(link_system_libraries), which each link gomp under openmp-runtime-comp:

if env::var("CARGO_CFG_TARGET_ENV").as_deref() != Ok("msvc") {
    println!("cargo:rustc-link-lib=gomp");
}

I used CARGO_CFG_TARGET_ENV rather than cfg!(target_env = ...) since the latter
reflects the host in a build script. Linux, macOS and windows-gnu are unaffected.

Why this matters on Windows: with OPENMP_RUNTIME=NONE (the default here), CT2's CPU
parallelism uses a static thread_local BS::thread_pool whose destructor deadlocks on
thread exit. Building CT2 with OpenMP compiles that path out, so openmp-runtime-comp
is currently the only way to avoid that hang on Windows, and right now the feature
can't even link on MSVC.

This doesn't fix everything on Windows on its own. There's a second deadlock in the Ruy
backend's thread_local ruy::Context that OpenMP doesn't touch, currently avoided by
the #[cfg(windows)] impl Drop that bypasses the UniquePtr drop (which leaks the
model). The real fix for that is upstream in CTranslate2 OpenNMT/CTranslate2#2076, after which the
Drop bypass can be reverted.

Thanks!

`gomp` is GNU's OpenMP runtime and does not exist on the MSVC toolchain, so
building with `openmp-runtime-comp` on x86_64-pc-windows-msvc fails with
`LNK1181: cannot open input file 'gomp.lib'`. MSVC's /openmp emits a
/DEFAULTLIB:VCOMP directive into every object, so its runtime links
automatically and no explicit link is needed.

Skip the gomp link on the MSVC target env only, in both the source-build and
system-library paths. Other toolchains, including *-pc-windows-gnu (MinGW/GCC),
still link it as before.

Refs jkawamoto#64
@jkawamoto

Copy link
Copy Markdown
Owner

Thank you for the detailed investigation and explanation!

That makes sense, especially the distinction between MSVC and windows-gnu here, and thanks for pointing out why CARGO_CFG_TARGET_ENV is the right choice in a build script.

I also appreciate the additional context about the Windows hangs and the remaining Ruy-related issue.

The proposed change looks good to me. I’ll merge the PR.

@jkawamoto
jkawamoto merged commit fdeb83d into jkawamoto:main Jul 18, 2026
14 checks passed
@timo9378

Copy link
Copy Markdown
Contributor Author

Thanks for the quick review and merge, really appreciate it! Do you have a rough idea of when this might go out in a release? No rush at all. Just so I know whether to keep patching it locally in the meantime. Thanks again!

@jkawamoto

Copy link
Copy Markdown
Owner

Thanks again for the awesome PR.

Just wanted to let you know that I've just published v0.9.22 with your fix included.

Appreciate your help!

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.

2 participants