From 85ac641ddf5adde31b5d2f58b76ae5db251218a9 Mon Sep 17 00:00:00 2001 From: Greg Estren Date: Tue, 13 Sep 2016 00:32:09 +0000 Subject: Rollback of startup options changes. -- MOS_MIGRATED_REVID=132940326 --- src/main/cpp/BUILD | 7 +- src/main/cpp/blaze.cc | 253 ++++++++++--------- src/main/cpp/blaze.h | 25 -- src/main/cpp/blaze_globals.h | 6 +- src/main/cpp/blaze_startup_options.cc | 163 ++++++++++++ src/main/cpp/blaze_startup_options.h | 219 ++++++++++++++++ src/main/cpp/blaze_startup_options_common.cc | 284 +++++++++++++++++++++ src/main/cpp/main.cc | 25 -- src/main/cpp/option_processor.cc | 12 +- src/main/cpp/option_processor.h | 8 +- src/main/cpp/startup_options.cc | 362 --------------------------- src/main/cpp/startup_options.h | 211 ---------------- 12 files changed, 807 insertions(+), 768 deletions(-) delete mode 100644 src/main/cpp/blaze.h create mode 100644 src/main/cpp/blaze_startup_options.cc create mode 100644 src/main/cpp/blaze_startup_options.h create mode 100644 src/main/cpp/blaze_startup_options_common.cc delete mode 100644 src/main/cpp/main.cc delete mode 100644 src/main/cpp/startup_options.cc delete mode 100644 src/main/cpp/startup_options.h diff --git a/src/main/cpp/BUILD b/src/main/cpp/BUILD index 64de8eb688..4a2ff8ad7a 100644 --- a/src/main/cpp/BUILD +++ b/src/main/cpp/BUILD @@ -69,13 +69,12 @@ cc_binary( name = "client", srcs = [ "blaze.cc", - "blaze.h", "blaze_globals.h", - "main.cc", + "blaze_startup_options.cc", + "blaze_startup_options.h", + "blaze_startup_options_common.cc", "option_processor.cc", "option_processor.h", - "startup_options.cc", - "startup_options.h", "workspace_layout.cc", "workspace_layout.h", ], diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc index 25eae2f166..9316a7f707 100644 --- a/src/main/cpp/blaze.cc +++ b/src/main/cpp/blaze.cc @@ -23,7 +23,6 @@ // - exiting with the right error/WTERMSIG code. // - debugger + profiler support. // - mutual exclusion between batch invocations. -#include "src/main/cpp/blaze.h" #include #include @@ -68,10 +67,10 @@ #include "src/main/cpp/blaze_abrupt_exit.h" #include "src/main/cpp/blaze_globals.h" +#include "src/main/cpp/blaze_startup_options.h" #include "src/main/cpp/blaze_util.h" #include "src/main/cpp/blaze_util_platform.h" #include "src/main/cpp/option_processor.h" -#include "src/main/cpp/startup_options.h" #include "src/main/cpp/util/errors.h" #include "src/main/cpp/util/exit_code.h" #include "src/main/cpp/util/file.h" @@ -226,7 +225,7 @@ class BlazeServer { static GlobalVariables *globals; static BlazeServer *blaze_server; -static void InitGlobals(OptionProcessor *option_processor) { +static void InitGlobals() { globals = new GlobalVariables; globals->server_pid = -1; globals->sigint_count = 0; @@ -235,14 +234,12 @@ static void InitGlobals(OptionProcessor *option_processor) { globals->extract_data_time = 0; globals->command_wait_time = 0; globals->restart_reason = NO_RESTART; - globals->option_processor = option_processor; - globals->options = NULL; // Initialized after parsing with option_processor. } uint64_t BlazeServer::AcquireLock() { return blaze::AcquireLock( - globals->options->output_base, globals->options->batch, - globals->options->block_for_lock, &blaze_lock_); + globals->options.output_base, globals->options.batch, + globals->options.block_for_lock, &blaze_lock_); } // Communication method that uses an AF_UNIX socket and a custom protocol. @@ -379,7 +376,7 @@ static string GetInstallBase(const string &root, const string &self_path) { if (extractor.get() == NULL) { die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "\nFailed to open %s as a zip file: (%d) %s", - globals->options->product_name.c_str(), errno, strerror(errno)); + globals->options.product_name.c_str(), errno, strerror(errno)); } if (extractor->ProcessAll() < 0) { die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, @@ -410,15 +407,15 @@ static vector GetArgumentArray() { // ~/src/build_root/WORKSPACE file) will appear in ps(1) as "blaze(src)". string workspace = blaze_util::Basename(blaze_util::Dirname(globals->workspace)); - string product = globals->options->product_name; + string product = globals->options.product_name; blaze_util::ToLower(&product); result.push_back(product + "(" + workspace + ")"); - globals->options->AddJVMArgumentPrefix( + globals->options.AddJVMArgumentPrefix( blaze_util::Dirname(blaze_util::Dirname(globals->jvm_path)), &result); result.push_back("-XX:+HeapDumpOnOutOfMemoryError"); - string heap_crash_path = globals->options->output_base; + string heap_crash_path = globals->options.output_base; result.push_back("-XX:HeapDumpPath=" + ConvertPath(heap_crash_path)); result.push_back("-Xverify:none"); @@ -426,20 +423,20 @@ static vector GetArgumentArray() { vector user_options; user_options.insert(user_options.begin(), - globals->options->host_jvm_args.begin(), - globals->options->host_jvm_args.end()); + globals->options.host_jvm_args.begin(), + globals->options.host_jvm_args.end()); // Add JVM arguments particular to building blaze64 and particular JVM // versions. string error; blaze_exit_code::ExitCode jvm_args_exit_code = - globals->options->AddJVMArguments(globals->options->GetHostJavabase(), + globals->options.AddJVMArguments(globals->options.GetHostJavabase(), &result, user_options, &error); if (jvm_args_exit_code != blaze_exit_code::SUCCESS) { die(jvm_args_exit_code, "%s", error.c_str()); } - if (globals->options->batch && globals->options->oom_more_eagerly) { + if (globals->options.batch && globals->options.oom_more_eagerly) { // Put this OOM trigger with kill after --host_jvm_args, in case // --host_jvm_args contains user-specified OOM triggers since we want those // to execute first. @@ -448,7 +445,7 @@ static vector GetArgumentArray() { // We put all directories on the java.library.path that contain .so files. string java_library_path = "-Djava.library.path="; - string real_install_dir = blaze_util::JoinPath(globals->options->install_base, + string real_install_dir = blaze_util::JoinPath(globals->options.install_base, "_embedded_binaries"); bool first = true; for (const auto& it : globals->extracted_binaries) { @@ -466,7 +463,7 @@ static vector GetArgumentArray() { // Force use of latin1 for file names. result.push_back("-Dfile.encoding=ISO-8859-1"); - if (globals->options->host_jvm_debug) { + if (globals->options.host_jvm_debug) { fprintf(stderr, "Running host JVM under debugger (listening on TCP port 5005).\n"); // Start JVM so that it listens for a connection from a @@ -476,51 +473,51 @@ static vector GetArgumentArray() { } result.insert(result.end(), user_options.begin(), user_options.end()); - globals->options->AddJVMArgumentSuffix(real_install_dir, + globals->options.AddJVMArgumentSuffix(real_install_dir, globals->extracted_binaries[0], &result); // JVM arguments are complete. Now pass in Blaze startup flags. - if (!globals->options->batch) { + if (!globals->options.batch) { result.push_back("--max_idle_secs"); - result.push_back(ToString(globals->options->max_idle_secs)); + result.push_back(ToString(globals->options.max_idle_secs)); } else { // --batch must come first in the arguments to Java main() because // the code expects it to be at args[0] if it's been set. result.push_back("--batch"); } - if (globals->options->command_port != 0) { + if (globals->options.command_port != 0) { result.push_back( - "--command_port=" + ToString(globals->options->command_port)); + "--command_port=" + ToString(globals->options.command_port)); } result.push_back("--install_base=" + - blaze::ConvertPath(globals->options->install_base)); + blaze::ConvertPath(globals->options.install_base)); result.push_back("--install_md5=" + globals->install_md5); result.push_back("--output_base=" + - blaze::ConvertPath(globals->options->output_base)); + blaze::ConvertPath(globals->options.output_base)); result.push_back("--workspace_directory=" + blaze::ConvertPath(globals->workspace)); - if (globals->options->allow_configurable_attributes) { + if (globals->options.allow_configurable_attributes) { result.push_back("--allow_configurable_attributes"); } - if (globals->options->deep_execroot) { + if (globals->options.deep_execroot) { result.push_back("--deep_execroot"); } else { result.push_back("--nodeep_execroot"); } - if (globals->options->oom_more_eagerly) { + if (globals->options.oom_more_eagerly) { result.push_back("--experimental_oom_more_eagerly"); } result.push_back("--experimental_oom_more_eagerly_threshold=" + - ToString(globals->options->oom_more_eagerly_threshold)); + ToString(globals->options.oom_more_eagerly_threshold)); - if (globals->options->watchfs) { + if (globals->options.watchfs) { result.push_back("--watchfs"); } - if (globals->options->fatal_event_bus_exceptions) { + if (globals->options.fatal_event_bus_exceptions) { result.push_back("--fatal_event_bus_exceptions"); } else { result.push_back("--nofatal_event_bus_exceptions"); @@ -528,34 +525,33 @@ static vector GetArgumentArray() { // This is only for Blaze reporting purposes; the real interpretation of the // jvm flags occurs when we set up the java command line. - if (globals->options->host_jvm_debug) { + if (globals->options.host_jvm_debug) { result.push_back("--host_jvm_debug"); } - if (!globals->options->host_jvm_profile.empty()) { - result.push_back("--host_jvm_profile=" + - globals->options->host_jvm_profile); + if (!globals->options.host_jvm_profile.empty()) { + result.push_back("--host_jvm_profile=" + globals->options.host_jvm_profile); } - if (!globals->options->host_jvm_args.empty()) { - for (const auto &arg : globals->options->host_jvm_args) { + if (!globals->options.host_jvm_args.empty()) { + for (const auto &arg : globals->options.host_jvm_args) { result.push_back("--host_jvm_args=" + arg); } } - if (globals->options->invocation_policy != NULL && - strlen(globals->options->invocation_policy) > 0) { + if (globals->options.invocation_policy != NULL && + strlen(globals->options.invocation_policy) > 0) { result.push_back(string("--invocation_policy=") + - globals->options->invocation_policy); + globals->options.invocation_policy); } - result.push_back("--product_name=" + globals->options->product_name); + result.push_back("--product_name=" + globals->options.product_name); - globals->options->AddExtraOptions(&result); + globals->options.AddExtraOptions(&result); // The option sources are transmitted in the following format: // --option_sources=option1:source1:option2:source2:... string option_sources = "--option_sources="; first = true; - for (const auto& it : globals->options->option_sources) { + for (const auto& it : globals->options.option_sources) { if (!first) { option_sources += ":"; } @@ -611,11 +607,10 @@ static void GoToWorkspace() { // Check the java version if a java version specification is bundled. On // success, returns the executable path of the java command. static void VerifyJavaVersionAndSetJvm() { - string exe = globals->options->GetJvm(); + string exe = globals->options.GetJvm(); string version_spec_file = blaze_util::JoinPath( - blaze_util::JoinPath(globals->options->install_base, - "_embedded_binaries"), + blaze_util::JoinPath(globals->options.install_base, "_embedded_binaries"), "java.version"); string version_spec = ""; if (ReadFile(version_spec_file, &version_spec)) { @@ -644,7 +639,7 @@ static void VerifyJavaVersionAndSetJvm() { static void StartServer(BlazeServerStartup** server_startup) { vector jvm_args_vector = GetArgumentArray(); string argument_string = GetArgumentString(jvm_args_vector); - string server_dir = globals->options->output_base + "/server"; + string server_dir = globals->options.output_base + "/server"; // Write the cmdline argument string to the server dir. If we get to this // point, there is no server running, so we don't overwrite the cmdline file // for the existing server. If might be that the server dies and the cmdline @@ -657,8 +652,8 @@ static void StartServer(BlazeServerStartup** server_startup) { globals->restart_reason = NO_DAEMON; } - string exe = globals->options->GetExe(globals->jvm_path, - globals->extracted_binaries[0]); + string exe = globals->options.GetExe(globals->jvm_path, + globals->extracted_binaries[0]); // Go to the workspace before we daemonize, so // we can still print errors to the terminal. GoToWorkspace(); @@ -682,22 +677,22 @@ static void StartStandalone(BlazeServer* server) { if (VerboseLogging()) { fprintf(stderr, "Starting %s in batch mode.\n", - globals->options->product_name.c_str()); + globals->options.product_name.c_str()); } - string command = globals->option_processor->GetCommand(); + string command = globals->option_processor.GetCommand(); vector command_arguments; - globals->option_processor->GetCommandArguments(&command_arguments); + globals->option_processor.GetCommandArguments(&command_arguments); if (!command_arguments.empty() && command == "shutdown") { - string product = globals->options->product_name; + string product = globals->options.product_name; blaze_util::ToLower(&product); fprintf(stderr, "WARNING: Running command \"shutdown\" in batch mode. Batch mode " "is triggered\nwhen not running %s within a workspace. If you " "intend to shutdown an\nexisting %s server, run \"%s " "shutdown\" from the directory where\nit was started.\n", - globals->options->product_name.c_str(), - globals->options->product_name.c_str(), product.c_str()); + globals->options.product_name.c_str(), + globals->options.product_name.c_str(), product.c_str()); } vector jvm_args_vector = GetArgumentArray(); if (command != "") { @@ -711,7 +706,7 @@ static void StartStandalone(BlazeServer* server) { GoToWorkspace(); - string exe = globals->options->GetExe(globals->jvm_path, + string exe = globals->options.GetExe(globals->jvm_path, globals->extracted_binaries[0]); ExecuteProgram(exe, jvm_args_vector); pdie(blaze_exit_code::INTERNAL_ERROR, "execv of '%s' failed", exe.c_str()); @@ -741,7 +736,7 @@ bool AfUnixBlazeServer::Connect() { struct sockaddr_un addr; addr.sun_family = AF_UNIX; - string socket_file = globals->options->output_base + "/server/server.socket"; + string socket_file = globals->options.output_base + "/server/server.socket"; char *resolved_path = realpath(socket_file.c_str(), NULL); if (resolved_path != NULL) { strncpy(addr.sun_path, resolved_path, sizeof addr.sun_path); @@ -751,7 +746,7 @@ bool AfUnixBlazeServer::Connect() { int result = connect(server_socket_, paddr, sizeof addr); connected_ = result == 0; if (connected_) { - string server_dir = globals->options->output_base + "/server"; + string server_dir = globals->options.output_base + "/server"; globals->server_pid = GetServerPid(server_dir); if (globals->server_pid <= 0) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, @@ -784,7 +779,7 @@ static int ServerEof() { // or a JVM crash. Print out the jvm.out file in case there's something // useful. fprintf(stderr, "Error: unexpected EOF from %s server.\n" - "Contents of '%s':\n", globals->options->product_name.c_str(), + "Contents of '%s':\n", globals->options.product_name.c_str(), globals->jvm_log_file.c_str()); WriteFileToStreamOrDie(stderr, globals->jvm_log_file.c_str()); return GetExitCodeForAbruptExit(*globals); @@ -882,7 +877,7 @@ unsigned int AfUnixBlazeServer::Communicate() { // the socket (the read will usually block). fprintf(stderr, "INFO: Waiting for response from %s server (pid %d)...\n", - globals->options->product_name.c_str(), globals->server_pid); + globals->options.product_name.c_str(), globals->server_pid); break; } else { // result < 0 // Error. For EINTR we try again, all other errors are fatal. @@ -1010,7 +1005,7 @@ static int GetServerPid(const string &server_dir) { // Starts up a new server and connects to it. Exits if it didn't work not. static void StartServerAndConnect(BlazeServer *server) { - string server_dir = globals->options->output_base + "/server"; + string server_dir = globals->options.output_base + "/server"; // The server dir has the socket, so we don't allow access by other // users. @@ -1028,15 +1023,15 @@ static void StartServerAndConnect(BlazeServer *server) { // disaster. int server_pid = GetServerPid(server_dir); if (server_pid > 0) { - if (KillServerProcess(server_pid, globals->options->output_base, - globals->options->install_base)) { + if (KillServerProcess(server_pid, globals->options.output_base, + globals->options.install_base)) { fprintf(stderr, "Killed non-responsive server process (pid=%d)\n", server_pid); } } - SetScheduling(globals->options->batch_cpu_scheduling, - globals->options->io_nice_level); + SetScheduling(globals->options.batch_cpu_scheduling, + globals->options.io_nice_level); BlazeServerStartup* server_startup; StartServer(&server_startup); @@ -1091,7 +1086,7 @@ void AfUnixBlazeServer::KillRunningServer() { close(server_socket_); server_socket_ = -1; fprintf(stderr, "Sending SIGTERM to previous %s server (pid=%d)... ", - globals->options->product_name.c_str(), globals->server_pid); + globals->options.product_name.c_str(), globals->server_pid); fflush(stderr); kill(globals->server_pid, SIGTERM); if (WaitForServerDeath(globals->server_pid, 10)) { @@ -1103,7 +1098,7 @@ void AfUnixBlazeServer::KillRunningServer() { // If the previous attempt did not suceeded, kill the whole group. fprintf(stderr, "Sending SIGKILL to previous %s server process group (pid=%d)... ", - globals->options->product_name.c_str(), globals->server_pid); + globals->options.product_name.c_str(), globals->server_pid); fflush(stderr); killpg(globals->server_pid, SIGKILL); if (WaitForServerDeath(globals->server_pid, 10)) { @@ -1219,18 +1214,18 @@ static void ActuallyExtractData(const string &argv0, } fprintf(stderr, "Extracting %s installation...\n", - globals->options->product_name.c_str()); + globals->options.product_name.c_str()); std::unique_ptr extractor( devtools_ijar::ZipExtractor::Create(argv0.c_str(), &processor)); if (extractor.get() == NULL) { die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "\nFailed to open %s as a zip file: (%d) %s", - globals->options->product_name.c_str(), errno, strerror(errno)); + globals->options.product_name.c_str(), errno, strerror(errno)); } if (extractor->ProcessAll() < 0) { die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "\nFailed to extract %s as a zip file: %s", - globals->options->product_name.c_str(), extractor->GetError()); + globals->options.product_name.c_str(), extractor->GetError()); } const time_t TEN_YEARS_IN_SEC = 3600 * 24 * 365 * 10; @@ -1293,10 +1288,10 @@ static void ActuallyExtractData(const string &argv0, static void ExtractData(const string &self_path) { // If the install dir doesn't exist, create it, if it does, we know it's good. struct stat buf; - if (stat(globals->options->install_base.c_str(), &buf) == -1) { + if (stat(globals->options.install_base.c_str(), &buf) == -1) { uint64_t st = MonotonicClock(); // Work in a temp dir to avoid races. - string tmp_install = globals->options->install_base + ".tmp." + + string tmp_install = globals->options.install_base + ".tmp." + ToString(getpid()); string tmp_binaries = tmp_install + "/_embedded_binaries"; ActuallyExtractData(self_path, tmp_binaries); @@ -1307,7 +1302,7 @@ static void ExtractData(const string &self_path) { // Now rename the completed installation to its final name. If this // fails due to an ENOTEMPTY then we assume another good // installation snuck in before us. - if (rename(tmp_install.c_str(), globals->options->install_base.c_str()) == -1 + if (rename(tmp_install.c_str(), globals->options.install_base.c_str()) == -1 && errno != ENOTEMPTY) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "install base directory '%s' could not be renamed into place", @@ -1318,12 +1313,12 @@ static void ExtractData(const string &self_path) { die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "Error: Install base directory '%s' could not be created. " "It exists but is not a directory.", - globals->options->install_base.c_str()); + globals->options.install_base.c_str()); } const time_t time_now = time(NULL); string real_install_dir = blaze_util::JoinPath( - globals->options->install_base, + globals->options.install_base, "_embedded_binaries"); for (const auto& it : globals->extracted_binaries) { string path = blaze_util::JoinPath(real_install_dir, it); @@ -1332,7 +1327,7 @@ static void ExtractData(const string &self_path) { die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "Error: corrupt installation: file '%s' missing." " Please remove '%s' and try again.", - path.c_str(), globals->options->install_base.c_str()); + path.c_str(), globals->options.install_base.c_str()); } // Check that the timestamp is in the future. A past timestamp would indicate // that the file has been tampered with. See ActuallyExtractData(). @@ -1340,7 +1335,7 @@ static void ExtractData(const string &self_path) { die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "Error: corrupt installation: file '%s' " "modified. Please remove '%s' and try again.", - path.c_str(), globals->options->install_base.c_str()); + path.c_str(), globals->options.install_base.c_str()); } } } @@ -1385,7 +1380,7 @@ static void KillRunningServerIfDifferentStartupOptions(BlazeServer* server) { return; } - string cmdline_path = globals->options->output_base + "/server/cmdline"; + string cmdline_path = globals->options.output_base + "/server/cmdline"; string joined_arguments; // No, /proc/$PID/cmdline does not work, because it is limited to 4K. Even @@ -1403,7 +1398,7 @@ static void KillRunningServerIfDifferentStartupOptions(BlazeServer* server) { fprintf(stderr, "WARNING: Running %s server needs to be killed, because the " "startup options are different.\n", - globals->options->product_name.c_str()); + globals->options.product_name.c_str()); server->KillRunningServer(); } } @@ -1418,18 +1413,18 @@ static void EnsureCorrectRunningVersion(BlazeServer* server) { // target dirs don't match, or if the symlink was not present, then kill any // running servers. Lastly, symlink to our installation so others know which // installation is running. - string installation_path = globals->options->output_base + "/install"; + string installation_path = globals->options.output_base + "/install"; string prev_installation; bool ok = ReadDirectorySymlink(installation_path.c_str(), &prev_installation); if (!ok || !CompareAbsolutePaths( - prev_installation, globals->options->install_base)) { + prev_installation, globals->options.install_base)) { if (server->Connected()) { server->KillRunningServer(); } globals->restart_reason = NEW_VERSION; UnlinkPath(installation_path.c_str()); - if (!SymlinkDirectories(globals->options->install_base.c_str(), + if (!SymlinkDirectories(globals->options.install_base.c_str(), installation_path.c_str())) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "failed to create installation symlink '%s'", @@ -1437,10 +1432,10 @@ static void EnsureCorrectRunningVersion(BlazeServer* server) { } const time_t time_now = time(NULL); struct utimbuf times = { time_now, time_now }; - if (utime(globals->options->install_base.c_str(), ×) == -1) { + if (utime(globals->options.install_base.c_str(), ×) == -1) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "failed to set timestamp on '%s'", - globals->options->install_base.c_str()); + globals->options.install_base.c_str()); } } } @@ -1451,20 +1446,20 @@ static void handler(int signum) { case SIGINT: if (++globals->sigint_count >= 3) { sigprintf("\n%s caught third interrupt signal; killed.\n\n", - globals->options->product_name.c_str()); + globals->options.product_name.c_str()); if (globals->server_pid != -1) { - KillServerProcess(globals->server_pid, globals->options->output_base, - globals->options->install_base); + KillServerProcess(globals->server_pid, globals->options.output_base, + globals->options.install_base); } _exit(1); } sigprintf("\n%s caught interrupt signal; shutting down.\n\n", - globals->options->product_name.c_str()); + globals->options.product_name.c_str()); blaze_server->Cancel(); break; case SIGTERM: sigprintf("\n%s caught terminate signal; shutting down.\n\n", - globals->options->product_name.c_str()); + globals->options.product_name.c_str()); blaze_server->Cancel(); break; case SIGPIPE: @@ -1485,13 +1480,13 @@ static void handler(int signum) { // Constructs the command line for a server request. static string BuildServerRequest() { vector arg_vector; - string command = globals->option_processor->GetCommand(); + string command = globals->option_processor.GetCommand(); if (command != "") { arg_vector.push_back(command); AddLoggingArgs(&arg_vector); } - globals->option_processor->GetCommandArguments(&arg_vector); + globals->option_processor.GetCommandArguments(&arg_vector); string request("blaze"); for (vector::iterator it = arg_vector.begin(); @@ -1574,12 +1569,12 @@ static ATTRIBUTE_NORETURN void SendServerRequest(BlazeServer* server) { static void ParseOptions(int argc, const char *argv[]) { string error; blaze_exit_code::ExitCode parse_exit_code = - globals->option_processor->ParseOptions(argc, argv, globals->workspace, - globals->cwd, &error); + globals->option_processor.ParseOptions(argc, argv, globals->workspace, + globals->cwd, &error); if (parse_exit_code != blaze_exit_code::SUCCESS) { die(parse_exit_code, "%s", error.c_str()); } - globals->options = globals->option_processor->GetParsedStartupOptions(); + globals->options = globals->option_processor.GetParsedStartupOptions(); } // Returns the canonical form of a path. @@ -1606,21 +1601,21 @@ static void ComputeWorkspace() { } // Figure out the base directories based on embedded data, username, cwd, etc. -// Sets globals->options->install_base, globals->options->output_base, +// Sets globals->options.install_base, globals->options.output_base, // globals->lockfile, globals->jvm_log_file. static void ComputeBaseDirectories(const string &self_path) { // Only start a server when in a workspace because otherwise we won't do more // than emit a help message. if (!WorkspaceLayout::InWorkspace(globals->workspace)) { - globals->options->batch = true; + globals->options.batch = true; } // The default install_base is /install/ // but if an install_base is specified on the command line, we use that as // the base instead. - if (globals->options->install_base.empty()) { - string install_user_root = globals->options->output_user_root + "/install"; - globals->options->install_base = + if (globals->options.install_base.empty()) { + string install_user_root = globals->options.output_user_root + "/install"; + globals->options.install_base = GetInstallBase(install_user_root, self_path); } else { // We call GetInstallBase anyway to populate extracted_binaries and @@ -1628,21 +1623,21 @@ static void ComputeBaseDirectories(const string &self_path) { GetInstallBase("", self_path); } - if (globals->options->output_base.empty()) { + if (globals->options.output_base.empty()) { #if !defined(__CYGWIN__) - globals->options->output_base = GetHashedBaseDir( - globals->options->output_user_root, globals->workspace); + globals->options.output_base = GetHashedBaseDir( + globals->options.output_user_root, globals->workspace); #else - globals->options->output_base = GetHashedBaseDirForWindows( - blaze::GetOutputRoot(), globals->options->product_name, + globals->options.output_base = GetHashedBaseDirForWindows( + blaze::GetOutputRoot(), globals->options.product_name, blaze::GetUserName(), globals->workspace); #endif } struct stat buf; - const char *output_base = globals->options->output_base.c_str(); + const char *output_base = globals->options.output_base.c_str(); if (stat(output_base, &buf) == -1) { - if (MakeDirectories(globals->options->output_base, 0777) == -1) { + if (MakeDirectories(globals->options.output_base, 0777) == -1) { pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR, "Output base directory '%s' could not be created", output_base); @@ -1662,9 +1657,9 @@ static void ComputeBaseDirectories(const string &self_path) { } ExcludePathFromBackup(output_base); - globals->options->output_base = MakeCanonical(output_base); - globals->lockfile = globals->options->output_base + "/lock"; - globals->jvm_log_file = globals->options->output_base + "/server/jvm.out"; + globals->options.output_base = MakeCanonical(output_base); + globals->lockfile = globals->options.output_base + "/lock"; + globals->jvm_log_file = globals->options.output_base + "/server/jvm.out"; } static void CheckEnvironment() { @@ -1690,7 +1685,7 @@ static void CheckEnvironment() { if (getenv("TEST_TMPDIR") != NULL) { fprintf(stderr, "INFO: $TEST_TMPDIR defined: output root default is " - "'%s'.\n", globals->options->output_root.c_str()); + "'%s'.\n", globals->options.output_root.c_str()); } // TODO(bazel-team): We've also seen a failure during loading (creating @@ -1739,7 +1734,7 @@ static void CheckBinaryPath(const string& argv0) { // Typically, this happens inside a temp directory, so we have to be // careful about symlink attacks. static void CreateSecureOutputRoot() { - const char* root = globals->options->output_user_root.c_str(); + const char* root = globals->options.output_user_root.c_str(); struct stat fileinfo = {}; if (MakeDirectories(root, 0755) == -1) { @@ -1783,8 +1778,8 @@ static void CreateSecureOutputRoot() { // code to a file. In case the server becomes unresonsive or terminates // unexpectedly (in a way that isn't already handled), we can observe the file, // if it exists. (If it doesn't, then we know something went horribly wrong.) -int Main(int argc, const char *argv[], OptionProcessor *option_processor) { - InitGlobals(option_processor); +int main(int argc, const char *argv[]) { + InitGlobals(); SetupStreams(); // Must be done before command line parsing. @@ -1793,15 +1788,15 @@ int Main(int argc, const char *argv[], OptionProcessor *option_processor) { ParseOptions(argc, argv); #ifdef __CYGWIN__ - if (globals->options->command_port == -1) { + if (globals->options.command_port == -1) { // AF_UNIX does not work on Windows, so use gRPC instead. - globals->options->command_port = 0; + globals->options.command_port = 0; } #endif string error; blaze_exit_code::ExitCode reexec_options_exit_code = - globals->options->CheckForReExecuteOptions(argc, argv, &error); + globals->options.CheckForReExecuteOptions(argc, argv, &error); if (reexec_options_exit_code != blaze_exit_code::SUCCESS) { die(reexec_options_exit_code, "%s", error.c_str()); } @@ -1811,13 +1806,13 @@ int Main(int argc, const char *argv[], OptionProcessor *option_processor) { const string self_path = GetSelfPath(); ComputeBaseDirectories(self_path); - blaze_server = globals->options->command_port >= 0 + blaze_server = globals->options.command_port >= 0 ? static_cast(new GrpcBlazeServer()) : static_cast(new AfUnixBlazeServer()); globals->command_wait_time = blaze_server->AcquireLock(); - WarnFilesystemType(globals->options->output_base); + WarnFilesystemType(globals->options.output_base); ExtractData(self_path); VerifyJavaVersionAndSetJvm(); @@ -1826,9 +1821,9 @@ int Main(int argc, const char *argv[], OptionProcessor *option_processor) { EnsureCorrectRunningVersion(blaze_server); KillRunningServerIfDifferentStartupOptions(blaze_server); - if (globals->options->batch) { - SetScheduling(globals->options->batch_cpu_scheduling, - globals->options->io_nice_level); + if (globals->options.batch) { + SetScheduling(globals->options.batch_cpu_scheduling, + globals->options.io_nice_level); StartStandalone(blaze_server); } else { SendServerRequest(blaze_server); @@ -1869,7 +1864,7 @@ GrpcBlazeServer::~GrpcBlazeServer() { bool GrpcBlazeServer::Connect() { assert(!connected_); - std::string server_dir = globals->options->output_base + "/server"; + std::string server_dir = globals->options.output_base + "/server"; std::string port; std::string ipv4_prefix = "127.0.0.1:"; std::string ipv6_prefix_1 = "[0:0:0:0:0:0:0:1]:"; @@ -2023,7 +2018,7 @@ void GrpcBlazeServer::KillRunningServer() { command_server::RunRequest request; command_server::RunResponse response; request.set_cookie(request_cookie_); - request.set_block_for_lock(globals->options->block_for_lock); + request.set_block_for_lock(globals->options.block_for_lock); request.set_client_description( "pid=" + ToString(getpid()) + " (for shutdown)"); request.add_arg("shutdown"); @@ -2033,8 +2028,8 @@ void GrpcBlazeServer::KillRunningServer() { while (reader->Read(&response)) {} // Kill the server process for good measure. - KillServerProcess(globals->server_pid, globals->options->output_base, - globals->options->install_base); + KillServerProcess(globals->server_pid, globals->options.output_base, + globals->options.install_base); connected_ = false; } @@ -2043,17 +2038,17 @@ unsigned int GrpcBlazeServer::Communicate() { assert(connected_); vector arg_vector; - string command = globals->option_processor->GetCommand(); + string command = globals->option_processor.GetCommand(); if (command != "") { arg_vector.push_back(command); AddLoggingArgs(&arg_vector); } - globals->option_processor->GetCommandArguments(&arg_vector); + globals->option_processor.GetCommandArguments(&arg_vector); command_server::RunRequest request; request.set_cookie(request_cookie_); - request.set_block_for_lock(globals->options->block_for_lock); + request.set_block_for_lock(globals->options.block_for_lock); request.set_client_description("pid=" + ToString(getpid())); for (const string& arg : arg_vector) { request.add_arg(arg); @@ -2132,3 +2127,7 @@ void GrpcBlazeServer::Cancel() { } } // namespace blaze + +int main(int argc, const char *argv[]) { + return blaze::main(argc, argv); +} diff --git a/src/main/cpp/blaze.h b/src/main/cpp/blaze.h deleted file mode 100644 index 25f484e34f..0000000000 --- a/src/main/cpp/blaze.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef BAZEL_SRC_MAIN_CPP_BLAZE_H_ -#define BAZEL_SRC_MAIN_CPP_BLAZE_H_ - -#include "src/main/cpp/option_processor.h" - -namespace blaze { - -int Main(int argc, const char *argv[], OptionProcessor* option_processor); - -} // namespace blaze - -#endif // BAZEL_SRC_MAIN_CPP_BLAZE_H_ diff --git a/src/main/cpp/blaze_globals.h b/src/main/cpp/blaze_globals.h index eba73b00d0..4b80b49c30 100644 --- a/src/main/cpp/blaze_globals.h +++ b/src/main/cpp/blaze_globals.h @@ -23,8 +23,8 @@ #include #include +#include "src/main/cpp/blaze_startup_options.h" #include "src/main/cpp/option_processor.h" -#include "src/main/cpp/startup_options.h" using std::vector; @@ -53,7 +53,7 @@ struct GlobalVariables { // Option processor responsible for parsing RC files and converting them into // the argument list passed on to the server. - OptionProcessor *option_processor; + OptionProcessor option_processor; // The path of the JVM executable that should be used to launch Blaze. string jvm_path; @@ -72,7 +72,7 @@ struct GlobalVariables { vector extracted_binaries; // Parsed startup options. - StartupOptions *options; // TODO(jmmv): This should really be const. + BlazeStartupOptions options; // The time in ms the launcher spends before sending the request to the blaze // server. diff --git a/src/main/cpp/blaze_startup_options.cc b/src/main/cpp/blaze_startup_options.cc new file mode 100644 index 0000000000..01cdb5d999 --- /dev/null +++ b/src/main/cpp/blaze_startup_options.cc @@ -0,0 +1,163 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "src/main/cpp/blaze_startup_options.h" + +#include +#include // errno, ENOENT +#include // getenv, exit +#include // strerror +#include // access + +#include + +#include "src/main/cpp/blaze_util_platform.h" +#include "src/main/cpp/blaze_util.h" +#include "src/main/cpp/util/exit_code.h" +#include "src/main/cpp/util/file.h" +#include "src/main/cpp/util/strings.h" + +namespace blaze { + +using std::vector; + +struct StartupOptions {}; + +BlazeStartupOptions::BlazeStartupOptions() { + Init(); +} + +BlazeStartupOptions::BlazeStartupOptions(const BlazeStartupOptions &rhs) + : product_name(rhs.product_name), + output_base(rhs.output_base), + install_base(rhs.install_base), + output_root(rhs.output_root), + output_user_root(rhs.output_user_root), + deep_execroot(rhs.deep_execroot), + block_for_lock(rhs.block_for_lock), + host_jvm_debug(rhs.host_jvm_debug), + host_jvm_profile(rhs.host_jvm_profile), + host_jvm_args(rhs.host_jvm_args), + batch(rhs.batch), + batch_cpu_scheduling(rhs.batch_cpu_scheduling), + io_nice_level(rhs.io_nice_level), + max_idle_secs(rhs.max_idle_secs), + oom_more_eagerly(rhs.oom_more_eagerly), + oom_more_eagerly_threshold(rhs.oom_more_eagerly_threshold), + watchfs(rhs.watchfs), + allow_configurable_attributes(rhs.allow_configurable_attributes), + option_sources(rhs.option_sources), + command_port(rhs.command_port), + invocation_policy(rhs.invocation_policy), + host_javabase(rhs.host_javabase) {} + +BlazeStartupOptions::~BlazeStartupOptions() { +} + +BlazeStartupOptions& BlazeStartupOptions::operator=( + const BlazeStartupOptions &rhs) { + Copy(rhs, this); + return *this; +} + +string BlazeStartupOptions::GetOutputRoot() { + return blaze::GetOutputRoot(); +} + +void BlazeStartupOptions::AddExtraOptions(vector *result) const {} + +blaze_exit_code::ExitCode BlazeStartupOptions::ProcessArgExtra( + const char *arg, const char *next_arg, const string &rcfile, + const char **value, bool *is_processed, string *error) { + *is_processed = false; + return blaze_exit_code::SUCCESS; +} + +blaze_exit_code::ExitCode BlazeStartupOptions::CheckForReExecuteOptions( + int argc, const char *argv[], string *error) { + return blaze_exit_code::SUCCESS; +} + +string BlazeStartupOptions::GetDefaultHostJavabase() const { + return blaze::GetDefaultHostJavabase(); +} + +string BlazeStartupOptions::GetJvm() { + string java_program = GetHostJavabase() + "/bin/java"; + if (access(java_program.c_str(), X_OK) == -1) { + if (errno == ENOENT) { + fprintf(stderr, "Couldn't find java at '%s'.\n", java_program.c_str()); + } else { + fprintf(stderr, "Couldn't access %s: %s\n", java_program.c_str(), + strerror(errno)); + } + exit(1); + } + // If the full JDK is installed + string jdk_rt_jar = GetHostJavabase() + "/jre/lib/rt.jar"; + // If just the JRE is installed + string jre_rt_jar = GetHostJavabase() + "/lib/rt.jar"; + if ((access(jdk_rt_jar.c_str(), R_OK) == 0) + || (access(jre_rt_jar.c_str(), R_OK) == 0)) { + return java_program; + } + fprintf(stderr, "Problem with java installation: " + "couldn't find/access rt.jar in %s\n", GetHostJavabase().c_str()); + exit(1); +} + +string BlazeStartupOptions::GetExe(const string &jvm, const string &jar_path) { + return jvm; +} + +void BlazeStartupOptions::AddJVMArgumentPrefix(const string &javabase, + std::vector *result) const { +} + +void BlazeStartupOptions::AddJVMArgumentSuffix(const string &real_install_dir, + const string &jar_path, + std::vector *result) const { + result->push_back("-jar"); + result->push_back(blaze::ConvertPath( + blaze_util::JoinPath(real_install_dir, jar_path))); +} + +blaze_exit_code::ExitCode BlazeStartupOptions::AddJVMArguments( + const string &host_javabase, vector *result, + const vector &user_options, string *error) const { + // Configure logging + const string propFile = output_base + "/javalog.properties"; + if (!WriteFile( + "handlers=java.util.logging.FileHandler\n" + ".level=INFO\n" + "java.util.logging.FileHandler.level=INFO\n" + "java.util.logging.FileHandler.pattern=" + + output_base + "/java.log\n" + "java.util.logging.FileHandler.limit=50000\n" + "java.util.logging.FileHandler.count=1\n" + "java.util.logging.FileHandler.formatter=" + "java.util.logging.SimpleFormatter\n", + propFile)) { + perror(("Couldn't write logging file " + propFile).c_str()); + } else { + result->push_back("-Djava.util.logging.config.file=" + propFile); + } + return blaze_exit_code::SUCCESS; +} + +blaze_exit_code::ExitCode BlazeStartupOptions::ValidateStartupOptions( + const std::vector& args, string* error) { + return blaze_exit_code::SUCCESS; +} + +} // namespace blaze diff --git a/src/main/cpp/blaze_startup_options.h b/src/main/cpp/blaze_startup_options.h new file mode 100644 index 0000000000..17982abd17 --- /dev/null +++ b/src/main/cpp/blaze_startup_options.h @@ -0,0 +1,219 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef BAZEL_SRC_MAIN_CPP_BLAZE_STARTUP_OPTIONS_H_ +#define BAZEL_SRC_MAIN_CPP_BLAZE_STARTUP_OPTIONS_H_ + +#include +#include +#include +#include + +#include "src/main/cpp/util/exit_code.h" + +namespace blaze { + +using std::string; + +struct StartupOptions; + +// This class holds the parsed startup options for Blaze. +// These options and their defaults must be kept in sync with those in +// src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java. +// The latter are purely decorative (they affect the help message, +// which displays the defaults). The actual defaults are defined +// in the constructor. +// +// TODO(bazel-team): The encapsulation is not quite right -- there are some +// places in blaze.cc where some of these fields are explicitly modified. Their +// names also don't conform to the style guide. +class BlazeStartupOptions { + public: + BlazeStartupOptions(); + BlazeStartupOptions(const BlazeStartupOptions &rhs); + ~BlazeStartupOptions(); + BlazeStartupOptions& operator=(const BlazeStartupOptions &rhs); + + // Parses a single argument, either from the command line or from the .blazerc + // "startup" options. + // + // rcfile should be an empty string if the option being parsed does not come + // from a blazerc. + // + // Sets "is_space_separated" true if arg is unary and uses the "--foo bar" + // style, so its value is in next_arg. + // + // Sets "is_space_separated" false if arg is either nullary + // (e.g. "--[no]batch") or is unary but uses the "--foo=bar" style. + // + // Returns the exit code after processing the argument. "error" will contain + // a descriptive string for any return value other than + // blaze_exit_code::SUCCESS. + blaze_exit_code::ExitCode ProcessArg( + const string &arg, const string &next_arg, const string &rcfile, + bool *is_space_separated, string *error); + + // Adds any other options needed to result. + void AddExtraOptions(std::vector *result) const; + + // Checks if Blaze needs to be re-executed. Does not return, if so. + // + // Returns the exit code after the check. "error" will contain a descriptive + // string for any return value other than blaze_exit_code::SUCCESS. + blaze_exit_code::ExitCode CheckForReExecuteOptions( + int argc, const char *argv[], string *error); + + // Checks extra fields when processing arg. + // + // Returns the exit code after processing the argument. "error" will contain + // a descriptive string for any return value other than + // blaze_exit_code::SUCCESS. + blaze_exit_code::ExitCode ProcessArgExtra( + const char *arg, const char *next_arg, const string &rcfile, + const char **value, bool *is_processed, string *error); + + // Return the default path to the JDK used to run Blaze itself + // (must be an absolute directory). + string GetDefaultHostJavabase() const; + + // Returns the path to the JVM. This should be called after parsing + // the startup options. + string GetJvm(); + + // Returns the executable used to start the Blaze server, typically the given + // JVM. + string GetExe(const string &jvm, const string &jar_path); + + // Adds JVM prefix flags to be set. These will be added before all other + // JVM flags. + void AddJVMArgumentPrefix(const string &javabase, + std::vector *result) const; + + // Adds JVM suffix flags. These will be added after all other JVM flags, and + // just before the Blaze server startup flags. + void AddJVMArgumentSuffix(const string &real_install_dir, + const string &jar_path, std::vector *result) const; + + // Adds JVM tuning flags for Blaze. + // + // Returns the exit code after this operation. "error" will be set to a + // descriptive string for any value other than blaze_exit_code::SUCCESS. + blaze_exit_code::ExitCode AddJVMArguments( + const string &host_javabase, std::vector *result, + const std::vector &user_options, string *error) const; + + // The capitalized name of this binary. + string product_name; + + // Blaze's output base. Everything is relative to this. See + // the BlazeDirectories Java class for details. + string output_base; + + // Installation base for a specific release installation. + string install_base; + + // The toplevel directory containing Blaze's output. When Blaze is + // run by a test, we use TEST_TMPDIR, simplifying the correct + // hermetic invocation of Blaze from tests. + string output_root; + + // Blaze's output_user_root. Used only for computing install_base and + // output_base. + string output_user_root; + + // Whether to put the execroot at $OUTPUT_BASE/$WORKSPACE_NAME (if false) or + // $OUTPUT_BASE/execroot/$WORKSPACE_NAME (if true). + bool deep_execroot; + + // Block for the Blaze server lock. Otherwise, + // quit with non-0 exit code if lock can't + // be acquired immediately. + bool block_for_lock; + + bool host_jvm_debug; + + string host_jvm_profile; + + std::vector host_jvm_args; + + bool batch; + + // From the man page: "This policy is useful for workloads that are + // non-interactive, but do not want to lower their nice value, and for + // workloads that want a deterministic scheduling policy without + // interactivity causing extra preemptions (between the workload's tasks)." + bool batch_cpu_scheduling; + + // If negative, don't mess with ionice. Otherwise, set a level from 0-7 + // for best-effort scheduling. 0 is highest priority, 7 is lowest. + int io_nice_level; + + int max_idle_secs; + + bool oom_more_eagerly; + + int oom_more_eagerly_threshold; + + // If true, Blaze will listen to OS-level file change notifications. + bool watchfs; + + // Temporary experimental flag that permits configurable attribute syntax + // in BUILD files. This will be removed when configurable attributes is + // a more stable feature. + bool allow_configurable_attributes; + + // Temporary flag for enabling EventBus exceptions to be fatal. + bool fatal_event_bus_exceptions; + + // A string to string map specifying where each option comes from. If the + // value is empty, it was on the command line, if it is a string, it comes + // from a blazerc file, if a key is not present, it is the default. + std::map option_sources; + + // This can be used for site-specific startup options. For Bazel, this is + // stubbed + // out. + std::unique_ptr extra_options; + + // Sanity check for the startup options + static blaze_exit_code::ExitCode ValidateStartupOptions( + const std::vector& args, string* error); + + // Returns the GetHostJavabase. This should be called after parsing + // the --host_javabase option. + string GetHostJavabase(); + + // Port for gRPC command server. 0 means let the kernel choose, -1 means no + // gRPC command server. + int command_port; + + // Invocation policy proto. May be NULL. + const char* invocation_policy; + + private: + string host_javabase; + + // Sets default values for members. + void Init(); + + // Copies member variables from rhs to lhs. This cannot use the compiler- + // generated copy constructor because extra_options is a unique_ptr and + // unique_ptr deletes its copy constructor. + void Copy(const BlazeStartupOptions &rhs, BlazeStartupOptions *lhs); + + // Returns the directory to use for storing outputs. + string GetOutputRoot(); +}; + +} // namespace blaze +#endif // BAZEL_SRC_MAIN_CPP_BLAZE_STARTUP_OPTIONS_H_ diff --git a/src/main/cpp/blaze_startup_options_common.cc b/src/main/cpp/blaze_startup_options_common.cc new file mode 100644 index 0000000000..449907b4a2 --- /dev/null +++ b/src/main/cpp/blaze_startup_options_common.cc @@ -0,0 +1,284 @@ +// Copyright 2014 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "src/main/cpp/blaze_startup_options.h" + +#include +#include +#include + +#include "src/main/cpp/blaze_util.h" +#include "src/main/cpp/blaze_util_platform.h" +#include "src/main/cpp/util/exit_code.h" +#include "src/main/cpp/util/file.h" +#include "src/main/cpp/util/numbers.h" +#include "src/main/cpp/util/strings.h" + +#ifndef PRODUCT_NAME +#define PRODUCT_NAME "Bazel" +#endif + +namespace blaze { + +void BlazeStartupOptions::Init() { + bool testing = getenv("TEST_TMPDIR") != NULL; + if (testing) { + output_root = MakeAbsolute(getenv("TEST_TMPDIR")); + } else { + output_root = GetOutputRoot(); + } + + product_name = PRODUCT_NAME; + string product_name_lower = PRODUCT_NAME; + blaze_util::ToLower(&product_name_lower); + output_user_root = blaze_util::JoinPath( + output_root, "_" + product_name_lower + "_" + GetUserName()); + deep_execroot = true; + block_for_lock = true; + host_jvm_debug = false; + host_javabase = ""; + batch = false; + batch_cpu_scheduling = false; + allow_configurable_attributes = false; + fatal_event_bus_exceptions = false; + io_nice_level = -1; + // 3 hours (but only 15 seconds if used within a test) + max_idle_secs = testing ? 15 : (3 * 3600); + oom_more_eagerly_threshold = 100; + command_port = 0; + oom_more_eagerly = false; + watchfs = false; + invocation_policy = NULL; +} + +string BlazeStartupOptions::GetHostJavabase() { + if (host_javabase.empty()) { + host_javabase = GetDefaultHostJavabase(); + } + return host_javabase; +} + +void BlazeStartupOptions::Copy( + const BlazeStartupOptions &rhs, BlazeStartupOptions *lhs) { + assert(lhs); + + lhs->product_name = rhs.product_name; + lhs->output_base = rhs.output_base; + lhs->install_base = rhs.install_base; + lhs->output_root = rhs.output_root; + lhs->output_user_root = rhs.output_user_root; + lhs->deep_execroot = rhs.deep_execroot; + lhs->block_for_lock = rhs.block_for_lock; + lhs->host_jvm_debug = rhs.host_jvm_debug; + lhs->host_jvm_profile = rhs.host_jvm_profile; + lhs->host_javabase = rhs.host_javabase; + lhs->host_jvm_args = rhs.host_jvm_args; + lhs->batch = rhs.batch; + lhs->batch_cpu_scheduling = rhs.batch_cpu_scheduling; + lhs->io_nice_level = rhs.io_nice_level; + lhs->max_idle_secs = rhs.max_idle_secs; + lhs->command_port = rhs.command_port; + lhs->oom_more_eagerly = rhs.oom_more_eagerly; + lhs->oom_more_eagerly_threshold = rhs.oom_more_eagerly_threshold; + lhs->watchfs = rhs.watchfs; + lhs->allow_configurable_attributes = rhs.allow_configurable_attributes; + lhs->fatal_event_bus_exceptions = rhs.fatal_event_bus_exceptions; + lhs->option_sources = rhs.option_sources; + lhs->invocation_policy = rhs.invocation_policy; +} + +blaze_exit_code::ExitCode BlazeStartupOptions::ProcessArg( + const string &argstr, const string &next_argstr, const string &rcfile, + bool *is_space_separated, string *error) { + // We have to parse a specific option syntax, so GNU getopts won't do. All + // options begin with "--" or "-". Values are given together with the option + // delimited by '=' or in the next option. + const char* arg = argstr.c_str(); + const char* next_arg = next_argstr.empty() ? NULL : next_argstr.c_str(); + const char* value = NULL; + + if ((value = GetUnaryOption(arg, next_arg, "--output_base")) != NULL) { + output_base = MakeAbsolute(value); + option_sources["output_base"] = rcfile; + } else if ((value = GetUnaryOption(arg, next_arg, + "--install_base")) != NULL) { + install_base = MakeAbsolute(value); + option_sources["install_base"] = rcfile; + } else if ((value = GetUnaryOption(arg, next_arg, + "--output_user_root")) != NULL) { + output_user_root = MakeAbsolute(value); + option_sources["output_user_root"] = rcfile; + } else if (GetNullaryOption(arg, "--deep_execroot")) { + deep_execroot = true; + option_sources["deep_execroot"] = rcfile; + } else if (GetNullaryOption(arg, "--nodeep_execroot")) { + deep_execroot = false; + option_sources["deep_execroot"] = rcfile; + } else if (GetNullaryOption(arg, "--noblock_for_lock")) { + block_for_lock = false; + option_sources["block_for_lock"] = rcfile; + } else if (GetNullaryOption(arg, "--host_jvm_debug")) { + host_jvm_debug = true; + option_sources["host_jvm_debug"] = rcfile; + } else if ((value = GetUnaryOption(arg, next_arg, + "--host_jvm_profile")) != NULL) { + host_jvm_profile = value; + option_sources["host_jvm_profile"] = rcfile; + } else if ((value = GetUnaryOption(arg, next_arg, + "--host_javabase")) != NULL) { + // TODO(bazel-team): Consider examining the javabase and re-execing in case + // of architecture mismatch. + host_javabase = MakeAbsolute(value); + option_sources["host_javabase"] = rcfile; + } else if ((value = GetUnaryOption(arg, next_arg, "--host_jvm_args")) != + NULL) { + host_jvm_args.push_back(value); + option_sources["host_jvm_args"] = rcfile; // NB: This is incorrect + } else if ((value = GetUnaryOption(arg, next_arg, "--bazelrc")) != NULL) { + if (rcfile != "") { + *error = "Can't specify --bazelrc in the .bazelrc file."; + return blaze_exit_code::BAD_ARGV; + } + } else if ((value = GetUnaryOption(arg, next_arg, "--blazerc")) != NULL) { + if (rcfile != "") { + *error = "Can't specify --blazerc in the .blazerc file."; + return blaze_exit_code::BAD_ARGV; + } + } else if (GetNullaryOption(arg, "--nomaster_blazerc") || + GetNullaryOption(arg, "--master_blazerc")) { + if (rcfile != "") { + *error = "Can't specify --[no]master_blazerc in .blazerc file."; + return blaze_exit_code::BAD_ARGV; + } + option_sources["blazerc"] = rcfile; + } else if (GetNullaryOption(arg, "--nomaster_bazelrc") || + GetNullaryOption(arg, "--master_bazelrc")) { + if (rcfile != "") { + *error = "Can't specify --[no]master_bazelrc in .bazelrc file."; + return blaze_exit_code::BAD_ARGV; + } + option_sources["blazerc"] = rcfile; + } else if (GetNullaryOption(arg, "--batch")) { + batch = true; + option_sources["batch"] = rcfile; + } else if (GetNullaryOption(arg, "--nobatch")) { + batch = false; + option_sources["batch"] = rcfile; + } else if (GetNullaryOption(arg, "--batch_cpu_scheduling")) { + batch_cpu_scheduling = true; + option_sources["batch_cpu_scheduling"] = rcfile; + } else if (GetNullaryOption(arg, "--nobatch_cpu_scheduling")) { + batch_cpu_scheduling = false; + option_sources["batch_cpu_scheduling"] = rcfile; + } else if (GetNullaryOption(arg, "--allow_configurable_attributes")) { + allow_configurable_attributes = true; + option_sources["allow_configurable_attributes"] = rcfile; + } else if (GetNullaryOption(arg, "--noallow_configurable_attributes")) { + allow_configurable_attributes = false; + option_sources["allow_configurable_attributes"] = rcfile; + } else if (GetNullaryOption(arg, "--fatal_event_bus_exceptions")) { + fatal_event_bus_exceptions = true; + option_sources["fatal_event_bus_exceptions"] = rcfile; + } else if (GetNullaryOption(arg, "--nofatal_event_bus_exceptions")) { + fatal_event_bus_exceptions = false; + option_sources["fatal_event_bus_exceptions"] = rcfile; + } else if ((value = GetUnaryOption(arg, next_arg, + "--io_nice_level")) != NULL) { + if (!blaze_util::safe_strto32(value, &io_nice_level) || + io_nice_level > 7) { + blaze_util::StringPrintf(error, + "Invalid argument to --io_nice_level: '%s'. Must not exceed 7.", + value); + return blaze_exit_code::BAD_ARGV; + } + option_sources["io_nice_level"] = rcfile; + } else if ((value = GetUnaryOption(arg, next_arg, + "--max_idle_secs")) != NULL) { + if (!blaze_util::safe_strto32(value, &max_idle_secs) || + max_idle_secs < 0) { + blaze_util::StringPrintf(error, + "Invalid argument to --max_idle_secs: '%s'.", value); + return blaze_exit_code::BAD_ARGV; + } + option_sources["max_idle_secs"] = rcfile; + } else if (GetNullaryOption(arg, "-x")) { + fprintf(stderr, "WARNING: The -x startup option is now ignored " + "and will be removed in a future release\n"); + } else if (GetNullaryOption(arg, "--experimental_oom_more_eagerly")) { + oom_more_eagerly = true; + option_sources["experimental_oom_more_eagerly"] = rcfile; + } else if (GetNullaryOption(arg, "--noexperimental_oom_more_eagerly")) { + oom_more_eagerly = false; + option_sources["experimental_oom_more_eagerly"] = rcfile; + } else if ((value = GetUnaryOption( + arg, next_arg, + "--experimental_oom_more_eagerly_threshold")) != NULL) { + if (!blaze_util::safe_strto32(value, &oom_more_eagerly_threshold) || + oom_more_eagerly_threshold < 0) { + blaze_util::StringPrintf(error, + "Invalid argument to " + "--experimental_oom_more_eagerly_threshold: " + "'%s'.", + value); + return blaze_exit_code::BAD_ARGV; + } + option_sources["experimental_oom_more_eagerly_threshold"] = rcfile; + } else if (GetNullaryOption(arg, "--watchfs")) { + watchfs = true; + option_sources["watchfs"] = rcfile; + } else if (GetNullaryOption(arg, "--nowatchfs")) { + watchfs = false; + option_sources["watchfs"] = rcfile; + } else if ((value = GetUnaryOption( + arg, next_arg, "--command_port")) != NULL) { + if (!blaze_util::safe_strto32(value, &command_port) || + command_port < -1 || command_port > 65535) { + blaze_util::StringPrintf(error, + "Invalid argument to --command_port: '%s'. " + "Must be a valid port number or -1 to disable the gRPC server.\n", + value); + return blaze_exit_code::BAD_ARGV; + } + option_sources["webstatusserver"] = rcfile; + } else if ((value = GetUnaryOption(arg, next_arg, "--invocation_policy")) + != NULL) { + if (invocation_policy == NULL) { + invocation_policy = value; + option_sources["invocation_policy"] = rcfile; + } else { + *error = "The startup flag --invocation_policy cannot be specified " + "multiple times."; + return blaze_exit_code::BAD_ARGV; + } + } else { + bool extra_argument_processed; + blaze_exit_code::ExitCode process_extra_arg_exit_code = ProcessArgExtra( + arg, next_arg, rcfile, &value, &extra_argument_processed, error); + if (process_extra_arg_exit_code != blaze_exit_code::SUCCESS) { + return process_extra_arg_exit_code; + } + if (!extra_argument_processed) { + blaze_util::StringPrintf( + error, + "Unknown %s startup option: '%s'.\n" + " For more info, run '%s help startup_options'.", + product_name.c_str(), arg, product_name.c_str()); + return blaze_exit_code::BAD_ARGV; + } + } + + *is_space_separated = ((value == next_arg) && (value != NULL)); + return blaze_exit_code::SUCCESS; +} + +} // namespace blaze diff --git a/src/main/cpp/main.cc b/src/main/cpp/main.cc deleted file mode 100644 index c58b826661..0000000000 --- a/src/main/cpp/main.cc +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2016 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include "src/main/cpp/blaze.h" -#include "src/main/cpp/option_processor.h" -#include "src/main/cpp/startup_options.h" - -int main(int argc, const char *argv[]) { - return blaze::Main(argc, argv, - new blaze::OptionProcessor( - std::unique_ptr(new blaze::StartupOptions()))); -} diff --git a/src/main/cpp/option_processor.cc b/src/main/cpp/option_processor.cc index bb56efc624..87560b8a00 100644 --- a/src/main/cpp/option_processor.cc +++ b/src/main/cpp/option_processor.cc @@ -160,10 +160,8 @@ blaze_exit_code::ExitCode OptionProcessor::RcFile::Parse( return blaze_exit_code::SUCCESS; } -OptionProcessor::OptionProcessor( - std::unique_ptr default_startup_options) : - initialized_(false), - parsed_startup_options_(std::move(default_startup_options)) { +OptionProcessor::OptionProcessor() + : initialized_(false), parsed_startup_options_(new BlazeStartupOptions()) { } // Return the path to the user's rc file. If cmdLineRcFile != NULL, @@ -241,7 +239,7 @@ blaze_exit_code::ExitCode OptionProcessor::ParseOptions( } blaze_exit_code::ExitCode validate_startup_options_exit_code = - parsed_startup_options_->ValidateStartupOptions(args, error); + BlazeStartupOptions::ValidateStartupOptions(args, error); if (validate_startup_options_exit_code != blaze_exit_code::SUCCESS) { return validate_startup_options_exit_code; } @@ -460,8 +458,8 @@ const string& OptionProcessor::GetCommand() const { return command_; } -StartupOptions* OptionProcessor::GetParsedStartupOptions() const { - return parsed_startup_options_.get(); +const BlazeStartupOptions& OptionProcessor::GetParsedStartupOptions() const { + return *parsed_startup_options_.get(); } OptionProcessor::~OptionProcessor() { diff --git a/src/main/cpp/option_processor.h b/src/main/cpp/option_processor.h index bb777e917b..e9dd44c0f7 100644 --- a/src/main/cpp/option_processor.h +++ b/src/main/cpp/option_processor.h @@ -21,7 +21,7 @@ #include #include -#include "src/main/cpp/startup_options.h" +#include "src/main/cpp/blaze_startup_options.h" #include "src/main/cpp/util/exit_code.h" namespace blaze { @@ -33,7 +33,7 @@ using std::string; // to the server. class OptionProcessor { public: - OptionProcessor(std::unique_ptr default_startup_options); + OptionProcessor(); virtual ~OptionProcessor(); @@ -59,7 +59,7 @@ class OptionProcessor { // executed in. void GetCommandArguments(std::vector* result) const; - StartupOptions* GetParsedStartupOptions() const; + const BlazeStartupOptions& GetParsedStartupOptions() const; virtual blaze_exit_code::ExitCode FindUserBlazerc(const char* cmdLineRcFile, const string& rc_basename, @@ -115,7 +115,7 @@ class OptionProcessor { string command_; std::vector command_arguments_; bool initialized_; - std::unique_ptr parsed_startup_options_; + std::unique_ptr parsed_startup_options_; }; } // namespace blaze diff --git a/src/main/cpp/startup_options.cc b/src/main/cpp/startup_options.cc deleted file mode 100644 index 156cda916d..0000000000 --- a/src/main/cpp/startup_options.cc +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#include "src/main/cpp/startup_options.h" - -#include -#include // errno, ENOENT -#include // strerror -#include // access - -#include -#include - -#include "src/main/cpp/blaze_util_platform.h" -#include "src/main/cpp/blaze_util.h" -#include "src/main/cpp/util/exit_code.h" -#include "src/main/cpp/util/file.h" -#include "src/main/cpp/util/numbers.h" -#include "src/main/cpp/util/strings.h" - -#ifndef PRODUCT_NAME -#define PRODUCT_NAME "Bazel" -#endif - -namespace blaze { - -using std::vector; - -StartupOptions::StartupOptions() { - Init(); -} - -StartupOptions::~StartupOptions() { -} - -// TODO(jmmv): Integrate Init into the StartupOptions constructor. -void StartupOptions::Init() { - bool testing = getenv("TEST_TMPDIR") != NULL; - if (testing) { - output_root = MakeAbsolute(getenv("TEST_TMPDIR")); - } else { - output_root = GetOutputRoot(); - } - - // TODO(jmmv): Now that we have per-product main.cc files, inject the - // product_name at construction time instead of using preprocessor - // definitions. - product_name = PRODUCT_NAME; - string product_name_lower = PRODUCT_NAME; - blaze_util::ToLower(&product_name_lower); - output_user_root = blaze_util::JoinPath( - output_root, "_" + product_name_lower + "_" + GetUserName()); - deep_execroot = true; - block_for_lock = true; - host_jvm_debug = false; - host_javabase = ""; - batch = false; - batch_cpu_scheduling = false; - allow_configurable_attributes = false; - fatal_event_bus_exceptions = false; - io_nice_level = -1; - // 3 hours (but only 15 seconds if used within a test) - max_idle_secs = testing ? 15 : (3 * 3600); - oom_more_eagerly_threshold = 100; - command_port = 0; - oom_more_eagerly = false; - watchfs = false; - invocation_policy = NULL; -} - -string StartupOptions::GetOutputRoot() { - return blaze::GetOutputRoot(); -} - -void StartupOptions::AddExtraOptions(vector *result) const {} - -blaze_exit_code::ExitCode StartupOptions::ProcessArg( - const string &argstr, const string &next_argstr, const string &rcfile, - bool *is_space_separated, string *error) { - // We have to parse a specific option syntax, so GNU getopts won't do. All - // options begin with "--" or "-". Values are given together with the option - // delimited by '=' or in the next option. - const char* arg = argstr.c_str(); - const char* next_arg = next_argstr.empty() ? NULL : next_argstr.c_str(); - const char* value = NULL; - - if ((value = GetUnaryOption(arg, next_arg, "--output_base")) != NULL) { - output_base = MakeAbsolute(value); - option_sources["output_base"] = rcfile; - } else if ((value = GetUnaryOption(arg, next_arg, - "--install_base")) != NULL) { - install_base = MakeAbsolute(value); - option_sources["install_base"] = rcfile; - } else if ((value = GetUnaryOption(arg, next_arg, - "--output_user_root")) != NULL) { - output_user_root = MakeAbsolute(value); - option_sources["output_user_root"] = rcfile; - } else if (GetNullaryOption(arg, "--deep_execroot")) { - deep_execroot = true; - option_sources["deep_execroot"] = rcfile; - } else if (GetNullaryOption(arg, "--nodeep_execroot")) { - deep_execroot = false; - option_sources["deep_execroot"] = rcfile; - } else if (GetNullaryOption(arg, "--noblock_for_lock")) { - block_for_lock = false; - option_sources["block_for_lock"] = rcfile; - } else if (GetNullaryOption(arg, "--host_jvm_debug")) { - host_jvm_debug = true; - option_sources["host_jvm_debug"] = rcfile; - } else if ((value = GetUnaryOption(arg, next_arg, - "--host_jvm_profile")) != NULL) { - host_jvm_profile = value; - option_sources["host_jvm_profile"] = rcfile; - } else if ((value = GetUnaryOption(arg, next_arg, - "--host_javabase")) != NULL) { - // TODO(bazel-team): Consider examining the javabase and re-execing in case - // of architecture mismatch. - host_javabase = MakeAbsolute(value); - option_sources["host_javabase"] = rcfile; - } else if ((value = GetUnaryOption(arg, next_arg, "--host_jvm_args")) != - NULL) { - host_jvm_args.push_back(value); - option_sources["host_jvm_args"] = rcfile; // NB: This is incorrect - } else if ((value = GetUnaryOption(arg, next_arg, "--bazelrc")) != NULL) { - if (rcfile != "") { - *error = "Can't specify --bazelrc in the .bazelrc file."; - return blaze_exit_code::BAD_ARGV; - } - } else if ((value = GetUnaryOption(arg, next_arg, "--blazerc")) != NULL) { - if (rcfile != "") { - *error = "Can't specify --blazerc in the .blazerc file."; - return blaze_exit_code::BAD_ARGV; - } - } else if (GetNullaryOption(arg, "--nomaster_blazerc") || - GetNullaryOption(arg, "--master_blazerc")) { - if (rcfile != "") { - *error = "Can't specify --[no]master_blazerc in .blazerc file."; - return blaze_exit_code::BAD_ARGV; - } - option_sources["blazerc"] = rcfile; - } else if (GetNullaryOption(arg, "--nomaster_bazelrc") || - GetNullaryOption(arg, "--master_bazelrc")) { - if (rcfile != "") { - *error = "Can't specify --[no]master_bazelrc in .bazelrc file."; - return blaze_exit_code::BAD_ARGV; - } - option_sources["blazerc"] = rcfile; - } else if (GetNullaryOption(arg, "--batch")) { - batch = true; - option_sources["batch"] = rcfile; - } else if (GetNullaryOption(arg, "--nobatch")) { - batch = false; - option_sources["batch"] = rcfile; - } else if (GetNullaryOption(arg, "--batch_cpu_scheduling")) { - batch_cpu_scheduling = true; - option_sources["batch_cpu_scheduling"] = rcfile; - } else if (GetNullaryOption(arg, "--nobatch_cpu_scheduling")) { - batch_cpu_scheduling = false; - option_sources["batch_cpu_scheduling"] = rcfile; - } else if (GetNullaryOption(arg, "--allow_configurable_attributes")) { - allow_configurable_attributes = true; - option_sources["allow_configurable_attributes"] = rcfile; - } else if (GetNullaryOption(arg, "--noallow_configurable_attributes")) { - allow_configurable_attributes = false; - option_sources["allow_configurable_attributes"] = rcfile; - } else if (GetNullaryOption(arg, "--fatal_event_bus_exceptions")) { - fatal_event_bus_exceptions = true; - option_sources["fatal_event_bus_exceptions"] = rcfile; - } else if (GetNullaryOption(arg, "--nofatal_event_bus_exceptions")) { - fatal_event_bus_exceptions = false; - option_sources["fatal_event_bus_exceptions"] = rcfile; - } else if ((value = GetUnaryOption(arg, next_arg, - "--io_nice_level")) != NULL) { - if (!blaze_util::safe_strto32(value, &io_nice_level) || - io_nice_level > 7) { - blaze_util::StringPrintf(error, - "Invalid argument to --io_nice_level: '%s'. Must not exceed 7.", - value); - return blaze_exit_code::BAD_ARGV; - } - option_sources["io_nice_level"] = rcfile; - } else if ((value = GetUnaryOption(arg, next_arg, - "--max_idle_secs")) != NULL) { - if (!blaze_util::safe_strto32(value, &max_idle_secs) || - max_idle_secs < 0) { - blaze_util::StringPrintf(error, - "Invalid argument to --max_idle_secs: '%s'.", value); - return blaze_exit_code::BAD_ARGV; - } - option_sources["max_idle_secs"] = rcfile; - } else if (GetNullaryOption(arg, "-x")) { - fprintf(stderr, "WARNING: The -x startup option is now ignored " - "and will be removed in a future release\n"); - } else if (GetNullaryOption(arg, "--experimental_oom_more_eagerly")) { - oom_more_eagerly = true; - option_sources["experimental_oom_more_eagerly"] = rcfile; - } else if (GetNullaryOption(arg, "--noexperimental_oom_more_eagerly")) { - oom_more_eagerly = false; - option_sources["experimental_oom_more_eagerly"] = rcfile; - } else if ((value = GetUnaryOption( - arg, next_arg, - "--experimental_oom_more_eagerly_threshold")) != NULL) { - if (!blaze_util::safe_strto32(value, &oom_more_eagerly_threshold) || - oom_more_eagerly_threshold < 0) { - blaze_util::StringPrintf(error, - "Invalid argument to " - "--experimental_oom_more_eagerly_threshold: " - "'%s'.", - value); - return blaze_exit_code::BAD_ARGV; - } - option_sources["experimental_oom_more_eagerly_threshold"] = rcfile; - } else if (GetNullaryOption(arg, "--watchfs")) { - watchfs = true; - option_sources["watchfs"] = rcfile; - } else if (GetNullaryOption(arg, "--nowatchfs")) { - watchfs = false; - option_sources["watchfs"] = rcfile; - } else if ((value = GetUnaryOption( - arg, next_arg, "--command_port")) != NULL) { - if (!blaze_util::safe_strto32(value, &command_port) || - command_port < -1 || command_port > 65535) { - blaze_util::StringPrintf(error, - "Invalid argument to --command_port: '%s'. " - "Must be a valid port number or -1 to disable the gRPC server.\n", - value); - return blaze_exit_code::BAD_ARGV; - } - option_sources["webstatusserver"] = rcfile; - } else if ((value = GetUnaryOption(arg, next_arg, "--invocation_policy")) - != NULL) { - if (invocation_policy == NULL) { - invocation_policy = value; - option_sources["invocation_policy"] = rcfile; - } else { - *error = "The startup flag --invocation_policy cannot be specified " - "multiple times."; - return blaze_exit_code::BAD_ARGV; - } - } else { - bool extra_argument_processed; - blaze_exit_code::ExitCode process_extra_arg_exit_code = ProcessArgExtra( - arg, next_arg, rcfile, &value, &extra_argument_processed, error); - if (process_extra_arg_exit_code != blaze_exit_code::SUCCESS) { - return process_extra_arg_exit_code; - } - if (!extra_argument_processed) { - blaze_util::StringPrintf( - error, - "Unknown %s startup option: '%s'.\n" - " For more info, run '%s help startup_options'.", - product_name.c_str(), arg, product_name.c_str()); - return blaze_exit_code::BAD_ARGV; - } - } - - *is_space_separated = ((value == next_arg) && (value != NULL)); - return blaze_exit_code::SUCCESS; -} - -blaze_exit_code::ExitCode StartupOptions::ProcessArgExtra( - const char *arg, const char *next_arg, const string &rcfile, - const char **value, bool *is_processed, string *error) { - *is_processed = false; - return blaze_exit_code::SUCCESS; -} - -blaze_exit_code::ExitCode StartupOptions::CheckForReExecuteOptions( - int argc, const char *argv[], string *error) { - return blaze_exit_code::SUCCESS; -} - -string StartupOptions::GetDefaultHostJavabase() const { - return blaze::GetDefaultHostJavabase(); -} - -string StartupOptions::GetHostJavabase() { - if (host_javabase.empty()) { - host_javabase = GetDefaultHostJavabase(); - } - return host_javabase; -} - -string StartupOptions::GetJvm() { - string java_program = GetHostJavabase() + "/bin/java"; - if (access(java_program.c_str(), X_OK) == -1) { - if (errno == ENOENT) { - fprintf(stderr, "Couldn't find java at '%s'.\n", java_program.c_str()); - } else { - fprintf(stderr, "Couldn't access %s: %s\n", java_program.c_str(), - strerror(errno)); - } - exit(1); - } - // If the full JDK is installed - string jdk_rt_jar = GetHostJavabase() + "/jre/lib/rt.jar"; - // If just the JRE is installed - string jre_rt_jar = GetHostJavabase() + "/lib/rt.jar"; - if ((access(jdk_rt_jar.c_str(), R_OK) == 0) - || (access(jre_rt_jar.c_str(), R_OK) == 0)) { - return java_program; - } - fprintf(stderr, "Problem with java installation: " - "couldn't find/access rt.jar in %s\n", GetHostJavabase().c_str()); - exit(1); -} - -string StartupOptions::GetExe(const string &jvm, const string &jar_path) { - return jvm; -} - -void StartupOptions::AddJVMArgumentPrefix(const string &javabase, - std::vector *result) const { -} - -void StartupOptions::AddJVMArgumentSuffix(const string &real_install_dir, - const string &jar_path, - std::vector *result) const { - result->push_back("-jar"); - result->push_back(blaze::ConvertPath( - blaze_util::JoinPath(real_install_dir, jar_path))); -} - -blaze_exit_code::ExitCode StartupOptions::AddJVMArguments( - const string &host_javabase, vector *result, - const vector &user_options, string *error) const { - // Configure logging - const string propFile = output_base + "/javalog.properties"; - if (!WriteFile( - "handlers=java.util.logging.FileHandler\n" - ".level=INFO\n" - "java.util.logging.FileHandler.level=INFO\n" - "java.util.logging.FileHandler.pattern=" - + output_base + "/java.log\n" - "java.util.logging.FileHandler.limit=50000\n" - "java.util.logging.FileHandler.count=1\n" - "java.util.logging.FileHandler.formatter=" - "java.util.logging.SimpleFormatter\n", - propFile)) { - perror(("Couldn't write logging file " + propFile).c_str()); - } else { - result->push_back("-Djava.util.logging.config.file=" + propFile); - } - return blaze_exit_code::SUCCESS; -} - -blaze_exit_code::ExitCode StartupOptions::ValidateStartupOptions( - const std::vector& args, string* error) { - return blaze_exit_code::SUCCESS; -} - -} // namespace blaze diff --git a/src/main/cpp/startup_options.h b/src/main/cpp/startup_options.h deleted file mode 100644 index d1f33308cb..0000000000 --- a/src/main/cpp/startup_options.h +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -#ifndef BAZEL_SRC_MAIN_CPP_STARTUP_OPTIONS_H_ -#define BAZEL_SRC_MAIN_CPP_STARTUP_OPTIONS_H_ - -#include -#include -#include -#include - -#include "src/main/cpp/util/exit_code.h" - -namespace blaze { - -using std::string; - -// This class holds the parsed startup options for Blaze. -// These options and their defaults must be kept in sync with those in -// src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java. -// The latter are purely decorative (they affect the help message, -// which displays the defaults). The actual defaults are defined -// in the constructor. -// -// TODO(bazel-team): The encapsulation is not quite right -- there are some -// places in blaze.cc where some of these fields are explicitly modified. Their -// names also don't conform to the style guide. -class StartupOptions { - public: - StartupOptions(); - virtual ~StartupOptions(); - - // Parses a single argument, either from the command line or from the .blazerc - // "startup" options. - // - // rcfile should be an empty string if the option being parsed does not come - // from a blazerc. - // - // Sets "is_space_separated" true if arg is unary and uses the "--foo bar" - // style, so its value is in next_arg. - // - // Sets "is_space_separated" false if arg is either nullary - // (e.g. "--[no]batch") or is unary but uses the "--foo=bar" style. - // - // Returns the exit code after processing the argument. "error" will contain - // a descriptive string for any return value other than - // blaze_exit_code::SUCCESS. - blaze_exit_code::ExitCode ProcessArg( - const string &arg, const string &next_arg, const string &rcfile, - bool *is_space_separated, string *error); - - // Adds any other options needed to result. - // - // TODO(jmmv): Now that we support site-specific options via subclasses of - // StartupOptions, the "ExtraOptions" concept makes no sense; remove it. - virtual void AddExtraOptions(std::vector *result) const; - - // Checks if Blaze needs to be re-executed. Does not return, if so. - // - // Returns the exit code after the check. "error" will contain a descriptive - // string for any return value other than blaze_exit_code::SUCCESS. - virtual blaze_exit_code::ExitCode CheckForReExecuteOptions( - int argc, const char *argv[], string *error); - - // Checks extra fields when processing arg. - // - // Returns the exit code after processing the argument. "error" will contain - // a descriptive string for any return value other than - // blaze_exit_code::SUCCESS. - // - // TODO(jmmv): Now that we support site-specific options via subclasses of - // StartupOptions, the "ExtraOptions" concept makes no sense; remove it. - virtual blaze_exit_code::ExitCode ProcessArgExtra( - const char *arg, const char *next_arg, const string &rcfile, - const char **value, bool *is_processed, string *error); - - // Return the default path to the JDK used to run Blaze itself - // (must be an absolute directory). - virtual string GetDefaultHostJavabase() const; - - // Returns the path to the JVM. This should be called after parsing - // the startup options. - virtual string GetJvm(); - - // Returns the executable used to start the Blaze server, typically the given - // JVM. - virtual string GetExe(const string &jvm, const string &jar_path); - - // Adds JVM prefix flags to be set. These will be added before all other - // JVM flags. - virtual void AddJVMArgumentPrefix(const string &javabase, - std::vector *result) const; - - // Adds JVM suffix flags. These will be added after all other JVM flags, and - // just before the Blaze server startup flags. - virtual void AddJVMArgumentSuffix(const string &real_install_dir, - const string &jar_path, std::vector *result) const; - - // Adds JVM tuning flags for Blaze. - // - // Returns the exit code after this operation. "error" will be set to a - // descriptive string for any value other than blaze_exit_code::SUCCESS. - virtual blaze_exit_code::ExitCode AddJVMArguments( - const string &host_javabase, std::vector *result, - const std::vector &user_options, string *error) const; - - // The capitalized name of this binary. - string product_name; - - // Blaze's output base. Everything is relative to this. See - // the BlazeDirectories Java class for details. - string output_base; - - // Installation base for a specific release installation. - string install_base; - - // The toplevel directory containing Blaze's output. When Blaze is - // run by a test, we use TEST_TMPDIR, simplifying the correct - // hermetic invocation of Blaze from tests. - string output_root; - - // Blaze's output_user_root. Used only for computing install_base and - // output_base. - string output_user_root; - - // Whether to put the execroot at $OUTPUT_BASE/$WORKSPACE_NAME (if false) or - // $OUTPUT_BASE/execroot/$WORKSPACE_NAME (if true). - bool deep_execroot; - - // Block for the Blaze server lock. Otherwise, - // quit with non-0 exit code if lock can't - // be acquired immediately. - bool block_for_lock; - - bool host_jvm_debug; - - string host_jvm_profile; - - std::vector host_jvm_args; - - bool batch; - - // From the man page: "This policy is useful for workloads that are - // non-interactive, but do not want to lower their nice value, and for - // workloads that want a deterministic scheduling policy without - // interactivity causing extra preemptions (between the workload's tasks)." - bool batch_cpu_scheduling; - - // If negative, don't mess with ionice. Otherwise, set a level from 0-7 - // for best-effort scheduling. 0 is highest priority, 7 is lowest. - int io_nice_level; - - int max_idle_secs; - - bool oom_more_eagerly; - - int oom_more_eagerly_threshold; - - // If true, Blaze will listen to OS-level file change notifications. - bool watchfs; - - // Temporary experimental flag that permits configurable attribute syntax - // in BUILD files. This will be removed when configurable attributes is - // a more stable feature. - bool allow_configurable_attributes; - - // Temporary flag for enabling EventBus exceptions to be fatal. - bool fatal_event_bus_exceptions; - - // A string to string map specifying where each option comes from. If the - // value is empty, it was on the command line, if it is a string, it comes - // from a blazerc file, if a key is not present, it is the default. - std::map option_sources; - - // Sanity check for the startup options - virtual blaze_exit_code::ExitCode ValidateStartupOptions( - const std::vector& args, string* error); - - // Returns the GetHostJavabase. This should be called after parsing - // the --host_javabase option. - string GetHostJavabase(); - - // Port for gRPC command server. 0 means let the kernel choose, -1 means no - // gRPC command server. - int command_port; - - // Invocation policy proto. May be NULL. - const char* invocation_policy; - - private: - string host_javabase; - - // Sets default values for members. - void Init(); - - // Returns the directory to use for storing outputs. - virtual string GetOutputRoot(); -}; - -} // namespace blaze -#endif // BAZEL_SRC_MAIN_CPP_STARTUP_OPTIONS_H_ -- cgit v1.2.3