use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.
the class AppleStaticLibrary method create.
@Override
public final ConfiguredTarget create(RuleContext ruleContext) throws InterruptedException, RuleErrorException {
PlatformType platformType = MultiArchSplitTransitionProvider.getPlatformType(ruleContext);
ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap = ruleContext.getPrerequisitesByConfiguration("deps", Mode.SPLIT);
ImmutableListMultimap<BuildConfiguration, ObjcProvider> configToObjcAvoidDepsMap = ruleContext.getPrerequisitesByConfiguration(AppleStaticLibraryRule.AVOID_DEPS_ATTR_NAME, Mode.SPLIT, ObjcProvider.class);
ImmutableListMultimap<BuildConfiguration, CcLinkParamsProvider> configToCcAvoidDepsMap = ruleContext.getPrerequisitesByConfiguration(AppleStaticLibraryRule.AVOID_DEPS_ATTR_NAME, Mode.SPLIT, CcLinkParamsProvider.class);
Set<BuildConfiguration> childConfigurations = getChildConfigurations(ruleContext);
IntermediateArtifacts ruleIntermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext);
NestedSetBuilder<Artifact> librariesToLipo = NestedSetBuilder.<Artifact>stableOrder();
NestedSetBuilder<Artifact> filesToBuild = NestedSetBuilder.<Artifact>stableOrder().add(ruleIntermediateArtifacts.combinedArchitectureArchive());
ObjcProvider.Builder objcProviderBuilder = new ObjcProvider.Builder();
for (BuildConfiguration childConfig : childConfigurations) {
ProtobufSupport protoSupport = new ProtobufSupport(ruleContext, childConfig).registerGenerationActions().registerCompilationActions();
Optional<ObjcProvider> protosObjcProvider = protoSupport.getObjcProvider();
IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext, childConfig);
ObjcCommon common = common(ruleContext, childConfig, intermediateArtifacts, nullToEmptyList(configToDepsCollectionMap.get(childConfig)), protosObjcProvider);
ObjcProvider objcProvider = common.getObjcProvider().subtractSubtrees(configToObjcAvoidDepsMap.get(childConfig), configToCcAvoidDepsMap.get(childConfig));
librariesToLipo.add(intermediateArtifacts.strippedSingleArchitectureLibrary());
CompilationSupport.createForConfig(ruleContext, childConfig).registerCompileAndArchiveActions(common).registerFullyLinkAction(objcProvider, intermediateArtifacts.strippedSingleArchitectureLibrary()).validateAttributes();
ruleContext.assertNoErrors();
addTransitivePropagatedKeys(objcProviderBuilder, objcProvider);
}
AppleConfiguration appleConfiguration = ruleContext.getFragment(AppleConfiguration.class);
new LipoSupport(ruleContext).registerCombineArchitecturesAction(librariesToLipo.build(), ruleIntermediateArtifacts.combinedArchitectureArchive(), appleConfiguration.getMultiArchPlatform(platformType));
RuleConfiguredTargetBuilder targetBuilder = ObjcRuleClasses.ruleConfiguredTarget(ruleContext, filesToBuild.build());
objcProviderBuilder.add(MULTI_ARCH_LINKED_ARCHIVES, ruleIntermediateArtifacts.combinedArchitectureArchive());
targetBuilder.addProvider(ObjcProvider.class, objcProviderBuilder.build());
return targetBuilder.build();
}
use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.
the class TestActionBuilder method createTestAction.
/**
* Creates a test action and artifacts for the given rule. The test action will
* use the specified executable and runfiles.
*
* @return ordered list of test artifacts, one per action. These are used to drive
* execution in Skyframe, and by AggregatingTestListener and
* TestResultAnalyzer to keep track of completed and pending test runs.
*/
private TestParams createTestAction(int shards) {
PathFragment targetName = new PathFragment(ruleContext.getLabel().getName());
BuildConfiguration config = ruleContext.getConfiguration();
AnalysisEnvironment env = ruleContext.getAnalysisEnvironment();
Root root = config.getTestLogsDirectory(ruleContext.getRule().getRepository());
NestedSetBuilder<Artifact> inputsBuilder = NestedSetBuilder.stableOrder();
inputsBuilder.addTransitive(NestedSetBuilder.create(Order.STABLE_ORDER, runfilesSupport.getRunfilesMiddleman()));
NestedSet<Artifact> testRuntime = PrerequisiteArtifacts.nestedSet(ruleContext, "$test_runtime", Mode.HOST);
inputsBuilder.addTransitive(testRuntime);
TestTargetProperties testProperties = new TestTargetProperties(ruleContext, executionRequirements);
// If the test rule does not provide InstrumentedFilesProvider, there's not much that we can do.
final boolean collectCodeCoverage = config.isCodeCoverageEnabled() && instrumentedFiles != null;
TreeMap<String, String> testEnv = new TreeMap<>();
TestTargetExecutionSettings executionSettings;
if (collectCodeCoverage) {
inputsBuilder.addTransitive(instrumentedFiles.getCoverageSupportFiles());
// Add instrumented file manifest artifact to the list of inputs. This file will contain
// exec paths of all source files that should be included into the code coverage output.
NestedSet<Artifact> metadataFiles = instrumentedFiles.getInstrumentationMetadataFiles();
inputsBuilder.addTransitive(metadataFiles);
inputsBuilder.addTransitive(PrerequisiteArtifacts.nestedSet(ruleContext, "$coverage_support", Mode.DONT_CHECK));
// We don't add this attribute to non-supported test target
if (ruleContext.isAttrDefined("$lcov_merger", LABEL)) {
Artifact lcovMerger = ruleContext.getPrerequisiteArtifact("$lcov_merger", Mode.TARGET);
if (lcovMerger != null) {
inputsBuilder.addTransitive(PrerequisiteArtifacts.nestedSet(ruleContext, "$lcov_merger", Mode.TARGET));
// Pass this LcovMerger_deploy.jar path to collect_coverage.sh
testEnv.put("LCOV_MERGER", lcovMerger.getExecPathString());
}
}
Artifact instrumentedFileManifest = InstrumentedFileManifestAction.getInstrumentedFileManifest(ruleContext, instrumentedFiles.getInstrumentedFiles(), metadataFiles);
executionSettings = new TestTargetExecutionSettings(ruleContext, runfilesSupport, executable, instrumentedFileManifest, shards);
inputsBuilder.add(instrumentedFileManifest);
for (Pair<String, String> coverageEnvEntry : instrumentedFiles.getCoverageEnvironment()) {
testEnv.put(coverageEnvEntry.getFirst(), coverageEnvEntry.getSecond());
}
} else {
executionSettings = new TestTargetExecutionSettings(ruleContext, runfilesSupport, executable, null, shards);
}
testEnv.putAll(extraEnv);
if (config.getRunUnder() != null) {
Artifact runUnderExecutable = executionSettings.getRunUnderExecutable();
if (runUnderExecutable != null) {
inputsBuilder.add(runUnderExecutable);
}
}
int runsPerTest = config.getRunsPerTestForLabel(ruleContext.getLabel());
Iterable<Artifact> inputs = inputsBuilder.build();
int shardRuns = (shards > 0 ? shards : 1);
List<Artifact> results = Lists.newArrayListWithCapacity(runsPerTest * shardRuns);
ImmutableList.Builder<Artifact> coverageArtifacts = ImmutableList.builder();
boolean useExperimentalTestRunner = false;
if (ruleContext.attributes().has("use_testrunner", Type.BOOLEAN)) {
useExperimentalTestRunner = ruleContext.attributes().get("use_testrunner", Type.BOOLEAN) && ruleContext.attributes().get("tags", Type.STRING_LIST).contains("experimental_testrunner");
}
for (int run = 0; run < runsPerTest; run++) {
// Use a 1-based index for user friendliness.
String testRunDir = runsPerTest > 1 ? String.format("run_%d_of_%d", run + 1, runsPerTest) : "";
for (int shard = 0; shard < shardRuns; shard++) {
String shardRunDir = (shardRuns > 1 ? String.format("shard_%d_of_%d", shard + 1, shards) : "");
if (testRunDir.isEmpty()) {
shardRunDir = shardRunDir.isEmpty() ? "" : shardRunDir + PathFragment.SEPARATOR_CHAR;
} else {
testRunDir += PathFragment.SEPARATOR_CHAR;
shardRunDir = shardRunDir.isEmpty() ? testRunDir : shardRunDir + "_" + testRunDir;
}
Artifact testLog = ruleContext.getPackageRelativeArtifact(targetName.getRelative(shardRunDir + "test.log"), root);
Artifact cacheStatus = ruleContext.getPackageRelativeArtifact(targetName.getRelative(shardRunDir + "test.cache_status"), root);
Artifact coverageArtifact = null;
if (collectCodeCoverage) {
coverageArtifact = ruleContext.getPackageRelativeArtifact(targetName.getRelative(shardRunDir + "coverage.dat"), root);
coverageArtifacts.add(coverageArtifact);
}
Artifact microCoverageArtifact = null;
if (collectCodeCoverage && config.isMicroCoverageEnabled()) {
microCoverageArtifact = ruleContext.getPackageRelativeArtifact(targetName.getRelative(shardRunDir + "coverage.micro.dat"), root);
}
env.registerAction(new TestRunnerAction(ruleContext.getActionOwner(), inputs, testRuntime, testLog, cacheStatus, coverageArtifact, microCoverageArtifact, testProperties, testEnv, executionSettings, shard, run, config, ruleContext.getWorkspaceName(), useExperimentalTestRunner));
results.add(cacheStatus);
}
}
// TODO(bazel-team): Passing the reportGenerator to every TestParams is a bit strange.
Artifact reportGenerator = null;
if (config.isCodeCoverageEnabled()) {
// It's not enough to add this if the rule has coverage enabled because the command line may
// contain rules with baseline coverage but no test rules that have coverage enabled, and in
// that case, we still need the report generator.
reportGenerator = ruleContext.getPrerequisiteArtifact("$coverage_report_generator", Mode.HOST);
}
return new TestParams(runsPerTest, shards, TestTimeout.getTestTimeout(ruleContext.getRule()), ruleContext.getRule().getRuleClass(), ImmutableList.copyOf(results), coverageArtifacts.build(), reportGenerator);
}
use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.
the class MultiArchBinarySupport method objcProviderByDepConfiguration.
/**
* Returns a map from from dependency configuration to the {@link ObjcCommon} which comprises all
* information about the dependencies in that configuration. This can be used both to register
* actions in {@link #registerActions} and collect provider information to be propagated upstream.
*
* @param childConfigurations the set of configurations in which dependencies of the current rule
* are built
* @param configToDepsCollectionMap a map from child configuration to providers that "deps" of the
* current rule have propagated in that configuration
* @param configurationToNonPropagatedObjcMap a map from child configuration to providers that
* "non_propagated_deps" of the current rule have propagated in that configuration
* @param dylibObjcProviders {@link ObjcProvider}s that dynamic library dependencies of the
* current rule have propagated
* @param dylibProtoProviders {@link ObjcProtoProvider} providers that dynamic library
* dependencies of the current rule have propagated
* @param bundleLoaderObjcProvider Optional ObjcProvider containing artifacts and paths to be
* included in this binary's compilation actions
* @throws RuleErrorException if there are attribute errors in the current rule context
*/
public Map<BuildConfiguration, ObjcProvider> objcProviderByDepConfiguration(Set<BuildConfiguration> childConfigurations, ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap, ImmutableListMultimap<BuildConfiguration, ObjcProvider> configurationToNonPropagatedObjcMap, Iterable<ObjcProvider> dylibObjcProviders, Iterable<ObjcProtoProvider> dylibProtoProviders) throws RuleErrorException, InterruptedException {
ImmutableMap.Builder<BuildConfiguration, ObjcProvider> configurationToObjcProviderBuilder = ImmutableMap.builder();
for (BuildConfiguration childConfig : childConfigurations) {
Optional<ObjcProvider> protosObjcProvider;
if (ObjcRuleClasses.objcConfiguration(ruleContext).enableAppleBinaryNativeProtos()) {
ProtobufSupport protoSupport = new ProtobufSupport(ruleContext, childConfig, protoArtifactsToAvoid(dylibProtoProviders)).registerGenerationActions().registerCompilationActions();
protosObjcProvider = protoSupport.getObjcProvider();
} else {
protosObjcProvider = Optional.absent();
}
IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext, childConfig);
Iterable<ObjcProvider> additionalDepProviders = Iterables.concat(dylibObjcProviders, ruleContext.getPrerequisites("bundles", Mode.TARGET, ObjcProvider.class), protosObjcProvider.asSet());
ObjcCommon common = common(ruleContext, childConfig, intermediateArtifacts, nullToEmptyList(configToDepsCollectionMap.get(childConfig)), nullToEmptyList(configurationToNonPropagatedObjcMap.get(childConfig)), additionalDepProviders);
ObjcProvider objcProvider = common.getObjcProvider().subtractSubtrees(dylibObjcProviders, ImmutableList.<CcLinkParamsProvider>of());
configurationToObjcProviderBuilder.put(childConfig, objcProvider);
}
return configurationToObjcProviderBuilder.build();
}
use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.
the class MultiArchBinarySupport method registerActions.
/**
* Registers actions to create a multi-arch Apple binary.
*
* @param platform the platform for which the binary is targeted
* @param extraLinkArgs the extra linker args to add to link actions linking single-architecture
* binaries together
* @param configurationToObjcProvider a map from from dependency configuration to the
* {@link ObjcProvider} which comprises all information about the dependencies in that
* configuration. Can be obtained via {@link #objcProviderByDepConfiguration}
* @param extraLinkInputs the extra linker inputs to be made available during link actions
* @param configToDepsCollectionMap a multimap from dependency configuration to the
* list of provider collections which are propagated from the dependencies of that
* configuration
* @param outputLipoBinary the artifact (lipo'ed binary) which should be output as a result of
* this support
* @throws RuleErrorException if there are attribute errors in the current rule context
*/
public void registerActions(Platform platform, ExtraLinkArgs extraLinkArgs, Map<BuildConfiguration, ObjcProvider> configurationToObjcProvider, Iterable<Artifact> extraLinkInputs, ImmutableListMultimap<BuildConfiguration, TransitiveInfoCollection> configToDepsCollectionMap, Artifact outputLipoBinary) throws RuleErrorException, InterruptedException {
NestedSetBuilder<Artifact> binariesToLipo = NestedSetBuilder.<Artifact>stableOrder();
for (BuildConfiguration childConfig : configurationToObjcProvider.keySet()) {
IntermediateArtifacts intermediateArtifacts = ObjcRuleClasses.intermediateArtifacts(ruleContext, childConfig);
ImmutableList.Builder<J2ObjcMappingFileProvider> j2ObjcMappingFileProviders = ImmutableList.builder();
J2ObjcEntryClassProvider.Builder j2ObjcEntryClassProviderBuilder = new J2ObjcEntryClassProvider.Builder();
for (TransitiveInfoCollection dep : configToDepsCollectionMap.get(childConfig)) {
if (dep.getProvider(J2ObjcMappingFileProvider.class) != null) {
j2ObjcMappingFileProviders.add(dep.getProvider(J2ObjcMappingFileProvider.class));
}
if (dep.getProvider(J2ObjcEntryClassProvider.class) != null) {
j2ObjcEntryClassProviderBuilder.addTransitive(dep.getProvider(J2ObjcEntryClassProvider.class));
}
}
J2ObjcMappingFileProvider j2ObjcMappingFileProvider = J2ObjcMappingFileProvider.union(j2ObjcMappingFileProviders.build());
J2ObjcEntryClassProvider j2ObjcEntryClassProvider = j2ObjcEntryClassProviderBuilder.build();
binariesToLipo.add(intermediateArtifacts.strippedSingleArchitectureBinary());
ObjcProvider objcProvider = configurationToObjcProvider.get(childConfig);
CompilationArtifacts compilationArtifacts = CompilationSupport.compilationArtifacts(ruleContext, ObjcRuleClasses.intermediateArtifacts(ruleContext, childConfig));
CompilationSupport.createForConfig(ruleContext, childConfig).registerCompileAndArchiveActions(compilationArtifacts, objcProvider).registerLinkActions(objcProvider, j2ObjcMappingFileProvider, j2ObjcEntryClassProvider, extraLinkArgs, extraLinkInputs, DsymOutputType.APP).validateAttributes();
ruleContext.assertNoErrors();
}
new LipoSupport(ruleContext).registerCombineArchitecturesAction(binariesToLipo.build(), outputLipoBinary, platform);
}
use of com.google.devtools.build.lib.analysis.config.BuildConfiguration in project bazel by bazelbuild.
the class InfoCommand method exec.
@Override
public ExitCode exec(final CommandEnvironment env, final OptionsProvider optionsProvider) {
final BlazeRuntime runtime = env.getRuntime();
env.getReporter().switchToAnsiAllowingHandler();
Options infoOptions = optionsProvider.getOptions(Options.class);
OutErr outErr = env.getReporter().getOutErr();
// Creating a BuildConfiguration is expensive and often unnecessary. Delay the creation until
// it is needed.
Supplier<BuildConfiguration> configurationSupplier = new Supplier<BuildConfiguration>() {
private BuildConfiguration configuration;
@Override
public BuildConfiguration get() {
if (configuration != null) {
return configuration;
}
try {
// In order to be able to answer configuration-specific queries, we need to setup the
// package path. Since info inherits all the build options, all the necessary information
// is available here.
env.setupPackageCache(optionsProvider, runtime.getDefaultsPackageContent(optionsProvider));
// TODO(bazel-team): What if there are multiple configurations? [multi-config]
configuration = env.getConfigurations(optionsProvider).getTargetConfigurations().get(0);
return configuration;
} catch (InvalidConfigurationException e) {
env.getReporter().handle(Event.error(e.getMessage()));
throw new ExitCausingRuntimeException(ExitCode.COMMAND_LINE_ERROR);
} catch (AbruptExitException e) {
throw new ExitCausingRuntimeException("unknown error: " + e.getMessage(), e.getExitCode());
} catch (InterruptedException e) {
env.getReporter().handle(Event.error("interrupted"));
throw new ExitCausingRuntimeException(ExitCode.INTERRUPTED);
}
}
};
Map<String, InfoItem> items = getInfoItemMap(env, optionsProvider);
try {
if (infoOptions.showMakeEnvironment) {
Map<String, String> makeEnv = configurationSupplier.get().getMakeEnvironment();
for (Map.Entry<String, String> entry : makeEnv.entrySet()) {
InfoItem item = new InfoItem.MakeInfoItem(entry.getKey(), entry.getValue());
items.put(item.getName(), item);
}
}
List<String> residue = optionsProvider.getResidue();
if (residue.size() > 1) {
env.getReporter().handle(Event.error("at most one key may be specified"));
return ExitCode.COMMAND_LINE_ERROR;
}
String key = residue.size() == 1 ? residue.get(0) : null;
env.getEventBus().post(new NoBuildEvent());
if (key != null) {
// print just the value for the specified key:
byte[] value;
if (items.containsKey(key)) {
value = items.get(key).get(configurationSupplier, env);
} else {
env.getReporter().handle(Event.error("unknown key: '" + key + "'"));
return ExitCode.COMMAND_LINE_ERROR;
}
try {
outErr.getOutputStream().write(value);
outErr.getOutputStream().flush();
} catch (IOException e) {
env.getReporter().handle(Event.error("Cannot write info block: " + e.getMessage()));
return ExitCode.ANALYSIS_FAILURE;
}
} else {
// print them all
// We'll need this later anyway
configurationSupplier.get();
for (InfoItem infoItem : items.values()) {
if (infoItem.isHidden()) {
continue;
}
outErr.getOutputStream().write((infoItem.getName() + ": ").getBytes(StandardCharsets.UTF_8));
outErr.getOutputStream().write(infoItem.get(configurationSupplier, env));
}
}
} catch (AbruptExitException e) {
return e.getExitCode();
} catch (ExitCausingRuntimeException e) {
return e.getExitCode();
} catch (IOException e) {
return ExitCode.LOCAL_ENVIRONMENTAL_ERROR;
} catch (InterruptedException e) {
return ExitCode.INTERRUPTED;
}
return ExitCode.SUCCESS;
}
Aggregations