Fix six Linux/gcc portability gaps surfaced building flare - #64
Merged
Conversation
Verified by building the whole flare RPC framework end to end on aarch64
Linux/gcc (Ubuntu container): every target compiles + links, the tests
run, and cc-check-undefined reports zero findings -- matching the macOS
baseline. clang had masked all six; they only bit on Linux/gcc.
Build/link (internal/cc, internal/build):
* precreate build-dir include directories. A globally-configured
-Ibuild_dir/<pkg> (flare's cc_config.extra_incs lists
build_dir/thirdparty) is a fatal -Wmissing-include-dirs under -Werror
when the dir doesn't exist yet; ninja's lazy per-edge mkdir races the
first compile. Blade sidesteps this by makedirs'ing build_dir/<pkg>
per target -- we now do the same (+ any build-dir-rooted global -I).
clang silently ignores a missing -I dir, so this only failed on gcc.
* put vcpkg archives inside the target's --start-group on ELF. GNU ld
re-scans only within a group, so curl -> ssl -> crypto forward refs
across the group boundary went unresolved; ld64 re-scans regardless.
* apply per-target extra_cppflags/extra_cxxflags/extra_cflags/
extra_asflags (#492) -- flare's crypto md5/sha pass
-Wno-deprecated-declarations for OpenSSL 3.x's HMAC deprecation.
* normalize incs/export_incs like Blade's _incs_to_fullpath: a leading
// is root-relative (strip it), else package-relative. flare's
foreign_cc_library sets export_incs='//'+build_dir/.../include, which
reached gcc as the nonexistent -I//build_dir/... .
* select a foreign_cc_library's archive by lib<name>.a, not an
arbitrary .a. One autotools gen_rule (gperftools_build) emits many
archives shared by sibling targets (tcmalloc, profiler, ...); the old
"any .a" left consumers of :profiler without libprofiler.a
(ProfilerStart/Stop/Flush undefined across 45 targets).
cc-check-undefined system baseline on Linux (internal/ccundef):
* strip ELF symbol-version suffixes (sym@@GLIBCXX_3.4 -> sym) so the
versioned libstdc++/libc/libgcc exports match a consumer's bare
undefined ref -- otherwise every C++ target flagged std symbols.
* treat nm IFUNC types i/I as defined (glibc memcpy/memmove/... are
indirect functions).
* follow the glibc `libc.so` linker script to its members (libc.so.6 +
libc_nonshared.a + AS_NEEDED loader) and scan every resolvable lib
spelling, so the real versioned ELF (libgcc_s.so.1 -> _Unwind_Resume)
and the static helpers are both covered; also scan libgcc.a (aarch64
outline atomics __aarch64_ldadd*/cas*/swp*).
* baseline __stack_chk_* (loader-provided; U in every scannable lib).
Unit tests cover ELF link grouping, // include normalization, foreign
archive selection, and the stack-protector baseline.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Building the whole flare RPC framework end to end on aarch64 Linux/gcc (in an Ubuntu container) surfaced six portability gaps that clang had masked. After these fixes every
//flare/...target compiles + links, the tests run, andcc-check-undefinedreports zero findings — matching the macOS/Python baseline.Build / link (
internal/cc,internal/build)-I-dir race — a globally-configured-Ibuild_dir/<pkg>(flare listsbuild_dir/thirdpartyincc_config.extra_incs) is fatal under-Wmissing-include-dirs -Werrorwhen the dir doesn't exist yet; ninja's lazy per-edgemkdirraces the first compile. Now precreatebuild_dir/<pkg>per target (as Blade'smakedirsdoes) + any build-dir-rooted global-I. clang silently ignores a missing-Idir, so this only broke on gcc.--start-groupsocurl → ssl → crypto/protobuf → abslforward refs resolve (GNU ld re-scans only within a group; ld64 re-scans regardless).extra_cppflags/extra_cxxflags/extra_cflags/extra_asflags(#492) — flare's cryptomd5/shapass-Wno-deprecated-declarationsfor OpenSSL 3.x's HMAC deprecation.//-rooted include normalization — mirror Blade's_incs_to_fullpath(leading//= root-relative; else package-relative). flare'sforeign_cc_librarysetsexport_incs='//'+build_dir/.../include, which reached gcc as a nonexistent-I//build_dir/....foreign_cc_libraryselection — picklib<name>.a, not an arbitrary.a. One gen_rule (gperftools_build) emits many archives shared by sibling targets; the old code left consumers of:profilerwithoutlibprofiler.a(ProfilerStart/Stop/Flushundefined across 45 targets).cc-check-undefinedLinux baseline (internal/ccundef)sym@@GLIBCXX_3.4 → sym); treat nm IFUNCi/Ias defined (glibcmemcpy/memmove); follow the glibclibc.solinker script + scan every resolvable spelling (reallibgcc_s.so.1→_Unwind_Resume,libc_nonshared.a) and scanlibgcc.a(aarch64 outline atomics); baseline__stack_chk_*(loader-provided,Ueverywhere). Without these, every C++ target on Linux flagged std-library symbols.Tests
Unit tests cover ELF link grouping,
//include normalization, foreign archive selection, and the stack-protector baseline; the flare whole-repo build/link/test + clean undefined-check is the integration proof.