Troubles after compiler installed via opam

I’m not quite sure where this issue belongs to, so posting it here instead of on a random issue tracker.

Recently, a friend of mine wanted to install OCaml on their FreeBSD system. FreeBSD ships since some years clang as the default C compiler, while some applications (e.g.: grub2-bhyve, uefi) still require gcc for installation.

Additionally, if you keep on updating to the latest FreeBSD without every removing binaries, you’ll end up with both gcc(-4.2.1) and clang(-5.0.0) installed at the same time.

So, an installation of the OCaml port (4.02.3) worked fine for my friend, since this explicitly passes “-cc $(CC)” to OCaml’s configure. While a “opam switch” to a newer OCaml compiler worked as well, it failed to install arbitrary opam packages.

The reason for this is that OCaml’s configure tries first to find a gcc binary (if no configure argument is provided), and found the 4.2.1. This was then preserved in Makefile.config, and used by various opam packages (via ocamlbuild I suspect).

Now this initial experience with OCaml was not very intuitive for my friend. How can we get out of this situation? I had assumed POSIX would require that a cc binary is around, but it doesn’t (there’s optionally a c99 binary). I couldn’t find a way in opam to pass a -cc argument via opam switch to the OCaml build system (this would also not be very intuitive, but at least unblock the installation in this specific case).

Should the OCaml configure be changed to first try to find a cc binary (there is some shell code which deals with cross compilation which I do not understand), and if unsuccessful, move on to gcc? Should the compiler definitions in opam be modified to pass -cc $CC to OCaml’s configure?

How do various Linux flavours these days deal with that? The systems I have access to (some ubuntu) has a cc binary installed which is a link to gcc, but is having a cc around widely adapted? Does MacOSX have a gcc binary around at all? The cross compilation is rather gcc specific (by looking for ${TOOLPREF}/gcc.

I hope there is a smooth solution, but I don’t know which this is. Are there any systems where cc is likely an outdated compiler, and gcc is the thing you want to run? Thanks for feedback! FWIW, since OpenBSD recently switched their default compiler from gcc to clang, there may be some people running into this issue as well.

You can create your own opam file for compiler and add whatever C compiler you want using env field; here is example.

I think the state of this can be improved in the opam2 ocaml compiler packages by specifically configuring a value for cc and not depending on the configure autodetection. It should be possible to do this in opam2.

A quick check on OpenBSD/amd64/current shows that there is a cc and clang binary (hardlinked) available. I think that there are various gcc workarounds in the runtime though, so it needs to understand which compiler flavour it is compiled against.

I think this should be an issue on https://github.com/ocaml/opam/issues directly, since it affects the base compiler packages and is pretty important to get right. The choice of cc obviously propagates down into every other package, and many modern distros are now providing a choice between gcc and clang. cc @AltGr

There are different ways to affect the environment: opam 1.2.2 has a env: field for compilers, and there is also a build-env: that can be specified in packages (2.0, and I think that was already in 1.2.2).
What’s new in 2.0 is the package setenv: field, which you can use to export environment variables (both to dependent packages and to the user shell through eval $(opam env)).One possibility would be to have a cc package that does the detection and exports an OCAML_CC variable, for use by the ocaml compiler and other packages.

This should be enough to fix the issue by only modifying the repository (assuming it’s in 2.0 format, which is not yet the case: right now we have to change the rewrite, too, since the various ocaml packages are automatically generated)

Thanks for your answers so far. I’m not sure I follow them, though.
AFAICT the OCaml package does not respect any CC environment variable,
or does it?

Also, can we find a solution for this in the current opam repository, or
do we really need to wait for opam 2?

It’s possible to define an exported env with 1.2.2, in .comp files only, but the solution with a dedicated cc package wouldn’t work. As for specifying the options to the OCaml compiler, if we modify the compiler definitions anyway, we can probably pass the correct options to its ./configure ?