haskell-language-server: add reproducibility flags to build.sh#267
Closed
edge-delta[bot] wants to merge 36 commits into
Closed
haskell-language-server: add reproducibility flags to build.sh#267edge-delta[bot] wants to merge 36 commits into
edge-delta[bot] wants to merge 36 commits into
Conversation
Add package for the Haskell Language Server (HLS), the official LSP implementation for Haskell. Builds from source using GHC + Cabal with dynamic linking, copying the binary and all required shared libraries via ldd dependency resolution. - Source: GitHub tag 2.14.0.0 with automatic extraction - Build deps: base, cabal, ghc - Runtime deps: glibc - Network access enabled for cabal dependency index updates - Includes standalone version check test
The base-soup rebuild recompiles gcc-15.2.0 against the new glibc 2.43 headers, which implement ISO C23 const-preserving string macros (strchr et al. now return `const char *` for a `const char *` input). gcc-15.2.0 predates this, so libgomp/affinity-fmt.c (`char *q = strchr(p+1,'}')`) discards const and fails -Werror=discarded-qualifiers — the FTBFS the buildbot hit. The pointer is only used for `q - p`, never written, so it's a source-pedantry mismatch, not a runtime bug. Downgrade only that single warning (everything else stays -Werror) via CFLAGS_FOR_TARGET (the documented knob for target libs like libgomp) + CFLAGS, for gcc's own build only — the shipped compiler is byte-identical. Interim escape hatch; gcc-16.1.0 fixes this upstream and builds cleanly against glibc 2.43 (LFS pairs them with no workaround), so the clean follow-up is bumping gcc to 16. This is the same C23 wave hitting the whole ecosystem (openssl, grub, libevent, ...). Refs in build.sh. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
…2.43 C23 rebuild glibc 2.43's ISO C23 const-preserving string macros (strchr/strstr/memchr/... return `const char *` for const input) cause an ecosystem-wide -Werror=discarded-qualifiers FTBFS wave. The make stack's shared CFLAGS land after each package's own -Werror on the compile line, so appending the downgrade here fixes the whole make/autotools fleet in one place. Interim until a gcc-16 bump (which fixes it upstream). Co-Authored-By: Claude Opus 4.8 <[email protected]>
…ires gcc/build.sh Co-Authored-By: Claude Opus 4.8 <[email protected]>
…TBFS
libxcrypt has a hand-written build.sh that *assigns* CFLAGS (not the make
stack), so the stacks/make/stack.ncl fleet lever from this PR can't reach it.
Its crypt-{gost,sm3}-yescrypt.c assign const-qualified strchr() results to a
plain char*, tripping libxcrypt's own configure-enabled -Werror under glibc
2.43's ISO C23 const-preserving string macros. Downgrade only that one warning,
appended after -Werror so the later flag wins.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
elfutils hardcodes CFLAGS in its build.sh (bypasses the make stack) and defaults -Werror on. glibc 2.43's ISO C23 const-preserving bsearch/strchr-family lookups discard const into plain pointers (libcpu/riscv_disasm.c known_csrs bsearch), tripping -Werror=discarded-qualifiers. elfutils is notorious for multiple distinct -Werror trips across toolchain bumps, so use its own --disable-werror off-switch rather than chase warnings one flag at a time. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…disable-werror unrecognized) elfutils' configure has no --disable-werror in this version (it warned 'unrecognized options: --disable-werror' and kept -Werror on, so the C23 discarded-qualifiers trip in libcpu/riscv_disasm.c persisted). Use the same surgical CFLAGS flag as libxcrypt instead: automake emits $(AM_CFLAGS) $(CFLAGS), and elfutils' -Werror lives in AM_CFLAGS, so a -Wno-error in CFLAGS lands after it on the compile line and wins. The whole libelf tree compiled clean before the single trip, so the one warning is the only break. Co-Authored-By: Claude Opus 4.8 <[email protected]>
strace hardcodes CFLAGS in build.sh (bypasses make stack) and self-enables -Werror. glibc 2.43's ISO C23 const-preserving bsearch returns const for a const arg; src/ioctl.c assigns it to a plain pointer (iop = bsearch(..., ioctlent, ...)). Downgrade only that warning, appended after strace's -Werror on the compile line so the later flag wins. Same glibc-2.43 C23 class as #238. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…reads collision or-tools FetchContent's SCIP v10.0.0, which bundles tinycthread (a C11 <threads.h> shim doing `#define once_flag pthread_once_t`). glibc 2.43 surfaces its native once_flag/call_once into SCIP's TU, so that macro corrupts glibc's `typedef __once_flag once_flag;` into a pthread_once_t redefinition -> hard "conflicting types" FTBFS (not the -Werror class; -Wno-error can't help). or-tools 9.15 is already the latest release and pins current SCIP, so no version bump escapes it. or-tools hard-FORCEs SCIP TPI=tny in its bundled cmake, so a -DTPI=... is overridden. sed the forced TPI to omp before cmake: SCIP uses its OpenMP task interface (no tinycthread), staying parallel + THREADSAFE (SCIP auto-forces THREADSAFE on for non-none TPI). libgomp is present from gcc. A grep guard fails the build loudly if upstream renames the line. Leaf package (nothing depends on it) but in the glibc closure, so it must build. glibc-2.43 class, #238. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…package) Info-ZIP unzip 6.0 has been frozen since 2009 and carries unfixed CVE-2014-8139/8140/8141 + CVE-2018-1000035 (4 HIGH) with no upstream to track — it was both vuln-exposed AND update-dark (pkgmgr check: no-source). bsdunzip, added to libarchive in 3.7.0, is its maintained successor. - New `packages/libarchive` (3.8.7, GithubRepo libarchive/libarchive, BSD-2): builds bsdtar/bsdcpio/bsdcat/bsdunzip + libarchive.so against zlib/bzip2/lzma (heavy optional backends disabled to keep the dep set lean). Source staged to gs://minimal-staging-archives/. - `packages/unzip` becomes a thin compat shim: a /usr/bin/unzip symlink to bsdunzip (libarchive runtime dep). Info-ZIP source + build dropped. bsdunzip is a drop-in for the flags our callers use — verified in bsdunzip.1 that -o/-q/-d/-p are all supported, so bun + chromium-bin + chromium-headless-shell-bin keep invoking `unzip` unchanged. Version-tracking now follows libarchive, so it's no longer update-dark. Locally validated: both build.ncl parse + resolve; `pkgmgr check --package unzip` now reports up_to_date (3.8.7) instead of a `no-source` skip. DRAFT — needs the buildbot to verify: libarchive compiles with the chosen configure flags, bsdunzip is produced, the symlink + OutputBin lint pass, the roundtrip test extracts via bsdunzip, and the three consumers (bun, chromium-bin, chromium-headless-shell-bin) still build against bsdunzip. Co-Authored-By: Claude Opus 4.8 <[email protected]>
Co-Authored-By: Claude Opus 4.8 <[email protected]>
The sandbox rejected the /usr/bin/unzip -> bsdunzip symlink: bsdunzip lives in the libarchive package's output, so the symlink 'points outside output directory'. Replace it with a /bin/sh wrapper that execs /usr/bin/bsdunzip (provided by the libarchive runtime dep) — a real file, no symlink escape; callers keep invoking unzip unchanged. Co-Authored-By: Claude Opus 4.8 <[email protected]>
The kernel bakes build time/user/host into the image via scripts/mkcompile_h (surfaced in /proc/version), so vmlinuz differed byte-for-byte across otherwise-identical rebuilds. Pin all three (timestamp from SOURCE_DATE_EPOCH) so the image is deterministic. Verified reproducible on aarch64: two from-scratch forced rebuilds produced byte-identical output (repro-check diff, 3/3 files identical). Co-Authored-By: Claude Opus 4.8 <[email protected]>
…zip plan) Reverses the bsdunzip migration: bun's build invokes `unzip -o -DD -d` and `-DD` (don't-restore-timestamps) is an Info-ZIP-only flag bsdunzip lacks, so swapping unzip→bsdunzip broke bun's build. Info-ZIP is the only impl with `-DD`. Instead, do what every distro does — keep frozen Info-ZIP 6.0 and apply the backported security patches. We were shipping the pristine `unzip_6.0.orig` tarball with NO patches, which is exactly why it scanned 4 HIGH. Now stage + apply Debian's full 6.0-29 series (31 patches): fixes CVE-2014-8139/8140/8141/ 9636/9913, CVE-2015-7696/7697, CVE-2016-9844, CVE-2018-1000035, CVE-2019-13232, CVE-2022-0529/0530 + build fixes. Patch 30 drops the K&R gmtime()/localtime() declarations, replacing the manual sed that lived in build.sh. Drops the new libarchive package (no remaining consumer). unzip stays update-dark, which is correct: 6.0 is EOL and the patches are its maintenance. Follow-up: VEX the patched CVE IDs so the version-based scanner (which can't see the backported fixes) clears them. Co-Authored-By: Claude Opus 4.8 <[email protected]>
… edits) The previous commit's git-add aborted on the already-removed libarchive pathspec, so the build.ncl patches Source + build.sh apply-loop never staged. This adds them: the staged-tarball Source and the series-apply loop (and removes the now-redundant gmtime sed, handled by patch 30). Co-Authored-By: Claude Opus 4.8 <[email protected]>
The in-guest minimald session bring-up inits a minimal context that shells out to git. Without git in the runtime closure, an interactive `minimal attach` (PTY shell) fails at session bring-up with: init of minimal context: The git command was not found in path The non-interactive exec path is unaffected (it skips the context init), which is why this surfaced only once interactive attach was wired up on the client. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
socat was only used by the package's own /sbin/microvm-init: a standalone block-root bring-up that wrote the READY marker on vsock 7350 and ran an echo server on 2222. The minvmd flow never runs it — minimald ships as the initramfs pid-1, mounts this image and chroots in, writes READY itself, and serves SSH directly on vsock 2222 (run_on_vsock, libkrun >= 1.19, no relay). minvmd has no socat-relay fallback. Remove socat from runtime_deps and delete the now-dead microvm-init stub + its etc/microvm manifest, leaving a pure userland (base + git). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Two independent causes of cross-rebuild divergence: 1. Rust CLI codegen: parallel codegen-units (.llvm.<hash> symbols) plus ahash/const-random's compile-time seed. Pin both via RUSTFLAGS (-C codegen-units=1, path remaps) and CONST_RANDOM_SEED=0. 2. pnpm state files embed wall-clock timestamps (.modules.yaml prunedAt, .pnpm-workspace-state-v1.json lastValidatedTimestamp) and aren't needed at runtime. Drop both before packaging. Verified on aarch64: with the codegen fixes, two from-scratch builds were identical in 12737/12738 files (sole diff = the pnpm timestamp file); removing it yields byte-identical output (repro-check diff, 0 differences). Co-Authored-By: Claude Opus 4.8 <[email protected]>
NSPR bakes a wall-clock build time into its embedded version string and ignores SOURCE_DATE_EPOCH, so libnspr4.so differed across rebuilds. The version header (pr/src/Makefile.in) has two stamps: _BUILD_STRING from $(shell date) and _BUILD_TIME from config/now.c. Both are make variables, so override them rather than patching source: SH_NOW="" omits _BUILD_TIME (defaults to 0 in prvrsion.c) and SH_DATE is pinned from SOURCE_DATE_EPOCH. Verified on aarch64: two from-scratch builds are byte-identical (repro-check diff, 72/72 files, 0 differences). Co-Authored-By: Claude Opus 4.8 <[email protected]>
The build sandbox already exports SOURCE_DATE_EPOCH=0, and minimal-check's build-script disallowed-patterns checker rejects re-setting it. Reference the sandbox-provided value instead; behavior is identical (SH_DATE still resolves to the epoch-0 date). Co-Authored-By: Claude Opus 4.8 <[email protected]>
…_EPOCH The sandbox already exports SOURCE_DATE_EPOCH=0 and PYTHONHASHSEED=0, and minimal-check's disallowed-patterns checker rejects re-setting them. The guidance from #259 wrongly told authors to export them (and claimed the sandbox does not pin the clock), which made the nspr repro PR fail CI. - State the sandbox provides both; do not set them in build.sh. - Replace the bad export bullet with the correct pattern (pin the specific stamp; nspr SH_DATE/SH_NOW as the example). - Fold libtool .la cleanup into the C/C++ bullet; make explicit that authors apply only the bullet for their build system. Co-Authored-By: Claude Opus 4.8 <[email protected]>
7f9397b to
248ded5
Compare
Member
|
Thanks for all the help Edge Delta, we are working on them directly, closing out this advisory PR, we don't allow bots to do PRs unless they are our own for now. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The
haskell-language-serverpackage added in PR #214 is missing the reproducibility flags required by AGENTS.md §Reproducibility. Without these flags, two builds of the same source will produce different binaries due to embedded build paths and linker-generated build-ids — breaking the content-addressed build cache.Detected via GitHub Push Event Monitor alert (monitorEventId
3FHkOYBzm6gzDAG75zinbN3HN4g) on theunstablebranch push at2026-06-17T23:28:57Z.Related issues
Changes
cabal buildinvocation:-optc-ffile-prefix-map=$(pwd)=/builddir— strips absolute build paths from C stub object files (GHC invokes gcc for C/Cmm code)-optl-Wl,--build-id=none— suppresses the linker's random build-id in the final ELF binarystrip --remove-section=.note.gnu.build-idon the installed binary (covers edge cases where cabal re-links without our-optlflag)Checklist
min checkpasses for the affected packages/harnesses.min patched-build <name>succeeds for any package I added or modified.source_provenancepoints to the canonical upstream and the source builds from source (not a prebuilt release binary) where the required toolchain is available.sha256against the upstream archive.Notes for reviewers
This follows the same pattern as
agent-browser(PR #264) which added--remap-path-prefix+--build-id=nonefor Rust, andvirtio-linux(PR #261) which pinnedKBUILD_BUILD_*. The Haskell equivalent uses GHC's-optc(pass to C compiler) and-optl(pass to linker) forwarding mechanisms.The
stackpackage (packages/stack/build.sh) has the same gap — it also does a barecabal buildwithout reproducibility flags — but that's a pre-existing issue outside the scope of this push's changes.This pull/merge request was created by Edge Delta AI Teammates — see #code-issues for the original conversation.