From c1ecca22d2cb761bd094fcd40eb8b13e826e777e Mon Sep 17 00:00:00 2001 From: Brentley Jones Date: Wed, 2 Mar 2022 08:19:41 -0600 Subject: [PATCH] Fix aggressive params file assumption (#14930) 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 (cherry picked from commit 24e82426e689853b0d9a04e7b9b6f13e145cf2d6) Co-authored-by: Keith Smiley --- .../build/lib/rules/cpp/LinkCommandLine.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) 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 b26e71c76bf501..8bd65bb8897542 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 @@ -276,13 +276,13 @@ CommandLine paramCmdLine() { paramFile, linkTargetType, forcedToolPath, featureConfiguration, actionName, variables); } - public static void extractArgumentsForStaticLinkParamFile( + private static void extractArgumentsForStaticLinkParamFile( List args, List commandlineArgs, List 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 @@ -290,7 +290,7 @@ public static void extractArgumentsForStaticLinkParamFile( } } - public static void extractArgumentsForDynamicLinkParamFile( + private static void extractArgumentsForDynamicLinkParamFile( List args, List commandlineArgs, List 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. @@ -298,7 +298,7 @@ public static void extractArgumentsForDynamicLinkParamFile( 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 @@ -306,6 +306,13 @@ public static void extractArgumentsForDynamicLinkParamFile( } } + 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