Fix support for empty `script_executable` value in .gn file.
A recent CL [1] broke the Fuchsia build because the latter sets
the `script_executable` value to the empty script in its `.gn`
file. This use case is documented to let GN invoke action scripts
directly.
This fixes the issue and adds a unit-test for this use case.
[1] https://gn-review.googlesource.com/c/gn/+/13260
Bug: None
Change-Id: I2660c6de0e8f41790c60bbb072149f1d7360e7f0
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/13460
Reviewed-by: Brett Wilson <brettw@chromium.org>
Commit-Queue: David Turner <digit@google.com>
diff --git a/src/gn/setup.cc b/src/gn/setup.cc
index 8f1bd7a..68d42b7 100644
--- a/src/gn/setup.cc
+++ b/src/gn/setup.cc
@@ -126,12 +126,14 @@
help --root-target").
script_executable [optional]
- Path to specific Python executable or other interpreter to use in
- action targets and exec_script calls. By default GN searches the
- PATH for Python to execute these scripts.
+ By default, GN runs the scripts used in action targets and exec_script
+ calls using the Python interpreter found in PATH. This value specifies the
+ Python executable or other interpreter to use instead.
- If set to the empty string, the path specified in action targets
- and exec_script calls will be executed directly.
+ If set to the empty string, the scripts will be executed directly.
+
+ The command-line switch --script-executable will override this value (see
+ "gn help --script-executable")
secondary_source [optional]
Label of an alternate directory tree to find input files. When searching
@@ -781,12 +783,17 @@
if (!value->VerifyTypeIs(Value::STRING, err)) {
return false;
}
- base::FilePath python_path =
- ProcessFileExtensions(UTF8ToFilePath(value->string_value()));
- if (python_path.empty()) {
- *err = Err(Location(), "Could not find \"" + value->string_value() +
- "\" from dotfile in PATH.");
- return false;
+ // Note that an empty string value is valid, and means that the scripts
+ // invoked by actions will be run directly.
+ base::FilePath python_path;
+ if (!value->string_value().empty()) {
+ python_path =
+ ProcessFileExtensions(UTF8ToFilePath(value->string_value()));
+ if (python_path.empty()) {
+ *err = Err(Location(), "Could not find \"" + value->string_value() +
+ "\" from dotfile in PATH.");
+ return false;
+ }
}
build_settings_.set_python_path(python_path);
} else {
diff --git a/src/gn/setup_unittest.cc b/src/gn/setup_unittest.cc
index d905355..8239589 100644
--- a/src/gn/setup_unittest.cc
+++ b/src/gn/setup_unittest.cc
@@ -46,6 +46,33 @@
EXPECT_EQ(gen_deps[0], base::MakeAbsoluteFilePath(dot_gn_name));
}
+TEST_F(SetupTest, EmptyScriptExecutableDoesNotGenerateError) {
+ base::CommandLine cmdline(base::CommandLine::NO_PROGRAM);
+
+ // Create a temp directory containing a .gn file and a BUILDCONFIG.gn file,
+ // pass it as --root.
+ base::ScopedTempDir in_temp_dir;
+ ASSERT_TRUE(in_temp_dir.CreateUniqueTempDir());
+ base::FilePath in_path = in_temp_dir.GetPath();
+ base::FilePath dot_gn_name = in_path.Append(FILE_PATH_LITERAL(".gn"));
+ WriteFile(dot_gn_name,
+ "buildconfig = \"//BUILDCONFIG.gn\"\n"
+ "script_executable = \"\"\n");
+
+ WriteFile(in_path.Append(FILE_PATH_LITERAL("BUILDCONFIG.gn")), "");
+ cmdline.AppendSwitchASCII(switches::kRoot, FilePathToUTF8(in_path));
+
+ // Create another temp dir for writing the generated files to.
+ base::ScopedTempDir build_temp_dir;
+ ASSERT_TRUE(build_temp_dir.CreateUniqueTempDir());
+
+ // Run setup and check that the .gn file is in the scheduler's gen deps.
+ Setup setup;
+ Err err;
+ EXPECT_TRUE(setup.DoSetupWithErr(FilePathToUTF8(build_temp_dir.GetPath()),
+ true, cmdline, &err));
+}
+
#if defined(OS_WIN)
TEST_F(SetupTest, MissingScriptExeGeneratesSetupErrorOnWindows) {
base::CommandLine cmdline(base::CommandLine::NO_PROGRAM);
diff --git a/src/gn/switches.cc b/src/gn/switches.cc
index 6caec3a..e670517 100644
--- a/src/gn/switches.cc
+++ b/src/gn/switches.cc
@@ -119,8 +119,8 @@
action targets and exec_script calls. By default GN searches the
PATH for Python to execute these scripts.
- If set to the empty string, the path specified in action targets
- and exec_script calls will be executed directly.
+ If set to the empty string, the path of scripts specified in action
+ targets and exec_script calls will be executed directly.
)";
const char kQuiet[] = "q";