示例#1
0
  /** Create the actions for "--save_temps". */
  private ImmutableList<Artifact> createTempsActions(
      Artifact source,
      String outputName,
      CppCompileActionBuilder builder,
      boolean usePic,
      boolean generateDotd,
      PathFragment ccRelativeName) {
    if (!cppConfiguration.getSaveTemps()) {
      return ImmutableList.of();
    }

    String path = source.getFilename();
    boolean isCFile = CppFileTypes.C_SOURCE.matches(path);
    boolean isCppFile = CppFileTypes.CPP_SOURCE.matches(path);

    if (!isCFile && !isCppFile) {
      return ImmutableList.of();
    }

    ArtifactCategory category =
        isCFile ? ArtifactCategory.PREPROCESSED_C_SOURCE : ArtifactCategory.PREPROCESSED_CPP_SOURCE;

    String outputArtifactNameBase = getOutputNameBaseWith(outputName, usePic);

    CppCompileActionBuilder dBuilder = new CppCompileActionBuilder(builder);
    dBuilder.setOutputs(category, outputArtifactNameBase, generateDotd);
    setupCompileBuildVariables(
        dBuilder,
        usePic,
        ccRelativeName,
        source.getExecPath(),
        null,
        null,
        ImmutableMap.<String, String>of());
    semantics.finalizeCompileActionBuilder(ruleContext, dBuilder);
    CppCompileAction dAction = dBuilder.build();
    ruleContext.registerAction(dAction);

    CppCompileActionBuilder sdBuilder = new CppCompileActionBuilder(builder);
    sdBuilder.setOutputs(ArtifactCategory.GENERATED_ASSEMBLY, outputArtifactNameBase, generateDotd);
    setupCompileBuildVariables(
        sdBuilder,
        usePic,
        ccRelativeName,
        source.getExecPath(),
        null,
        null,
        ImmutableMap.<String, String>of());
    semantics.finalizeCompileActionBuilder(ruleContext, sdBuilder);
    CppCompileAction sdAction = sdBuilder.build();
    ruleContext.registerAction(sdAction);

    return ImmutableList.of(dAction.getOutputFile(), sdAction.getOutputFile());
  }
示例#2
0
  private void createHeaderAction(
      String outputName,
      Builder result,
      AnalysisEnvironment env,
      CppCompileActionBuilder builder,
      boolean generateDotd) {
    String outputNameBase =
        CppHelper.getCompileArtifactName(
            ruleContext, ArtifactCategory.GENERATED_HEADER, outputName);

    builder
        .setOutputs(ArtifactCategory.PROCESSED_HEADER, outputNameBase, generateDotd)
        // If we generate pic actions, we prefer the header actions to use the pic artifacts.
        .setPicMode(this.getGeneratePicActions());
    setupCompileBuildVariables(
        builder,
        this.getGeneratePicActions(),
        /*ccRelativeName=*/ null,
        /*autoFdoImportPath=*/ null,
        /*gcnoFile=*/ null,
        /*dwoFile=*/ null,
        ImmutableMap.<String, String>of());
    semantics.finalizeCompileActionBuilder(ruleContext, builder);
    CppCompileAction compileAction = builder.build();
    env.registerAction(compileAction);
    Artifact tokenFile = compileAction.getOutputFile();
    result.addHeaderTokenFile(tokenFile);
  }
示例#3
0
 /** Sets fields that overlap for cc_library and cc_binary rules. */
 public CcLibraryHelper fromCommon(CcCommon common) {
   this.addCopts(common.getCopts())
       .addDefines(common.getDefines())
       .addDeps(ruleContext.getPrerequisites("deps", Mode.TARGET))
       .addIncludeDirs(common.getIncludeDirs())
       .addLooseIncludeDirs(common.getLooseIncludeDirs())
       .addPicIndependentObjectFiles(common.getLinkerScripts())
       .addSystemIncludeDirs(common.getSystemIncludeDirs())
       .setNoCopts(common.getNoCopts())
       .setHeadersCheckingMode(semantics.determineHeadersCheckingMode(ruleContext));
   return this;
 }
示例#4
0
  private void createFakeSourceAction(
      String outputName,
      CcCompilationOutputs.Builder result,
      AnalysisEnvironment env,
      CppCompileActionBuilder builder,
      ArtifactCategory outputCategory,
      boolean addObject,
      PathFragment ccRelativeName,
      PathFragment execPath,
      boolean usePic,
      boolean generateDotd) {
    String outputNameBase = getOutputNameBaseWith(outputName, usePic);
    String tempOutputName =
        ruleContext
            .getConfiguration()
            .getBinFragment()
            .getRelative(CppHelper.getObjDirectory(ruleContext.getLabel()))
            .getRelative(
                CppHelper.getCompileArtifactName(
                    ruleContext,
                    outputCategory,
                    getOutputNameBaseWith(outputName + ".temp", usePic)))
            .getPathString();
    builder
        .setPicMode(usePic)
        .setOutputs(outputCategory, outputNameBase, generateDotd)
        .setTempOutputFile(new PathFragment(tempOutputName));

    setupCompileBuildVariables(
        builder,
        usePic,
        ccRelativeName,
        execPath,
        /*gcnoFile=*/ null,
        /*dwoFile=*/ null,
        ImmutableMap.<String, String>of());
    semantics.finalizeCompileActionBuilder(ruleContext, builder);
    CppCompileAction action = builder.build();
    env.registerAction(action);
    if (addObject) {
      if (usePic) {
        result.addPicObjectFile(action.getOutputFile());
      } else {
        result.addObjectFile(action.getOutputFile());
      }
    }
  }
