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:
Jon Ross-Perkins
2022-10-05 17:34:04 -07:00
committed by GitHub
parent 4785201d80
commit 0b9bda10b7
9 changed files with 82 additions and 62 deletions
+8
View File
@@ -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"],
+31
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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");
}
+4 -12
View File
@@ -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;
+1
View File
@@ -55,6 +55,7 @@ cc_binary(
srcs = ["driver_main.cpp"],
deps = [
":driver",
"//common:bazel_working_dir",
"@llvm-project//llvm:Support",
],
)
+2 -9
View File
@@ -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;