Skip to content

build: update and shrink build images, migrate to clang 19#3771

Merged
morrisonlevi merged 31 commits intomasterfrom
levi/clang-17-to-19
Apr 9, 2026
Merged

build: update and shrink build images, migrate to clang 19#3771
morrisonlevi merged 31 commits intomasterfrom
levi/clang-17-to-19

Conversation

@morrisonlevi
Copy link
Copy Markdown
Collaborator

@morrisonlevi morrisonlevi commented Apr 3, 2026

Description

A few key changes:

  • Update the PHP versions to the latest. Sort out various dependency pins and patches.
  • Update clang from 17 to 19. Going to clang 19 matches Rust 1.84, but libdatadog recently introduced a compiler flag which was introduced in clang 19 (though anciently in GCC). libdatadog has since been patched, but it's a good idea to upgrade anyway.
    • This doesn't port all of appsec's tests, because going from Clang 17 -> 19 requires quite some changes, needs a dedicated PR.
  • Shrink the CentOS 7 base image from 5.12 GB to 2.72 GB on disk (arm64) and from 1,820 MB to 793 over the wire (again arm64). This comes from a variety of sources including:
    • Dropping some kernel and firmware updates (these are container images, the host is the thing that needs those, not our container).
    • Deleting sources of some dev tools like cmake. Also delete some help docs for cmake, as well as ccmake and cpack.
    • Moving devtoolset-9 to being part of the LLVM layer, and removing it in that same layer. It's not needed after LLVM builds.
    • Drops protobuf. This used to be a dependency for the profiler, but it hasn't been one for quite some time.

Reviewer checklist

  • Test coverage seems ok.
  • Appropriate labels assigned.

@datadog-prod-us1-6
Copy link
Copy Markdown

datadog-prod-us1-6 bot commented Apr 3, 2026

✅ Tests

🎉 All green!

❄️ No new flaky tests detected
🧪 All tests passed

🎯 Code Coverage (details)
Patch Coverage: 100.00%
Overall Coverage: 60.68% (-0.01%)

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: f7dc60b | Docs | Datadog PR Page | Was this helpful? React with 👍/👎 or give us feedback!

This matches Rust 1.84, but libdatadog recently introduced a flag
which was introduced in this version. Although this should not cause
a hard failure and libdatadog should be patched, it's also a good
idea to upgrade.
@morrisonlevi morrisonlevi force-pushed the levi/clang-17-to-19 branch from 9171217 to eb6cef6 Compare April 6, 2026 15:28
morrisonlevi and others added 4 commits April 6, 2026 09:36
- Exclude kernel-core, kernel-modules, linux-firmware globally via yum.conf
  (~183 MB; these are useless in containers)
- Move devtoolset-9 into the LLVM RUN layer and remove it afterward (~196 MB)
- Build LLVM with CLANG_BUILD_TOOLS=OFF and LLVM_INSTALL_TOOLCHAIN_ONLY=ON
  to skip building unused tools (~1.3 GB)
