Example #1
0
  /**
   * 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;
  }
Example #2
0
  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);
        }
      }
    }
  }
Example #3
0
 /** @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");
 }