Skip to content

feat: self-contained Linux release archives, as coretrace ships ctrace - #20

Merged
SizzleUnrlsd merged 5 commits into
mainfrom
feat/self-contained-release
Sep 26, 2026
Merged

SizzleUnrlsd merged 5 commits into
mainfrom
feat/self-contained-release

Conversation

@SizzleUnrlsd

@SizzleUnrlsd SizzleUnrlsd commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

Closes #19. Stacked on #18 (chore/standalone-release): merge that one first.

Same approach as coretrace for ctrace: the LLVM libraries and Clang's headers ship in the archive, the CLI points coretrace-compiler at itself, and the archive is verified on bare images before it is published.

Change

  1. LLVM libraries shipped (CMakeLists.txt, Linux only). install(TARGETS ... RUNTIME_DEPENDENCY_SET) copies the CLI's dependencies found under LLVM_LIBRARY_DIRS into lib/ (libLLVM, libclang-cpp), with libstdc++ and libgcc_s; glibc stays the system's. INSTALL_RPATH is $ORIGIN/../lib. The CMake minimum moves to 3.21 for RUNTIME_DEPENDENCY_SET.
  2. Clang headers shipped (cmake/ClangHeaders.cmake, all platforms). The resource directory's include/ of the clang coretrace-compiler was configured with is installed at lib/clang/<version>/include. src/shipped_toolchain.cpp: when those headers are there and CT_CLANG is not set, Main() sets CT_CLANG to the CLI itself, from which coretrace-compiler derives the resource directory. A user's CT_CLANG keeps priority.
  3. Instrumented programs linked against the shipped C++ runtime. This one is specific to the analyzer, which links programs where ctrace only compiles. The runtime archives are built with GCC 13, and linking them on a bare Ubuntu 22.04 (libstdc++ 11) failed with undefined reference to std::__cxx11::basic_string::_M_replace_cold (the first verification run showed it). The Linux install tree now also carries the unversioned lib/libstdc++.so link, and when it exists next to the CLI, Main() appends -L<lib> -Wl,-rpath,<lib> to linking runs.
  4. Dockerfile.release, after coretrace's Dockerfile.release-binaries: Ubuntu 22.04 base with GCC 13 and LLVM 20 (so the archive runs on glibc 2.35 and newer), build, the full test suite, cmake --install --strip, patchelf ($ORIGIN on each .so, $ORIGIN/../lib on each executable, bin/cc included), an ldd check, then the archive unpacked and run on bare Ubuntu 22.04, Debian 12, Rocky Linux 9 and Ubuntu 24.04 with only g++ or gcc-c++ installed and no clang or LLVM: test/release/check-analysis.sh runs runtime-analyzer -- heap_overflow_write.c with env -i and expects exit 1 with the heap-buffer-overflow finding. Artifacts are exported only when every stage passes.
  5. release.yml rewritten: amd64 on ubuntu-24.04, arm64 on ubuntu-24.04-arm, docker buildx build --target artifacts, checksum validation, artifacts uploaded; on a v* tag the tag must equal v<project version> and the archives with their .sha256 are attached to the GitHub Release as runtime-analyzer-<version>-linux-<arch>.tar.gz. It also runs on pull requests that touch the release files, without publishing, so this pull request's checks include both archives.

What stays the system's: a C++ build environment (g++ on Debian and Ubuntu, gcc-c++ on RHEL), because each instrumented program is linked against the runtime, which is C++. The README says so.

