Skip to content

Add ocaml-option-llvm for cross-platform LLVM toolchain support#29582

Open
smorimoto wants to merge 1 commit intomasterfrom
add-ocaml-option-clang-cl
Open

Add ocaml-option-llvm for cross-platform LLVM toolchain support#29582
smorimoto wants to merge 1 commit intomasterfrom
add-ocaml-option-clang-cl

Conversation

@smorimoto
Copy link
Copy Markdown
Member

@smorimoto smorimoto commented Mar 22, 2026

Summary

  • Add ocaml-option-llvm package as a pure marker following the established ocaml-option-* pattern
  • On Windows it sets CC=clang-cl (with a system-msvc dependency), whilst on other platforms it sets CC=clang (switching from GCC to Clang)
  • As upstream OCaml gains support for specifying alternative linkers and assemblers, this package can be extended incrementally to configure lld-link, llvm-ar, llvm-mt, llvm-rc, etc. on all platforms

Changes

  • New package: ocaml-option-llvm.1 — pure marker with flags: compiler, depends on system-msvc on Windows only, conflicts with ocaml-option-32bit, ocaml-option-musl, ocaml-option-address-sanitizer, ocaml-option-leak-sanitizer
  • ocaml-options-vanilla: add unconditional conflict with ocaml-option-llvm
  • ocaml-variants.5.2.0+msvc: add ocaml-option-llvm as depopt with CC=clang-cl build arg
  • ocaml-compiler.5.3.0 through 5.6 (12 packages): add ocaml-option-llvm as depopt with CC=clang-cl on Windows / CC=clang elsewhere; add !ocaml-option-llvm:installed guard to the existing CC=cc line on macOS/OpenBSD

Design

Follows the same pattern as ocaml-option-musl (CC=musl-gcc): a pure marker package that compiler packages reference via depopts and {ocaml-option-llvm:installed} guards in their build sections. No setenv is used — the CC override is scoped to the compiler's ./configure invocation only.

Conflict analysis

All existing CC= overrides in the build sections were checked for potential conflicts:

  • CC=cc on macOS/OpenBSD — guarded with !ocaml-option-llvm:installed to prevent double CC=
  • CC=clang for tsan on macOS — compatible (same value), no conflict needed
  • CC=musl-gcc, CC=gcc -m32, sanitiser CC= lines — all incompatible, declared as conflicts on the option package

ocaml-option-tsan is intentionally not conflicted — tsan already uses CC=clang on macOS (same as llvm), and on Linux it does not set CC at all, so the combination works correctly.

Ref: ocaml/setup-ocaml#1073

@MisterDA
Copy link
Copy Markdown
Contributor

MisterDA commented Mar 23, 2026

It would be good to have this but I think switching the C compiler is just a part of the solution. IMO the whole MSVC toolchain should be replaced by LLVM tools in this context. There's not just the C compiler, but also the archive program llvm-ar, the manifest processor llvm-mt, the resource compiler llvm-rc, the assembler llvm-ml64, and the linker lld-link.

Of all of these as of LLVM 22 only llvm-ml64 doesn't have all the features to build OCaml, but interestingly either the Microsoft ml64.exe assembler or the MinGW-w64 assembler (as in x86_64-w64-mingw32-as) can be used instead, as both produce identical object files.

As of the 5.6 trunk of 2026-03-23, OCaml doesn't support the user specifying another default linker, doesn't support lld-link, and doesn't support well switching the assembler. I have plans to fix that but it will take me a long time to submit the patches, and have them reviewed and merged.

Maybe we could have a ocaml-option-llvm instead, that would use the LLVM toolchain?

@smorimoto
Copy link
Copy Markdown
Member Author

That's a fair point — renaming to ocaml-option-llvm and extending it as upstream support lands sounds like the right approach.

One thought on scope: rather than restricting this to Windows, would it make sense to have ocaml-option-llvm work cross-platform from the start? On Windows it would set CC=clang-cl (with a system-msvc dependency), whilst on Linux it would set CC=clang (switching from GCC to Clang). On macOS it would be largely a no-op since cc is already Apple Clang, but it would keep things consistent.

As the LLVM toolchain support in OCaml matures, we could then incrementally add the linker, archiver, assembler, etc. on all platforms — not just Windows.

Does that align with what you had in mind, or would you prefer to keep the initial scope Windows-only?

@MisterDA
Copy link
Copy Markdown
Contributor

That is exactly what I had in mind ;)

Add an ocaml-option-llvm package following the established ocaml-option-*
pure marker pattern. On Windows it sets CC=clang-cl (with a system-msvc
dependency), whilst on other platforms it sets CC=clang.

This allows the LLVM toolchain to be properly scoped to the OCaml
compiler build. As upstream OCaml gains support for specifying
alternative linkers and assemblers, this package can be extended
incrementally to configure lld-link, llvm-ar, llvm-mt, llvm-rc, etc.

Changes:
- New package: ocaml-option-llvm.1 (conflicts with 32bit, musl,
  address-sanitizer, leak-sanitizer)
- ocaml-options-vanilla: add unconditional conflict
- ocaml-variants.5.2.0+msvc: add as depopt with CC=clang-cl
- ocaml-compiler.5.3.0 through 5.6: add as depopt with CC=clang-cl
  on Windows and CC=clang elsewhere; add !ocaml-option-llvm guard
  to the existing CC=cc line
@smorimoto smorimoto force-pushed the add-ocaml-option-clang-cl branch from 9346fc9 to fa5fb3a Compare March 23, 2026 18:53
@smorimoto smorimoto changed the title Add ocaml-option-clang-cl for MSVC clang-cl compiler support Add ocaml-option-llvm for cross-platform LLVM toolchain support Mar 23, 2026
@smorimoto
Copy link
Copy Markdown
Member Author

Done!

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