Alpine mainstream OCaml is broken

Trying to fix the broken OCaml mainstream, but I have zero previous experience with Alpine, so if anyone wants to take a look - I would appreciate this:

I tried to build packages locally then install with apk --allow-untrusted, it installs fine, but the binaries compiled with this now throw this error:

Error relocating ./mybinary: secure_getenv: symbol not found

P.S. What is worse, I can’t base my image on Alpine:3.10 release e.g., because both 4.08.1 and 4.09.0 releases fail with this bug https://github.com/ocaml/ocaml/issues/8965. It was fixed, but no release available yet.

P.P.S. If I try to use 4.09.0+trunk variant:

opam repository add beta --all-switches git+https://github.com/ocaml/ocaml-beta-repository.git && \
opam switch create 4.09.0+trunk --repositories=default,beta && \
opam switch 4.09.0+trunk

it fails with the following error:

[ERROR] The compilation of ocaml failed at "/home/user/.opam/4.09.0+trunk/bin/ocaml /home/user/.opam/4.09.0+trunk/share/ocaml-config/gen_ocaml_config.ml 4.09.0 ocaml".

#=== ERROR while compiling ocaml.4.09.0 =======================================#
# context              2.0.3 | linux/x86_64 | ocaml-variants.4.09.0+trunk | https://opam.ocaml.org#f70ee2a2
# path                 ~/.opam/4.09.0+trunk/.opam-switch/build/ocaml.4.09.0
# command              ~/.opam/4.09.0+trunk/bin/ocaml /home/user/.opam/4.09.0+trunk/share/ocaml-config/gen_ocaml_config.ml 4.09.0 ocaml
# exit-code            1
# env-file             ~/.opam/log/ocaml-35-ebe0e0.env
# output-file          ~/.opam/log/ocaml-35-ebe0e0.out
### output ###
# OCaml version mismatch: 4.09.1, expected 4.09.0

P.P.P.S I can’t use 4.10+trunk because many dependencies I use will not build.

Any single way I try to workaround that broken package basically I hit the wall…

1 Like

To summarize the issue: the OCaml upstream was incompatible with Alpine starting with 4.08, and there is now a fix upstream, which may not reach upstream-released versions of OCaml before 4.10. The question is how to get a working Alpine+OCaml in the meantime.

I don’t know of any plans to make a new 4.09 bugfix release yet, and I’m pretty sure that there will not be another 4.08 release. On the other hand, there is an upstream patch that is already included in the 4.09 maintenance branch, and should be pretty easy to backport to 4.08 as well (ask me if you need help).

What’s the package-management process for Alpine in these situations? Is there a way to apply a patch in the distribution, as is routinely done by Debian or Fedora? It sounds like a pretty natural thing to do here, it should be easy, and would solve the problem for all Alpine users of 4.08 and 4.09.

Yes, I know about the patch. But I don’t know any way to tell opam to use the patch when you choose the switch. I can build the package manually from the container with abuild -r, but then it generates the wrong binaries with the error I mentioned. I found a workaround by using ocaml/opam2:alpine image, but it’s needlessly big, compared to the vanilla Alpine.

It looks like Alpine packages are desribed by an APKBUILD file plus a set of patches to be applied to the software (as instructed in the APKBUILD file), see for example https://github.com/alpinelinux/aports/tree/9ca1d63bdd5936b3e1662933bf748c0957aa3632/community/ocaml.

I’m suggesting that you send a pull-request to the Alpine packages repository, fixing the issues for all affected versions of OCaml available through this channel, by adding this patch (or a variant of this patch if necessary) to their patchset.

That problems affects only building with opam, but if you build from the package source the patch is unnecessary. The package source pull request already linked, they need just to accept the patch and rebuild it. Trickier part would be about secure_getenv: symbol not found error which I have no idea where to start from.

Just a start… Something like configure detects the presence of secure_getenv, which means it gets used by the runtime system, but the libc hasn’t the symbol.

1 Like

We routinely build all Jane Street packages with Alpine [1]
(in a Docker container), using opam.

Here is the command we execute before the actual build:

RUN apk update && apk upgrade && apk add \
    bash \
    build-base \
    coreutils \
    curl \
    git \
    linux-pam linux-pam-dev \
    m4 \
    patch \
    perl \
    pkgconfig \
    rsync \
    tar \
    xz \
    zlib-dev gmp-dev pcre-dev zstd-dev openssl-dev libffi-dev \
    libressl-dev linux-headers net-snmp-dev net-snmp-libs

Among other things, it will install the GNU variant of stat.

I cannot remember seeing the secure_getenv problem under
Alpine (where we do build vanilla OCaml), but you might be
interested in the following patch (disabling the detection of
the secure function):

https://github.com/janestreet/ocaml/commit/6e7eed95eaf5a2a55972997142b41f3e20529bb2

[1] Alpine Linux v3.10, according to /etc/os-release

3 Likes

Thanks @xclerc! Do we know why the detection of secure_getenv is problematic and whether the upstream check could be adapted to work better?

If I remember correctly, our problem had to do with a
compile-on-centos-6-then-run-on-centos-7 scenario [1]

It is not clear to me what happens for @XVilka on Alpine.

[1] https://github.com/ocaml/ocaml/pull/1331

I found a workaround by using ocaml/opam2:alpine image, but it’s needlessly big, compared to the vanilla Alpine.

You can use the much smaller OCurrent ones instead, e.g.

docker run --rm -it ocurrent/opam:alpine-3.10-ocaml-4.08

I haven’t noticed any problems with this combination, and ocaml-ci uses it as part of its test matrix, so lots of projects are building with it.

2 Likes

Yesterday updated to Fedora 31 and it made the things even worse - it doesn’t support docker because of the switch to cgroups-v2, so you can use the rootless podman, but it’s incompatible with docker in some edge cases. Every single thing I touch while doing my simple OCaml development breaks. Every single one!

Yesterday updated to Fedora 31 and it made the things even worse - it doesn’t support docker

I haven’t tested them, but there are Fedora 31 RPMs on Docker’s website:

https://download.docker.com/linux/fedora/31/x86_64/stable/Packages/

You can switch to cgroups-v1 to use docker: https://medium.com/nttlabs/cgroup-v2-596d035be4d7

I was lucky, only 2 bugs were blocking my workflow to work on podman, I was able to start using it a few weeks ago. In general they are quite responsive and fix reported problems.

Just an update - 4.09.0 landed in Alpine Edge and works fine. I am using podman these days with some workarounds against its bugs. It is not as stable as the original Docker, but 99.999% of my cases work just fine now.

2 Likes

Any reason why OCaml is not built for the x86 architecture in Alpine?

When I build it from source, I get Segmentation fault when running the compiler.

I encourage you to open an issue at their GitLab then: https://gitlab.alpinelinux.org/alpine/aports/issues

I use x86_84 builds.

Just an update. Tried today with newly released Alpine 3.11 and it is still the same problem, even with the custom 4.09.0 switch:

Error relocating ./mybinary: secure_getenv: symbol not found

Reported the issue to them.