- Remove LLVM internal C++ headers and cmake config dirs post-install (~54 MB)
- Add --disable-static to libxml2, libffi, oniguruma, curl, sqlite3 configure
- Remove .a static archives from openssl and zlib after install
- Fix catch2 build/source cleanup (cd - && rm -fr build was a no-op)
- Remove cmake Help docs and man pages post-install (~10 MB)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PHP 8.5: RC3 -> 8.5.4 (stable) across centos-7, bookworm
- PHP 8.4: 8.4.1/8.4.16 -> 8.4.19 across centos-7, bookworm
- PHP 8.3: 8.3.14/8.3.29 -> 8.3.30 across centos-7, bookworm
- PHP 8.2: 8.2.26/8.2.28 -> 8.2.30 across centos-7, bookworm
- PHP 8.1: 8.1.8/8.1.31 -> 8.1.32 across centos-6, centos-7
- PHP 8.0: 8.0.15/8.0.21/8.0.27 -> 8.0.30 across centos-6, centos-7, alpine
- PHP 7.4: 7.4.30 -> 7.4.33 on centos-6

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@morrisonlevi morrisonlevi changed the title build: migrate clang 17 -> 19 build: update build images, migrate to clang 19 Apr 7, 2026
@morrisonlevi morrisonlevi changed the title build: update build images, migrate to clang 19 build: update and shrink build images, migrate to clang 19 Apr 7, 2026
morrisonlevi and others added 4 commits April 6, 2026 19:58
- sqlsrv 5.13.0 raised minimum to PHP 8.3; pin PHP 8.1-8.2 to 5.12.0
- grpc 1.80.0 uses EG(max_allowed_stack_size) gated on PHP_VERSION_ID>=80300
  but the field is absent in ASan builds because the ZEND_CHECK_STACK_LIMIT
  autoconf test cannot execute sanitized binaries during configure; pin to
  1.78.0 which predates that change

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
preserve_none + -fsanitize=address crashes clang 19+ on x86-64
(llvm/llvm-project#95928). Apply a patch at source-tree build time
that guards ZEND_PRESERVE_NONE with __has_feature(address_sanitizer),
following the fix pattern from llvm-project commit 996157c.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds -s (silent) to all make invocations in build-php.sh and to
MAKEFLAGS in build-extensions.sh (which covers pecl installs too).
Compiler errors still print via stderr; only the cc/ld recipe lines
are suppressed. Reduces log volume significantly given parallel stages.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@morrisonlevi morrisonlevi force-pushed the levi/clang-17-to-19 branch from 2d15ef6 to 7da2707 Compare April 7, 2026 15:24
script:
- cd dockerfiles/ci/alpine_compile_extension
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_TOKEN" $CI_REGISTRY
- echo "$CI_REGISTRY_TOKEN" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is this to prevent tokens from leaking into the logs?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Something like that, something complained here, claude recommended this as more secure anyway and it seemed plausible enough while being harmless if wrong.

sed -i s/^mirrorlist=http/#mirrorlist=http/g /etc/yum.repos.d/*.repo; \
echo 'ip_resolve = IPv4' >>/etc/yum.conf; \
# kernel and linux-firmware are useless in containers (host kernel is used);
# excluding them globally prevents ~183 MB of waste from being pulled in as side-effects.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nice

@@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Is there a test for this patch, and a test to see when this patch is no longer necessary?

Copy link
Copy Markdown
Collaborator Author

@morrisonlevi morrisonlevi Apr 7, 2026

Choose a reason for hiding this comment

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

We cannot build the PHP 8.5 CI image without this patch, the build will fail. I'll need to make an upstream PR, I have not done this yet, just discovered this edge late last night or this morning (can't quite remember which).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

PR is open: php/php-src#21676

morrisonlevi and others added 6 commits April 7, 2026 16:20
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ctest is required by the appsec C components ASAN job (make test calls
ctest internally). cpack remains removed as it is genuinely unused.

Also updates clang-tidy, llvm-cov, llvm-profdata, clang-format, and
libc++ references from version 17 to 19 in appsec CI and cmake config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Alpine compile extension image: llvm17-libs/clang17-dev/llvm17 → 19
- build-profiler.sh, generate-profiler.php, build-debug-artifact:
  Alpine aarch64 clang symlink llvm17 → llvm19
- appsec/cmake/clang-format.cmake: llvm@17 → llvm@19
- centos-7 base.Dockerfile: remove -DCLANG_BUILD_TOOLS=OFF which
  prevented the clang binary itself from being built/installed,
  leaving broken symlinks and breaking bindgen

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Newer clang versions return a per-target path from -print-runtime-dir
(e.g. .../lib/x86_64-pc-linux-gnu) but Debian/Ubuntu packages install
compiler-rt runtime libs in a sibling "linux/" directory. Add that as a
fallback search path for both find_library and target_link_directories.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… variadic

