/** * Constructs the C++ compiler actions. It generally creates one action for every specified source * file. It takes into account LIPO, fake-ness, coverage, and PIC, in addition to using the * settings specified on the current object. This method should only be called once. */ public CcCompilationOutputs createCcCompileActions() { CcCompilationOutputs.Builder result = new CcCompilationOutputs.Builder(); Preconditions.checkNotNull(context); AnalysisEnvironment env = ruleContext.getAnalysisEnvironment(); if (shouldProvideHeaderModules()) { Artifact moduleMapArtifact = context.getCppModuleMap().getArtifact(); Label moduleMapLabel = Label.parseAbsoluteUnchecked(context.getCppModuleMap().getName()); CppCompileActionBuilder builder = initializeCompileAction(moduleMapArtifact, moduleMapLabel, /*forInterface=*/ true); // A header module compile action is just like a normal compile action, but: // - the compiled source file is the module map // - it creates a header module (.pcm file). createSourceAction( FileSystemUtils.removeExtension(semantics.getEffectiveSourcePath(moduleMapArtifact)) .getPathString(), result, env, moduleMapArtifact, builder, ArtifactCategory.CPP_MODULE, /*addObject=*/ false, /*enableCoverage=*/ false, /*generateDwo=*/ false, CppFileTypes.mustProduceDotdFile(moduleMapArtifact.getFilename()), ImmutableMap.<String, String>of()); } for (CppSource source : sourceFiles) { Artifact sourceArtifact = source.getSource(); Label sourceLabel = source.getLabel(); String outputName = FileSystemUtils.removeExtension(semantics.getEffectiveSourcePath(sourceArtifact)) .getPathString(); CppCompileActionBuilder builder = initializeCompileAction(sourceArtifact, sourceLabel, /*forInterface=*/ false); if (CppFileTypes.CPP_HEADER.matches(source.getSource().getExecPath())) { createHeaderAction( outputName, result, env, builder, CppFileTypes.mustProduceDotdFile(sourceArtifact.getFilename())); } else { createSourceAction( outputName, result, env, sourceArtifact, builder, ArtifactCategory.OBJECT_FILE, /*addObject=*/ true, isCodeCoverageEnabled(), /*generateDwo=*/ cppConfiguration.useFission(), CppFileTypes.mustProduceDotdFile(sourceArtifact.getFilename()), source.getBuildVariables()); } } compilationOutputs = result.build(); return compilationOutputs; }
private void createSourceAction( String outputName, CcCompilationOutputs.Builder result, AnalysisEnvironment env, Artifact sourceArtifact, CppCompileActionBuilder builder, ArtifactCategory outputCategory, boolean addObject, boolean enableCoverage, boolean generateDwo, boolean generateDotd, Map<String, String> sourceSpecificBuildVariables) { PathFragment ccRelativeName = semantics.getEffectiveSourcePath(sourceArtifact); if (cppConfiguration.isLipoOptimization()) { // TODO(bazel-team): we shouldn't be needing this, merging context with the binary // is a superset of necessary information. LipoContextProvider lipoProvider = Preconditions.checkNotNull(CppHelper.getLipoContextProvider(ruleContext), outputName); builder.setContext( CppCompilationContext.mergeForLipo(lipoProvider.getLipoContext(), context)); } boolean generatePicAction = getGeneratePicActions(); // If we always need pic for everything, then don't bother to create a no-pic action. boolean generateNoPicAction = getGenerateNoPicActions(); Preconditions.checkState(generatePicAction || generateNoPicAction); if (fake) { boolean usePic = !generateNoPicAction; createFakeSourceAction( outputName, result, env, builder, outputCategory, addObject, ccRelativeName, sourceArtifact.getExecPath(), usePic, generateDotd); } else { // Create PIC compile actions (same as non-PIC, but use -fPIC and // generate .pic.o, .pic.d, .pic.gcno instead of .o, .d, .gcno.) if (generatePicAction) { String picOutputBase = CppHelper.getCompileArtifactName(ruleContext, ArtifactCategory.PIC_FILE, outputName); CppCompileActionBuilder picBuilder = copyAsPicBuilder(builder, picOutputBase, outputCategory, generateDotd); String gcnoFileName = CppHelper.getCompileArtifactName( ruleContext, ArtifactCategory.COVERAGE_DATA_FILE, picOutputBase); Artifact gcnoFile = enableCoverage ? CppHelper.getCompileOutputArtifact(ruleContext, gcnoFileName) : null; Artifact dwoFile = generateDwo ? getDwoFile(picBuilder.getOutputFile()) : null; setupCompileBuildVariables( picBuilder, /*usePic=*/ true, ccRelativeName, sourceArtifact.getExecPath(), gcnoFile, dwoFile, sourceSpecificBuildVariables); if (maySaveTemps) { result.addTemps( createTempsActions( sourceArtifact, outputName, picBuilder, /*usePic=*/ true, /*generateDotd=*/ generateDotd, ccRelativeName)); } picBuilder.setGcnoFile(gcnoFile); picBuilder.setDwoFile(dwoFile); semantics.finalizeCompileActionBuilder(ruleContext, picBuilder); CppCompileAction picAction = picBuilder.build(); env.registerAction(picAction); if (addObject) { result.addPicObjectFile(picAction.getOutputFile()); if (featureConfiguration.isEnabled(CppRuleClasses.THIN_LTO) && CppFileTypes.LTO_SOURCE.matches(sourceArtifact.getFilename())) { result.addLTOBitcodeFile(picAction.getOutputFile()); } } if (dwoFile != null) { // Host targets don't produce .dwo files. result.addPicDwoFile(dwoFile); } if (cppConfiguration.isLipoContextCollector() && !generateNoPicAction) { result.addLipoScannable(picAction); } } if (generateNoPicAction) { Artifact noPicOutputFile = CppHelper.getCompileOutputArtifact( ruleContext, CppHelper.getCompileArtifactName(ruleContext, outputCategory, outputName)); builder.setOutputs(outputCategory, outputName, generateDotd); String gcnoFileName = CppHelper.getCompileArtifactName( ruleContext, ArtifactCategory.COVERAGE_DATA_FILE, outputName); // Create non-PIC compile actions Artifact gcnoFile = !cppConfiguration.isLipoOptimization() && enableCoverage ? CppHelper.getCompileOutputArtifact(ruleContext, gcnoFileName) : null; Artifact noPicDwoFile = generateDwo ? getDwoFile(noPicOutputFile) : null; setupCompileBuildVariables( builder, /*usePic=*/ false, ccRelativeName, sourceArtifact.getExecPath(), gcnoFile, noPicDwoFile, sourceSpecificBuildVariables); if (maySaveTemps) { result.addTemps( createTempsActions( sourceArtifact, outputName, builder, /*usePic=*/ false, /*generateDotd*/ generateDotd, ccRelativeName)); } builder.setGcnoFile(gcnoFile); builder.setDwoFile(noPicDwoFile); semantics.finalizeCompileActionBuilder(ruleContext, builder); CppCompileAction compileAction = builder.build(); env.registerAction(compileAction); Artifact objectFile = compileAction.getOutputFile(); if (addObject) { result.addObjectFile(objectFile); if (featureConfiguration.isEnabled(CppRuleClasses.THIN_LTO) && CppFileTypes.LTO_SOURCE.matches(sourceArtifact.getFilename())) { result.addLTOBitcodeFile(objectFile); } } if (noPicDwoFile != null) { // Host targets don't produce .dwo files. result.addDwoFile(noPicDwoFile); } if (cppConfiguration.isLipoContextCollector()) { result.addLipoScannable(compileAction); } } } }
/** @return the pic header module artifact for the current target. */ public Artifact getPicHeaderModule(Artifact moduleMapArtifact) { PathFragment objectDir = CppHelper.getObjDirectory(ruleContext.getLabel()); PathFragment outputName = objectDir.getRelative(semantics.getEffectiveSourcePath(moduleMapArtifact)); return ruleContext.getRelatedArtifact(outputName, ".pic.pcm"); }