mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 21:40:12 +01:00
This also switches to a more Bazel-based install layout, skipping the FHS-based synthetic layout. The FHS-based layout is still reconstructed explicitly when building an installable tar-ball. The biggest change is to configure the just-built install as a Bazel toolchain, including allowing it to build its own runtime libraries as native Bazel libraries. This removes the need for a monolithic runtimes build, all of that code logic is removed. This should also pave the way to using the just-built toolchain for doing a full 3-stage bootstrap. Building the 2nd stage is included here as it was a particularly effective way to test that the Bazel integration was fully working. Adding a 3rd-stage check for stability is future work, but should be pretty easy. There is a down-side: this uses the busybox to do the runtimes compilation, which means they will be re-built after ~any change to Carbon. However, the integration with Bazel should largely pay for this, and we can continue to factor the tests away from depending on built runtimes in most cases. Now that we're building and testing the runtimes more directly, this surfaced a problem with the layout of runtimes on macOS that is fixed here. All of the Darwin OSes use a custom layout for their resource directory compared to other targets. We now model this in both the C++ built runtimes and the Bazel built runtimes. Assisted-by: Gemini via Antigravity
142 lines
4.8 KiB
C++
142 lines
4.8 KiB
C++
// 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 "toolchain/base/install_paths.h"
|
|
|
|
#include <gmock/gmock.h>
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <filesystem>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "common/check.h"
|
|
#include "common/error_test_helpers.h"
|
|
#include "common/filesystem.h"
|
|
#include "llvm/ADT/SmallString.h"
|
|
#include "llvm/Support/FormatVariadic.h"
|
|
#include "testing/base/global_exe_path.h"
|
|
#include "tools/cpp/runfiles/runfiles.h"
|
|
|
|
namespace Carbon {
|
|
|
|
class InstallPathsTestPeer {
|
|
public:
|
|
static auto GetRoot(const InstallPaths& paths) -> std::filesystem::path {
|
|
return paths.root_;
|
|
}
|
|
};
|
|
|
|
namespace {
|
|
|
|
using ::bazel::tools::cpp::runfiles::Runfiles;
|
|
using ::testing::_;
|
|
using ::testing::Eq;
|
|
using ::testing::HasSubstr;
|
|
using Testing::IsSuccess;
|
|
using ::testing::Optional;
|
|
using ::testing::StartsWith;
|
|
|
|
class InstallPathsTest : public ::testing::Test {
|
|
public:
|
|
InstallPathsTest() {
|
|
std::string error;
|
|
test_runfiles_.reset(Runfiles::Create(Testing::GetExePath().str(), &error));
|
|
CARBON_CHECK(test_runfiles_ != nullptr, "{0}", error);
|
|
}
|
|
|
|
// Test the install paths found with the given `exe_path`. Will check that
|
|
// the detected install root path has the expected location relative to the
|
|
// FHS layout, and then check that the path accessors point to the right kind
|
|
// of file or directory.
|
|
auto TestInstallPaths(const InstallPaths& paths) -> void {
|
|
std::filesystem::path root_path = InstallPathsTestPeer::GetRoot(paths);
|
|
|
|
SCOPED_TRACE(llvm::formatv("Install root: '{0}'", root_path));
|
|
|
|
// Open the root directory.
|
|
auto root_result = Filesystem::Cwd().OpenDir(root_path);
|
|
ASSERT_THAT(root_result, IsSuccess(_));
|
|
Filesystem::Dir root = *std::move(root_result);
|
|
|
|
std::filesystem::path core_package_path = paths.core_package();
|
|
ASSERT_THAT(core_package_path, StartsWith(root_path));
|
|
EXPECT_THAT(Filesystem::Cwd().Access(core_package_path / "prelude.carbon"),
|
|
IsSuccess(Eq(true)))
|
|
<< "path: " << core_package_path;
|
|
|
|
std::filesystem::path llvm_bin_path = paths.llvm_install_bin();
|
|
ASSERT_THAT(llvm_bin_path, StartsWith(root_path));
|
|
auto open_result = Filesystem::Cwd().OpenDir(llvm_bin_path);
|
|
ASSERT_THAT(open_result, IsSuccess(_));
|
|
Filesystem::Dir llvm_bin = *std::move(open_result);
|
|
|
|
for (std::filesystem::path bin_name : {"ld.lld", "ld64.lld"}) {
|
|
EXPECT_THAT(
|
|
llvm_bin.Access(bin_name, Filesystem::AccessCheckFlags::Execute),
|
|
IsSuccess(Eq(true)))
|
|
<< "path: " << (llvm_bin_path / bin_name);
|
|
}
|
|
}
|
|
|
|
std::unique_ptr<Runfiles> test_runfiles_;
|
|
};
|
|
|
|
TEST_F(InstallPathsTest, RootBusybox) {
|
|
std::string installed_busybox_path =
|
|
test_runfiles_->Rlocation("carbon/toolchain/install/carbon-busybox");
|
|
|
|
auto paths = InstallPaths::MakeExeRelative(installed_busybox_path);
|
|
ASSERT_THAT(paths.error(), Eq(std::nullopt)) << *paths.error();
|
|
TestInstallPaths(paths);
|
|
}
|
|
|
|
TEST_F(InstallPathsTest, RootExplicit) {
|
|
std::string marker_path =
|
|
test_runfiles_->Rlocation("carbon/toolchain/install/carbon_install.txt");
|
|
|
|
llvm::StringRef root_path = marker_path;
|
|
CARBON_CHECK(root_path.consume_back("carbon_install.txt"),
|
|
"Unexpected suffix of the marker path: {0}", marker_path);
|
|
|
|
auto paths = InstallPaths::Make(root_path);
|
|
ASSERT_THAT(paths.error(), Eq(std::nullopt)) << *paths.error();
|
|
TestInstallPaths(paths);
|
|
}
|
|
|
|
TEST_F(InstallPathsTest, TestRunfiles) {
|
|
auto paths = InstallPaths::MakeForBazelRunfiles(Testing::GetExePath());
|
|
ASSERT_THAT(paths.error(), Eq(std::nullopt)) << *paths.error();
|
|
TestInstallPaths(paths);
|
|
}
|
|
|
|
TEST_F(InstallPathsTest, BinaryRunfiles) {
|
|
std::filesystem::path test_binary_path =
|
|
test_runfiles_->Rlocation("carbon/toolchain/base/test_binary");
|
|
ASSERT_THAT(Filesystem::Cwd().Access(test_binary_path,
|
|
Filesystem::AccessCheckFlags::Execute),
|
|
IsSuccess(Eq(true)))
|
|
<< "path: " << test_binary_path;
|
|
|
|
auto paths = InstallPaths::MakeForBazelRunfiles(test_binary_path.native());
|
|
ASSERT_THAT(paths.error(), Eq(std::nullopt)) << *paths.error();
|
|
TestInstallPaths(paths);
|
|
}
|
|
|
|
TEST_F(InstallPathsTest, Errors) {
|
|
auto paths = InstallPaths::Make("/foo/bar/baz");
|
|
EXPECT_THAT(paths.error(), Optional(HasSubstr("foo/bar/baz")));
|
|
EXPECT_THAT(InstallPathsTestPeer::GetRoot(paths), Eq(""));
|
|
|
|
paths = InstallPaths::MakeExeRelative("foo/bar/baz");
|
|
EXPECT_THAT(paths.error(), Optional(HasSubstr("foo/bar/baz")));
|
|
EXPECT_THAT(InstallPathsTestPeer::GetRoot(paths), Eq(""));
|
|
|
|
// Note that we can't test the runfiles code path from within a test because
|
|
// it succeeds some of the time even with a bogus executable name.
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace Carbon
|