clang 19 with -Werror,-Wc23-extensions rejects calling a variadic macro
with no argument for '...'. CONFIG's body called SYSCFG(type, name) with
only 2 args. Pass CONFIG's own __VA_ARGS__ through instead — CONFIG is
always called with at least a default value, so the variadic arg is never
empty. SYSCFG ignores the extra args in this context anyway.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@morrisonlevi morrisonlevi force-pushed the levi/clang-17-to-19 branch from 5a57599 to 3ee2336 Compare April 8, 2026 18:30
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@morrisonlevi morrisonlevi force-pushed the levi/clang-17-to-19 branch from 8e5bfc7 to dc150da Compare April 8, 2026 18:53
@morrisonlevi morrisonlevi marked this pull request as ready for review April 8, 2026 19:15
@morrisonlevi morrisonlevi requested review from a team as code owners April 8, 2026 19:15
@pr-commenter
Copy link
Copy Markdown

pr-commenter bot commented Apr 8, 2026

Benchmarks [ appsec ]

Benchmark execution time: 2026-04-08 20:00:02

Comparing candidate commit dc150da in PR branch levi/clang-17-to-19 with baseline commit 14dabf8 in branch master.

Found 0 performance improvements and 0 performance regressions! Performance is the same for 12 metrics, 0 unstable metrics.

morrisonlevi and others added 10 commits April 8, 2026 14:41
- acceptor.cpp: use designated initializer for timeval (layout is
  system-dependent, so positional init is unsafe)
- extension/.clang-tidy: suppress checks new in clang-tidy 19 that fire
  on pre-existing C code (math-missing-parentheses, macro-to-enum,
  multi-level-implicit-pointer-conversion, redundant-casting)
- helper/.clang-tidy: suppress modernize-use-designated-initializers for
  internal structs where positional init is unambiguous

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
clang-tidy 19 readability-avoid-return-with-void-value rejects
returning the result of a void function call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Reverts all appsec source/config changes that were made to accommodate
clang-19 warnings and formatting. Appsec jobs stay on clang-17 for now.
Bumps appsec CI image from bookworm-6 to bookworm-7.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bookworm-7 only ships clang-19 in its apt repo; appsec jobs still
need clang-17 so stay on bookworm-6 for now.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The test lacks a SKIPIF guard for IPv6 availability. In CI (Kubernetes
pods), IPv6 is unavailable so socket_create() returns false, causing a
TypeError instead of the expected warnings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
zai_reset_observed_frame_post_bailout (PHP 8.0/8.1) calls
zend_observer_fcall_end_all after a sandbox bailout. At that point
current_observed_frame may point to a dummy_execute_data that was
stack-allocated inside zend_call_function and already freed by the
unwind. PHP 8.2+ is safe via zai_set_observed_frame(NULL).

Suppress for the "multiple observers" ASAN job while Bob investigates
a proper fix in zai_reset_observed_frame_post_bailout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Same stack-use-after-return in zai_reset_observed_frame_post_bailout
seen in Zend Abstract Interface Tests with debug-zts-asan.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ASAN error

ASAN suppression files don't support fun: entries; that's TSan/LSan format.
Use detect_stack_use_after_return=0 in the affected jobs instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
-# define ZEND_PRESERVE_NONE __attribute__((preserve_none))
+# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
+/* preserve_none + ASan crashes clang 19+ on x86-64, see llvm/llvm-project#95928 */
+# define ZEND_PRESERVE_NONE
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Bummer, that's what enables the tail call VM. Which is something probably worth testing under asan for interceptors.

Maybe we should go straight for newer clang versions where that's fixed.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

See my upstream PHP PR: php/php-src#21676 because LLVM itself disabled it in main just 1 week ago: llvm/llvm-project#190001.

Copy link
Copy Markdown
Collaborator

@bwoebi bwoebi left a comment

Choose a reason for hiding this comment

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

Overall looks great, thanks

@morrisonlevi morrisonlevi merged commit 635ed66 into master Apr 9, 2026
2097 of 2100 checks passed
@morrisonlevi morrisonlevi deleted the levi/clang-17-to-19 branch April 9, 2026 15:01
@github-actions github-actions bot added this to the 1.18.0 milestone Apr 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants