Opam switch create and gcc10

I have trouble building a local switch using ocaml-base-compiler.4.06.1 on archlinux, following an upgrade to gcc 10. Apparently it uses -fno-common by default, which breaks the compilation of OCaml’s runtime because some symbols are declared twice.

I really can’t get it to work. I tried, before creating the switch:

  • setting OCAMLPARAM='ccopt=-fcommon'
  • setting CC, cc, OPAMVAR_cc, OPAMVAR_CC to gcc -fcommon
  • setting CFLAGS

Every time the switch creation fails because of errors like "multiple definition of caml_major_ring’"` in a .h and a .c of the runtime. Any idea?

Is this a problem specific to 4.06 ?

Nicolás

I need a 4.06 switch, I can try with another version.

Your environment variables will not get passed to the compiler, because of opam’s sandbox, I think.

If it is still a problem with a recent version, it may be easier to get people interested in looking into it : )

Nicolás

The problem appears with any version of the compiler that does not integrate https://github.com/ocaml/ocaml/pull/9180 , in other words, for any compiler version strictly inferior to 4.09.1 .

A suggestion: create an empty switch, then opam pin add ocaml-variants.4.06.1 --edit, and there change the ./configure invocation to add your specific options. I don’t know which one is supposed to work, possibly ./configure CC='gcc -fcommon' ....

1 Like

This worked, after a lot of trial and error, by editing the configure line into:

["./configure" "-prefix" prefix "-with-debug-runtime" "-cc" "gcc -fcommon"]

1 Like

Ah, I forgot that 4.06.1 still uses the old configure script… For future reference, I believe that -cc is the right option with versions older than 4.08, and CC= should be the right one for versions starting at 4.08.0. So if someone needs to build a 4.08 switch with gcc 10, I think the right configure line will be:
["./configure" "-prefix" prefix "-with-debug-runtime" "CC='gcc -fcommon'"]
I haven’t actually tested though.

1 Like

And this just in: I need that anyway because of ocaml-secondary-compiler :neutral_face:

It should be safe to pass -fno-common to all of the older compilers in the opam-repository, shouldn’t it? If so, it’s time to modify them all to get compatibility with Fedora 31 and modern Arch… unless there’s some ancient gcc still in circulation which doesn’t have that option.

1 Like

You probably mean to pass -fcommon (to make gcc use its pre-GCC 10 default behavior).
The option seems to have been added in GCC 4.4 in 2011 . Since this is two year before the first release of opam, it sounds likely that all opam users already have a compatible GCC.
And patching the older compiler packages like suggested by @c-cube in https://github.com/ocaml/opam-repository/issues/16538 seems indeed to be the lightest choice.

To avoid problems with the ecossystem a global wrapper is the best option

#! /bin/sh

eval /usr/bin/gcc -fcommon '"$@"'

at /usr/local/bin/gcc

2 Likes

@octachron I would be in favor of backporting the fix in the upstream 4.06 maintenance branch. We could even consider tagging a minor maintenance release for it (and possibly other similar patches). This is better than patching the opam package or tweaking the opam configuration along at least the following dimensions:

  • It makes it easier for other distributions to find and reuse the change.
  • It makes it easier to find for compiler developers that go back to older version for development purposes (typically: to bisect to find a bug).

Do you mean backporting the configuration fix or the multiple definition fixes? Another natural question is then how far back should we go? Should we patch 3.12 for instance?

In general my approach would be to do whatever we want (and have the time to do), and/but push the changes to the place where it makes the most sense. If we want to “fix” old versions of the compiler, I think that their maintenance branches are the place that make the most sense.

I would backport the multiple definition fixes – unless there are reason to believe that it may break things? – for the versions that people care about in practice (we can guess a few versions and then wait for requests to do other backports lazily).

Should we patch 3.12 for instance?

It certainly makes sense to me to ensure that we can build the 3.12 branch with a modern C compiler, but it probably does not need a release (unless we can have one with essentially zero work).

I just checked Debian and Ubuntu LTS releases and Debian oldstable is at 4.02 and Ubuntu 16.04 is at 4.02 as well, so these seem like a decent cutoff line (haven’t checked RHEL). On the other hand, they are extremely unlikely to ever get GCC 10 so that problem might just never effectively manifest.

We’ll need to patch existing releases as well in opam with -fcommon, since otherwise they’ll fail today. We’ll obviously pick up any patch releases that @octachron and @gasche decide on, but I don’t see a huge amount of utility in those releases for older distributions. They can just pass -fcommon in their packages much more easily as a backport.

I’m looking at a large-scale patch to opam-repository to support Fedora 32 and Arch Linux at the moment. @c-cube, thanks for the offer to port it back to some compilers, but we need to do it all the way back to 4.02 due to the CI containers needing to compiler systematically with gcc10. I’m taking a look at this now.

3 Likes

Awesome, thank you @avsm!!

Thanks man! Saved my day.