Restructure compiler flags: separate compile and final-link profiles#1
Merged
Sam Gammon (sgammon) merged 6 commits intomainfrom May 5, 2026
Merged
Conversation
Drop GCC-only diagnostics that clang silently no-ops or rejects under
upstream -Werror (Wlogical-op, Wduplicated-cond/branches, Wtrampolines,
Wtraditional-conversion, Wformat-signedness, Wstringop-overflow=N,
Wformat-{overflow,truncation}=N, Warith-conversion, Whardened) and move
the clang-compatible warning set into base.txt so it applies on darwin
too. Remove the duplicate -fstack-clash-protection from base — it's
linux-only per the comment and Apple's clang rejects it.
Add modern hardening across the matrix: -fzero-call-used-regs=used-gpr
and -fasynchronous-unwind-tables in base; -D_FORTIFY_SOURCE=3 plus
-D_GLIBCXX_ASSERTIONS, -fno-semantic-interposition, -fno-plt and a
broader lld bundle (--icf=safe, --gc-sections, --as-needed,
-z pack-relative-relocs, --build-id=sha1, -O2) on linux;
-D_FORTIFY_SOURCE=2, -D_LIBCPP_HARDENING_MODE_FAST and Mach-O
-dead_strip / -bind_at_load / -fixup_chains on darwin.
Set the previously-missing arch baselines: -march=x86-64-v3 on
{linux,darwin}-amd64; -march=armv8.2-a+crypto+crc+dotprod with
-mbranch-protection=standard and -z force-bti / -z pac-plt on
linux-arm64; -mcpu=apple-m1 with -mbranch-protection=standard on
darwin-arm64. Enable -fcf-protection=full (Intel CET) on linux-amd64
only — macOS userspace doesn't back IBT/SHSTK.
Address the musl/libstdc++/dependency-build constraints surfaced in review: - Drop -Wconversion (too noisy across Netty JNI glue and BoringSSL intrinsics; re-enable per-target if needed). - Drop -Wl,--gc-sections from linux.txt and -Wl,-dead_strip from darwin.txt — these flags are applied to dependency builds whose intermediate links (conftests, test executables) need sections we'd otherwise strip. -ffunction-sections/-fdata-sections still emit the per-symbol granularity, and the consuming project picks up DCE at its own final link step. Documented as such in the README. - Replace -D_FORTIFY_SOURCE=3 with =2 on linux.txt: Linux/amd64 ships against musl, which tops out at level 2 — level 3 needs the glibc __builtin_dynamic_object_size chk variants. - Drop -D_GLIBCXX_ASSERTIONS (we don't ship libstdc++ on Linux); add -D_LIBCPP_HARDENING_MODE_FAST instead, since linux-amd64 ships a vendored libc++ that honors it. - Layer the cryptographic ISA extensions onto -march=x86-64-v3 to mirror our Rust profile: linux-amd64 gets +aes+pclmul+sha+vaes+gfni +rdrand and -mtune=znver3 (effective floor: Ice Lake / Zen 3+); darwin-amd64 keeps a conservative +aes+pclmul+rdrand subset that every Intel Mac has. Document toolchain + libc + ISA floors in the README and the consumer- final-link responsibility for section stripping.
Split the "applies to every translation unit + every link in the
dependency-build pipeline" set from the "applies only at the consuming
project's final executable / shared-library / dylib link" set.
Anything that strips Mach-O / ELF sections, rejects undefined symbols,
compresses debug info, or otherwise assumes "no further link will
follow" now lives in a *-bin sibling and is applied only at the
consumer's leaf link step.
Each leaf profile (linux-amd64, linux-arm64, darwin-amd64,
darwin-arm64) gets a *-bin counterpart that rolls up on top of the
existing chain (base → os → os-arch → os-arch-bin):
- linux-amd64-bin / linux-arm64-bin:
-Wl,--gc-sections DCE consumer of -ffunction/-fdata-sections
-Wl,-z,defs reject undefined symbols at final link
-Wl,--compress-debug-sections=zstd ~40-60% smaller .debug_* (lld 18+)
-Wl,--fatal-warnings promote linker warnings only at the leaf
- darwin-amd64-bin / darwin-arm64-bin:
-Wl,-dead_strip Mach-O analogue of --gc-sections
-Wl,-dead_strip_dylibs Mach-O analogue of --as-needed
README documents the compile-vs-binary profile split, lists the new
profiles in their own table, and updates the IMPORTANT callout to
point consumers at the *-bin profile instead of asking them to add
the flag manually.
Mirror the compile-side rollup on the binary-link side: introduce linux-bin.txt and darwin-bin.txt to hold OS-wide final-link flags, and reduce each linux-$arch-bin.txt / darwin-$arch-bin.txt to a placeholder for arch-specific leaf-link flags (currently none). The full rollup for a binary profile is now: base.txt → $os.txt → $os-$arch.txt → $os-bin.txt → $os-$arch-bin.txt linux-bin.txt now owns: -Wl,--gc-sections -Wl,-z,defs -Wl,--compress-debug-sections=zstd -Wl,--fatal-warnings darwin-bin.txt now owns: -Wl,-dead_strip -Wl,-dead_strip_dylibs The four leaf $os-$arch-bin.txt files remain as documented placeholders so the script can read them unconditionally and so we have a clear home for any future arch-specific final-link flag (ISA-targeted linker assertion, BTI/PAC tightening beyond what linux-arm64.txt enables, …). README updated: drop the implication that the leaf-bin files carried the strip/defs/compress flags, list linux-bin and darwin-bin as their own rows, and document the new five-stage rollup chain.
Add two equivalent CLIs (Bash + Bun/TypeScript) that print the
concatenated, comment-stripped flag list for a given (os, arch) pair
as a single whitespace-separated line, suitable for shell command
substitution into CFLAGS / LDFLAGS.
Surface (identical between the two):
cflags[.sh|.ts] [<os> <arch>] [--bin]
<os>: linux | darwin (defaults to host)
<arch>: amd64 | arm64 (defaults to host)
--bin: switch to the *-bin rollup (final-link flags)
Verified that both implementations emit byte-identical output across
all eight (os × arch × {compile, --bin}) combinations.
Both scripts have shebangs and execute permissions, so the canonical
invocations work as expected:
export CFLAGS="$(./cli/cflags.sh)"
export LDFLAGS="$(bun run ./cli/cflags.ts --bin)"
README documents the CLI, the surface, and the example export
patterns.
There was a problem hiding this comment.
Pull request overview
This PR reorganizes the compiler/linker flag profiles to separate “compile-time” flags (safe for all intermediate dependency builds) from “final-link-only” flags (safe only when producing the consuming project’s final binary), and adds a small CLI to emit the resolved flag set for a target.
Changes:
- Added new
*-bin.txt“binary profiles” to hold final-link-only flags like section GC / dead-strip, undefined-symbol rejection, debug-section compression, and fatal linker warnings. - Expanded Linux/Darwin compile profiles with additional hardening, relocation, and tuning flags; moved warning configuration to
base.txtfor cross-platform consistency. - Introduced CLI helpers (
cli/cflags.shandcli/cflags.ts) to concatenate and comment-strip the selected profile chain (compile vs--bin).
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Documents the new compile vs binary profile model and CLI usage. |
| base.txt | Adds cross-platform hardening/warning flags and clarifies toolchain assumptions. |
| linux.txt | Adds Linux/ELF compile/link hardening flags and moves warnings out. |
| linux-bin.txt | Introduces Linux final-link-only flags (gc-sections, defs, debug compression, fatal warnings). |
| linux-amd64.txt | Adds amd64 ISA baseline/tuning and CET hardening. |
| linux-arm64.txt | Adds arm64 ISA baseline and BTI/PAC-related flags. |
| linux-amd64-bin.txt | Placeholder for amd64-specific final-link-only flags. |
| linux-arm64-bin.txt | Placeholder for arm64-specific final-link-only flags. |
| darwin.txt | Introduces macOS compile/link flags, including -fuse-ld=lld and Mach-O hardening. |
| darwin-bin.txt | Introduces macOS final-link-only flags (dead-strip, dead_strip_dylibs). |
| darwin-amd64.txt | Adds Intel macOS ISA baseline/feature selection. |
| darwin-arm64.txt | Adds Apple Silicon targeting and branch protection flags. |
| darwin-amd64-bin.txt | Placeholder for Intel-macOS-specific final-link-only flags. |
| darwin-arm64-bin.txt | Placeholder for Apple-Silicon-specific final-link-only flags. |
| cli/cflags.sh | Bash script to emit the resolved flag list for a target, optionally including --bin. |
| cli/cflags.ts | Bun/TS script to emit the resolved flag list for a target, optionally including --bin. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Eight inline review comments, all valid; six stale-doc and one factual
fix in the file headers / README, plus one real bug in cli/cflags.ts.
Stale-doc fixes (header comments referenced files/profiles that this
repo never had):
- base.txt — drop the openbsd/freebsd/windows OS list and the
amd64.txt/arm64.txt/riscv64.txt arch layer; replace
with the actual file inventory and the documented
compile / binary rollup chains.
- linux.txt — header listed "linux / linux-aarch64 / linux-riscv64"
profiles. Only linux-amd64 and linux-arm64 exist.
- linux-amd64.txt — drop "and amd64.txt" from "appended after …".
- linux-arm64.txt — drop "and arm64.txt".
- darwin-amd64.txt — drop "and amd64.txt".
- darwin-arm64.txt — drop "and arm64.txt".
Factual fix:
- README.md "Toolchain & deployment floor" claimed the Darwin/amd64
x86-64-v3 baseline covered "all Intel Macs (Ivy Bridge+)". Ivy Bridge
is x86-64-v2 (no AVX2/BMI2/FMA), so v3 binaries do not run there.
Restate as "Haswell+ (2013); covers every Intel Mac supported by
macOS 12+" — every macOS 12 Intel host is Broadwell or newer, well
above the v3 floor. darwin-amd64.txt body comment also clarified to
stop implying Ivy Bridge is in scope.
Real bug:
- cli/cflags.ts usage() printed only the first paragraph of the header.
After stripping the `// ` marker, blank-comment separator lines
(`//` followed by nothing) become empty strings, and the previous
`split(/\n\s*\n/)[0]` picked the first paragraph and stopped.
Replaced with a loop that emits every consecutive `//` line after
the shebang. Verified `--help` now prints the full Usage and
Recognized-values block, and that the eight (os × arch × mode)
outputs still match byte-for-byte between cflags.sh and cflags.ts.
Sam Gammon (sgammon)
pushed a commit
that referenced
this pull request
May 6, 2026
CI: - New tests/probe.c — minimal C TU exercising libc calls, function- pointer dispatch, a small loop, and stack-allocated string formatting. Designed to stay warning-clean under the live -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-prototypes -Wshadow -Wundef set so any codegen regression breaks CI early. - New .github/workflows/ci.yml — matrix probe on three GitHub-hosted runners (ubuntu-24.04 / ubuntu-24.04-arm / macos-14). For each target it installs clang-22 + lld-22 (apt.llvm.org on Linux, Homebrew on macOS), asserts cli/cflags.sh and cli/cflags.ts emit byte-identical output for the compile and binary profiles, then compiles tests/probe.c with the compile profile (-c) and compile+links+runs it with the binary profile. - README CI section documents coverage and notes that darwin-amd64 is exercised locally pre-tag because GitHub no longer offers an Intel-Mac runner. Copilot review on PR #2 (3 valid comments addressed; 1 false positive skipped): - darwin.txt + linux.txt + README.md: the parked libc++ flag was written as the shorthand -D_LIBCPP_HARDENING_MODE_FAST in three comment blocks, but the real flag in labs.disabled.txt is -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST. Re-enabling via the shorthand is a silent no-op (libc++ checks the value of the macro, not its mere definition). All three call sites now use the exact spelling, and the README's parked-flag list is reformatted as a bullet list with -U_FORTIFY_SOURCE included for completeness. - linux.txt:45 (false positive): Copilot flagged -fno-plt as a newly-introduced undocumented flag. -fno-plt was added in PR #1 (commit 6d0e14c) and is not in this PR's diff; Copilot compared the PR description's "Added" section against the file content rather than against the actual diff. Skipped.
Sam Gammon (sgammon)
pushed a commit
that referenced
this pull request
May 6, 2026
CI: - New tests/probe.c — minimal C TU exercising libc calls, function- pointer dispatch, a small loop, and stack-allocated string formatting. Designed to stay warning-clean under the live -Wall -Wextra -Wpedantic -Wformat=2 -Wstrict-prototypes -Wshadow -Wundef set so any codegen regression breaks CI early. - New .github/workflows/ci.yml — matrix probe on three GitHub-hosted runners (ubuntu-24.04 / ubuntu-24.04-arm / macos-14). For each target it installs clang-22 + lld-22 (apt.llvm.org on Linux, Homebrew on macOS), asserts cli/cflags.sh and cli/cflags.ts emit byte-identical output for the compile and binary profiles, then compiles tests/probe.c with the compile profile (-c) and compile+links+runs it with the binary profile. - README CI section documents coverage and notes that darwin-amd64 is exercised locally pre-tag because GitHub no longer offers an Intel-Mac runner. Copilot review on PR #2 (3 valid comments addressed; 1 false positive skipped): - darwin.txt + linux.txt + README.md: the parked libc++ flag was written as the shorthand -D_LIBCPP_HARDENING_MODE_FAST in three comment blocks, but the real flag in labs.disabled.txt is -D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST. Re-enabling via the shorthand is a silent no-op (libc++ checks the value of the macro, not its mere definition). All three call sites now use the exact spelling, and the README's parked-flag list is reformatted as a bullet list with -U_FORTIFY_SOURCE included for completeness. - linux.txt:45 (false positive): Copilot flagged -fno-plt as a newly-introduced undocumented flag. -fno-plt was added in PR #1 (commit 6d0e14c) and is not in this PR's diff; Copilot compared the PR description's "Added" section against the file content rather than against the actual diff. Skipped.
Sam Gammon (sgammon)
added a commit
that referenced
this pull request
May 6, 2026
* chore: phase out hardening flags hurting startup; add three perf wins
We're prioritising startup time over defence-in-depth for now. Six
hardening flags move to a new tracked, non-consumed parking-lot file
labs.disabled.txt; three pure perf/size wins land in the live profiles.
Parked in labs.disabled.txt (each with its own re-enable criteria):
base.txt:
-fstack-protector-strong (canary prologue/epilogue)
-fzero-call-used-regs=used-gpr (per-return reg-clearing)
linux.txt:
-U_FORTIFY_SOURCE
-D_FORTIFY_SOURCE=2 (per-call libc bounds checks)
-D_LIBCPP_HARDENING_MODE_FAST (per-call libc++ bounds checks)
darwin.txt:
-U_FORTIFY_SOURCE
-D_FORTIFY_SOURCE=2
-D_LIBCPP_HARDENING_MODE_FAST
linux-amd64.txt:
-fcf-protection=full (ENDBR64 on every indirect target)
labs.disabled.txt is not loaded by the rollup or by cli/cflags.{sh,ts}
— the resolver only matches a closed set of {base, $os, $os-$arch,
$os-bin, $os-$arch-bin}.txt. Verified with a smoke test.
Kept on:
-fasynchronous-unwind-tables (better profiling > table size)
-fbasic-block-sections=all (linux-amd64) (Propeller is on the roadmap;
keeping the per-BB sections
avoids a rebuild-the-world
once we wire in the symbol-
ordering file)
Added (small, free startup wins):
base.txt:
-fmerge-all-constants (dedupe equal string/numeric
constant pool entries → smaller
binary, fewer relocs at load;
mild ISO violation we don't
depend on)
linux.txt:
-Wl,--hash-style=gnu (drop legacy sysv-hash; ~2x
faster dyn-symbol lookup at
load + smaller .dynsym)
-Wl,-O3 (replaces -Wl,-O2) (more aggressive linker-side
string/section merging; pure
link-time cost)
README features matrix updated; new "Phasing in" subsection lists the
parked flags and points at labs.disabled.txt. cli/cflags.{sh,ts}
output verified byte-identical across all eight (os × arch × mode)
combinations after the change.
* ci: add probe + cross-platform clang-22 workflow; address Copilot review
CI:
- New tests/probe.c — minimal C TU exercising libc calls, function-
pointer dispatch, a small loop, and stack-allocated string formatting.
Designed to stay warning-clean under the live -Wall -Wextra -Wpedantic
-Wformat=2 -Wstrict-prototypes -Wshadow -Wundef set so any codegen
regression breaks CI early.
- New .github/workflows/ci.yml — matrix probe on three GitHub-hosted
runners (ubuntu-24.04 / ubuntu-24.04-arm / macos-14). For each
target it installs clang-22 + lld-22 (apt.llvm.org on Linux,
Homebrew on macOS), asserts cli/cflags.sh and cli/cflags.ts emit
byte-identical output for the compile and binary profiles, then
compiles tests/probe.c with the compile profile (-c) and
compile+links+runs it with the binary profile.
- README CI section documents coverage and notes that darwin-amd64
is exercised locally pre-tag because GitHub no longer offers an
Intel-Mac runner.
Copilot review on PR #2 (3 valid comments addressed; 1 false positive
skipped):
- darwin.txt + linux.txt + README.md: the parked libc++ flag was
written as the shorthand -D_LIBCPP_HARDENING_MODE_FAST in three
comment blocks, but the real flag in labs.disabled.txt is
-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST. Re-enabling
via the shorthand is a silent no-op (libc++ checks the value of
the macro, not its mere definition). All three call sites now use
the exact spelling, and the README's parked-flag list is reformatted
as a bullet list with -U_FORTIFY_SOURCE included for completeness.
- linux.txt:45 (false positive): Copilot flagged -fno-plt as a
newly-introduced undocumented flag. -fno-plt was added in PR #1
(commit 6d0e14c) and is not in this PR's diff; Copilot compared
the PR description's "Added" section against the file content
rather than against the actual diff. Skipped.
* ci: harden toolchain install for arm64 runners
The first run of ci.yml passed on linux-amd64 but failed in ~30s on
linux-arm64 and darwin-arm64, both during the toolchain-install step.
I don't have direct access to the GHA logs from this session, so this
commit makes the install path more robust along the most likely
failure modes:
- Linux: replace the hand-rolled gpg + apt source setup with
apt.llvm.org's llvm.sh, which is the canonical installer and
handles distro/codename detection across noble/noble-arm64.
Drop --update-alternatives in favour of explicit symlinks in
/usr/local/bin (which precedes /usr/bin in PATH on ubuntu-24.04),
so `clang` and `ld.lld` resolve to the v22 binaries even if the
base image already has an unversioned `clang` from a different
source.
- Darwin: keep the Homebrew install but capture brew --prefix llvm
into a CC env var passed via $GITHUB_ENV so subsequent steps
invoke that clang explicitly instead of relying on PATH order.
Also prepend $(brew --prefix llvm)/bin so -fuse-ld=lld finds
ld64.lld.
- New "Toolchain sanity" step prints `which clang`, `clang --version`,
and `ld.lld` / `ld64.lld --version` so any future failure surfaces
the actual install state in the log.
Compile / link steps now invoke "$CC" explicitly rather than relying
on whichever `clang` is first in PATH.
* ci+arm64: drop strict BTI/PAC link flags; harden darwin install assertions
Two unrelated CI failures were chasing different root causes:
linux-arm64
ld.lld errored hard at link time:
ld.lld: error: /lib/aarch64-linux-gnu/Scrt1.o: -z force-bti:
file does not have GNU_PROPERTY_AARCH64_FEATURE_1_BTI property
…and the same for crti.o / crtn.o under -z pac-plt. lld treats
these two -z flags as strict — every input object must carry the
matching GNU property note or the link aborts. Stock Ubuntu noble
glibc CRT objects ship without those notes, so the link can never
succeed on a vanilla distro toolchain.
Drop -Wl,-z,force-bti and -Wl,-z,pac-plt from linux-arm64.txt.
Keep -mbranch-protection=standard so our own .o files still emit
the PAC/BTI sequences and per-object property notes — when the
rest of the link surface (CRT, libc) catches up, we can re-enable
the linker-side enforcement. Comment in linux-arm64.txt records
the rationale and the verbatim error message so the next person
who sees it knows what changed and what would need to be true to
flip it back on.
darwin-arm64
clang: error: invalid linker name in argument '-fuse-ld=lld'
This message is Apple-clang's signature for "I don't know what
'lld' is" — meaning Apple's /usr/bin/clang got picked up instead
of the brew-installed mainline clang. Two defensive changes to
ci.yml so the next failure surfaces the actual install state:
- Install step now hard-asserts that $(brew --prefix llvm)/bin/clang
AND $(brew --prefix llvm)/bin/ld64.lld both exist. If brew shipped
llvm without ld64.lld (rare but possible on some images), the step
fails immediately with the missing path printed instead of letting
the failure cascade into a confusing clang error two steps later.
- Toolchain sanity step now invokes "$CC" instead of bare `clang`,
explicitly rejects an Apple-clang $CC, and uses
`--print-prog-name=ld.lld` / `--print-prog-name=ld64.lld` to show
the lld path the driver would actually pick under -fuse-ld=lld.
* ci(darwin): install brew lld separately; symlink ld64.lld next to clang
Homebrew's `llvm` formula on macOS does not ship lld — confirmed by
listing /opt/homebrew/opt/llvm/bin on macos-14 (clang, MLIR tools,
FileCheck, ~150 binaries, zero lld variants). On Mac, `lld` is a
standalone Homebrew formula; the asymmetry vs Linux (where
apt.llvm.org bundles them in the llvm-toolchain-N package set) is
why my "install lld with the llvm formula" assumption broke darwin
CI even though linux CI worked.
Fix: `brew install llvm lld zstd` (add lld to the install list),
then symlink $(brew --prefix lld)/bin/ld64.lld into
$(brew --prefix llvm)/bin/ld64.lld so clang's `-fuse-ld=lld` driver
finds it in its own bin dir (clang searches there before falling
through to PATH). Hard-assert both binaries exist before continuing
so the failure mode is "MISSING: <path>" not the cryptic
"invalid linker name in argument '-fuse-ld=lld'" that surfaces two
steps later when Apple's clang inadvertently gets picked up.
* ci(darwin): tighten Apple-clang detector; was false-positive on triple
The toolchain-sanity guard that's supposed to reject Apple's clang
fired a false positive on macos-14: \$CC was correctly set to
/opt/homebrew/opt/llvm/bin/clang (Homebrew clang 22.1.4), but the
naive `grep -qiE 'apple|xcode'` matched on the target triple line:
Target: arm64-apple-darwin23.6.0
…which every clang on macOS prints, Homebrew or otherwise. Restrict
the match to the *version banner* (first line) and require the exact
"Apple clang" string Apple's binary uses there. Homebrew's banner is
"Homebrew clang version 22.1.4"; Xcode/Apple's is "Apple clang
version 15.x.y …". The discriminator is the leading word, not the
case-insensitive presence of "apple" anywhere in the multi-line
output.
Net: lld install succeeded, brew clang is the one running, and CI
should now get past the sanity step.
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
This PR restructures the clang/lld compiler flag organization to distinguish between compile-time flags (applied to all translation units and intermediate dependency builds) and final-link-only flags (applied only at the consuming project's final executable/library link step). This separation prevents overly aggressive optimizations (like
--gc-sections) from breaking intermediate builds while still enabling full optimization at the final link.Key Changes
Introduced binary profiles (
*-bin.txtfiles): New profile layer for final-link-only flags that would break intermediate dependency builds (autoconf conftests, BoringSSL test binaries, etc.)linux-bin.txt: ELF-wide final-link flags (--gc-sections,-z defs,--compress-debug-sections=zstd,--fatal-warnings)darwin-bin.txt: Mach-O-wide final-link flags (-dead_strip,-dead_strip_dylibs)linux-amd64-bin.txt,linux-arm64-bin.txt,darwin-amd64-bin.txt,darwin-arm64-bin.txtExpanded Linux compile flags (
linux.txt):-fno-semantic-interpositionfor intra-DSO call optimization-fno-pltwith-Wl,-z,nowfor PLT-less call lowering_FORTIFY_SOURCE=2hardening (musl-compatible level 2)_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FASTfor libc++ bounds checking-Wl,-z,pack-relative-relocs,-Wl,--as-needed,-Wl,--icf=safe,-Wl,--build-id=sha1,-Wl,-O2New Darwin compile flags (
darwin.txt):-fuse-ld=lldto use mainline LLVM linker instead of ld64_FORTIFY_SOURCE=2and_LIBCPP_HARDENING_MODE_FAST-bind_at_load,-fixup_chains,-no_data_in_code_infoEnhanced base.txt:
-fzero-call-used-regs=used-gprfor ROP/JOP gadget surface reduction-fasynchronous-unwind-tablesfor profiler/crash-collector support-fstack-clash-protectionout (now Linux-only in linux.txt)Expanded architecture-specific flags:
linux-amd64.txt: Added x86-64-v3 ISA baseline with crypto extensions (AES, PCLMUL, SHA, VAES, GFNI, RDRAND),-mtune=znver3, and-fcf-protection=full(Intel CET)linux-arm64.txt: Added ARMv8.2-A baseline with crypto/CRC/dotprod,-mbranch-protection=standard(PAC+BTI),-Wl,-z,force-bti,-Wl,-z,pac-pltdarwin-amd64.txt: Added x86-64-v3 baseline with conservative crypto extensions (no SHA/VAES/GFNI)darwin-arm64.txt: Added-mcpu=apple-m1targeting and-mbranch-protection=standardAdded CLI tools:
cli/cflags.sh: Bash script to concatenate and output flags for a given (oshttps://claude.ai/code/session_01CGzQMHWJw5FZ8weeEtqKWJ