Create opam switch specifying custom C compiler

On my system, I have both gcc and clang installed. I would like to set up an opam switch where the ocaml compiler is built with clang. I tried the following:

opam source ocaml.4.14.1

Modified the downloaded opam file to set the CC environment variable, like so:

setenv: [
  [CAML_LD_LIBRARY_PATH = "%{_:stubsdir}%"]
  [CAML_LD_LIBRARY_PATH += "%{lib}%/stublibs"]
  [OCAML_TOPLEVEL_PATH = "%{toplevel}%"]
  [CC = "clang"]
  [CPP = "clang"]
opam switch create 4.14.1+clang --empty
opam install ./ocaml.4.14.1/opam

After the compiler gets built, when I run ocamlopt -config, I see that it was built with gcc:
c_compiler: gcc. Is this a bug? How can I create an opam switch with my choice of C compiler?

1 Like

It’s simpler than I thought. I found the following to work:
env CC=clang opam switch create 4.14.1+clang 4.14.1

1 Like

What are the benefits of doing this?

I needed this specifically for a project that uses bindings to the Objective-C runtime. On Linux I’m only able to make it work when binding to the newer Objective-C runtime which is intended to be used with clang.

What approach would you recommend for indicating in the opam file that setting up the switch with clang is a prerequisite for installing the package? There is a conf-clang package in opam, but it only makes sure clang is installed on the system.

One way would to have an ocaml-option-clang package that indicates (or requests, depending on how you see it) that the C compiler is a kind of clang. But that might be tricky to do because it requires changing how the ocaml-variants+options package works and this option might not compose well with the others.

(to answer your initial question, setenv: sets up environment variables in the opam switch once a package is installed, which is a different feature)

1 Like

Since I did considerable work on exactly this topic for my bazel build of the compilers I’ll throw a few possibly irrelevant cents. A compiler build records the c compiler (and linker?) used for the build. When you use the compiler… Well you can’t really do that, you can only use the cmd processors, which drive the compiler and possibly other tools. Which may involve calling out to the tools (c compiler, linker) used to build the OCaml tools.

That’s good enough in almost all cases but it does compromise hermeticity unless the full paths to the c compiler and linker are recorded. If not, what happens if you are working with multiple versions of the c toolchain? The ocamlopt cmd might call clang and ld; what it gets depends on your env config.

Not a big deal I reckon but kind of a fun problem.