// Copyright 2017 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. package com.google.devtools.build.lib.buildtool; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.devtools.build.lib.actions.LocalHostCapacity; import com.google.devtools.build.lib.util.OptionsUtils; import com.google.devtools.build.lib.vfs.PathFragment; import com.google.devtools.common.options.Converters; import com.google.devtools.common.options.Converters.RangeConverter; import com.google.devtools.common.options.Option; import com.google.devtools.common.options.OptionDocumentationCategory; import com.google.devtools.common.options.OptionEffectTag; import com.google.devtools.common.options.OptionMetadataTag; import com.google.devtools.common.options.OptionsBase; import com.google.devtools.common.options.OptionsParsingException; import java.util.ArrayList; import java.util.List; import java.util.logging.Logger; import java.util.regex.Pattern; /** * Options interface for {@link BuildRequest}: can be used to parse command-line arguments. * *
See also {@code ExecutionOptions}; from the user's point of view, there's no qualitative
* difference between these two sets of options.
*/
public class BuildRequestOptions extends OptionsBase {
private static final Logger logger = Logger.getLogger(BuildRequestOptions.class.getName());
private static final int JOBS_TOO_HIGH_WARNING = 1500;
@VisibleForTesting public static final int MAX_JOBS = 3000;
/* "Execution": options related to the execution of a build: */
@Option(
name = "jobs",
abbrev = 'j',
defaultValue = "auto",
category = "strategy",
documentationCategory = OptionDocumentationCategory.EXECUTION_STRATEGY,
effectTags = {OptionEffectTag.HOST_MACHINE_RESOURCE_OPTIMIZATIONS, OptionEffectTag.EXECUTION},
converter = JobsConverter.class,
help =
"The number of concurrent jobs to run. 0 means build sequentially."
+ " \"auto\" means to use a reasonable value derived from the machine's hardware"
+ " profile (e.g. the number of processors). Values above "
+ MAX_JOBS
+ " are not allowed, and values above "
+ JOBS_TOO_HIGH_WARNING
+ " may cause memory issues."
)
public int jobs;
@Option(
name = "progress_report_interval",
defaultValue = "0",
category = "verbosity",
documentationCategory = OptionDocumentationCategory.LOGGING,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
converter = ProgressReportIntervalConverter.class,
help =
"The number of seconds to wait between two reports on still running jobs. The "
+ "default value 0 means to use the default 10:30:60 incremental algorithm."
)
public int progressReportInterval;
@Option(
name = "explain",
defaultValue = "null",
category = "verbosity",
documentationCategory = OptionDocumentationCategory.LOGGING,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
converter = OptionsUtils.PathFragmentConverter.class,
help =
"Causes the build system to explain each executed step of the "
+ "build. The explanation is written to the specified log file."
)
public PathFragment explanationPath;
@Option(
name = "verbose_explanations",
defaultValue = "false",
category = "verbosity",
documentationCategory = OptionDocumentationCategory.LOGGING,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
help =
"Increases the verbosity of the explanations issued if --explain is enabled. "
+ "Has no effect if --explain is not enabled."
)
public boolean verboseExplanations;
@Option(
name = "output_filter",
converter = Converters.RegexPatternConverter.class,
defaultValue = "null",
category = "flags",
documentationCategory = OptionDocumentationCategory.LOGGING,
effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
help = "Only shows warnings for rules with a name matching the provided regular expression."
)
public Pattern outputFilter;
@Deprecated
@Option(
name = "dump_makefile",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.NO_OP},
metadataTags = {OptionMetadataTag.DEPRECATED},
help = "this flag has no effect."
)
public boolean dumpMakefile;
@Deprecated
@Option(
name = "dump_action_graph",
defaultValue = "false",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.NO_OP},
metadataTags = {OptionMetadataTag.DEPRECATED},
help = "this flag has no effect."
)
public boolean dumpActionGraph;
@Deprecated
@Option(
name = "dump_action_graph_for_package",
allowMultiple = true,
defaultValue = "",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {OptionEffectTag.NO_OP},
metadataTags = {OptionMetadataTag.DEPRECATED},
help = "this flag has no effect."
)
public List If true, then symlinks use the actual output directories of the top-level targets. The
* symlinks will be created iff all top-level targets share the same output directory. Otherwise,
* any stale symlinks from previous invocations will be deleted to avoid ambiguity.
*
* If false, then symlinks use the output directory implied by command-line flags, regardless
* of whether top-level targets have transitions which change them (or even have any output
* directories at all, as in the case of a build with no targets or one which only builds source
* files).
*/
public boolean useTopLevelTargetsForSymlinks() {
return useTopLevelTargetsForSymlinks;
}
@Option(
name = "use_action_cache",
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
effectTags = {
OptionEffectTag.BAZEL_INTERNAL_CONFIGURATION,
OptionEffectTag.HOST_MACHINE_RESOURCE_OPTIMIZATIONS
},
help = "Whether to use the action cache"
)
public boolean useActionCache;
@Option(
name = "track_incremental_state",
oldName = "keep_incrementality_data",
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.BUILD_TIME_OPTIMIZATION,
effectTags = {OptionEffectTag.LOSES_INCREMENTAL_STATE},
help =
"If false, Blaze will not persist data that allows for invalidation and re-evaluation "
+ "on incremental builds in order to save memory on this build. Subsequent builds "
+ "will not have any incrementality with respect to this one. Usually you will want "
+ "to specify --batch when setting this to false."
)
public boolean trackIncrementalState;
@Option(
name = "keep_state_after_build",
defaultValue = "true",
documentationCategory = OptionDocumentationCategory.BUILD_TIME_OPTIMIZATION,
effectTags = {OptionEffectTag.LOSES_INCREMENTAL_STATE},
help =
"If false, Blaze will discard the inmemory state from this build when the build finishes. "
+ "Subsequent builds will not have any incrementality with respect to this one."
)
public boolean keepStateAfterBuild;
/** Converter for jobs: [0, MAX_JOBS] or "auto". */
public static class JobsConverter extends RangeConverter {
/**
* If not null, indicates the value to return when "auto" is selected. Useful for cases where
* the number of jobs is bound by another factor different than what we compute here.
*/
private static Integer fixedAutoJobs;
public JobsConverter() {
super(0, MAX_JOBS);
}
@Override
public Integer convert(String input) throws OptionsParsingException {
if (input.equals("auto")) {
int jobs;
if (fixedAutoJobs == null) {
jobs = (int) Math.ceil(LocalHostCapacity.getLocalHostCapacity().getCpuUsage());
if (jobs > MAX_JOBS) {
logger.warning(
"Detected "
+ jobs
+ " processors, which exceed the maximum allowed number of jobs of "
+ MAX_JOBS
+ "; something seems wrong");
jobs = MAX_JOBS;
}
} else {
jobs = fixedAutoJobs;
}
logger.info("Flag \"jobs\" was set to \"auto\"; using " + jobs + " jobs");
return jobs;
} else {
return super.convert(input);
}
}
@Override
public String getTypeDescription() {
return "\"auto\" or " + super.getTypeDescription();
}
/**
* Sets the value to return by this converter when "auto" is selected.
*
* @param jobs the number of jobs to return, or null to reenable automated detection
*/
public static void setFixedAutoJobs(Integer jobs) {
Preconditions.checkArgument(jobs == null || jobs <= MAX_JOBS);
fixedAutoJobs = jobs;
}
}
/** Converter for progress_report_interval: [0, 3600]. */
public static class ProgressReportIntervalConverter extends RangeConverter {
public ProgressReportIntervalConverter() {
super(0, 3600);
}
}
}