示例#5
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);
        }
      }
    }
  }
示例#6
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;
  }
示例#7
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");
 }
示例#8
0
  /** Create context for cc compile action from generated inputs. */
  private CppCompilationContext initializeCppCompilationContext(CppModel model) {
    CppCompilationContext.Builder contextBuilder = new CppCompilationContext.Builder(ruleContext);

    // Setup the include path; local include directories come before those inherited from deps or
    // from the toolchain; in case of aliasing (same include file found on different entries),
    // prefer the local include rather than the inherited one.

    // Add in the roots for well-formed include names for source files and
    // generated files. It is important that the execRoot (EMPTY_FRAGMENT) comes
    // before the genfilesFragment to preferably pick up source files. Otherwise
    // we might pick up stale generated files.
    PathFragment repositoryPath =
        ruleContext.getLabel().getPackageIdentifier().getRepository().getPathFragment();
    contextBuilder.addQuoteIncludeDir(repositoryPath);
    contextBuilder.addQuoteIncludeDir(
        ruleContext.getConfiguration().getGenfilesFragment().getRelative(repositoryPath));

    for (PathFragment systemIncludeDir : systemIncludeDirs) {
      contextBuilder.addSystemIncludeDir(systemIncludeDir);
    }
    for (PathFragment includeDir : includeDirs) {
      contextBuilder.addIncludeDir(includeDir);
    }

    contextBuilder.mergeDependentContexts(
        AnalysisUtils.getProviders(deps, CppCompilationContext.class));
    CppHelper.mergeToolchainDependentContext(ruleContext, contextBuilder);

    // But defines come after those inherited from deps.
    contextBuilder.addDefines(defines);

    // There are no ordering constraints for declared include dirs/srcs, or the pregrepped headers.
    contextBuilder.addDeclaredIncludeSrcs(publicHeaders);
    contextBuilder.addDeclaredIncludeSrcs(publicTextualHeaders);
    contextBuilder.addDeclaredIncludeSrcs(privateHeaders);
    contextBuilder.addPregreppedHeaderMap(
        CppHelper.createExtractInclusions(ruleContext, semantics, publicHeaders));
    contextBuilder.addPregreppedHeaderMap(
        CppHelper.createExtractInclusions(ruleContext, semantics, publicTextualHeaders));
    contextBuilder.addPregreppedHeaderMap(
        CppHelper.createExtractInclusions(ruleContext, semantics, privateHeaders));
    contextBuilder.addCompilationPrerequisites(prerequisites);

    // Add this package's dir to declaredIncludeDirs, & this rule's headers to declaredIncludeSrcs
    // Note: no include dir for STRICT mode.
    if (headersCheckingMode == HeadersCheckingMode.WARN) {
      contextBuilder.addDeclaredIncludeWarnDir(ruleContext.getLabel().getPackageFragment());
      for (PathFragment looseIncludeDir : looseIncludeDirs) {
        contextBuilder.addDeclaredIncludeWarnDir(looseIncludeDir);
      }
    } else if (headersCheckingMode == HeadersCheckingMode.LOOSE) {
      contextBuilder.addDeclaredIncludeDir(ruleContext.getLabel().getPackageFragment());
      for (PathFragment looseIncludeDir : looseIncludeDirs) {
        contextBuilder.addDeclaredIncludeDir(looseIncludeDir);
      }
    }

    if (featureConfiguration.isEnabled(CppRuleClasses.MODULE_MAPS)) {
      CppModuleMap cppModuleMap = CppHelper.addCppModuleMapToContext(ruleContext, contextBuilder);
      // TODO(bazel-team): addCppModuleMapToContext second-guesses whether module maps should
      // actually be enabled, so we need to double-check here. Who would write code like this?
      if (cppModuleMap != null) {
        CppModuleMapAction action =
            new CppModuleMapAction(
                ruleContext.getActionOwner(),
                cppModuleMap,
                privateHeaders,
                publicHeaders,
                collectModuleMaps(),
                additionalExportedHeaders,
                featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULES),
                featureConfiguration.isEnabled(CppRuleClasses.MODULE_MAP_HOME_CWD),
                featureConfiguration.isEnabled(CppRuleClasses.GENERATE_SUBMODULES),
                !featureConfiguration.isEnabled(CppRuleClasses.MODULE_MAP_WITHOUT_EXTERN_MODULE));
        ruleContext.registerAction(action);
      }
      if (model.getGeneratesPicHeaderModule()) {
        contextBuilder.setPicHeaderModule(model.getPicHeaderModule(cppModuleMap.getArtifact()));
      }
      if (model.getGeneratesNoPicHeaderModule()) {
        contextBuilder.setHeaderModule(model.getHeaderModule(cppModuleMap.getArtifact()));
      }
      if (featureConfiguration.isEnabled(CppRuleClasses.USE_HEADER_MODULES)
          && featureConfiguration.isEnabled(CppRuleClasses.TRANSITIVE_MODULE_MAPS)) {
        contextBuilder.setProvideTransitiveModuleMaps(true);
      }
    }

    semantics.setupCompilationContext(ruleContext, contextBuilder);
    return contextBuilder.build();
  }