示例#1
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;
 }
示例#2
0
  /** Create the C++ compile and link actions, and the corresponding C++-related providers. */
  public Info build() {
    // Fail early if there is no lipo context collector on the rule - otherwise we end up failing
    // in lipo optimization.
    Preconditions.checkState(
        // 'cc_inc_library' rules do not compile, and thus are not affected by LIPO.
        ruleContext.getRule().getRuleClass().equals("cc_inc_library")
            || ruleContext.getRule().isAttrDefined(":lipo_context_collector", BuildType.LABEL));

    if (checkDepsGenerateCpp) {
      for (LanguageDependentFragment dep :
          AnalysisUtils.getProviders(deps, LanguageDependentFragment.class)) {
        LanguageDependentFragment.Checker.depSupportsLanguage(
            ruleContext, dep, CppRuleClasses.LANGUAGE);
      }
    }

    CppModel model = initializeCppModel();
    CppCompilationContext cppCompilationContext = initializeCppCompilationContext(model);
    model.setContext(cppCompilationContext);
    boolean compileHeaderModules = featureConfiguration.isEnabled(CppRuleClasses.HEADER_MODULES);
    Preconditions.checkState(
        !compileHeaderModules || cppCompilationContext.getCppModuleMap() != null,
        "All cc rules must support module maps.");

    // Create compile actions (both PIC and non-PIC).
    CcCompilationOutputs ccOutputs = model.createCcCompileActions();
    if (!objectFiles.isEmpty() || !picObjectFiles.isEmpty()) {
      // Merge the pre-compiled object files into the compiler outputs.
      ccOutputs =
          new CcCompilationOutputs.Builder()
              .merge(ccOutputs)
              .addLTOBitcodeFile(ccOutputs.getLtoBitcodeFiles())
              .addObjectFiles(objectFiles)
              .addPicObjectFiles(picObjectFiles)
              .build();
    }

    // Create link actions (only if there are object files or if explicitly requested).
    CcLinkingOutputs ccLinkingOutputs = CcLinkingOutputs.EMPTY;
    if (emitLinkActionsIfEmpty || !ccOutputs.isEmpty()) {
      // On some systems, the linker gives an error message if there are no input files. Even with
      // the check above, this can still happen if there is a .nopic.o or .o files in srcs, but no
      // other files. To fix that, we'd have to check for each link action individually.
      //
      // An additional pre-existing issue is that the header check tokens are dropped if we don't
      // generate any link actions, effectively disabling header checking in some cases.
      if (linkType.isStaticLibraryLink()) {
        // TODO(bazel-team): This can't create the link action for a cc_binary yet.
        ccLinkingOutputs = model.createCcLinkActions(ccOutputs);
      }
    }
    CcLinkingOutputs originalLinkingOutputs = ccLinkingOutputs;
    if (!(staticLibraries.isEmpty()
        && picStaticLibraries.isEmpty()
        && dynamicLibraries.isEmpty())) {
      // Merge the pre-compiled libraries (static & dynamic) into the linker outputs.
      ccLinkingOutputs =
          new CcLinkingOutputs.Builder()
              .merge(ccLinkingOutputs)
              .addStaticLibraries(staticLibraries)
              .addPicStaticLibraries(picStaticLibraries)
              .addDynamicLibraries(dynamicLibraries)
              .addExecutionDynamicLibraries(dynamicLibraries)
              .build();
    }

    DwoArtifactsCollector dwoArtifacts = DwoArtifactsCollector.transitiveCollector(ccOutputs, deps);
    Runfiles cppStaticRunfiles = collectCppRunfiles(ccLinkingOutputs, true);
    Runfiles cppSharedRunfiles = collectCppRunfiles(ccLinkingOutputs, false);

    // By very careful when adding new providers here - it can potentially affect a lot of rules.
    // We should consider merging most of these providers into a single provider.
    Map<Class<? extends TransitiveInfoProvider>, TransitiveInfoProvider> providers =
        new LinkedHashMap<>();
    providers.put(
        CppRunfilesProvider.class, new CppRunfilesProvider(cppStaticRunfiles, cppSharedRunfiles));
    providers.put(CppCompilationContext.class, cppCompilationContext);
    providers.put(
        CppDebugFileProvider.class,
        new CppDebugFileProvider(
            dwoArtifacts.getDwoArtifacts(), dwoArtifacts.getPicDwoArtifacts()));
    providers.put(TransitiveLipoInfoProvider.class, collectTransitiveLipoInfo(ccOutputs));
    Map<String, NestedSet<Artifact>> outputGroups = new TreeMap<>();
    outputGroups.put(OutputGroupProvider.TEMP_FILES, getTemps(ccOutputs));
    if (emitCompileProviders) {
      boolean isLipoCollector =
          ruleContext.getFragment(CppConfiguration.class).isLipoContextCollector();
      boolean processHeadersInDependencies =
          ruleContext.getFragment(CppConfiguration.class).processHeadersInDependencies();
      boolean usePic = CppHelper.usePic(ruleContext, false);
      outputGroups.put(
          OutputGroupProvider.FILES_TO_COMPILE,
          ccOutputs.getFilesToCompile(isLipoCollector, processHeadersInDependencies, usePic));
      outputGroups.put(
          OutputGroupProvider.COMPILATION_PREREQUISITES,
          CcCommon.collectCompilationPrerequisites(ruleContext, cppCompilationContext));
    }

    // TODO(bazel-team): Maybe we can infer these from other data at the places where they are
    // used.
    if (emitCcNativeLibrariesProvider) {
      providers.put(
          CcNativeLibraryProvider.class,
          new CcNativeLibraryProvider(collectNativeCcLibraries(ccLinkingOutputs)));
    }
    providers.put(
        CcExecutionDynamicLibrariesProvider.class,
        collectExecutionDynamicLibraryArtifacts(ccLinkingOutputs.getExecutionDynamicLibraries()));

    boolean forcePic = ruleContext.getFragment(CppConfiguration.class).forcePic();
    if (emitCcSpecificLinkParamsProvider) {
      providers.put(
          CcSpecificLinkParamsProvider.class,
          new CcSpecificLinkParamsProvider(
              createCcLinkParamsStore(ccLinkingOutputs, cppCompilationContext, forcePic)));
    } else {
      providers.put(
          CcLinkParamsProvider.class,
          new CcLinkParamsProvider(
              createCcLinkParamsStore(ccLinkingOutputs, cppCompilationContext, forcePic)));
    }
    return new Info(
        providers,
        outputGroups,
        ccOutputs,
        ccLinkingOutputs,
        originalLinkingOutputs,
        cppCompilationContext);
  }
    public LinkCommandLine build() {

      if (linkTargetType.isStaticLibraryLink()) {
        Preconditions.checkArgument(
            linkstamps.isEmpty(),
            "linkstamps may only be present on dynamic library or executable links");
        Preconditions.checkArgument(
            buildInfoHeaderArtifacts.isEmpty(),
            "build info headers may only be present on dynamic library or executable links");
      }

      ImmutableList<String> actualLinkstampCompileOptions;
      if (linkstampCompileOptions.isEmpty()) {
        actualLinkstampCompileOptions = DEFAULT_LINKSTAMP_OPTIONS;
      } else {
        actualLinkstampCompileOptions =
            ImmutableList.copyOf(
                Iterables.concat(DEFAULT_LINKSTAMP_OPTIONS, linkstampCompileOptions));
      }

      // The ruleContext can be null for some tests.
      if (ruleContext != null) {
        if (featureConfiguration == null) {
          if (toolchain != null) {
            featureConfiguration =
                CcCommon.configureFeatures(
                    ruleContext, toolchain, CcLibraryHelper.SourceCategory.CC);
          } else {
            featureConfiguration = CcCommon.configureFeatures(ruleContext);
          }
        }
      }

      if (variables == null) {
        variables = Variables.EMPTY;
      }

      String actionName = linkTargetType.getActionName();

      return new LinkCommandLine(
          actionName,
          configuration,
          owner,
          output,
          interfaceOutput,
          buildInfoHeaderArtifacts,
          linkerInputs,
          runtimeInputs,
          linkTargetType,
          linkStaticness,
          linkopts,
          features,
          linkstamps,
          actualLinkstampCompileOptions,
          CppHelper.getFdoBuildStamp(ruleContext),
          runtimeSolibDir,
          nativeDeps,
          useTestOnlyFlags,
          needWholeArchive,
          paramFile,
          interfaceSoBuilder,
          noWholeArchiveFlags,
          variables,
          featureConfiguration);
    }