Fix aggressive params file assumption
Most programs that accept params files use the `@file` syntax. For Apple
platform builds `@` can be the start of non-params file arguments as
well, such as `-rpath @executable_path/Frameworks`. There is a small
list of options where this is the case, so this new behavior no longer
assumes params files if args start with `@`, they also have to not start
with one of the 3 keywords used with this (from `man dyld` on macOS).
This should always hold since params files generated by bazel should
always start with `bazel-out`, if someone renames the symlinks to one of
the keywords, they're on their own.
Previously the workaround was to always make sure to pass the
`-Wl,-rpath,@executable_path` form of these arguments, but this makes
users not have to worry about this.
In a few other places we check this by checking if the file exists,
which is likely more accurate, but feels excessive and potentially
dangerous in this context.
Related: https://github.com/bazelbuild/bazel/pull/13148
Fixes: https://github.com/bazelbuild/bazel/issues/14316
Closes #14650.
PiperOrigin-RevId: 430195929
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
index 0403d2d..8ff77d4 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/LinkCommandLine.java
@@ -270,13 +270,13 @@
paramFile, linkTargetType, forcedToolPath, featureConfiguration, actionName, variables);
}
- public static void extractArgumentsForStaticLinkParamFile(
+ private static void extractArgumentsForStaticLinkParamFile(
List<String> args, List<String> commandlineArgs, List<String> paramFileArgs) {
commandlineArgs.add(args.get(0)); // ar command, must not be moved!
int argsSize = args.size();
for (int i = 1; i < argsSize; i++) {
String arg = args.get(i);
- if (arg.startsWith("@")) {
+ if (isLikelyParamFile(arg)) {
commandlineArgs.add(arg); // params file, keep it in the command line
} else {
paramFileArgs.add(arg); // the rest goes to the params file
@@ -284,7 +284,7 @@
}
}
- public static void extractArgumentsForDynamicLinkParamFile(
+ private static void extractArgumentsForDynamicLinkParamFile(
List<String> args, List<String> commandlineArgs, List<String> paramFileArgs) {
// Note, that it is not important that all linker arguments are extracted so that
// they can be moved into a parameter file, but the vast majority should.
@@ -292,7 +292,7 @@
int argsSize = args.size();
for (int i = 1; i < argsSize; i++) {
String arg = args.get(i);
- if (arg.startsWith("@")) {
+ if (isLikelyParamFile(arg)) {
commandlineArgs.add(arg); // params file, keep it in the command line
} else {
paramFileArgs.add(arg); // the rest goes to the params file
@@ -300,6 +300,13 @@
}
}
+ private static boolean isLikelyParamFile(String arg) {
+ return arg.startsWith("@")
+ && !arg.startsWith("@rpath")
+ && !arg.startsWith("@loader_path")
+ && !arg.startsWith("@executable_path");
+ }
+
/**
* Returns a raw link command for the given link invocation, including both command and arguments
* (argv). The version that uses the expander is preferred, but that one can't be used during