mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-01 09:25:00 +01:00
The install directory contains the BUILD logic for creating an installable tree of data files and executables for the toolchain, and a library to facilitate toolchain code accessing the paths to their data within this installation. Then adds an installation of LLD in a synthetic LLVM installation, and teaches the Clang runner to configure this and use it for linking instead of the system linker. Currently, the install paths only really manage access to the LLVM binaries installed and used by the Clang runner for linking, but eventually other data files like the prelude and runtime libraries will be fleshed out as well. There are TODOs for moving more things over here such as the prelude. One interesting aspect of this is where to put helpers like parts of LLVM in our install. This PR suggests nesting those files under `lib/carbon`. While using a `lib` subdirectory isn't a perfect fit for the FHS (Filesystem Hierarchy Standard), having a single location where private data is collected is significantly superior to spreading them across the system. This also matches similar patterns used by Clang itself and several other language toolchains and standard libraries. The install directory also provides a natural place for us to build out packaging rules to create installable packages in various formats, but that remains future work. --------- Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
110 lines
3.7 KiB
C++
110 lines
3.7 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/install/install_paths.h"
|
|
|
|
#include <memory>
|
|
|
|
#include "common/check.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/Support/FileSystem.h"
|
|
#include "llvm/Support/Path.h"
|
|
#include "tools/cpp/runfiles/runfiles.h"
|
|
|
|
namespace Carbon {
|
|
|
|
// The location within our Bazel output tree of the prefix_root.
|
|
static constexpr llvm::StringLiteral PrefixRoot =
|
|
"_main/toolchain/install/prefix_root/";
|
|
|
|
// Path within an install prefix for our marker of a valid install.
|
|
static constexpr llvm::StringLiteral MarkerPath =
|
|
"lib/carbon/carbon_install.txt";
|
|
|
|
auto InstallPaths::MakeExeRelative(llvm::StringRef exe_path) -> InstallPaths {
|
|
InstallPaths paths;
|
|
|
|
// Map from the executable path from the executable path to an install
|
|
// prefix path.
|
|
if (!llvm::sys::fs::exists(exe_path)) {
|
|
paths.SetError(llvm::Twine("No file at executable path: ") + exe_path);
|
|
return paths;
|
|
}
|
|
paths = InstallPaths(exe_path);
|
|
|
|
// TODO: Detect a Windows executable path and use custom logic to map to the
|
|
// correct install prefix for that platform.
|
|
|
|
// We assume an executable will be in a `bin` directory and this is a
|
|
// FHS-like install prefix. We remove the filename and walk up to find the
|
|
// expected install prefix.
|
|
llvm::sys::path::remove_filename(paths.prefix_);
|
|
llvm::sys::path::append(paths.prefix_, llvm::sys::path::Style::posix, "../");
|
|
|
|
paths.CheckMarkerFile();
|
|
return paths;
|
|
}
|
|
|
|
auto InstallPaths::MakeForBazelRunfiles(llvm::StringRef exe_path)
|
|
-> InstallPaths {
|
|
using bazel::tools::cpp::runfiles::Runfiles;
|
|
std::string runtimes_error;
|
|
std::unique_ptr<Runfiles> runfiles(
|
|
Runfiles::Create(exe_path.str(), &runtimes_error));
|
|
CARBON_CHECK(runfiles != nullptr)
|
|
<< "Failed to find runtimes tree: " << runtimes_error;
|
|
|
|
std::string relative_marker_path = (PrefixRoot.str() + MarkerPath).str();
|
|
std::string runtimes_marker_path = runfiles->Rlocation(relative_marker_path);
|
|
|
|
// Start from the marker, remove that filename, and walk up to find the
|
|
// install prefix.
|
|
InstallPaths paths(runtimes_marker_path);
|
|
llvm::sys::path::remove_filename(paths.prefix_);
|
|
llvm::sys::path::append(paths.prefix_, llvm::sys::path::Style::posix,
|
|
"../../");
|
|
|
|
paths.CheckMarkerFile();
|
|
CARBON_CHECK(!paths.error()) << *paths.error();
|
|
return paths;
|
|
}
|
|
|
|
auto InstallPaths::Make(llvm::StringRef install_prefix) -> InstallPaths {
|
|
InstallPaths paths(install_prefix);
|
|
paths.CheckMarkerFile();
|
|
return paths;
|
|
}
|
|
|
|
auto InstallPaths::SetError(llvm::Twine message) -> void {
|
|
// Use an empty prefix on error as that should use the working directory which
|
|
// is the least likely problematic.
|
|
prefix_ = "";
|
|
error_ = {message.str()};
|
|
}
|
|
|
|
auto InstallPaths::CheckMarkerFile() -> void {
|
|
llvm::SmallString<256> path(prefix_);
|
|
llvm::sys::path::append(path, llvm::sys::path::Style::posix, MarkerPath);
|
|
if (!llvm::sys::fs::exists(path)) {
|
|
SetError(llvm::Twine("No install marker at path: ") + path);
|
|
}
|
|
}
|
|
|
|
auto InstallPaths::driver() const -> std::string {
|
|
llvm::SmallString<256> path(prefix_);
|
|
// TODO: Adjust this to work equally well on Windows.
|
|
llvm::sys::path::append(path, llvm::sys::path::Style::posix, "bin/carbon");
|
|
return path.str().str();
|
|
}
|
|
|
|
auto InstallPaths::llvm_install_bin() const -> std::string {
|
|
llvm::SmallString<256> path(prefix_);
|
|
// TODO: Adjust this to work equally well on Windows.
|
|
llvm::sys::path::append(path, llvm::sys::path::Style::posix,
|
|
"lib/carbon/llvm/bin/");
|
|
return path.str().str();
|
|
}
|
|
|
|
} // namespace Carbon
|