Browse Source

Add linkstamp support to get the target name (#5451)

This removes hardcoding of the test target name from file_test.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Jon Ross-Perkins 11 months ago
parent
commit
b1004012c3

+ 20 - 0
common/BUILD

@@ -36,6 +36,26 @@ cc_library(
     ],
 )
 
+cc_library(
+    name = "build_data",
+    srcs = ["build_data_linkstamp.h"],
+    hdrs = ["build_data.h"],
+    linkstamp = "build_data_linkstamp.cpp",
+    deps = ["@llvm-project//llvm:Support"],
+)
+
+cc_test(
+    name = "build_data_test",
+    size = "small",
+    srcs = ["build_data_test.cpp"],
+    deps = [
+        ":build_data",
+        ":ostream",
+        "//testing/base:gtest_main",
+        "@googletest//:gtest",
+    ],
+)
+
 cc_library(
     name = "command_line",
     srcs = ["command_line.cpp"],

+ 36 - 0
common/build_data.h

@@ -0,0 +1,36 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef CARBON_COMMON_BUILD_DATA_H_
+#define CARBON_COMMON_BUILD_DATA_H_
+
+#include "common/build_data_linkstamp.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace Carbon::BuildData {
+
+// Build information for a binary, from bazel. Stamped values come from:
+// https://github.com/bazelbuild/bazel/blob/master/src/main/java/com/google/devtools/build/lib/rules/cpp/CppLinkstampCompileHelper.java
+
+// NOLINTBEGIN(readability-identifier-naming): We want to use constant-style
+// names for the public variables, but cannot use constexpr.
+
+// The platform, per https://bazel.build/extending/platforms.
+inline const llvm::StringRef Platform = Internal::platform;
+
+// Whether coverage is enabled.
+inline const bool BuildCoverageEnabled = Internal::build_coverage_enabled;
+
+// The binary target, such as `//common:build_data_test`.
+inline const llvm::StringRef TargetName = Internal::target_name;
+
+// The path to the build target, such as
+// `bazel-out/k8-fastbuild/bin/common/build_data_test`.
+inline const llvm::StringRef BuildTarget = Internal::build_target;
+
+// NOLINTEND(readability-identifier-naming)
+
+}  // namespace Carbon::BuildData
+
+#endif  // CARBON_COMMON_BUILD_DATA_H_

+ 14 - 0
common/build_data_linkstamp.cpp

@@ -0,0 +1,14 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include "common/build_data_linkstamp.h"
+
+namespace Carbon::BuildData::Internal {
+
+const std::string_view platform = GPLATFORM;
+const bool build_coverage_enabled = BUILD_COVERAGE_ENABLED;
+const std::string_view target_name = G3_TARGET_NAME;
+const std::string_view build_target = G3_BUILD_TARGET;
+
+}  // namespace Carbon::BuildData::Internal

+ 31 - 0
common/build_data_linkstamp.h

@@ -0,0 +1,31 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#ifndef CARBON_COMMON_BUILD_DATA_LINKSTAMP_H_
+#define CARBON_COMMON_BUILD_DATA_LINKSTAMP_H_
+
+#include <string_view>
+
+namespace Carbon::BuildData::Internal {
+
+// See build_data.h; the list of names here should match.
+//
+// Bazel will build dependencies on the `:build_data` library (which exposes
+// `build_data_linkstamp.h`) throughout the build process, but
+// `build_data_linkstamp.cpp` is compiled and linked per-binary -- essentially a
+// separate library. In essence, `build_data_linkstamp.h` is exposing values
+// that are assigned later (this has consequences like preventing `constexpr`
+// use).
+//
+// Also, when build_data_linkstamp.cpp is compiled, this doesn't receive deps,
+// so we can't use things like `llvm::StringRef` here. As a result, we use
+// `build_data.h` as an intermediary to do a `StringRef` wrap.
+extern const std::string_view platform;
+extern const bool build_coverage_enabled;
+extern const std::string_view target_name;
+extern const std::string_view build_target;
+
+}  // namespace Carbon::BuildData::Internal
+
+#endif  // CARBON_COMMON_BUILD_DATA_LINKSTAMP_H_

