Repository navigation
Compare link-interface flags from CMake's libraries fragments - #44
Open
anakanemison wants to merge 1 commit into
Open
anakanemison wants to merge 1 commit into
anakanemison wants to merge 1 commit into
Conversation
anakanemison
force-pushed
the
mschaller/u09-link-interface-flags
branch
from
October 26, 2026 13:30
4bba057 to
695e7c1
Compare
anakanemison
force-pushed
the
mschaller/u09-link-interface-flags
branch
from
November 2, 2026 17:50
695e7c1 to
da2e00c
Compare
The CMake File API reports a target's link line in fragments by role. Flags that a dependency carries on its link interface (Python's -Xlinker -export-dynamic, OpenMP's -fopenmp, Threads' -pthread) arrive in the "libraries" fragments, not "flags". extract_cmake.py read "libraries" only for dependency names, so these flags reached neither the dep closure nor the link-flag comparison, and a Bazel binary missing one converged. Observed in any2bazel-lab: on a Blender migration, the lab verified that -Xlinker -export-dynamic sits only in the blender target's libraries fragment. By the migrating agent's own report, the diff converged without it and Python extension modules then failed to resolve CPython symbols at run time, caught only by its functional test; the lab did not reproduce the failure, because that tree was not kept. A "libraries" fragment that is not a library and starts with "-" is now added to the target's link argv, so it is compared like any link flag. "-Xlinker X" pairs are folded into "-Wl,X" first, so the fragment is classified by what it passes to the linker. Excluded, because they position or locate the libraries around them or name the CMake build tree: -L, -framework, rpaths in every spelling (-Wl,-rpath, -Wl,--rpath, -Wl,-R, and -Xlinker -rpath -Xlinker <dir>), the whole-archive, push/pop-state, group, -Bstatic/-Bdynamic and as-needed toggles, and -force_load. canonicalize_link_flags also folds "-Xlinker X" into "-Wl,X" on both sides, before its noise filters, so the pair compares as one flag, and then joins an rpath given as two linker arguments (`-Wl,-rpath` then `-Wl,DIR`) into `-Wl,-rpath,DIR`, which is what the linker receives. So these three spellings of one rpath compare equal: `-Xlinker -rpath -Xlinker DIR` (what CMake's LINKER:-rpath,DIR becomes under Clang), `-Wl,-rpath -Wl,DIR` and `-Wl,-rpath,DIR`. `-Wl,-rpath=DIR`, `-Wl,--rpath,DIR` and `-Wl,-R,DIR` are not unified with them, as before. Bazel spells its own rpaths the first way, as $ORIGIN/, $EXEC_ORIGIN/ or @loader_path/ paths into its _solib_<cpu> directories; on the Bazel side exactly those (an anchored match) are toolchain link noise, otherwise they would appear as Bazel-only link flags on every binary. A project's own rpath (-Wl,-rpath,$ORIGIN/../lib, -Wl,-rpath=/opt/lib, -Wl,-rpath-link,...) is kept and compared. One limitation: any non-library "libraries" fragment becomes a link flag the Bazel side must have, including one that carries a CMake build-tree path Bazel cannot reproduce (-Wl,--version-script,<build dir>/sym.map; this holds when the map file's basename does not start with "lib", since a fragment ending in lib<name>.<ext> is still read as the external dependency <name>, as before). A version script decides which symbols are exported, so such a flag is not benign: its exact CMake spelling may go in ignore.link_flags only after confirming the Bazel link passes an equivalent script with the same content, and SKILL.md's link_flags_diff row now says so. A multi-token fragment is classified as a whole, as before, so `-Wl,-Bstatic -lfoo -Wl,-Bdynamic` in one fragment still loses its -lfoo; splitting fragments per token is left out because rpath pairs would then need their own pairing logic. A behavior change: a migration that converged before may now show a link_flags_diff for such a flag, most often -pthread (Threads::Threads with THREADS_PREFER_PTHREAD_FLAG) or -fopenmp. That is a real difference in the link command; add the flag to linkopts or record it in ignore.link_flags. SKILL.md says these flags are compared. No migration run exercised this change; it was checked on the stored Blender models. Lab-Proposal: P25 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
anakanemison
force-pushed
the
mschaller/u09-link-interface-flags
branch
from
November 9, 2026 18:45
da2e00c to
f214978
Compare
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.
Flags a dependency carries on its link interface (
-Xlinker -export-dynamic,-fopenmp,-pthread) arrive in the CMake File API'slibrariesfragments, which extract_cmake.py read only for dependency names, so a Bazel binary missing one converged. Such a fragment is now added to the target's link argv and compared, except those that position or locate libraries (-L, rpaths, whole-archive and similar toggles).-Xlinker Xis folded into-Wl,Xon both sides, so the common spellings of one rpath compare equal.On a Blender migration in any2bazel-lab,
-Xlinker -export-dynamicsat only in that fragment; the diff converged without it, and by the agent's report Python modules then failed to load. Checked on the stored Blender models; no migration run exercised it. A migration that converged before may now show alink_flags_diff, most often for-pthreador-fopenmp, which is a real difference in the link command.Stacked on #43 (tracking issue: #35).
pytest tests/: 185 passed (132 onmain). Lab proposal: P25.🤖 Generated with Claude Code