mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:50:14 +01:00
Refactor common main logic (#2260)
1) toolchain and explorer use the same working dir logic, share it 2) explorer's carbon.cpp and main_bin.cpp use the same relative path logic, share it 3) You can append a longer path in one call with the right kind of iterator 4) Fix what's maybe a bug in passing `relative_prelude_path.str()` to `cl::init` 5) Collapse Main and ExplorerMain to avoid passing more parameters between
This commit is contained in:
@@ -4,6 +4,14 @@
|
||||
|
||||
package(default_visibility = ["//visibility:public"])
|
||||
|
||||
cc_library(
|
||||
name = "bazel_working_dir",
|
||||
hdrs = ["bazel_working_dir.h"],
|
||||
deps = [
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "check",
|
||||
srcs = ["check_internal.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_BAZEL_WORKING_DIR_H_
|
||||
#define CARBON_COMMON_BAZEL_WORKING_DIR_H_
|
||||
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
// Behave as if the working directory is where `bazel run` was invoked.
|
||||
// This should only be used in development binaries, not release.
|
||||
inline auto SetWorkingDirForBazel() -> bool {
|
||||
char* build_working_dir = getenv("BUILD_WORKING_DIRECTORY");
|
||||
if (build_working_dir == nullptr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (std::error_code err =
|
||||
llvm::sys::fs::set_current_path(build_working_dir)) {
|
||||
llvm::errs() << "Failed to set working directory: " << err.message();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
#endif // CARBON_COMMON_BAZEL_WORKING_DIR_H_
|
||||
+2
-1
@@ -33,11 +33,12 @@ cc_library(
|
||||
cc_binary(
|
||||
name = "explorer",
|
||||
srcs = ["main_bin.cpp"],
|
||||
env = macos_malloc_env(),
|
||||
deps = [
|
||||
":main",
|
||||
"//common:bazel_working_dir",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
env = macos_malloc_env(),
|
||||
)
|
||||
|
||||
py_binary(
|
||||
|
||||
+22
-14
@@ -19,16 +19,20 @@
|
||||
#include "explorer/interpreter/exec_program.h"
|
||||
#include "explorer/syntax/parse.h"
|
||||
#include "explorer/syntax/prelude.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/InitLLVM.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
namespace cl = llvm::cl;
|
||||
namespace path = llvm::sys::path;
|
||||
|
||||
static auto Main(llvm::StringRef default_prelude_file, int argc, char* argv[])
|
||||
-> bool {
|
||||
auto ExplorerMain(int argc, char** argv, void* static_for_main_addr,
|
||||
llvm::StringRef relative_prelude_path) -> int {
|
||||
llvm::setBugReportMsg(
|
||||
"Please report issues to "
|
||||
"https://github.com/carbon-language/carbon-lang/issues and include the "
|
||||
@@ -47,9 +51,18 @@ static auto Main(llvm::StringRef default_prelude_file, int argc, char* argv[])
|
||||
"trace_file",
|
||||
cl::desc("Output file for tracing; set to `-` to output to stdout."));
|
||||
|
||||
// Find the path of the executable if possible and use that as a relative root
|
||||
// Use the executable path as a base for the relative prelude path.
|
||||
std::string exe =
|
||||
llvm::sys::fs::getMainExecutable(argv[0], static_for_main_addr);
|
||||
llvm::StringRef install_path = path::parent_path(exe);
|
||||
llvm::SmallString<256> default_prelude_file(install_path);
|
||||
path::append(default_prelude_file,
|
||||
path::begin(relative_prelude_path, path::Style::posix),
|
||||
path::end(relative_prelude_path));
|
||||
std::string default_prelude_file_str(default_prelude_file);
|
||||
cl::opt<std::string> prelude_file_name("prelude", cl::desc("<prelude file>"),
|
||||
cl::init(default_prelude_file.str()));
|
||||
cl::init(default_prelude_file_str));
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv);
|
||||
|
||||
// Set up a stream for trace output.
|
||||
@@ -64,7 +77,7 @@ static auto Main(llvm::StringRef default_prelude_file, int argc, char* argv[])
|
||||
std::make_unique<llvm::raw_fd_ostream>(trace_file_name, err);
|
||||
if (err) {
|
||||
llvm::errs() << err.message() << "\n";
|
||||
return false;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
trace_stream = scoped_trace_stream.get();
|
||||
}
|
||||
@@ -77,7 +90,7 @@ static auto Main(llvm::StringRef default_prelude_file, int argc, char* argv[])
|
||||
ast = *std::move(parse_result);
|
||||
} else {
|
||||
llvm::errs() << "SYNTAX ERROR: " << parse_result.error() << "\n";
|
||||
return false;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
AddPrelude(prelude_file_name, &arena, &ast.declarations);
|
||||
@@ -88,7 +101,7 @@ static auto Main(llvm::StringRef default_prelude_file, int argc, char* argv[])
|
||||
ast = *std::move(analyze_result);
|
||||
} else {
|
||||
llvm::errs() << "COMPILATION ERROR: " << analyze_result.error() << "\n";
|
||||
return false;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Run the program.
|
||||
@@ -103,15 +116,10 @@ static auto Main(llvm::StringRef default_prelude_file, int argc, char* argv[])
|
||||
}
|
||||
} else {
|
||||
llvm::errs() << "RUNTIME ERROR: " << exec_result.error() << "\n";
|
||||
return false;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
auto ExplorerMain(llvm::StringRef default_prelude_file, int argc, char** argv)
|
||||
-> int {
|
||||
return Main(default_prelude_file, argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
+4
-3
@@ -9,9 +9,10 @@
|
||||
|
||||
namespace Carbon {
|
||||
|
||||
// Runs explorer.
|
||||
auto ExplorerMain(llvm::StringRef default_prelude_file, int argc, char** argv)
|
||||
-> int;
|
||||
// Runs explorer. relative_prelude_path must be POSIX-style, not native, and
|
||||
// will be translated to native.
|
||||
auto ExplorerMain(int argc, char** argv, void* static_for_main_addr,
|
||||
llvm::StringRef relative_prelude_path) -> int;
|
||||
|
||||
} // namespace Carbon
|
||||
|
||||
|
||||
+8
-23
@@ -2,31 +2,16 @@
|
||||
// Exceptions. See /LICENSE for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "common/bazel_working_dir.h"
|
||||
#include "explorer/main.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
auto main(int argc, char** argv) -> int {
|
||||
// This assumes execution from `bazel-bin/explorer`, either directly or with
|
||||
// `bazel run`.
|
||||
Carbon::SetWorkingDirForBazel();
|
||||
|
||||
static int static_for_main_addr;
|
||||
std::string exe = llvm::sys::fs::getMainExecutable(
|
||||
argv[0], static_cast<void*>(&static_for_main_addr));
|
||||
llvm::SmallString<256> prelude_path = llvm::sys::path::parent_path(exe);
|
||||
llvm::sys::path::append(prelude_path, "explorer.runfiles", "carbon",
|
||||
"explorer", "data");
|
||||
llvm::sys::path::append(prelude_path, "prelude.carbon");
|
||||
|
||||
// Behave as if the working directory is where `bazel run` was invoked.
|
||||
char* build_working_dir = getenv("BUILD_WORKING_DIRECTORY");
|
||||
if (build_working_dir != nullptr) {
|
||||
if (std::error_code err =
|
||||
llvm::sys::fs::set_current_path(build_working_dir)) {
|
||||
llvm::errs() << "Failed to set working directory: " << err.message();
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return Carbon::ExplorerMain(prelude_path, argc, argv);
|
||||
return Carbon::ExplorerMain(
|
||||
argc, argv, static_cast<void*>(&static_for_main_addr),
|
||||
// This assumes execution from `bazel-bin/explorer`, either directly or
|
||||
// with `bazel run`.
|
||||
"explorer.runfiles/carbon/explorer/data/prelude.carbon");
|
||||
}
|
||||
|
||||
@@ -3,23 +3,15 @@
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "explorer/main.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
|
||||
namespace fs = llvm::sys::fs;
|
||||
namespace path = llvm::sys::path;
|
||||
|
||||
auto main(int argc, char** argv) -> int {
|
||||
llvm::StringRef bin = path::filename(argv[0]);
|
||||
llvm::StringRef bin = llvm::sys::path::filename(argv[0]);
|
||||
if (bin == "carbon-explorer") {
|
||||
static int static_for_main_addr;
|
||||
std::string exe = fs::getMainExecutable(
|
||||
argv[0], static_cast<void*>(&static_for_main_addr));
|
||||
llvm::StringRef install_path = path::parent_path(exe);
|
||||
llvm::SmallString<256> prelude_file(install_path);
|
||||
path::append(prelude_file, "data", "prelude.carbon");
|
||||
return Carbon::ExplorerMain(prelude_file, argc, argv);
|
||||
return Carbon::ExplorerMain(argc, argv,
|
||||
static_cast<void*>(&static_for_main_addr),
|
||||
"data/prelude.carbon");
|
||||
} else {
|
||||
fprintf(stderr, "Unrecognized Carbon binary requested: %s", argv[0]);
|
||||
return 1;
|
||||
|
||||
@@ -55,6 +55,7 @@ cc_binary(
|
||||
srcs = ["driver_main.cpp"],
|
||||
deps = [
|
||||
":driver",
|
||||
"//common:bazel_working_dir",
|
||||
"@llvm-project//llvm:Support",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include <cstdlib>
|
||||
|
||||
#include "common/bazel_working_dir.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
@@ -14,15 +15,7 @@ auto main(int argc, char** argv) -> int {
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Behave as if the working directory is where `bazel run` was invoked.
|
||||
char* build_working_dir = getenv("BUILD_WORKING_DIRECTORY");
|
||||
if (build_working_dir != nullptr) {
|
||||
if (std::error_code err =
|
||||
llvm::sys::fs::set_current_path(build_working_dir)) {
|
||||
llvm::errs() << "Failed to set working directory: " << err.message();
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
Carbon::SetWorkingDirForBazel();
|
||||
|
||||
llvm::SmallVector<llvm::StringRef, 16> args(argv + 1, argv + argc);
|
||||
Carbon::Driver driver;
|
||||
|
||||
Reference in New Issue
Block a user