From b1004012c3288f0e011f94f5dd7473982b0d9927 Mon Sep 17 00:00:00 2001 From: Jon Ross-Perkins Date: Mon, 12 May 2025 12:01:01 -0700 Subject: [PATCH] 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 --- common/BUILD | 20 ++++++++++++++++ common/build_data.h | 36 ++++++++++++++++++++++++++++ common/build_data_linkstamp.cpp | 14 +++++++++++ common/build_data_linkstamp.h | 31 ++++++++++++++++++++++++ common/build_data_test.cpp | 29 ++++++++++++++++++++++ testing/file_test/BUILD | 1 + testing/file_test/file_test_base.cpp | 8 ++----- testing/file_test/file_test_base.h | 4 ---- toolchain/testing/file_test.cpp | 6 ----- 9 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 common/build_data.h create mode 100644 common/build_data_linkstamp.cpp create mode 100644 common/build_data_linkstamp.h create mode 100644 common/build_data_test.cpp diff --git a/common/BUILD b/common/BUILD index bd1e7d78fc1a..2bce78b3985f 100644 --- a/common/BUILD +++ b/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"], diff --git a/common/build_data.h b/common/build_data.h new file mode 100644 index 000000000000..5ffc1645469d --- /dev/null +++ b/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_ diff --git a/common/build_data_linkstamp.cpp b/common/build_data_linkstamp.cpp new file mode 100644 index 000000000000..9caaac5720a1 --- /dev/null +++ b/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 diff --git a/common/build_data_linkstamp.h b/common/build_data_linkstamp.h new file mode 100644 index 000000000000..d747113444c5 --- /dev/null +++ b/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 + +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_ diff --git a/common/build_data_test.cpp b/common/build_data_test.cpp new file mode 100644 index 000000000000..3ca55ac6df9b --- /dev/null +++ b/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 + +#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 diff --git a/testing/file_test/BUILD b/testing/file_test/BUILD index 2990b5ab7d91..dc775e2b2215 100644 --- a/testing/file_test/BUILD +++ b/testing/file_test/BUILD @@ -41,6 +41,7 @@ cc_library( deps = [ ":autoupdate", ":manifest", + "//common:build_data", "//common:check", "//common:error", "//common:exe_path", diff --git a/testing/file_test/file_test_base.cpp b/testing/file_test/file_test_base.cpp index 521e75e51dba..57da501ae61e 100644 --- a/testing/file_test/file_test_base.cpp +++ b/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 : ""; -} - // Runs the FileTestAutoupdater, returning the result. static auto RunAutoupdater(FileTestBase* test_base, const TestFile& test_file, bool dry_run) -> bool { diff --git a/testing/file_test/file_test_base.h b/testing/file_test/file_test_base.h index ffc36a4aed5a..540e2365ebf5 100644 --- a/testing/file_test/file_test_base.h +++ b/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, diff --git a/toolchain/testing/file_test.cpp b/toolchain/testing/file_test.cpp index 2fa78cc5ff20..f257d1abefa2 100644 --- a/toolchain/testing/file_test.cpp +++ b/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 {