Tests (written first)

  • unittests/shipped_toolchain_test.cpp (shipped_toolchain_unit): CT_CLANG set to the CLI when ../lib/clang/<version>/include/stddef.h exists next to it, left alone when the user set it, untouched without headers; -L/-rpath returned only when ../lib/libstdc++.so exists.
  • install_layout also expects lib/clang/*/include/stddef.h.
  • The four verification stages of Dockerfile.release are the end-to-end check; the first local run (arm64, before item 3) failed exactly there, at link time on Ubuntu 22.04.

Verification

  • macOS arm64: ctest --test-dir build 12/12, ./scripts/format-check.sh clean.
  • Docker, linux/arm64, before item 3: base, build, 12/12 tests and packaging passed; the Ubuntu 22.04 stage failed at link time as described. The run with item 3 is this pull request's Release workflow, on both architectures (my machine's Docker disk is full): run 36216034610 is green on amd64 and arm64, and each of the four bare images (Ubuntu 22.04, Debian 12, Rocky Linux 9, Ubuntu 24.04) links the program and reports the heap-buffer-overflow finding with exit 1.

coretrace-compiler compiles in process but needs a clang path to find
Clang's own headers (stddef.h, stdarg.h, the intrinsics), so an
installed analyzer required a clang on the machine it ran on.

cmake/ClangHeaders.cmake installs the resource directory's include/ of
the clang coretrace-compiler was configured with at
lib/clang/<version>/include, next to bin/runtime-analyzer. When those
headers are there and CT_CLANG is not set, Main() points CT_CLANG at
the CLI itself, from which coretrace-compiler derives the resource
directory. CT_CLANG set by the user keeps priority, and a build-tree
CLI, which ships nothing, changes nothing.

unittests/shipped_toolchain_test.cpp checks the rule on temporary
layouts; install_layout also expects the installed headers.

Refs #19
The CLI links libLLVM and libclang-cpp dynamically. On Linux,
install(RUNTIME_DEPENDENCY_SET) now copies the dependencies found under
LLVM's library directory into lib/, with libstdc++ and libgcc_s, as the
build compiler may be newer than the target's and they are backward
compatible; glibc stays the system's. The CLI gets an INSTALL_RPATH of
$ORIGIN/../lib. The CMake minimum moves from 3.16 to 3.21 for
RUNTIME_DEPENDENCY_SET.

Refs #19
The runtime archives are built with GCC 13, whose libstdc++ symbols
(_M_replace_cold and others) are missing from the libstdc++ 11 of
Ubuntu 22.04 or the 12 of Debian 12: linking an instrumented program
there failed with undefined references, although the GCC 13 libstdc++
is shipped in the archive's lib/ for the CLI itself.

The Linux install tree now also carries the unversioned lib/libstdc++.so
link that -lstdc++ resolves, and when that file exists next to the CLI,
Main() appends -L<lib> and -Wl,-rpath,<lib> to the compiler arguments
of a linking run, so that instrumented programs are linked against, and
load, the shipped runtime. A build-tree CLI, which ships nothing, and a
compile-only run are unchanged.

The shipped_toolchain unit test covers the arguments with and without
the shipped library. The release verification on a bare Ubuntu 22.04
image, which failed at link time, is the end-to-end check.

Refs #19
Dockerfile.release follows coretrace's Dockerfile.release-binaries:
an Ubuntu 22.04 base with GCC 13 and LLVM 20, so that the archive runs
on its glibc and on every newer distribution; the build and the test
suite; cmake --install --strip with the LLVM libraries, the runtime
archives and Clang's headers; patchelf setting $ORIGIN on each shipped
library and $ORIGIN/../lib on each executable (cc, installed by
coretrace-compiler's rules, has no rpath of its own); an ldd check that
nothing is left unresolved; then the archive unpacked and run on bare
Ubuntu 22.04, Debian 12, Rocky Linux 9 and Ubuntu 24.04 images with
only g++ or gcc-c++ installed and no clang or LLVM, where
test/release/check-analysis.sh expects the heap overflow of
heap_overflow_write.c to be reported with exit status 1. The artifacts
are exported only when every stage passes.

The Release workflow builds the archive for amd64 and arm64 on native
runners, on v* tags, on demand, and on pull requests touching the
release files; on a tag it checks that the tag matches the project
version and attaches the archives and their .sha256 to the GitHub
Release, named runtime-analyzer-<version>-linux-<arch>.tar.gz.

Refs #19
Base automatically changed from chore/standalone-release to main September 26, 2026 13:47
@SizzleUnrlsd SizzleUnrlsd self-assigned this Sep 26, 2026
@SizzleUnrlsd
SizzleUnrlsd merged commit 1a9508f into main Sep 26, 2026
6 checks passed
@SizzleUnrlsd
SizzleUnrlsd deleted the feat/self-contained-release branch September 26, 2026 13:47
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.

Make the Linux release self-contained: ship the LLVM libraries and the Clang headers

1 participant