Add cc_check_undefined (static undefined-symbol check) - #63
Merged
Conversation
Ports Blade's cc_check_undefined (#1225): for each cc_library, every
undefined external symbol must be resolvable from the library's own
archive, a declared dep's archive, the system libraries a final link
pulls in, or a residual/allow-list regex -- anything left is a missing
dependency. No real link: one `nm -P -g` per archive, set arithmetic,
regex full-match.
New internal/ccundef package:
* nm -P -g external extraction (U undefined; w/v weak-undef ambient; u +
uppercase defined) -- ELF .so gets -D.
* system-symbol baseline: macOS reads the SDK's .tbd stubs
(libc++/libSystem, via xcrun --show-sdk-path -- the dylibs live in the
dyld shared cache, only the text stubs are on disk); Linux resolves
each of libstdc++/c/m/pthread/dl/rt/gcc_s via `cc -print-file-name`
then nm's it. Conservative: an over-broad system set only reduces
findings.
* the residual baseline regexes verbatim from Blade (C++ ABI
typeinfo/vtable/guard, operator new/delete, PIC/TLS bootstrap,
coverage + sanitizer runtimes).
Wiring: build.CheckUndefined runs it as a post-build pass in build/test
(archives must exist); severity from cc_library_config.check_undefined +
check_undefined_severity (default on/warning), plus per-target and global
allow_undefined; --cc-check-undefined / --no-cc-check-undefined force
on/off. gen.LinkArchives exposes a node's own + dep + vcpkg (incl.
protobuf) archives.
Verified on flare (macOS/clang): the whole repo is CLEAN (0 findings),
matching Python Blade. A missing-dep intermediate (packing's protobuf
symbols) surfaced and was fixed by including the protobuf archive in the
link closure -- proving the check isn't vacuous. Unit tests cover the
resolution/baseline/allow logic and severity mapping.
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.
Ports Blade's
cc_check_undefined(#1225). For eachcc_library, every undefined external symbol must resolve to one of: the library's own archive, a declared dep's archive, a system library a final link would pull in, or a residual/allow-list regex. Anything left is a missing dependency — reported without a real link.How
internal/ccundef(new):nm -P -gexternal extraction, a system-symbol baseline (macOS reads the SDK.tbdtext stubs viaxcrun --show-sdk-path; Linux resolves libstdc++/c/m/pthread/dl/rt/gcc_s viacc -print-file-namethennm), and the residual baseline regexes verbatim from Blade (C++ ABI, operator new/delete, PIC/TLS bootstrap, coverage + sanitizer runtimes).build.CheckUndefinedruns as a post-build pass inbuild/test(archives must exist). Severity fromcc_library_config.check_undefined+check_undefined_severity(default on/warning), plus per-target and globalallow_undefined.--cc-check-undefined/--no-cc-check-undefinedforce on/off.gen.LinkArchivesexposes a node's own + dep + vcpkg (incl. protobuf) archives.Verification
On flare (macOS/clang) the whole repo is clean (0 findings), matching Python Blade. An intermediate missing-dep (
packing's protobuf symbols) surfaced and was fixed by including the protobuf archive in the link closure — proving the check isn't vacuous. Unit tests cover resolution/baseline/allow and severity mapping.