Skip to content

Preserve linker arguments across response files - #3350

Open
karim-alweheshy wants to merge 3 commits into
preview-stack-01-linker-flagsfrom
preview-stack-link-arguments
Open

karim-alweheshy wants to merge 3 commits into
preview-stack-01-linker-flagsfrom
preview-stack-link-arguments

Conversation

@karim-alweheshy

@karim-alweheshy karim-alweheshy commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fix existing Bazel-to-Xcode linker argument translation without introducing a
new Preview mode or changing library-path resolution.

  • Drop the tool name once across all argument chunks, not once per chunk.
  • Expand first-level response files while preserving dyld paths such as
    @rpath, @loader_path, and @executable_path.
  • Decode Bazel shell-quoted arguments and escape Clang response-file arguments
    without losing apostrophes, quotes, backslashes or whitespace.
  • Report malformed inputs instead of silently producing incomplete arguments.

Based on branch preview-stack-01-linker-flags. This correction is usable
without any later Preview changes. Library-group removal and Preview-specific
path/runtime handling are intentionally excluded.

Validation

  • Seven focused Python tests pass. The same tests fail against the parent
    implementation, reproducing dropped arguments, redirect handling and quoting
    errors. The existing bundle-flag regression remains covered.
  • All 99 root Bazel test targets pass on Bazel 9.2.0 and Xcode 27.0; unchanged
    targets reuse cached results.
  • Repository Buildifier and git diff --check pass.
  • A standalone Apple Clang control links and runs an executable using split
    argument files and an archive path containing spaces and an apostrophe.
    The parent fails this combined parsing/quoting case; this candidate passes.

Testing

Run bazel test //tools/params_processors:link_params_processor_tests and
bazel test //.... These checks validate argument translation and ordinary
generator regressions; they do not claim Preview Canvas rendering.

Signed-off-by: Karim Alweheshy <karim.alweheshy@reddit.com>
@karim-alweheshy
karim-alweheshy marked this pull request as ready for review September 23, 2026 15:57
@karim-alweheshy
karim-alweheshy requested a review from a team as a code owner September 23, 2026 15:57
@0xLucasMarcal

Copy link
Copy Markdown
Contributor

cc @brentleyjones

Comment on lines +126 to +148
if option in _WL_POSITIONAL_PATH_OPTS and option != "-filelist":
# Section arguments are metadata/content, not positional libraries.
for _ in range(max(_WL_POSITIONAL_PATH_OPTS[option])):
if driver_wrappers and end < len(linkopts) and linkopts[end] == "-Xlinker":
end += 1
end = min(end + 1, len(linkopts))
elif option in _SPLIT_PATH_OPTS | _SPLIT_NON_PATH_OPTS:
value_index = end
if driver_wrappers and value_index < len(linkopts) and linkopts[value_index] == "-Xlinker":
value_index += 1
if value_index < len(linkopts):
end = value_index + 1
if (option in _LIBRARY_INPUT_OPTS and
linkopts[value_index] in generated_product_paths):
index = end
continue
elif option in generated_product_paths:
index = end
continue

result.extend(linkopts[index:end])
index = end
return result

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This just reads bad. I get what it's doing, generally, but I feel it could be organized better or have way more comments.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comments in 60339e7 around the option categories and removal state machine: which operands stay grouped, when -Xlinker wrappers travel with a removed binding, and why unmatched operands remain ordered. This is comments-only; the AST and representative outputs are unchanged, and all 13 Python tests pass. Does that address the organization concern, or is there a section you would prefer split up?

Comment on lines +201 to +205
# This is a Clang response file, not a shell command. Quote the whole
# argument and escape response syntax. Double quotes also allow apostrophes
# introduced later by expansion of PROJECT_DIR or another build setting.
if any(character in opt for character in " \t\n\r'\"\\") or "$(" in opt:
return '"' + opt.replace("\\", "\\\\").replace('"', '\\"') + '"'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is interesting.

Comment thread tools/params_processors/link_params_processor.py Outdated
Signed-off-by: Karim Alweheshy <karim.alweheshy@reddit.com>
@karim-alweheshy
karim-alweheshy requested review from a team and brentleyjones October 1, 2026 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants