// 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_ #if defined(__APPLE__) #include #endif #include #include #include #include #include #include #include #include "src/main/cpp/util/exit_code.h" #include "src/main/cpp/util/path.h" namespace blaze { class WorkspaceLayout; // A startup flag tagged with its origin, either an rc file or the empty // string for the ones specified in the command line. // For instance, RcStartupFlag("somepath/.bazelrc", "--foo") is used to // represent that the line "startup --foo" was found when parsing // "somepath/.bazelrc". struct RcStartupFlag { const std::string source; const std::string value; RcStartupFlag(const std::string& source_arg, const std::string& value_arg) : source(source_arg), value(value_arg) {} }; // This class defines the startup options accepted by all versions Bazel, and // holds the parsed values. 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 (usually) purely decorative (they affect the help message, // which displays the defaults). The actual defaults are defined // in the constructor. // // Note that this class is not thread-safe. // // 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: virtual ~StartupOptions(); // Process an ordered list of RcStartupFlags using ProcessArg. blaze_exit_code::ExitCode ProcessArgs( const std::vector& rcstartup_flags, std::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; // Once startup options have been parsed, warn the user if certain options // might combine in surprising ways. virtual void MaybeLogStartupOptionWarnings() const = 0; // Returns the path to the JVM. This should be called after parsing // the startup options. virtual blaze_util::Path GetJvm() const; // Returns the executable used to start the Blaze server, typically the given // JVM. virtual blaze_util::Path GetExe(const blaze_util::Path &jvm, const std::string &jar_path) const; // Adds JVM prefix flags to be set. These will be added before all other // JVM flags. virtual void AddJVMArgumentPrefix(const blaze_util::Path &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 blaze_util::Path &real_install_dir, const std::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 blaze_util::Path &server_javabase, std::vector *result, const std::vector &user_options, std::string *error) const; // Checks whether "arg" is a valid nullary option (e.g. "--master_bazelrc" or // "--nomaster_bazelrc"). // // Returns true, if "arg" looks like either a valid nullary option or a // potentially valid unary option. In this case, "result" will be populated // with true iff "arg" is definitely a valid nullary option. // // Returns false, if "arg" looks like an attempt to pass a value to nullary // option (e.g. "--nullary_option=idontknowwhatimdoing"). In this case, // "error" will be populated with a user-friendly error message. // // Therefore, callers of this function should look at the return value and // then either look at "result" (on true) or "error" (on false). bool MaybeCheckValidNullary(const std::string &arg, bool *result, std::string *error) const; // Checks whether the argument is a valid unary option. // E.g. --blazerc=foo, --blazerc foo. bool IsUnary(const std::string& arg) const; std::string GetLowercaseProductName() const; // The capitalized name of this binary. const std::string product_name; // If supplied, alternate location to write the blaze server's jvm's stdout. // Otherwise a default path in the output base is used. blaze_util::Path server_jvm_out; // If supplied, alternate location to write a serialized failure_detail proto. // Otherwise a default path in the output base is used. blaze_util::Path failure_detail_out; // Blaze's output base. Everything is relative to this. See // the BlazeDirectories Java class for details. blaze_util::Path output_base; // Installation base for a specific release installation. std::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. std::string output_root; // Blaze's output_user_root. Used only for computing install_base and // output_base. std::string output_user_root; // Override more finegrained rc file flags and ignore them all. bool ignore_all_rc_files; // 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; bool autodetect_server_javabase; std::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 shutdown_on_low_sys_mem; bool oom_more_eagerly; int oom_more_eagerly_threshold; bool write_command_log; // If true, Blaze will listen to OS-level file change notifications. bool watchfs; // 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; // Returns the embedded JDK, or an empty string. blaze_util::Path GetEmbeddedJavabase() const; // The source of truth for the server javabase. enum class JavabaseType { UNKNOWN, // An explicit --server_javabase startup option. EXPLICIT, // The embedded JDK. EMBEDDED, // The default system JVM. SYSTEM }; // Returns the server javabase and its source of truth. This should be called // after parsing the --server_javabase option. std::pair GetServerJavabaseAndType() const; // Returns the server javabase. This should be called after parsing the // --server_javabase option. blaze_util::Path GetServerJavabase() const; // Returns the explicit value of the --server_javabase startup option or the // empty string if it was not specified on the command line. blaze_util::Path GetExplicitServerJavabase() const; // Port to start up the gRPC command server on. If 0, let the kernel choose. int command_port; // Connection timeout for each gRPC connection attempt. int connect_timeout_secs; // Local server startup timeout duration. int local_startup_timeout_secs; // Invocation policy proto, or an empty string. std::string invocation_policy; // Invocation policy can only be specified once. bool have_invocation_policy_; // Whether to output addition debugging information in the client. bool client_debug; // Whether the resulting command will be preempted if a subsequent command is // run. bool preemptible; // Value of the java.util.logging.FileHandler.formatter Java property. std::string java_logging_formatter; bool expand_configs_in_place; // The hash function to use when computing file digests. std::string digest_function; std::string unix_digest_hash_attribute_name; bool idle_server_tasks; // The startup options as received from the user and rc files, tagged with // their origin. This is populated by ProcessArgs. std::vector original_startup_options_; #if defined(__APPLE__) // The QoS class to apply to the Bazel server process. qos_class_t macos_qos_class; #endif // Whether to raise the soft coredump limit to the hard one or not. bool unlimit_coredumps; // Whether to create symbolic links on Windows for files. Requires // developer mode to be enabled. bool windows_enable_symlinks; protected: // Constructor for subclasses only so that site-specific extensions of this // class can override the product name. The product_name must be the // capitalized version of the name, as in "Bazel". StartupOptions(const std::string &product_name, const WorkspaceLayout *workspace_layout); // 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 std::string &rcfile, const char **value, bool *is_processed, std::string *error) = 0; // Checks whether the given javabase contains a java executable and runtime. // On success, returns blaze_exit_code::SUCCESS. On error, prints an error // message and returns an appropriate exit code with which the client should // terminate. blaze_exit_code::ExitCode SanityCheckJavabase( const blaze_util::Path &javabase, StartupOptions::JavabaseType javabase_type) const; // Returns the absolute path to the user's local JDK install, to be used as // the default target javabase and as a fall-back host_javabase. This is not // the embedded JDK. virtual blaze_util::Path GetSystemJavabase() const; // Adds JVM logging-related flags for Bazel. // // This is called by StartupOptions::AddJVMArguments and is a separate method // so that subclasses of StartupOptions can override it. virtual void AddJVMLoggingArguments(std::vector *result) const; // Adds JVM memory tuning flags for Bazel. // // This is called by StartupOptions::AddJVMArguments and is a separate method // so that subclasses of StartupOptions can override it. virtual blaze_exit_code::ExitCode AddJVMMemoryArguments( const blaze_util::Path &server_javabase, std::vector *result, const std::vector &user_options, std::string *error) const; virtual std::string GetRcFileBaseName() const = 0; void RegisterUnaryStartupFlag(const std::string& flag_name); // Register a nullary startup flag. // Both '--flag_name' and '--noflag_name' will be registered as valid nullary // flags. 'value' is the pointer to the boolean that will receive the flag's // value. void RegisterNullaryStartupFlag(const std::string &flag_name, bool *value); // Same as RegisterNullaryStartupFlag, but these flags are forbidden in // .bazelrc files. void RegisterNullaryStartupFlagNoRc(const std::string &flag_name, bool *value); typedef std::function SpecialNullaryFlagHandler; void RegisterSpecialNullaryStartupFlag(const std::string &flag_name, SpecialNullaryFlagHandler handler); // Override the flag name to use in the 'option_sources' map. void OverrideOptionSourcesKey(const std::string &flag_name, const std::string &new_name); private: // Prevent copying and moving the object to avoid invalidating pointers to // members (in all_nullary_startup_flags_ for example). StartupOptions() = delete; StartupOptions(const StartupOptions&) = delete; StartupOptions& operator=(const StartupOptions&) = delete; StartupOptions(StartupOptions&&) = delete; StartupOptions& operator=(StartupOptions&&) = delete; // 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 std::string &arg, const std::string &next_arg, const std::string &rcfile, bool *is_space_separated, std::string *error); // The server javabase as provided on the commandline. blaze_util::Path explicit_server_javabase_; // The default server javabase to be used and its source of truth (computed // lazily). Not guarded by a mutex - StartupOptions is not thread-safe. mutable std::pair default_server_javabase_; // Startup flags that don't expect a value, e.g. "home_rc". // Valid uses are "--home_rc" are "--nohome_rc". // Keys are positive and negative flag names (e.g. "--home_rc" and // "--nohome_rc"), values are pointers to the boolean to mutate. std::unordered_map all_nullary_startup_flags_; // Subset of 'all_nullary_startup_flags_'. // Contains positive and negative names (e.g. "--home_rc" and // "--nohome_rc") of flags that must not appear in .bazelrc files. std::unordered_set no_rc_nullary_startup_flags_; // Subset of 'all_nullary_startup_flags_'. // Contains positive and negative names (e.g. "--home_rc" and // "--nohome_rc") of flags that have a special handler. // Can be used for tri-state flags where omitting the flag completely means // leaving the tri-state as "auto". std::unordered_map special_nullary_startup_flags_; // Startup flags that expect a value, e.g. "bazelrc". // Valid uses are "--bazelrc=foo" and "--bazelrc foo". // Keys are flag names (e.g. "--bazelrc"), values are pointers to the string // to mutate. std::unordered_set valid_unary_startup_flags_; // Startup flags that use an alternative key name in the 'option_sources' map. // For example, "--[no]master_bazelrc" uses "blazerc" as the map key. std::unordered_map option_sources_key_override_; }; } // namespace blaze #endif // BAZEL_SRC_MAIN_CPP_STARTUP_OPTIONS_H_