Skip to content

fix: self-contained release binaries (libprofiler + Windows DLLs)#13

Merged
andylbrummer merged 2 commits into
mainfrom
fix-self-contained-release
Jun 20, 2026
Merged

fix: self-contained release binaries (libprofiler + Windows DLLs)#13
andylbrummer merged 2 commits into
mainfrom
fix-self-contained-release

Conversation

@andylbrummer

Copy link
Copy Markdown
Member

Problem

The published v0.6.0 binary failed to load on clean machines:

error while loading shared libraries: libprofiler.so.0: cannot open shared object file

And the Windows/macOS release legs (added one day after v0.6.0 tagged) have never shipped a working artifact. Two distinct "green CI, broken tarball" defects — the dep sits in the build tree next to the test exe, so lci_tests passes while the shipped bin/lci references libs that aren't bundled.

Fixes

  1. gperftools opt-in (src/CMakeLists.txt) — release auto-linked the system shared libprofiler/libtcmalloc whenever present on the build machine. Now gated behind LCI_ENABLE_GPERFTOOLS (default OFF). profiling.cpp already fails fast at runtime when absent. Verified: release lci NEEDED no longer lists profiler/tcmalloc (on a machine that has libprofiler installed). Fixes Linux and the macOS brew-libprofiler analogue.

  2. Windows static-md triplet (ci.yml + release.yml) — Windows configured vcpkg with the default x64-windows triplet → abseil/re2 built as DLLs, not bundled by CPack. Pin VCPKG_TARGET_TRIPLET=x64-windows-static-md on both legs (lockstep, so the gate exercises the shipped linkage). Static libs + dynamic CRT (/MD) matches the project/FetchContent default — no CRT mismatch.

Why only Windows leaked

BUILD_SHARED_LIBS=OFF governs only the FetchContent deps; vcpkg packages follow the triplet. Linux x64-linux and macOS arm64-osx are static-by-default, so only Windows defaulted to dynamic DLLs.

Verification

  • Linux unit suite: 1702/1702 green (1 env-gated skip), gperftools OFF.
  • Linux lci v0.7.0 NEEDED: no profiler/tcmalloc, only universal system libs.
  • Windows (real host, VS2022, via vcpkg at the pinned commit): re2:x64-windows → 2 DLLs (abseil_dll.dll, re2.dll); re2:x64-windows-static-md0 DLLs. Triplet forces LIBRARY=static for all manifest deps.

🤖 Generated with Claude Code

andylbrummer and others added 2 commits June 19, 2026 20:53
Release binaries dynamically linked the system shared libprofiler/libtcmalloc
whenever gperftools was present on the build machine. The self-hosted Linux
release runner has libgoogle-perftools-dev installed, so the shipped v0.6.0
binary hard-depended on libprofiler.so.0 and failed to load on any machine
without gperftools:

    error while loading shared libraries: libprofiler.so.0: cannot open
    shared object file: No such file or directory

gperftools is a dev-only profiling aid (--profile-cpu / --profile-memory).
Gate it behind LCI_ENABLE_GPERFTOOLS (default OFF) so release builds never
link it; profiling.cpp already fails fast at runtime with a rebuild hint when
absent. Opting in but missing gperftools now hard-errors at configure time
instead of silently skipping.

Verified on a machine WITH libprofiler.so.0 installed: release `lci` NEEDED
list no longer contains profiler/tcmalloc — only universal system libs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…md triplet

The Windows release leg configured vcpkg with the default x64-windows triplet,
which builds the manifest deps (abseil, re2, xxhash, ...) as DLLs. The CPack
TGZ ships only lci.exe, so the shipped binary references absl_*.dll / re2.dll
that are absent on any machine without the build tree — the Windows analogue of
the libprofiler.so.0 load failure. The unit gate passed regardless because the
DLLs sit next to the test exe in the build tree, so CI was green while the
tarball was broken.

Pin VCPKG_TARGET_TRIPLET=x64-windows-static-md on both the release and ci
windows legs (kept in lockstep so the gate exercises the shipped linkage). That
triplet links the vcpkg deps statically into lci.exe while keeping the dynamic
CRT (/MD) the project and its FetchContent deps already use, avoiding a CRT
mismatch. Verified the triplet exists at the pinned vcpkg commit
(f3e1065) and resolves to CRT=dynamic, LIBRARY=static.

BUILD_SHARED_LIBS=OFF only governs the FetchContent deps; vcpkg packages follow
the triplet, which is why Linux (x64-linux) and macOS (arm64-osx) were already
self-contained (static by default) and only Windows leaked DLLs.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@andylbrummer
andylbrummer merged commit 4228822 into main Jun 20, 2026
8 checks passed
@andylbrummer
andylbrummer deleted the fix-self-contained-release branch June 20, 2026 02:46
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.

1 participant