From cfa94aa861f3116462ff69345191c8c71ebd7d43 Mon Sep 17 00:00:00 2001 From: Keith Smiley Date: Wed, 26 Jan 2022 14:13:52 -0800 Subject: [PATCH] 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 --- .../build/lib/rules/cpp/LinkCommandLine.java | 13 +++++++++---- 1 file changed, 9 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 0403d2de3bcd1f..3535520b030cb0 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 @@ 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 @@ -284,7 +284,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. @@ -292,7 +292,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 @@ -300,6 +300,11 @@ 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