@Test public void testIncludePathOrder() throws Exception { scratch.file( "foo/BUILD", "cc_library(", " name = 'bar',", " includes = ['bar'],", ")", "cc_library(", " name = 'foo',", " srcs = ['foo.cc'],", " includes = ['foo'],", " deps = [':bar'],", ")"); ConfiguredTarget target = getConfiguredTarget("//foo"); CppCompileAction action = getCppCompileAction(target); String genfilesDir = target.getConfiguration().getGenfilesFragment().toString(); // Local include paths come first. assertContainsSublist( action.getCompilerOptions(), ImmutableList.of( "-isystem", "foo/foo", "-isystem", genfilesDir + "/foo/foo", "-isystem", "foo/bar", "-isystem", genfilesDir + "/foo/bar", "-isystem", TestConstants.GCC_INCLUDE_PATH)); }
/** * Returns the configurable attribute conditions necessary to evaluate the given configured * target, or null if not all dependencies have yet been SkyFrame-evaluated. */ @Nullable private Set<ConfigMatchingProvider> getConfigurableAttributeConditions( TargetAndConfiguration ctg, Environment env) { if (!(ctg.getTarget() instanceof Rule)) { return ImmutableSet.of(); } Rule rule = (Rule) ctg.getTarget(); RawAttributeMapper mapper = RawAttributeMapper.of(rule); Set<SkyKey> depKeys = new LinkedHashSet<>(); for (Attribute attribute : rule.getAttributes()) { for (Label label : mapper.getConfigurabilityKeys(attribute.getName(), attribute.getType())) { if (!BuildType.Selector.isReservedLabel(label)) { depKeys.add(ConfiguredTargetValue.key(label, ctg.getConfiguration())); } } } Map<SkyKey, SkyValue> cts = env.getValues(depKeys); if (env.valuesMissing()) { return null; } ImmutableSet.Builder<ConfigMatchingProvider> conditions = ImmutableSet.builder(); for (SkyValue ctValue : cts.values()) { ConfiguredTarget ct = ((ConfiguredTargetValue) ctValue).getConfiguredTarget(); conditions.add(Preconditions.checkNotNull(ct.getProvider(ConfigMatchingProvider.class))); } return conditions.build(); }
@Test public void testEmptyLinkopts() throws Exception { ConfiguredTarget hello = getConfiguredTarget("//hello:hello"); assertTrue( hello .getProvider(CcLinkParamsProvider.class) .getCcLinkParams(false, false) .getLinkopts() .isEmpty()); }
/** * Construct the event. * * @param targets The set of active targets that remain. * @param testTargets The collection of tests to be run. May be null. */ public TestFilteringCompleteEvent( Collection<? extends ConfiguredTarget> targets, Collection<? extends ConfiguredTarget> testTargets) { this.targets = ImmutableList.copyOf(targets); this.testTargets = testTargets == null ? null : ImmutableList.copyOf(testTargets); if (testTargets == null) { return; } for (ConfiguredTarget testTarget : testTargets) { Preconditions.checkState(testTarget.getProvider(TestProvider.class) != null); } }
private static PathFragment getOutputFilePath( ConfiguredTarget base, RuleContext ruleContext, String suffix) { PathFragment packagePathFragment = ruleContext.getLabel().getPackageIdentifier().getPathFragment(); String name = base.getLabel().getName(); return new PathFragment(packagePathFragment, new PathFragment(name + suffix)); }
private static JavaRuleIdeInfo makeJavaRuleIdeInfo( ConfiguredTarget base, RuleContext ruleContext, JavaRuleOutputJarsProvider outputJarsProvider, NestedSetBuilder<Artifact> ideResolveArtifacts, @Nullable Artifact packageManifest) { JavaRuleIdeInfo.Builder builder = JavaRuleIdeInfo.newBuilder(); collectJarsFromOutputJarsProvider(builder, ideResolveArtifacts, outputJarsProvider); Artifact jdeps = outputJarsProvider.getJdeps(); if (jdeps != null) { builder.setJdeps(makeArtifactLocation(jdeps)); } JavaGenJarsProvider genJarsProvider = base.getProvider(JavaGenJarsProvider.class); if (genJarsProvider != null) { collectGenJars(builder, ideResolveArtifacts, genJarsProvider); } Collection<Artifact> sourceFiles = getSources(ruleContext); for (Artifact sourceFile : sourceFiles) { builder.addSources(makeArtifactLocation(sourceFile)); } if (packageManifest != null) { builder.setPackageManifest(makeArtifactLocation(packageManifest)); } return builder.build(); }
@Nullable private static CppConfiguration getCppConfiguration(ConfiguredTarget base) { BuildConfiguration configuration = base.getConfiguration(); if (configuration != null) { return configuration.getFragment(CppConfiguration.class); } return null; }
/** * Checks that if this is an environment-restricted build, all top-level targets support the * expected environments. * * @param topLevelTargets the build's top-level targets * @throws ViewCreationFailedException if constraint enforcement is on, the build declares * environment-restricted top level configurations, and any top-level target doesn't support * the expected environments */ private void checkTargetEnvironmentRestrictions( Iterable<ConfiguredTarget> topLevelTargets, PackageManager packageManager) throws ViewCreationFailedException { for (ConfiguredTarget topLevelTarget : topLevelTargets) { BuildConfiguration config = topLevelTarget.getConfiguration(); if (config == null) { // TODO(bazel-team): support file targets (they should apply package-default constraints). continue; } else if (!config.enforceConstraints() || config.getTargetEnvironments().isEmpty()) { continue; } // Parse and collect this configuration's environments. EnvironmentCollection.Builder builder = new EnvironmentCollection.Builder(); for (Label envLabel : config.getTargetEnvironments()) { try { Target env = packageManager.getLoadedTarget(envLabel); builder.put(ConstraintSemantics.getEnvironmentGroup(env), envLabel); } catch (NoSuchPackageException | NoSuchTargetException | ConstraintSemantics.EnvironmentLookupException e) { throw new ViewCreationFailedException("invalid target environment", e); } } EnvironmentCollection expectedEnvironments = builder.build(); // Now check the target against those environments. SupportedEnvironmentsProvider provider = Verify.verifyNotNull(topLevelTarget.getProvider(SupportedEnvironmentsProvider.class)); Collection<Label> missingEnvironments = ConstraintSemantics.getUnsupportedEnvironments( provider.getEnvironments(), expectedEnvironments); if (!missingEnvironments.isEmpty()) { throw new ViewCreationFailedException( String.format( "This is a restricted-environment build. %s does not support" + " required environment%s %s", topLevelTarget.getLabel(), missingEnvironments.size() == 1 ? "" : "s", Joiner.on(", ").join(missingEnvironments))); } } }
@Test public void testFilesToBuildWithInterfaceSharedObjects() throws Exception { useConfiguration("--interface_shared_objects"); ConfiguredTarget hello = getConfiguredTarget("//hello:hello"); Artifact archive = getBinArtifact("libhello.a", hello); Artifact sharedObject = getBinArtifact("libhello.ifso", hello); Artifact implSharedObject = getBinArtifact("libhello.so", hello); Artifact sharedObjectLink = getSharedArtifact("_solib_k8/libhello_Slibhello.ifso", hello); Artifact implSharedObjectLink = getSharedArtifact("_solib_k8/libhello_Slibhello.so", hello); assertThat(getFilesToBuild(hello)).containsExactly(archive, sharedObject, implSharedObject); assertThat( LinkerInputs.toLibraryArtifacts( hello.getProvider(CcNativeLibraryProvider.class).getTransitiveCcNativeLibraries())) .containsExactly(sharedObjectLink); assertThat( hello .getProvider(CcExecutionDynamicLibrariesProvider.class) .getExecutionDynamicLibraryArtifacts()) .containsExactly(implSharedObjectLink); }
/** * Takes a set of configured targets, and checks if the distribution methods declared for the * targets are compatible with the constraints imposed by their prerequisites' licenses. * * @param configuredTargets the targets to check * @param keepGoing if false, and a licensing error is encountered, both generates an error * message on the reporter, <em>and</em> throws an exception. If true, then just generates a * message on the reporter. * @throws ViewCreationFailedException if the license checking failed (and not --keep_going) */ private void validateLicensingForTargets( Iterable<ConfiguredTarget> configuredTargets, boolean keepGoing) throws ViewCreationFailedException { for (ConfiguredTarget configuredTarget : configuredTargets) { final Target target = configuredTarget.getTarget(); if (TargetUtils.isTestRule(target)) { continue; // Tests are exempt from license checking } final Set<DistributionType> distribs = target.getDistributions(); BuildConfiguration config = configuredTarget.getConfiguration(); boolean staticallyLinked = (config != null) && config.performsStaticLink(); staticallyLinked |= (config != null) && (target instanceof Rule) && ((Rule) target).getRuleClassObject().hasAttr("linkopts", Type.STRING_LIST) && ConfiguredAttributeMapper.of((RuleConfiguredTarget) configuredTarget) .get("linkopts", Type.STRING_LIST) .contains("-static"); LicensesProvider provider = configuredTarget.getProvider(LicensesProvider.class); if (provider != null) { NestedSet<TargetLicense> licenses = provider.getTransitiveLicenses(); for (TargetLicense targetLicense : licenses) { if (!targetLicense .getLicense() .checkCompatibility( distribs, target, targetLicense.getLabel(), getReporter(), staticallyLinked)) { if (!keepGoing) { throw new ViewCreationFailedException("Build aborted due to licensing error"); } } } } else if (configuredTarget.getTarget() instanceof InputFile) { // Input file targets do not provide licenses because they do not // depend on the rule where their license is taken from. This is usually // not a problem, because the transitive collection of licenses always // hits the rule they come from, except when the input file is a // top-level target. Thus, we need to handle that case specially here. // // See FileTarget#getLicense for more information about the handling of // license issues with File targets. License license = configuredTarget.getTarget().getLicense(); if (!license.checkCompatibility( distribs, target, configuredTarget.getLabel(), getReporter(), staticallyLinked)) { if (!keepGoing) { throw new ViewCreationFailedException("Build aborted due to licensing error"); } } } } }
@Nullable @Override public SkyValue compute(SkyKey skyKey, Environment env) throws SkyFunctionException, InterruptedException { ImmutableMap<Action, ConflictException> badActions = PrecomputedValue.BAD_ACTIONS.get(env); ConfiguredTargetValue ctValue = (ConfiguredTargetValue) env.getValue(ConfiguredTargetValue.key((ConfiguredTargetKey) skyKey.argument())); SkyframeDependencyResolver resolver = buildViewProvider.getSkyframeBuildView().createDependencyResolver(env); if (env.valuesMissing()) { return null; } for (Action action : ctValue.getActions()) { if (badActions.containsKey(action)) { throw new ActionConflictFunctionException(badActions.get(action)); } } ConfiguredTarget ct = ctValue.getConfiguredTarget(); TargetAndConfiguration ctgValue = new TargetAndConfiguration(ct.getTarget(), ct.getConfiguration()); Set<ConfigMatchingProvider> configConditions = getConfigurableAttributeConditions(ctgValue, env); if (configConditions == null) { return null; } ListMultimap<Attribute, Dependency> deps; try { BuildConfiguration hostConfiguration = buildViewProvider.getSkyframeBuildView().getHostConfiguration(ct.getConfiguration()); deps = resolver.dependentNodeMap( ctgValue, hostConfiguration, /*aspect=*/ null, configConditions); if (ct.getConfiguration() != null && ct.getConfiguration().useDynamicConfigurations()) { deps = ConfiguredTargetFunction.trimConfigurations( env, ctgValue, deps, hostConfiguration, ruleClassProvider); } } catch (EvalException e) { throw new PostConfiguredTargetFunctionException(e); } catch (ConfiguredTargetFunction.DependencyEvaluationException e) { throw new PostConfiguredTargetFunctionException(e); } env.getValues(Iterables.transform(deps.values(), TO_KEYS)); if (env.valuesMissing()) { return null; } return new PostConfiguredTargetValue(ct); }
@Deprecated private RuleIdeInfo.Kind getRuleKind(Rule rule, ConfiguredTarget base) { switch (rule.getRuleClassObject().getName()) { case "java_library": return Kind.JAVA_LIBRARY; case "java_import": return Kind.JAVA_IMPORT; case "java_test": return Kind.JAVA_TEST; case "java_binary": return Kind.JAVA_BINARY; case "android_library": return Kind.ANDROID_LIBRARY; case "android_binary": return Kind.ANDROID_BINARY; case "android_test": return Kind.ANDROID_TEST; case "android_robolectric_test": return Kind.ANDROID_ROBOELECTRIC_TEST; case "proto_library": return Kind.PROTO_LIBRARY; case "java_plugin": return Kind.JAVA_PLUGIN; case "android_resources": return Kind.ANDROID_RESOURCES; case "cc_library": return Kind.CC_LIBRARY; case "cc_binary": return Kind.CC_BINARY; case "cc_test": return Kind.CC_TEST; case "cc_inc_library": return Kind.CC_INC_LIBRARY; case "cc_toolchain": return Kind.CC_TOOLCHAIN; case "java_wrap_cc": return Kind.JAVA_WRAP_CC; default: { if (base.getProvider(AndroidSdkProvider.class) != null) { return RuleIdeInfo.Kind.ANDROID_SDK; } else { return RuleIdeInfo.Kind.UNRECOGNIZED; } } } }
/** * Helper for differential analysis which aggregates the TestSummary for an individual target, * reporting runs on the EventBus if necessary. */ private TestSummary.Builder aggregateAndReportSummary( ConfiguredTarget testTarget, AggregatingTestListener listener) { // If already reported by the listener, no work remains for this target. TestSummary.Builder summary = listener.getCurrentSummary(testTarget); Label testLabel = testTarget.getLabel(); Preconditions.checkNotNull( summary, "%s did not complete test filtering, but has a test result", testLabel); if (listener.targetReported(testTarget)) { return summary; } Collection<Artifact> incompleteRuns = listener.getIncompleteRuns(testTarget); Map<Artifact, TestResult> statusMap = listener.getStatusMap(); // We will get back multiple TestResult instances if test had to be retried several // times before passing. Sharding and multiple runs of the same test without retries // will be represented by separate artifacts and will produce exactly one TestResult. for (Artifact testStatus : TestProvider.getTestStatusArtifacts(testTarget)) { // When a build is interrupted ( eg. a broken target with --nokeep_going ) runResult could // be null for an unrelated test because we were not able to even try to execute the test. // In that case, for tests that were previously passing we return null ( == NO STATUS), // because checking if the cached test target is up-to-date would require running the // dependency checker transitively. TestResult runResult = statusMap.get(testStatus); boolean isIncompleteRun = incompleteRuns.contains(testStatus); if (runResult == null) { summary = markIncomplete(summary); } else if (isIncompleteRun) { // Only process results which were not recorded by the listener. boolean newlyFetched = !statusMap.containsKey(testStatus); summary = incrementalAnalyze(summary, runResult); if (newlyFetched) { eventBus.post(runResult); } Preconditions.checkState( listener.getIncompleteRuns(testTarget).contains(testStatus) == isIncompleteRun, "TestListener changed in differential analysis. Ensure it isn't still registered."); } } // The target was not posted by the listener and must be posted now. eventBus.post(summary.build()); return summary; }
private DependenciesResult processDependencies( ConfiguredTarget base, RuleContext ruleContext, AndroidStudioInfoFilesProvider.Builder providerBuilder) { // Calculate direct dependencies ImmutableList.Builder<TransitiveInfoCollection> directDepsBuilder = ImmutableList.builder(); for (PrerequisiteAttr prerequisiteAttr : PREREQUISITE_ATTRS) { if (ruleContext.attributes().has(prerequisiteAttr.name, prerequisiteAttr.type)) { directDepsBuilder.addAll(ruleContext.getPrerequisites(prerequisiteAttr.name, Mode.TARGET)); } } List<TransitiveInfoCollection> directDeps = directDepsBuilder.build(); // Add exports from direct dependencies NestedSetBuilder<Label> dependenciesBuilder = NestedSetBuilder.stableOrder(); for (AndroidStudioInfoFilesProvider depProvider : AnalysisUtils.getProviders(directDeps, AndroidStudioInfoFilesProvider.class)) { dependenciesBuilder.addTransitive(depProvider.getExportedDeps()); } for (TransitiveInfoCollection dep : directDeps) { dependenciesBuilder.add(dep.getLabel()); } NestedSet<Label> dependencies = dependenciesBuilder.build(); // Propagate my own exports JavaExportsProvider javaExportsProvider = base.getProvider(JavaExportsProvider.class); if (javaExportsProvider != null) { providerBuilder .exportedDepsBuilder() .addTransitive(javaExportsProvider.getTransitiveExports()); } // android_library without sources exports all its deps if (ruleContext.getRule().getRuleClass().equals("android_library")) { JavaSourceInfoProvider sourceInfoProvider = base.getProvider(JavaSourceInfoProvider.class); boolean hasSources = sourceInfoProvider != null && !sourceInfoProvider.getSourceFiles().isEmpty(); if (!hasSources) { for (TransitiveInfoCollection dep : directDeps) { providerBuilder.exportedDepsBuilder().add(dep.getLabel()); } } } // runtime_deps List<? extends TransitiveInfoCollection> runtimeDeps = ImmutableList.of(); NestedSetBuilder<Label> runtimeDepsBuilder = NestedSetBuilder.stableOrder(); if (ruleContext.attributes().has("runtime_deps", BuildType.LABEL_LIST)) { runtimeDeps = ruleContext.getPrerequisites("runtime_deps", Mode.TARGET); for (TransitiveInfoCollection dep : runtimeDeps) { runtimeDepsBuilder.add(dep.getLabel()); } } // resources @Nullable TransitiveInfoCollection resources = ruleContext.attributes().has("resources", BuildType.LABEL) ? ruleContext.getPrerequisite("resources", Mode.TARGET) : null; // Propagate providers from all prerequisites (deps + runtime_deps) ImmutableList.Builder<TransitiveInfoCollection> prerequisitesBuilder = ImmutableList.builder(); prerequisitesBuilder.addAll(directDeps); prerequisitesBuilder.addAll(runtimeDeps); if (resources != null) { prerequisitesBuilder.add(resources); } List<TransitiveInfoCollection> prerequisites = prerequisitesBuilder.build(); for (AndroidStudioInfoFilesProvider depProvider : AnalysisUtils.getProviders(prerequisites, AndroidStudioInfoFilesProvider.class)) { providerBuilder.ideInfoFilesBuilder().addTransitive(depProvider.getIdeInfoFiles()); providerBuilder.ideInfoTextFilesBuilder().addTransitive(depProvider.getIdeInfoTextFiles()); providerBuilder.ideResolveFilesBuilder().addTransitive(depProvider.getIdeResolveFiles()); } return new DependenciesResult( dependencies, runtimeDepsBuilder.build(), resources != null ? resources.getLabel() : null); }
private AndroidStudioInfoFilesProvider createIdeBuildArtifact( ConfiguredTarget base, RuleContext ruleContext, Kind ruleKind, DependenciesResult dependenciesResult, AndroidStudioInfoFilesProvider.Builder providerBuilder) { Artifact ideInfoFile = derivedArtifact(base, ruleContext, ASWB_BUILD_SUFFIX); Artifact ideInfoTextFile = derivedArtifact(base, ruleContext, ASWB_BUILD_TEXT_SUFFIX); providerBuilder.ideInfoFilesBuilder().add(ideInfoFile); providerBuilder.ideInfoTextFilesBuilder().add(ideInfoTextFile); NestedSetBuilder<Artifact> ideResolveArtifacts = providerBuilder.ideResolveFilesBuilder(); RuleIdeInfo.Builder outputBuilder = RuleIdeInfo.newBuilder(); outputBuilder.setLabel(base.getLabel().toString()); outputBuilder.setBuildFile( ruleContext.getRule().getPackage().getBuildFile().getPath().toString()); outputBuilder.setBuildFileArtifactLocation( makeArtifactLocation(ruleContext.getRule().getPackage())); if (ruleKind != Kind.UNRECOGNIZED) { outputBuilder.setKind(ruleKind); } outputBuilder.setKindString(ruleContext.getRule().getRuleClass()); // Java rules JavaRuleOutputJarsProvider outputJarsProvider = base.getProvider(JavaRuleOutputJarsProvider.class); if (outputJarsProvider != null) { Artifact packageManifest = createPackageManifest(base, ruleContext); if (packageManifest != null) { providerBuilder.ideInfoFilesBuilder().add(packageManifest); ruleContext.registerAction( makePackageManifestAction(ruleContext, packageManifest, getJavaSources(ruleContext))); } JavaRuleIdeInfo javaRuleIdeInfo = makeJavaRuleIdeInfo( base, ruleContext, outputJarsProvider, ideResolveArtifacts, packageManifest); outputBuilder.setJavaRuleIdeInfo(javaRuleIdeInfo); } // C rules CppCompilationContext cppCompilationContext = base.getProvider(CppCompilationContext.class); if (cppCompilationContext != null) { CRuleIdeInfo cRuleIdeInfo = makeCRuleIdeInfo(base, ruleContext, cppCompilationContext); outputBuilder.setCRuleIdeInfo(cRuleIdeInfo); } // CCToolchain rule CppConfiguration cppConfiguration = getCppConfiguration(base); if (cppConfiguration != null) { CToolchainIdeInfo cToolchainIdeInfo = makeCToolchainIdeInfo(ruleContext, cppConfiguration); if (cToolchainIdeInfo != null) { outputBuilder.setCToolchainIdeInfo(cToolchainIdeInfo); } } // Android rules AndroidIdeInfoProvider androidIdeInfoProvider = base.getProvider(AndroidIdeInfoProvider.class); if (androidIdeInfoProvider != null) { outputBuilder.setAndroidRuleIdeInfo( makeAndroidRuleIdeInfo( base, androidIdeInfoProvider, dependenciesResult, ideResolveArtifacts)); } AndroidStudioInfoFilesProvider provider = providerBuilder.build(); outputBuilder.addAllDependencies(transform(dependenciesResult.deps, LABEL_TO_STRING)); outputBuilder.addAllRuntimeDeps(transform(dependenciesResult.runtimeDeps, LABEL_TO_STRING)); outputBuilder.addAllTags(base.getTarget().getAssociatedRule().getRuleTags()); final RuleIdeInfo ruleIdeInfo = outputBuilder.build(); ruleContext.registerAction( makeProtoWriteAction(ruleContext.getActionOwner(), ruleIdeInfo, ideInfoFile)); ruleContext.registerAction( makeProtoTextWriteAction(ruleContext.getActionOwner(), ruleIdeInfo, ideInfoTextFile)); return provider; }
private void assertNoCppModuleMapAction(String label) throws Exception { ConfiguredTarget target = getConfiguredTarget(label); assertNull(target.getProvider(CppCompilationContext.class).getCppModuleMap()); }
private CppModuleMapAction getCppModuleMapAction(String label) throws Exception { ConfiguredTarget target = getConfiguredTarget(label); CppModuleMap cppModuleMap = target.getProvider(CppCompilationContext.class).getCppModuleMap(); return (CppModuleMapAction) getGeneratingAction(cppModuleMap.getArtifact()); }