Tree of simple text files which compound into final clang and LLD flags when building Elide. On Unix-like platforms, Elide and related repos may consult this one to build with a uniform suite of flags across compilation units.
Flag files allow comments which start with #. Comments are thus inline explaining the purpose of most flags.
There are two classes of profile:
- Compile profiles (
base,linux,darwin,linux-amd64, …) apply to every translation unit and link stage in the dependency-build pipeline (Netty C, BoringSSL, autoconf conftests, …). Anything here must be safe at intermediate link stages. - Binary profiles (
*-bin) apply only at the consuming project's final executable / shared-library / dylib link. They hold flags — section stripping, undefined-symbol rejection, debug compression, fatal warnings — that would break a dependency's intermediate conftest or test-binary link if applied earlier. The chain mirrors the compile side: an OS-levellinux-bin/darwin-bincarries the OS-wide final-link flags, and a leaf*-arch-binlayers any arch-specific final-link flags on top. The full rollup forlinux-amd64-binisbase → linux → linux-amd64 → linux-bin → linux-amd64-bin.
These flags assume the following floor; downstream consumers should match or override per-profile.
| Layer | Floor |
|---|---|
| Compiler | mainline LLVM clang 22.x (Polly-enabled), on every platform |
| Linker | lld (ld.lld on Linux, ld64.lld on Darwin) |
| Linux libc | musl 1.2.x primary; glibc 2.36+ for any glibc consumers |
| Linux libc++ | Vendored libc++ (Linux/amd64); _LIBCPP_HARDENING_MODE honored |
| macOS | macOS 12+ (dyld 4 / chained-fixups format) |
| Linux/amd64 ISA | x86-64-v3 + aes/pclmul/sha/vaes/gfni/rdrand → Ice Lake / Zen 3+ |
| Darwin/amd64 ISA | x86-64-v3 + aes/pclmul/rdrand → Haswell+ (2013); covers every Intel Mac supported by macOS 12+ |
| Linux/arm64 ISA | armv8.2-a + crypto/crc/dotprod → Graviton 2+, Neoverse N1+, Altra |
| Darwin/arm64 ISA | apple-m1 (ARMv8.5-A) — every shipping Apple Silicon Mac |
Compiler features activated or facilitated by these flags:
| Feature | Platforms | Description |
|---|---|---|
| Thin LTO | All | Emits and optimizes as LLVM bitcode, program-wide |
| Function/Data Sections | All | -f{data,function}-sections (collected at final link, see below) |
| Constant merging | All | -fmerge-all-constants for smaller binary + fewer relocs at load |
| Stack Hardening | Linux | -fstack-clash-protection (canaries are parked, see "Phasing in") |
| Async Unwind Tables | All | -fasynchronous-unwind-tables for profilers + crash collectors |
| LLD as linker | All | -fuse-ld=lld required for Thin LTO |
Full RELRO + -fno-plt |
Linux | -z relro -z now plus PLT-less call lowering |
| No semantic interposition | Linux | -fno-semantic-interposition for intra-DSO inlining |
| DT_RELR relative relocations | Linux | -z pack-relative-relocs shrinks PIE relocation tables |
| LLD ICF (safe) | Linux | --icf=safe folds identical address-not-taken functions |
| GNU-hash dyn-symbol table | Linux | --hash-style=gnu (smaller, ~2× faster lookup at load) |
| LLD link optimization | Linux | -Wl,-O3 aggressive string/section merging at link time |
| Relative C++ ABI vtables | Linux | Enables relative vtable references program-wide |
| Propeller-ready BB sections | Linux amd64 | -fbasic-block-sections=all (awaiting symbol-ordering file) |
| Microarch tuning | Linux amd64 | -mtune=znver3 (mirrors Rust -Ztune-cpu=znver3) |
| PAC + BTI | arm64 (both) | -mbranch-protection=standard; -z force-bti on Linux |
| Mach-O fixup chains | Darwin | -bind_at_load, -fixup_chains, -no_data_in_code_info |
Some hardening flags are temporarily disabled in the live profiles to
prioritise startup time. They are tracked verbatim in
labs.disabled.txt with a re-enable plan per flag. Currently
parked, with the exact spelling needed when cut-and-pasting back into
the live profile:
-fstack-protector-strong-fzero-call-used-regs=used-gpr-fcf-protection=full-U_FORTIFY_SOURCE-D_FORTIFY_SOURCE=2-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_FAST
The file is not consumed by the rollup or by cli/cflags.{sh,ts}
— it is a parking lot, not a profile.
Important
Section-stripping and similar "no further link" flags live in *-bin,
not in the per-OS or per-arch compile profiles. The compile profiles
are applied to dependency builds (Netty, BoringSSL TCNative, autoconf
conftests, …) where intermediate links still reference symbols that
-Wl,--gc-sections / -Wl,-dead_strip would otherwise drop. The
compiler still emits per-function/data sections via
-ffunction-sections / -fdata-sections, so the consuming project
picks up the full DCE win by selecting the corresponding *-bin
profile (e.g. linux-amd64-bin) at its own final link step.
Note
-Wconversion is intentionally not enabled — it's too noisy across Netty's
JNI glue and BoringSSL's x86 intrinsics to be useful as a blanket warning.
Re-enable selectively per-target if needed.
Applied to every translation unit and every link in the dependency-build pipeline. Roll-up: e.g. linux-amd64 = base.txt + linux.txt + linux-amd64.txt.
| Profile | OS | Arch | Description |
|---|---|---|---|
| base | (All) | (All) | Baseline flags. |
| linux | Linux | (All) | Linux-only flags. |
| linux-amd64 | Linux | amd64 | Linux x86-64 flags. |
| linux-arm64 | Linux | aarch64 | Linux ARM64 flags. |
| darwin | macOS | (All) | macOS-only flags. |
| darwin-amd64 | Darwin | amd64 | macOS Intel flags. |
| darwin-arm64 | Darwin | aarch64 | macOS M-series flags. |
Applied only at the consuming project's final executable / shared-library / dylib link step. Holds flags that would break intermediate dependency-build links (autoconf conftests, BoringSSL test binaries, …). Roll-up: a *-bin profile inherits its compile-profile chain first, then adds the OS-wide *-bin layer, then the per-arch *-arch-bin layer. The full rollup for linux-amd64-bin is base → linux → linux-amd64 → linux-bin → linux-amd64-bin.
| Profile | OS | Arch | Adds |
|---|---|---|---|
| linux-bin | Linux | (All) | --gc-sections, -z defs, --compress-debug-sections=zstd, --fatal-warnings |
| linux-amd64-bin | Linux | amd64 | (placeholder for x86_64-only leaf-link flags) |
| linux-arm64-bin | Linux | aarch64 | (placeholder for aarch64-only leaf-link flags) |
| darwin-bin | Darwin | (All) | -dead_strip, -dead_strip_dylibs |
| darwin-amd64-bin | Darwin | amd64 | (placeholder for Intel-Mac-only leaf-link flags) |
| darwin-arm64-bin | Darwin | aarch64 | (placeholder for Apple-Silicon-only leaf-link flags) |
Note
Windows is not covered here because we do not (yet) compile with clang on Windows.
Two equivalent scripts in cli/ emit the resolved, comment-stripped flag list as a single whitespace-separated line, suitable for use directly with shell command substitution.
| Script | Runtime |
|---|---|
cli/cflags.sh |
Bash |
cli/cflags.ts |
Bun |
Both share the same surface:
cflags[.sh|.ts] [<os> <arch>] [--bin]
<os>∈linux | darwin— defaults to the host<arch>∈amd64 | arm64— defaults to the host--bin— switch from the compile rollup (base → os → os-arch) to the binary rollup (base → os → os-arch → os-bin → os-arch-bin)
Examples:
# host compile flags
export CFLAGS="$(./cli/cflags.sh)"
# host final-link flags
export LDFLAGS="$(./cli/cflags.sh --bin)"
# explicit cross-target
export CFLAGS="$(bun run ./cli/cflags.ts linux arm64)"
export LDFLAGS="$(bun run ./cli/cflags.ts linux arm64 --bin)".github/workflows/ci.yml runs on every push and PR; it resolves the flag set with both cli/cflags.sh and cli/cflags.ts, asserts they emit byte-identical output, and then compiles + links the tests/probe.c translation unit against the full compile and binary profiles for every supported target. The matrix covers:
| Target | GitHub runner |
|---|---|
linux-amd64 |
ubuntu-24.04 |
linux-arm64 |
ubuntu-24.04-arm |
darwin-arm64 |
macos-14 |
(darwin-amd64 is not covered: GitHub no longer offers an Intel-Mac runner. The profile is exercised locally before tagged releases.)
So far, the following projects consume these flags:
- Netty (
epoll,kqueue,io_uring, etc.) - Netty TCNative (BoringSSL-based TLS)