| // 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 <sys/qos.h> | 
 | #endif | 
 |  | 
 | #include <functional> | 
 | #include <map> | 
 | #include <string> | 
 | #include <unordered_map> | 
 | #include <unordered_set> | 
 | #include <utility> | 
 | #include <vector> | 
 |  | 
 | #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<RcStartupFlag>& 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<std::string> *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<std::string> *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<std::string> *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<std::string> *result, | 
 |       const std::vector<std::string> &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<std::string> 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<std::string, std::string> 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<blaze_util::Path, JavabaseType> 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<RcStartupFlag> 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<std::string> *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<std::string> *result, | 
 |       const std::vector<std::string> &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<void(bool)> 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<blaze_util::Path, JavabaseType> default_server_javabase_; | 
 |  | 
 |   // Startup flags that don't expect a value, e.g. "master_bazelrc". | 
 |   // Valid uses are "--master_bazelrc" are "--nomaster_bazelrc". | 
 |   // Keys are positive and negative flag names (e.g. "--master_bazelrc" and | 
 |   // "--nomaster_bazelrc"), values are pointers to the boolean to mutate. | 
 |   std::unordered_map<std::string, bool *> all_nullary_startup_flags_; | 
 |  | 
 |   // Subset of 'all_nullary_startup_flags_'. | 
 |   // Contains positive and negative names (e.g. "--master_bazelrc" and | 
 |   // "--nomaster_bazelrc") of flags that must not appear in .bazelrc files. | 
 |   std::unordered_set<std::string> no_rc_nullary_startup_flags_; | 
 |  | 
 |   // Subset of 'all_nullary_startup_flags_'. | 
 |   // Contains positive and negative names (e.g. "--master_bazelrc" and | 
 |   // "--nomaster_bazelrc") 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<std::string, SpecialNullaryFlagHandler> | 
 |       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<std::string> 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<std::string, std::string> option_sources_key_override_; | 
 | }; | 
 |  | 
 | }  // namespace blaze | 
 |  | 
 | #endif  // BAZEL_SRC_MAIN_CPP_STARTUP_OPTIONS_H_ |