// 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.analysis.constraints; import com.google.common.base.Joiner; import com.google.common.base.Verify; import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Multimap; import com.google.devtools.build.lib.analysis.ConfiguredTarget; import com.google.devtools.build.lib.analysis.OutputFileConfiguredTarget; import com.google.devtools.build.lib.analysis.TransitiveInfoCollection; import com.google.devtools.build.lib.analysis.ViewCreationFailedException; import com.google.devtools.build.lib.analysis.config.BuildConfiguration; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.events.ExtendedEventHandler; import com.google.devtools.build.lib.packages.EnvironmentGroup; import com.google.devtools.build.lib.packages.NoSuchPackageException; import com.google.devtools.build.lib.packages.NoSuchTargetException; import com.google.devtools.build.lib.packages.Target; import com.google.devtools.build.lib.pkgcache.PackageManager; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.Nullable; /** * Constraint semantics that apply to top-level targets. * *

Top-level targets are "special" because they have no parents that can assert expected * environment compatibility. So these expectations have to be declared by other means. * *

For all other targets see {@link ConstraintSemantics}. */ public class TopLevelConstraintSemantics { /** * Checks that if this is an environment-restricted build, all top-level targets support * expected top-level environments. Expected top-level environments can be declared explicitly * through {@code --target_environment} or implicitly through * {@code --experimental_auto_cpu_environment_group}. For the latter, top-level targets must * be compatible with the build's target configuration CPU. * *

If any target doesn't support an explicitly expected environment declared through * {@link BuildConfiguration.Options#targetEnvironments}, the entire build fails with an error. * *

If any target doesn't support an implicitly expected environment declared through * {@link BuildConfiguration.Options#autoCpuEnvironmentGroup}, the target is skipped during * execution while remaining targets execute as normal. * * @param topLevelTargets the build's top-level targets * @param packageManager object for retrieving loaded targets * @param eventHandler the build's event handler * * @return the set of bad top-level targets. * @throws ViewCreationFailedException if any target doesn't support an explicitly expected * environment declared through {@link BuildConfiguration.Options#targetEnvironments} */ public static Set checkTargetEnvironmentRestrictions( Iterable topLevelTargets, PackageManager packageManager, ExtendedEventHandler eventHandler) throws ViewCreationFailedException, InterruptedException { ImmutableSet.Builder badTargets = ImmutableSet.builder(); // Maps targets that are missing *explicitly* required environments to the set of environments // they're missing. These targets trigger a ViewCreationFailedException, which halts the build. // Targets with missing *implicitly* required environments don't belong here, since the build // continues while skipping them. Multimap exceptionInducingTargets = ArrayListMultimap.create(); for (ConfiguredTarget topLevelTarget : topLevelTargets) { BuildConfiguration config = topLevelTarget.getConfiguration(); boolean failBuildIfTargetIsBad = true; if (config == null) { // TODO(bazel-team): support file targets (they should apply package-default constraints). continue; } else if (!config.enforceConstraints()) { continue; } List