+ 29 - 0
common/build_data_test.cpp

@@ -0,0 +1,29 @@
+// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+// Exceptions. See /LICENSE for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+#include "common/build_data.h"
+
+#include <gmock/gmock.h>
+
+#include "common/ostream.h"
+
+namespace Carbon {
+namespace {
+
+using ::testing::EndsWith;
+using ::testing::HasSubstr;
+
+TEST(BuildDataTest, Values) {
+  EXPECT_FALSE(BuildData::Platform.empty());
+  // Can't really test BuildCoverageEnabled.
+
+  // This doesn't require `//`, for a bit of incremental robustness.
+  EXPECT_THAT(BuildData::TargetName, EndsWith("/common:build_data_test"));
+
+  // This doesn't examine the path, for platform robustness (e.g. `.exe`).
+  EXPECT_THAT(BuildData::BuildTarget, HasSubstr("build_data_test"));
+}
+
+}  // namespace
+}  // namespace Carbon

+ 1 - 0
testing/file_test/BUILD

@@ -41,6 +41,7 @@ cc_library(
     deps = [
         ":autoupdate",
         ":manifest",
+        "//common:build_data",
         "//common:check",
         "//common:error",
         "//common:exe_path",

+ 2 - 6
testing/file_test/file_test_base.cpp

@@ -37,6 +37,7 @@
 #include "absl/flags/flag.h"
 #include "absl/flags/parse.h"
 #include "absl/strings/str_join.h"
+#include "common/build_data.h"
 #include "common/check.h"
 #include "common/error.h"
 #include "common/exe_path.h"
@@ -138,7 +139,7 @@ static auto CompareFailPrefix(llvm::StringRef filename, bool success) -> void {
 auto FileTestBase::GetBazelCommand(BazelMode mode) -> std::string {
   RawStringOstream args;
   args << "bazel " << ((mode == BazelMode::Test) ? "test" : "run") << " "
-       << GetBazelLabel() << " ";
+       << BuildData::TargetName << " ";
 
   switch (mode) {
     case BazelMode::Autoupdate:
@@ -159,11 +160,6 @@ auto FileTestBase::GetBazelCommand(BazelMode mode) -> std::string {
   return args.TakeStr();
 }
 
-auto FileTestBase::GetBazelLabel() -> std::string {
-  const char* target = getenv("TEST_TARGET");
-  return target ? target : "<target>";
-}
-
 // Runs the FileTestAutoupdater, returning the result.
 static auto RunAutoupdater(FileTestBase* test_base, const TestFile& test_file,
                            bool dry_run) -> bool {

+ 0 - 4
testing/file_test/file_test_base.h

@@ -107,10 +107,6 @@ class FileTestBase {
   // run.
   virtual auto AllowParallelRun() const -> bool { return true; }
 
-  // Returns the name of the test (relative to the repo root).
-  // Returns a bazel label that can be used to invoke this test.
-  virtual auto GetBazelLabel() -> std::string;
-
   // Modes for GetBazelCommand.
   enum class BazelMode : uint8_t {
     Autoupdate,

+ 0 - 6
toolchain/testing/file_test.cpp

@@ -62,12 +62,6 @@ class ToolchainFileTest : public FileTestBase {
     return component_ != "language_server";
   }
 
-  // Force a fixed bazel label to avoid spurious test failures due to differing
-  // run commands when running file_test binary outside of bazel.
-  auto GetBazelLabel() -> std::string override {
-    return "//toolchain/testing:file_test";
-  }
-
  private:
   // Controls whether `Run()` includes the prelude.
   auto is_no_prelude() const -> bool {