Skip to content

Add a clang64 chain for Unix-CLI compilers targeting the MSVC ABI - #170

Open
MisterDA wants to merge 4 commits into
ocaml:masterfrom
MisterDA:clang64
Open

MisterDA wants to merge 4 commits into
ocaml:masterfrom
MisterDA:clang64

Conversation

@MisterDA

@MisterDA MisterDA commented Sep 14, 2026

Copy link
Copy Markdown
Contributor

A new clang64 chain for C compilers with a Unix-style command line targeting the MSVC ABI and runtime, such as clang --target=x86_64-pc-windows-msvc and zig cc -target x86_64-windows-msvc.

Currently the ocaml compiler mistakes them as having the "msvc" comptype (i.e., MSVC's CLI convention) since they target *-pc-windows, but these compilers have a "cc" comptype.

clang-cl acts as a drop-in replacement to cl.exe but now we can use the same features exactly from the regular clang front-end.

The clang64: support GNU-CLI linkers via -use-linker patch similarly lets user pick a unix-y front-end for the linker, rather than lld-link (the drop-in replacement to link.exe).

I have not added automated tests to this PR since the OCaml compiler needs a few more patches to make it work, that I intend to slowly but steadily. I do have reviewed and tested this PR which was written with the help of a LLM. The PR can be reviewed commit-by-commit.

@MisterDA
MisterDA force-pushed the clang64 branch 3 times, most recently from bfcec26 to 9ba9748 Compare September 15, 2026 09:50
Compilers such as clang --target=x86_64-pc-windows-msvc and
zig cc -target x86_64-windows-msvc have a Unix-style command line but
target the MSVC ABI and runtime. The new chain drives the linker
(lld-link by default, configurable with -use-linker) through the C
compiler, expressing the MSVC link semantics with -Wl,/option
arguments. The library search path is taken from the LIB environment
variable (as with the MSVC chains) and from the compiler's
-print-search-dirs. Import libraries are looked up with the MSVC
naming rules, and .lib import libraries are produced.

-Wl,/option spellings are now also recognized on the flexlink command
line and forwarded to the linker instead of being split at the colon.

The support objects are compiled with -fms-runtime-lib=dll, matching
the /MD of the MSVC chains.
By default the clang64 chain drives an lld-link-style linker through
the C compiler. This cannot work for linkers with a GNU-style command
line: for MSVC targets the compiler driver always constructs an
lld-link-style command, whatever linker binary is selected. When
-use-linker names a GNU-CLI linker (anything that is not lld,
lld-link or link, e.g. "ld.lld -m i386pep" or a binutils ld targeting
pep), invoke it directly, as the "ld" chain does, with GNU option
spellings: --shared, -e, --image-base, --subsystem, --out-implib, a
.def file for the exports, and the flexlink search path passed with
-L. The CRT import libraries are spelled out inside
--start-group/--end-group since there is no driver to add them and
GNU binutils ld does not process the DEFAULTLIB directives embedded
in the objects; vcruntime, ucrt and kernel32 are added to the chain's
default libraries for this purpose.

For the driver path, -use-linker values containing a directory
separator are now passed with --ld-path instead of -fuse-ld, which
only accepts linker flavors.

Validated with ld.lld -m i386pep (demo runs under wine). GNU binutils
ld currently mis-selects MSVC CRT archive members (msvcrt_md_kernel32
flavor) and cannot link executables against the MSVC CRT; this is a
binutils limitation.
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