use of com.google.devtools.build.lib.analysis.config.InvalidConfigurationException in project bazel by bazelbuild.
the class BuildTool method buildTargets.
/**
* The crux of the build system. Builds the targets specified in the request using the specified
* Executor.
*
* <p>Performs loading, analysis and execution for the specified set of targets, honoring the
* configuration options in the BuildRequest. Returns normally iff successful, throws an exception
* otherwise.
*
* <p>Callers must ensure that {@link #stopRequest} is called after this method, even if it
* throws.
*
* <p>The caller is responsible for setting up and syncing the package cache.
*
* <p>During this function's execution, the actualTargets and successfulTargets
* fields of the request object are set.
*
* @param request the build request that this build tool is servicing, which specifies various
* options; during this method's execution, the actualTargets and successfulTargets fields
* of the request object are populated
* @param result the build result that is the mutable result of this build
* @param validator target validator
*/
public void buildTargets(BuildRequest request, BuildResult result, TargetValidator validator) throws BuildFailedException, InterruptedException, ViewCreationFailedException, TargetParsingException, LoadingFailedException, AbruptExitException, InvalidConfigurationException, TestExecException {
validateOptions(request);
BuildOptions buildOptions = runtime.createBuildOptions(request);
// Sync the package manager before sending the BuildStartingEvent in runLoadingPhase()
env.setupPackageCache(request, DefaultsPackage.getDefaultsPackageContent(buildOptions));
ExecutionTool executionTool = null;
boolean catastrophe = false;
try {
env.getEventBus().post(new BuildStartingEvent(env, request));
LOG.info("Build identifier: " + request.getId());
executionTool = new ExecutionTool(env, request);
if (needsExecutionPhase(request.getBuildOptions())) {
// Initialize the execution tool early if we need it. This hides the latency of setting up
// the execution backends.
executionTool.init();
}
// Error out early if multi_cpus is set, but we're not in build or test command.
if (!request.getMultiCpus().isEmpty()) {
getReporter().handle(Event.warn("The --experimental_multi_cpu option is _very_ experimental and only intended for " + "internal testing at this time. If you do not work on the build tool, then you " + "should stop now!"));
if (!"build".equals(request.getCommandName()) && !"test".equals(request.getCommandName())) {
throw new InvalidConfigurationException("The experimental setting to select multiple CPUs is only supported for 'build' and " + "'test' right now!");
}
}
// Exit if there are any pending exceptions from modules.
env.throwPendingException();
// Target pattern evaluation.
LoadingResult loadingResult = evaluateTargetPatterns(request, validator);
// Exit if there are any pending exceptions from modules.
env.throwPendingException();
// Configuration creation.
BuildConfigurationCollection configurations = env.getSkyframeExecutor().createConfigurations(env.getReporter(), runtime.getConfigurationFactory(), buildOptions, request.getMultiCpus(), request.getViewOptions().keepGoing);
env.throwPendingException();
if (configurations.getTargetConfigurations().size() == 1) {
// TODO(bazel-team): This is not optimal - we retain backwards compatibility in the case
// where there's only a single configuration, but we don't send an event in the multi-config
// case. Can we do better? [multi-config]
env.getEventBus().post(new MakeEnvironmentEvent(configurations.getTargetConfigurations().get(0).getMakeEnvironment()));
}
LOG.info("Configurations created");
if (request.getBuildOptions().performAnalysisPhase) {
AnalysisResult analysisResult = runAnalysisPhase(request, loadingResult, configurations);
result.setBuildConfigurationCollection(configurations);
result.setActualTargets(analysisResult.getTargetsToBuild());
result.setTestTargets(analysisResult.getTargetsToTest());
LoadedPackageProvider bridge = new LoadedPackageProvider(env.getPackageManager(), env.getReporter());
checkTargetEnvironmentRestrictions(analysisResult.getTargetsToBuild(), bridge);
reportTargets(analysisResult);
// Execution phase.
if (needsExecutionPhase(request.getBuildOptions())) {
executionTool.executeBuild(request.getId(), analysisResult, result, configurations, analysisResult.getPackageRoots(), request.getTopLevelArtifactContext());
}
String delayedErrorMsg = analysisResult.getError();
if (delayedErrorMsg != null) {
throw new BuildFailedException(delayedErrorMsg);
}
} else {
getReporter().handle(Event.progress("Loading complete."));
LOG.info("No analysis requested, so finished");
String errorMessage = BuildView.createErrorMessage(loadingResult, null);
if (errorMessage != null) {
throw new BuildFailedException(errorMessage);
}
// Return.
}
} catch (RuntimeException e) {
// Print an error message for unchecked runtime exceptions. This does not concern Error
// subclasses such as OutOfMemoryError.
request.getOutErr().printErrLn("Unhandled exception thrown during build; message: " + e.getMessage());
catastrophe = true;
throw e;
} catch (Error e) {
catastrophe = true;
throw e;
} catch (InvalidConfigurationException e) {
// TODO(gregce): With "global configurations" we cannot tie a configuration creation failure
// to a single target and have to halt the entire build. Once configurations are genuinely
// created as part of the analysis phase they should report their error on the level of the
// target(s) that triggered them.
catastrophe = true;
throw e;
} finally {
if (!catastrophe) {
// Delete dirty nodes to ensure that they do not accumulate indefinitely.
long versionWindow = request.getViewOptions().versionWindowForDirtyNodeGc;
if (versionWindow != -1) {
env.getSkyframeExecutor().deleteOldNodes(versionWindow);
}
if (executionTool != null) {
executionTool.shutdown();
}
// The workspace status actions will not run with certain flags, or if an error
// occurs early in the build. Tell a lie so that the event is not missing.
// If multiple build_info events are sent, only the first is kept, so this does not harm
// successful runs (which use the workspace status action).
env.getEventBus().post(new BuildInfoEvent(env.getBlazeWorkspace().getWorkspaceStatusActionFactory().createDummyWorkspaceStatus()));
}
}
}
use of com.google.devtools.build.lib.analysis.config.InvalidConfigurationException in project bazel by bazelbuild.
the class CppConfiguration method resolveIncludeDir.
/**
* Resolve the given include directory.
*
* <p>If it starts with %sysroot%/, that part is replaced with the actual sysroot.
*
* <p>If it starts with %workspace%/, that part is replaced with the empty string
* (essentially making it relative to the build directory).
*
* <p>If it starts with %crosstool_top%/ or is any relative path, it is
* interpreted relative to the crosstool top. The use of assumed-crosstool-relative
* specifications is considered deprecated, and all such uses should eventually
* be replaced by "%crosstool_top%/".
*
* <p>If it is of the form %package(@repository//my/package)%/folder, then it is
* interpreted as the named folder in the appropriate package. All of the normal
* package syntax is supported. The /folder part is optional.
*
* <p>It is illegal if it starts with a % and does not match any of the above
* forms to avoid accidentally silently ignoring misspelled prefixes.
*
* <p>If it is absolute, it remains unchanged.
*/
static PathFragment resolveIncludeDir(String s, PathFragment sysroot, PathFragment crosstoolTopPathFragment) throws InvalidConfigurationException {
PathFragment pathPrefix;
String pathString;
int packageEndIndex = s.indexOf(PACKAGE_END);
if (packageEndIndex != -1 && s.startsWith(PACKAGE_START)) {
String packageString = s.substring(PACKAGE_START.length(), packageEndIndex);
try {
pathPrefix = PackageIdentifier.parse(packageString).getSourceRoot();
} catch (LabelSyntaxException e) {
throw new InvalidConfigurationException("The package '" + packageString + "' is not valid");
}
int pathStartIndex = packageEndIndex + PACKAGE_END.length();
if (pathStartIndex + 1 < s.length()) {
if (s.charAt(pathStartIndex) != '/') {
throw new InvalidConfigurationException("The path in the package for '" + s + "' is not valid");
}
pathString = s.substring(pathStartIndex + 1, s.length());
} else {
pathString = "";
}
} else if (s.startsWith(SYSROOT_START)) {
if (sysroot == null) {
throw new InvalidConfigurationException("A %sysroot% prefix is only allowed if the " + "default_sysroot option is set");
}
pathPrefix = sysroot;
pathString = s.substring(SYSROOT_START.length(), s.length());
} else if (s.startsWith(WORKSPACE_START)) {
pathPrefix = PathFragment.EMPTY_FRAGMENT;
pathString = s.substring(WORKSPACE_START.length(), s.length());
} else {
pathPrefix = crosstoolTopPathFragment;
if (s.startsWith(CROSSTOOL_START)) {
pathString = s.substring(CROSSTOOL_START.length(), s.length());
} else if (s.startsWith("%")) {
throw new InvalidConfigurationException("The include path '" + s + "' has an " + "unrecognized %prefix%");
} else {
pathString = s;
}
}
PathFragment path = new PathFragment(pathString);
if (!path.isNormalized()) {
throw new InvalidConfigurationException("The include path '" + s + "' is not normalized.");
}
return pathPrefix.getRelative(path);
}
use of com.google.devtools.build.lib.analysis.config.InvalidConfigurationException in project bazel by bazelbuild.
the class CppConfigurationLoader method createParameters.
@Nullable
protected CppConfigurationParameters createParameters(ConfigurationEnvironment env, BuildOptions options) throws InvalidConfigurationException, InterruptedException {
BlazeDirectories directories = env.getBlazeDirectories();
if (directories == null) {
return null;
}
Label crosstoolTopLabel = RedirectChaser.followRedirects(env, options.get(CppOptions.class).crosstoolTop, "crosstool_top");
if (crosstoolTopLabel == null) {
return null;
}
CrosstoolConfigurationLoader.CrosstoolFile file = CrosstoolConfigurationLoader.readCrosstool(env, crosstoolTopLabel);
if (file == null) {
return null;
}
CrosstoolConfig.CToolchain toolchain = CrosstoolConfigurationLoader.selectToolchain(file.getProto(), options, cpuTransformer);
// FDO
// TODO(bazel-team): move this to CppConfiguration.prepareHook
CppOptions cppOptions = options.get(CppOptions.class);
Path fdoZip;
if (cppOptions.fdoOptimize == null) {
fdoZip = null;
} else if (cppOptions.fdoOptimize.startsWith("//")) {
try {
Target target = env.getTarget(Label.parseAbsolute(cppOptions.fdoOptimize));
if (target == null) {
return null;
}
if (!(target instanceof InputFile)) {
throw new InvalidConfigurationException("--fdo_optimize cannot accept targets that do not refer to input files");
}
fdoZip = env.getPath(target.getPackage(), target.getName());
if (fdoZip == null) {
throw new InvalidConfigurationException("The --fdo_optimize parameter you specified resolves to a file that does not exist");
}
} catch (NoSuchPackageException | NoSuchTargetException | LabelSyntaxException e) {
env.getEventHandler().handle(Event.error(e.getMessage()));
throw new InvalidConfigurationException(e);
}
} else {
fdoZip = directories.getWorkspace().getRelative(cppOptions.fdoOptimize);
try {
// We don't check for file existence, but at least the filename should be well-formed.
FileSystemUtils.checkBaseName(fdoZip.getBaseName());
} catch (IllegalArgumentException e) {
throw new InvalidConfigurationException(e);
}
}
Label ccToolchainLabel;
Target crosstoolTop;
try {
crosstoolTop = env.getTarget(crosstoolTopLabel);
} catch (NoSuchThingException e) {
// Should have been found out during redirect chasing
throw new IllegalStateException(e);
}
if (crosstoolTop instanceof Rule && ((Rule) crosstoolTop).getRuleClass().equals("cc_toolchain_suite")) {
Rule ccToolchainSuite = (Rule) crosstoolTop;
ccToolchainLabel = NonconfigurableAttributeMapper.of(ccToolchainSuite).get("toolchains", BuildType.LABEL_DICT_UNARY).get(toolchain.getTargetCpu() + "|" + toolchain.getCompiler());
if (ccToolchainLabel == null) {
throw new InvalidConfigurationException(String.format("cc_toolchain_suite '%s' does not contain a toolchain for CPU '%s' and compiler '%s'", crosstoolTopLabel, toolchain.getTargetCpu(), toolchain.getCompiler()));
}
} else {
throw new InvalidConfigurationException(String.format("The specified --crosstool_top '%s' is not a valid cc_toolchain_suite rule", crosstoolTopLabel));
}
Target ccToolchain;
try {
ccToolchain = env.getTarget(ccToolchainLabel);
if (ccToolchain == null) {
return null;
}
} catch (NoSuchThingException e) {
throw new InvalidConfigurationException(String.format("The toolchain rule '%s' does not exist", ccToolchainLabel));
}
if (!(ccToolchain instanceof Rule) || !CcToolchainRule.isCcToolchain(ccToolchain)) {
throw new InvalidConfigurationException(String.format("The label '%s' is not a cc_toolchain rule", ccToolchainLabel));
}
return new CppConfigurationParameters(toolchain, file.getMd5(), options, fdoZip, crosstoolTopLabel, ccToolchainLabel);
}
use of com.google.devtools.build.lib.analysis.config.InvalidConfigurationException in project bazel by bazelbuild.
the class AspectFunction method compute.
@Nullable
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws AspectFunctionException, InterruptedException {
SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
NestedSetBuilder<Package> transitivePackages = NestedSetBuilder.stableOrder();
NestedSetBuilder<Label> transitiveRootCauses = NestedSetBuilder.stableOrder();
AspectKey key = (AspectKey) skyKey.argument();
ConfiguredAspectFactory aspectFactory;
Aspect aspect;
if (key.getAspectClass() instanceof NativeAspectClass) {
NativeAspectClass nativeAspectClass = (NativeAspectClass) key.getAspectClass();
aspectFactory = (ConfiguredAspectFactory) nativeAspectClass;
aspect = Aspect.forNative(nativeAspectClass, key.getParameters());
} else if (key.getAspectClass() instanceof SkylarkAspectClass) {
SkylarkAspectClass skylarkAspectClass = (SkylarkAspectClass) key.getAspectClass();
SkylarkAspect skylarkAspect;
try {
skylarkAspect = loadSkylarkAspect(env, skylarkAspectClass.getExtensionLabel(), skylarkAspectClass.getExportedName());
} catch (AspectCreationException e) {
throw new AspectFunctionException(e);
}
if (skylarkAspect == null) {
return null;
}
aspectFactory = new SkylarkAspectFactory(skylarkAspect);
aspect = Aspect.forSkylark(skylarkAspect.getAspectClass(), skylarkAspect.getDefinition(key.getParameters()), key.getParameters());
} else {
throw new IllegalStateException();
}
// Keep this in sync with the same code in ConfiguredTargetFunction.
PackageValue packageValue = (PackageValue) env.getValue(PackageValue.key(key.getLabel().getPackageIdentifier()));
if (packageValue == null) {
return null;
}
Package pkg = packageValue.getPackage();
if (pkg.containsErrors()) {
throw new AspectFunctionException(new BuildFileContainsErrorsException(key.getLabel().getPackageIdentifier()));
}
Target target;
try {
target = pkg.getTarget(key.getLabel().getName());
} catch (NoSuchTargetException e) {
throw new AspectFunctionException(e);
}
if (!(target instanceof Rule)) {
env.getListener().handle(Event.error(target.getLocation(), String.format("%s is attached to %s %s but aspects must be attached to rules", aspect.getAspectClass().getName(), target.getTargetKind(), target.getName())));
throw new AspectFunctionException(new AspectCreationException("aspects must be attached to rules"));
}
ConfiguredTargetValue configuredTargetValue;
try {
configuredTargetValue = (ConfiguredTargetValue) env.getValueOrThrow(ConfiguredTargetValue.key(key.getLabel(), key.getBaseConfiguration()), ConfiguredValueCreationException.class);
} catch (ConfiguredValueCreationException e) {
throw new AspectFunctionException(new AspectCreationException(e.getRootCauses()));
}
if (configuredTargetValue == null) {
// precomputed.
return null;
}
if (configuredTargetValue.getConfiguredTarget() == null) {
return null;
}
if (configuredTargetValue.getConfiguredTarget().getProvider(AliasProvider.class) != null) {
return createAliasAspect(env, target, aspect, key, configuredTargetValue.getConfiguredTarget());
}
ConfiguredTarget associatedTarget = configuredTargetValue.getConfiguredTarget();
ImmutableList.Builder<Aspect> aspectPathBuilder = ImmutableList.builder();
if (!key.getBaseKeys().isEmpty()) {
// We transitively collect all required aspects to reduce the number of restarts.
// Semantically it is enough to just request key.getBaseKeys().
ImmutableMap<AspectDescriptor, SkyKey> aspectKeys = getSkyKeysForAspects(key.getBaseKeys());
Map<SkyKey, SkyValue> values = env.getValues(aspectKeys.values());
if (env.valuesMissing()) {
return null;
}
try {
associatedTarget = getBaseTargetAndCollectPath(associatedTarget, key.getBaseKeys(), values, aspectPathBuilder);
} catch (DuplicateException e) {
env.getListener().handle(Event.error(associatedTarget.getTarget().getLocation(), e.getMessage()));
throw new AspectFunctionException(new AspectCreationException(e.getMessage(), associatedTarget.getLabel()));
}
}
aspectPathBuilder.add(aspect);
SkyframeDependencyResolver resolver = view.createDependencyResolver(env);
// When getting the dependencies of this hybrid aspect+base target, use the aspect's
// configuration. The configuration of the aspect will always be a superset of the target's
// (dynamic configuration mode: target is part of the aspect's config fragment requirements;
// static configuration mode: target is the same configuration as the aspect), so the fragments
// required by all dependencies (both those of the aspect and those of the base target)
// will be present this way.
TargetAndConfiguration originalTargetAndAspectConfiguration = new TargetAndConfiguration(target, key.getAspectConfiguration());
ImmutableList<Aspect> aspectPath = aspectPathBuilder.build();
try {
// Get the configuration targets that trigger this rule's configurable attributes.
ImmutableMap<Label, ConfigMatchingProvider> configConditions = ConfiguredTargetFunction.getConfigConditions(target, env, resolver, originalTargetAndAspectConfiguration, transitivePackages, transitiveRootCauses);
if (configConditions == null) {
// Those targets haven't yet been resolved.
return null;
}
OrderedSetMultimap<Attribute, ConfiguredTarget> depValueMap;
try {
depValueMap = ConfiguredTargetFunction.computeDependencies(env, resolver, originalTargetAndAspectConfiguration, aspectPath, configConditions, ruleClassProvider, view.getHostConfiguration(originalTargetAndAspectConfiguration.getConfiguration()), transitivePackages, transitiveRootCauses);
} catch (ConfiguredTargetFunctionException e) {
throw new AspectCreationException(e.getMessage());
}
if (depValueMap == null) {
return null;
}
if (!transitiveRootCauses.isEmpty()) {
throw new AspectFunctionException(new AspectCreationException("Loading failed", transitiveRootCauses.build()));
}
return createAspect(env, key, aspectPath, aspect, aspectFactory, associatedTarget, key.getAspectConfiguration(), configConditions, depValueMap, transitivePackages);
} catch (DependencyEvaluationException e) {
if (e.getCause() instanceof ConfiguredValueCreationException) {
ConfiguredValueCreationException cause = (ConfiguredValueCreationException) e.getCause();
throw new AspectFunctionException(new AspectCreationException(cause.getMessage(), cause.getAnalysisRootCause()));
} else if (e.getCause() instanceof InconsistentAspectOrderException) {
InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
throw new AspectFunctionException(new AspectCreationException(cause.getMessage()));
} else {
// Cast to InvalidConfigurationException as a consistency check. If you add any
// DependencyEvaluationException constructors, you may need to change this code, too.
InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
throw new AspectFunctionException(new AspectCreationException(cause.getMessage()));
}
} catch (AspectCreationException e) {
throw new AspectFunctionException(e);
}
}
use of com.google.devtools.build.lib.analysis.config.InvalidConfigurationException in project bazel by bazelbuild.
the class ConfiguredTargetFunction method compute.
@Override
public SkyValue compute(SkyKey key, Environment env) throws ConfiguredTargetFunctionException, InterruptedException {
SkyframeBuildView view = buildViewProvider.getSkyframeBuildView();
NestedSetBuilder<Package> transitivePackages = NestedSetBuilder.stableOrder();
NestedSetBuilder<Label> transitiveLoadingRootCauses = NestedSetBuilder.stableOrder();
ConfiguredTargetKey configuredTargetKey = (ConfiguredTargetKey) key.argument();
LabelAndConfiguration lc = LabelAndConfiguration.of(configuredTargetKey.getLabel(), configuredTargetKey.getConfiguration());
BuildConfiguration configuration = lc.getConfiguration();
PackageValue packageValue = (PackageValue) env.getValue(PackageValue.key(lc.getLabel().getPackageIdentifier()));
if (packageValue == null) {
return null;
}
// TODO(ulfjack): This tries to match the logic in TransitiveTargetFunction /
// TargetMarkerFunction. Maybe we can merge the two?
Package pkg = packageValue.getPackage();
Target target;
try {
target = pkg.getTarget(lc.getLabel().getName());
} catch (NoSuchTargetException e) {
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(e.getMessage()));
}
if (pkg.containsErrors()) {
transitiveLoadingRootCauses.add(lc.getLabel());
}
transitivePackages.add(pkg);
// null).
if (!target.isConfigurable()) {
configuration = null;
}
// associates the error with the dep, which is misleading.
if (useDynamicConfigurations(configuration) && configuration.trimConfigurations() && env.getValue(TransitiveTargetValue.key(lc.getLabel())) == null) {
return null;
}
TargetAndConfiguration ctgValue = new TargetAndConfiguration(target, configuration);
SkyframeDependencyResolver resolver = view.createDependencyResolver(env);
// TODO(janakr): this acquire() call may tie up this thread indefinitely, reducing the
// parallelism of Skyframe. This is a strict improvement over the prior state of the code, in
// which we ran with #processors threads, but ideally we would call #tryAcquire here, and if we
// failed, would exit this SkyFunction and restart it when permits were available.
cpuBoundSemaphore.acquire();
try {
// Get the configuration targets that trigger this rule's configurable attributes.
ImmutableMap<Label, ConfigMatchingProvider> configConditions = getConfigConditions(ctgValue.getTarget(), env, resolver, ctgValue, transitivePackages, transitiveLoadingRootCauses);
if (env.valuesMissing()) {
return null;
}
// attributes.
if (!transitiveLoadingRootCauses.isEmpty() && configConditions != NO_CONFIG_CONDITIONS) {
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
}
OrderedSetMultimap<Attribute, ConfiguredTarget> depValueMap = computeDependencies(env, resolver, ctgValue, ImmutableList.<Aspect>of(), configConditions, ruleClassProvider, view.getHostConfiguration(configuration), transitivePackages, transitiveLoadingRootCauses);
if (env.valuesMissing()) {
return null;
}
if (!transitiveLoadingRootCauses.isEmpty()) {
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(transitiveLoadingRootCauses.build()));
}
Preconditions.checkNotNull(depValueMap);
ConfiguredTargetValue ans = createConfiguredTarget(view, env, target, configuration, depValueMap, configConditions, transitivePackages);
return ans;
} catch (DependencyEvaluationException e) {
if (e.getCause() instanceof ConfiguredValueCreationException) {
throw new ConfiguredTargetFunctionException((ConfiguredValueCreationException) e.getCause());
} else if (e.getCause() instanceof InconsistentAspectOrderException) {
InconsistentAspectOrderException cause = (InconsistentAspectOrderException) e.getCause();
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(cause.getMessage(), target.getLabel()));
} else {
// Cast to InvalidConfigurationException as a consistency check. If you add any
// DependencyEvaluationException constructors, you may need to change this code, too.
InvalidConfigurationException cause = (InvalidConfigurationException) e.getCause();
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(cause.getMessage(), target.getLabel()));
}
} catch (AspectCreationException e) {
// getAnalysisRootCause may be null if the analysis of the aspect itself failed.
Label analysisRootCause = target.getLabel();
if (e.getAnalysisRootCause() != null) {
analysisRootCause = e.getAnalysisRootCause();
}
throw new ConfiguredTargetFunctionException(new ConfiguredValueCreationException(e.getMessage(), analysisRootCause));
} finally {
cpuBoundSemaphore.release();
}
}
Aggregations