Skip to content

ENT-14716: Fixed building core from source on RHEL 8 and 9 in ci scripts - #6472

Open
aleksandrychev wants to merge 1 commit into
cfengine:masterfrom
aleksandrychev:ENT-14716_rhel8_9_source_build
Open

aleksandrychev wants to merge 1 commit into
cfengine:masterfrom
aleksandrychev:ENT-14716_rhel8_9_source_build

Conversation

@aleksandrychev

@aleksandrychev aleksandrychev commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

Ticket: ENT-14716

Merge together:
NorthernTechHQ/libntech#300
#6472

Depends on NorthernTechHQ/libntech#300, which makes libntech's configure.ac check for the PCRE2 declarations it uses (AC_CHECK_DECLS). After it merges, this PR also needs a libntech submodule bump to pick it up.

Follow-up to #6470. With RHEL 8/9 allowed in ci/dependencies.sh, the golden-ami bake of the RHEL 8/9 arm64 build hosts got past the dependency install but then failed in ci/install.sh:

  • RHEL 9: core built and installed, then cf-key failed with liblmdb.so.1: cannot open shared object file. build_lmdb ran make install prefix=/usr, and lmdb's Makefile then puts the library in /usr/lib, which the runtime linker doesn't search on lib64 distributions. (librsync was fine; its cmake install already uses /usr/lib64.)
  • RHEL 8: the build failed in libntech's buffer.c with 'PCRE2_SUBSTITUTE_MATCHED' undeclared and 'PCRE2_SUBSTITUTE_LITERAL' undeclared. These were added in pcre2 10.34, and RHEL 8 ships 10.32.

RHEL 10 never hit either, because cf-remote finds a real el10 package there and the source build doesn't run.

Changes:

  • build_lmdb installs into /usr/lib64 when that directory exists, and into /usr/lib otherwise. Only RHEL and SUSE call it, and both are lib64.
  • ensure_pcre2 reads the list of pcre2 declarations libntech needs from the AC_CHECK_DECLS([PCRE2_...]) line in libntech/configure.ac (currently PCRE2_SUBSTITUTE_MATCHED and PCRE2_SUBSTITUTE_LITERAL). It then checks the system pcre2.h for them with gcc -E -dM. Only if one is missing does build_pcre2 build pcre2 into /opt/pcre2, leaving the system pcre2 alone. If the line is missing from libntech, the script fails instead of skipping the check.
  • build_pcre2 takes the pcre2 release from buildscripts' deps-packaging/pcre2/source and distfiles (the same release the CFEngine packages bundle) and checks the download with sha256sum --check.
  • ci/configure.sh passes --with-pcre2=/opt/pcre2 when that directory exists, and core's configure adds an rpath for it.

No pcre2 version is hard-coded in core: the required declarations come from libntech, and the version to build comes from buildscripts.

Testing: ran the full ci/install.sh (dependencies, configure, build, install, cf-key) on core master with these scripts and libntech#300's configure.ac in a fresh rockylinux/rockylinux:8 container (amd64):

system pcre2 10.32 lacks PCRE2_SUBSTITUTE_MATCHED required by libntech
building pcre2 in /tmp/tmp.fEubul0WYs
pcre2-10.49.tar.gz: OK
checking whether PCRE2_SUBSTITUTE_MATCHED is declared... yes
checking whether PCRE2_SUBSTITUTE_LITERAL is declared... yes
CFEngine Core 3.29.0a.f66fbb3f5
  libpcre2-8.so.0 => /opt/pcre2/lib/libpcre2-8.so.0

Configuring libntech against the system pcre2 10.32 now stops with configure: error: This release of CFEngine requires PCRE2 with PCRE2_SUBSTITUTE_MATCHED and PCRE2_SUBSTITUTE_LITERAL (10.34+).

An earlier run of the lmdb fix in rockylinux/rockylinux:9 completed ci/install.sh with liblmdb.so.1 => /lib64/liblmdb.so.1. On RHEL 9 the system pcre2 (10.40) has both declarations, so it's used as before (checked ensure_pcre2 in rockylinux/rockylinux:9: no pcre2 build).

The real arm64 RHEL 8/9 check is the next golden-ami bake, which clones core master.

🤖 Generated with Claude Code

@craigcomstock craigcomstock left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will work but I think we are dirtying up what should be fairly straightforward scripts that either work or don't. So I would argue that rhel-8 should maybe just fail due to age and if need be we could refactor libntech to macro ifdef around the pcre2 differences.

The better solution to fixing things here, I think, is to migrate away from requiring CFEngine to be installed on build hosts. See https://northerntech.atlassian.net/browse/ENT-14330

Comment thread ci/dependencies.sh

# rhel-8 has pcre2 10.32 but libntech needs at least 10.34 (PCRE2_SUBSTITUTE_MATCHED, PCRE2_SUBSTITUTE_LITERAL).
# Build it into /opt/pcre2, away from the system pcre2, and ci/configure.sh will use it from there.
build_pcre2() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If libntech needs a particular version of pcre2 then libntech should specify that and we should use that specification here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should just move this to buildscripts/ci/setup-cfengine-build-host.sh so we have the version there if we need to use it.

Comment thread ci/dependencies.sh Outdated
echo building pcre2 in "$tmpdir"
(
cd "$tmpdir"
curl --fail --location --silent --show-error --output pcre2.tar.gz https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.49/pcre2-10.49.tar.gz

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we are using a version from buildscripts and want to stay aligned we should grab the version FROM there instead of hard-coding it here and allowing the version to rot.

build_lmdb installed liblmdb into /usr/lib, which the runtime linker
does not search on lib64 distributions, so cf-key failed on RHEL 9.
It now installs into /usr/lib64 when that exists.

RHEL 8 ships pcre2 10.32, which lacks declarations libntech uses.
ensure_pcre2 reads them from libntech's AC_CHECK_DECLS line, and when
the system pcre2 lacks one, build_pcre2 builds the release pinned in
buildscripts deps-packaging into /opt/pcre2, which ci/configure.sh
then passes as --with-pcre2.

Ticket: ENT-14716
Changelog: none
Signed-off-by: Ihor Aleksandrychiev <ihor.aleksandrychiev@northern.tech>
@aleksandrychev
aleksandrychev force-pushed the ENT-14716_rhel8_9_source_build branch from 1ec3406 to 3a5f8b1 Compare November 4, 2026 18:39
Comment thread ci/dependencies.sh

# libntech's configure.ac lists the pcre2 declarations it needs (AC_CHECK_DECLS([PCRE2_...])).
# Build a newer pcre2 when the system one lacks any of them (rhel-8 has 10.32).
ensure_pcre2() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think any "guard" code should live in buildscripts/ci/setup-cfengine-build-host.sh and not here.

Here in core/ci/dependencies.sh we should just let things roll and fail if they will.

Comment thread ci/dependencies.sh

# rhel-8 has pcre2 10.32 but libntech needs at least 10.34 (PCRE2_SUBSTITUTE_MATCHED, PCRE2_SUBSTITUTE_LITERAL).
# Build it into /opt/pcre2, away from the system pcre2, and ci/configure.sh will use it from there.
build_pcre2() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should just move this to buildscripts/ci/setup-cfengine-build-host.sh so we have the version there if we need to use it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants