Преглед изворни кода

Add the Clang sysroot to the config output (#6642)

Chandler Carruth пре 3 месеци
родитељ
комит
f772d266a4

+ 24 - 20
toolchain/driver/config_subcommand.cpp

@@ -68,12 +68,17 @@ struct ConfigDataEntry {
 };
 };
 }  // namespace
 }  // namespace
 
 
-// Creates a Clang invocation and queries it for the include directories
-// searched during compilation. If there are any errors setting up Clang, this
-// will diagnose them using `driver_env.consumer` and return `std::nullopt`.
-static auto ComputeClangIncludeDirs(DriverEnv& driver_env,
-                                    llvm::StringRef target_str)
-    -> std::optional<llvm::SmallVector<std::string>> {
+// Creates a Clang invocation and queries it for config data to render.
+//
+// This includes the sysroot and the include directories searched during
+// compilation.
+//
+// If there are any errors setting up Clang, this will diagnose them using
+// `driver_env.consumer` and return `false`. If successful, returns `true`.
+static auto ComputeClangConfig(DriverEnv& driver_env,
+                               llvm::StringRef target_str,
+                               llvm::SmallVectorImpl<ConfigDataEntry>& data)
+    -> bool {
   // Build a library invocation of Clang in order to query its header search
   // Build a library invocation of Clang in order to query its header search
   // paths.
   // paths.
   std::shared_ptr clang_invocation =
   std::shared_ptr clang_invocation =
@@ -103,7 +108,7 @@ static auto ComputeClangIncludeDirs(DriverEnv& driver_env,
                       "unable to setup the requested target `{0}`",
                       "unable to setup the requested target `{0}`",
                       std::string);
                       std::string);
     driver_env.emitter.Emit(ConfigFailedToSetupTarget, target_str.str());
     driver_env.emitter.Emit(ConfigFailedToSetupTarget, target_str.str());
-    return std::nullopt;
+    return false;
   }
   }
 
 
   auto header_search = std::make_unique<clang::HeaderSearch>(
   auto header_search = std::make_unique<clang::HeaderSearch>(
@@ -117,14 +122,20 @@ static auto ComputeClangIncludeDirs(DriverEnv& driver_env,
   // If we ended up diagnosing any errors, just return. They will have been
   // If we ended up diagnosing any errors, just return. They will have been
   // converted to Carbon diagnostics.
   // converted to Carbon diagnostics.
   if (error_tracker.seen_error()) {
   if (error_tracker.seen_error()) {
-    return std::nullopt;
+    return false;
   }
   }
 
 
+  data.push_back({.key = "CLANG_SYSROOT",
+                  .value = clang_instance->getHeaderSearchOpts().Sysroot});
+
   llvm::SmallVector<std::string> search_paths;
   llvm::SmallVector<std::string> search_paths;
   for (const auto& search_dir : header_search->search_dir_range()) {
   for (const auto& search_dir : header_search->search_dir_range()) {
     search_paths.push_back(search_dir.getName().str());
     search_paths.push_back(search_dir.getName().str());
   }
   }
-  return search_paths;
+  data.push_back(
+      {.key = "CLANG_INCLUDE_DIRS", .value = std::move(search_paths)});
+
+  return true;
 }
 }
 
 
 static auto RenderDataAsJson(llvm::ArrayRef<ConfigDataEntry> data,
 static auto RenderDataAsJson(llvm::ArrayRef<ConfigDataEntry> data,
@@ -200,17 +211,10 @@ auto ConfigSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
                     .value = llvm::StringRef(*read_result).rtrim().str()});
                     .value = llvm::StringRef(*read_result).rtrim().str()});
   }
   }
 
 
-  // Compute and print Clang's include dirs if we can.
-  std::optional<llvm::SmallVector<std::string>> clang_include_dirs =
-      ComputeClangIncludeDirs(driver_env, options_.codegen_options.target);
-  if (clang_include_dirs) {
-    data.push_back(
-        {.key = "CLANG_INCLUDE_DIRS", .value = *std::move(clang_include_dirs)});
-  } else {
-    // This will have been diagnosed while computing, continue with degraded
-    // data.
-    result = false;
-  }
+  // Compute and print Clang's config entries if we can. This will have been
+  // diagnosed while computing, so just track if we hit errors.
+  result &=
+      ComputeClangConfig(driver_env, options_.codegen_options.target, data);
 
 
   llvm::sort(data, [](const ConfigDataEntry& lhs, const ConfigDataEntry& rhs) {
   llvm::sort(data, [](const ConfigDataEntry& lhs, const ConfigDataEntry& rhs) {
     return lhs.key < rhs.key;
     return lhs.key < rhs.key;

+ 5 - 0
toolchain/driver/driver_test.cpp

@@ -250,6 +250,11 @@ TEST_F(DriverTest, ConfigJson) {
       json_obj->getString("INSTALL_ROOT");
       json_obj->getString("INSTALL_ROOT");
   ASSERT_THAT(install_root, Ne(std::nullopt));
   ASSERT_THAT(install_root, Ne(std::nullopt));
   EXPECT_THAT(Filesystem::Cwd().OpenDir(install_root->str()), IsSuccess(_));
   EXPECT_THAT(Filesystem::Cwd().OpenDir(install_root->str()), IsSuccess(_));
+
+  std::optional<llvm::StringRef> clang_sysroot =
+      json_obj->getString("CLANG_SYSROOT");
+  ASSERT_THAT(clang_sysroot, Ne(std::nullopt));
+  EXPECT_THAT(Filesystem::Cwd().OpenDir(clang_sysroot->str()), IsSuccess(_));
 }
 }
 
 
 }  // namespace
 }  // namespace

+ 7 - 1
toolchain/driver/testdata/fail_config.carbon

@@ -14,10 +14,16 @@
 // CHECK:STDERR: error: unable to read the installation's digest file: {{.*}}
 // CHECK:STDERR: error: unable to read the installation's digest file: {{.*}}
 // CHECK:STDERR:
 // CHECK:STDERR:
 
 
-// The rest of the config should still be displayed:
+// The rest of the config should still be displayed.
+//
+// Note that the results here are not "portable", and depend on the `--target`
+// argument above. We pass explicit targets to get predictable results in Bazel
+// tests.
+//
 // CHECK:STDOUT: CLANG_INCLUDE_DIRS:
 // CHECK:STDOUT: CLANG_INCLUDE_DIRS:
 // CHECK:STDOUT:     {{.*}}/toolchain/install/prefix/lib/carbon/llvm/lib/clang/22/include
 // CHECK:STDOUT:     {{.*}}/toolchain/install/prefix/lib/carbon/llvm/lib/clang/22/include
 // CHECK:STDOUT: CLANG_RESOURCE_DIR: {{.*}}/toolchain/install/prefix/lib/carbon/llvm/lib/clang/22
 // CHECK:STDOUT: CLANG_RESOURCE_DIR: {{.*}}/toolchain/install/prefix/lib/carbon/llvm/lib/clang/22
+// CHECK:STDOUT: CLANG_SYSROOT: /
 // CHECK:STDOUT: INSTALL_ROOT: {{.*}}/toolchain/install/prefix/lib/carbon/
 // CHECK:STDOUT: INSTALL_ROOT: {{.*}}/toolchain/install/prefix/lib/carbon/
 // CHECK:STDOUT: LLVM_BINDIR: {{.*}}/toolchain/install/prefix/lib/carbon/llvm/bin
 // CHECK:STDOUT: LLVM_BINDIR: {{.*}}/toolchain/install/prefix/lib/carbon/llvm/bin
 // CHECK:STDOUT: VERSION: {{[0-9]+}}.{{[0-9]+}}.{{[0-9]+}}-{{.*}}
 // CHECK:STDOUT: VERSION: {{[0-9]+}}.{{[0-9]+}}.{{[0-9]+}}-{{.*}}