public BuildRule createBuildRule()

in src/com/facebook/buck/cxx/PrebuiltCxxLibraryDescription.java [377:957]


  public BuildRule createBuildRule(
      BuildRuleCreationContextWithTargetGraph context,
      BuildTarget buildTarget,
      BuildRuleParams params,
      PrebuiltCxxLibraryDescriptionArg args) {

    // See if we're building a particular "type" of this library, and if so, extract
    // it as an enum.
    Optional<Map.Entry<Flavor, Type>> type = LIBRARY_TYPE.getFlavorAndValue(buildTarget);
    Optional<Map.Entry<Flavor, UnresolvedCxxPlatform>> platform =
        getUnresolvedCxxPlatform(buildTarget);

    Optional<ImmutableMap<BuildTarget, Version>> selectedVersions =
        context.getTargetGraph().get(buildTarget).getSelectedVersions();

    ProjectFilesystem projectFilesystem = context.getProjectFilesystem();
    CellPathResolver cellRoots = context.getCellPathResolver();
    ActionGraphBuilder graphBuilder = context.getActionGraphBuilder();
    // If we *are* building a specific type of this lib, call into the type specific
    // rule builder methods.  Currently, we only support building a shared lib from the
    // pre-existing static lib, which we do here.
    if (type.isPresent()) {
      Preconditions.checkState(platform.isPresent());
      BuildTarget baseTarget =
          buildTarget.withoutFlavors(type.get().getKey(), platform.get().getKey());
      CxxPlatform cxxPlatform =
          platform.get().getValue().resolve(graphBuilder, buildTarget.getTargetConfiguration());
      if (type.get().getValue() == Type.EXPORTED_HEADERS) {
        return createExportedHeaderSymlinkTreeBuildRule(
            buildTarget, projectFilesystem, graphBuilder, cxxPlatform, args);
      } else if (type.get().getValue() == Type.SHARED) {
        return createSharedLibraryBuildRule(
            buildTarget,
            projectFilesystem,
            graphBuilder,
            cellRoots,
            cxxPlatform,
            selectedVersions,
            args);
      } else if (type.get().getValue() == Type.SHARED_INTERFACE) {
        return createSharedLibraryInterface(
            baseTarget,
            projectFilesystem,
            graphBuilder,
            cellRoots,
            cxxPlatform,
            selectedVersions,
            args);
      }
    }

    // Build up complete list of exported preprocessor flags (including versioned flags).
    ImmutableList.Builder<StringWithMacros> exportedPreprocessorFlagsBuilder =
        ImmutableList.builder();
    exportedPreprocessorFlagsBuilder.addAll(args.getExportedPreprocessorFlags());
    selectedVersions.ifPresent(
        versions ->
            args.getVersionedExportedPreprocessorFlags()
                .getMatchingValues(versions)
                .forEach(exportedPreprocessorFlagsBuilder::addAll));
    ImmutableList<StringWithMacros> exportedPreprocessorFlags =
        exportedPreprocessorFlagsBuilder.build();

    // Build up complete list of exported platform preprocessor flags (including versioned flags).
    PatternMatchedCollection.Builder<ImmutableList<StringWithMacros>>
        exportedPlatformPreprocessorFlagsBuilder = PatternMatchedCollection.builder();
    args.getExportedPlatformPreprocessorFlags()
        .getPatternsAndValues()
        .forEach(
            pair ->
                exportedPlatformPreprocessorFlagsBuilder.add(pair.getFirst(), pair.getSecond()));
    selectedVersions.ifPresent(
        versions ->
            args.getVersionedExportedPlatformPreprocessorFlags()
                .getMatchingValues(versions)
                .forEach(
                    flags ->
                        flags
                            .getPatternsAndValues()
                            .forEach(
                                pair ->
                                    exportedPlatformPreprocessorFlagsBuilder.add(
                                        pair.getFirst(), pair.getSecond()))));
    PatternMatchedCollection<ImmutableList<StringWithMacros>> exportedPlatformPreprocessorFlags =
        exportedPlatformPreprocessorFlagsBuilder.build();

    // Build up complete list of exported language preprocessor flags (including versioned flags).
    ImmutableListMultimap.Builder<CxxSource.Type, StringWithMacros>
        exportedLangPreprocessorFlagsBuilder = ImmutableListMultimap.builder();
    args.getExportedLangPreprocessorFlags().forEach(exportedLangPreprocessorFlagsBuilder::putAll);
    selectedVersions.ifPresent(
        versions ->
            args.getVersionedExportedLangPreprocessorFlags()
                .getMatchingValues(versions)
                .forEach(value -> value.forEach(exportedLangPreprocessorFlagsBuilder::putAll)));
    ImmutableMap<CxxSource.Type, Collection<StringWithMacros>> exportedLangPreprocessorFlags =
        exportedLangPreprocessorFlagsBuilder.build().asMap();

    // Build up complete list of exported language-platform preprocessor flags (including versioned
    // flags).
    ListMultimap<CxxSource.Type, PatternMatchedCollection<ImmutableList<StringWithMacros>>>
        exportedLangPlatformPreprocessorFlagsBuilder = ArrayListMultimap.create();
    args.getExportedLangPlatformPreprocessorFlags()
        .forEach(exportedLangPlatformPreprocessorFlagsBuilder::put);
    selectedVersions.ifPresent(
        versions ->
            args.getVersionedExportedLangPlatformPreprocessorFlags()
                .getMatchingValues(versions)
                .forEach(
                    value -> value.forEach(exportedLangPlatformPreprocessorFlagsBuilder::put)));
    ImmutableMap<CxxSource.Type, PatternMatchedCollection<ImmutableList<StringWithMacros>>>
        exportedLangPlatformPreprocessorFlags =
            ImmutableMap.copyOf(
                Maps.transformValues(
                    exportedLangPlatformPreprocessorFlagsBuilder.asMap(),
                    PatternMatchedCollection::concat));

    // Otherwise, we return the generic placeholder of this library, that dependents can use
    // get the real build rules via querying the action graph.
    PrebuiltCxxLibraryPaths paths = getPaths(buildTarget, args);
    return new PrebuiltCxxLibrary(buildTarget, projectFilesystem, params) {

      private final TransitiveCxxPreprocessorInputCache transitiveCxxPreprocessorInputCache =
          new TransitiveCxxPreprocessorInputCache(this);

      private boolean hasHeaders(CxxPlatform cxxPlatform) {
        if (!args.getExportedHeaders().isEmpty()) {
          return true;
        }
        for (SourceSortedSet sourceList :
            args.getExportedPlatformHeaders()
                .getMatchingValues(cxxPlatform.getFlavor().toString())) {
          if (!sourceList.isEmpty()) {
            return true;
          }
        }
        return false;
      }

      private ImmutableListMultimap<CxxSource.Type, Arg> getExportedPreprocessorFlags(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        return ImmutableListMultimap.copyOf(
            Multimaps.transformValues(
                CxxFlags.getLanguageFlagsWithMacros(
                    exportedPreprocessorFlags,
                    exportedPlatformPreprocessorFlags,
                    exportedLangPreprocessorFlags,
                    exportedLangPlatformPreprocessorFlags,
                    cxxPlatform),
                CxxDescriptionEnhancer.getStringWithMacrosArgsConverter(
                        getBuildTarget(), cellRoots, graphBuilder, cxxPlatform)
                    ::convert));
      }

      private String getSoname(CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        Optional<String> soname = args.getSoname();
        if (!soname.isPresent()
            && cxxPlatform.getLd().getType() == LinkerProvider.Type.WINDOWS
            && getImportLibrary(cxxPlatform, graphBuilder).isPresent()) {
          // TODO(fishb): We should allow `shared_lib` to be absent (ex. link against import lib
          //  of pre-deployed DLL)
          SourcePath sharedLibraryPath = requireSharedLibrary(cxxPlatform, false, graphBuilder);
          soname =
              Optional.ofNullable(
                  ((PathSourcePath) sharedLibraryPath).getRelativePath().getFileName().toString());
        }
        return PrebuiltCxxLibraryDescription.getSoname(getBuildTarget(), cxxPlatform, soname);
      }

      private boolean isPlatformSupported(CxxPlatform cxxPlatform) {
        return !args.getSupportedPlatformsRegex().isPresent()
            || args.getSupportedPlatformsRegex()
                .get()
                .matcher(cxxPlatform.getFlavor().toString())
                .find();
      }

      private Optional<SourcePath> getImportLibrary(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        return PrebuiltCxxLibraryDescription.this.getImportLibrary(
            buildTarget,
            graphBuilder,
            cellRoots,
            projectFilesystem,
            cxxPlatform,
            selectedVersions,
            args);
      }

      /**
       * Makes sure all build rules needed to produce the shared library are added to the action
       * graph.
       *
       * @return the {@link SourcePath} representing the actual shared library.
       */
      private SourcePath requireSharedLibrary(
          CxxPlatform cxxPlatform, boolean link, ActionGraphBuilder graphBuilder) {
        if (link
            && args.isSupportsSharedLibraryInterface()
            && cxxPlatform.getSharedLibraryInterfaceParams().isPresent()) {
          BuildTarget target =
              buildTarget.withAppendedFlavors(
                  cxxPlatform.getFlavor(), Type.SHARED_INTERFACE.getFlavor());
          BuildRule rule = graphBuilder.requireRule(target);
          return Objects.requireNonNull(rule.getSourcePathToOutput());
        }
        return PrebuiltCxxLibraryDescription.this.requireSharedLibrary(
            buildTarget,
            graphBuilder,
            cellRoots,
            projectFilesystem,
            cxxPlatform,
            selectedVersions,
            args);
      }

      /**
       * @return the {@link Optional} containing a {@link SourcePath} representing the actual static
       *     library.
       */
      @Override
      Optional<SourcePath> getStaticLibrary(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        return getStaticLibraryForSelectedVersions(cxxPlatform, graphBuilder, selectedVersions);
      }

      private Optional<SourcePath> getStaticLibraryForSelectedVersions(
          CxxPlatform cxxPlatform,
          ActionGraphBuilder graphBuilder,
          Optional<ImmutableMap<BuildTarget, Version>> versions) {
        return paths.getStaticLibrary(
            getProjectFilesystem(), graphBuilder, cellRoots, cxxPlatform, versions);
      }

      /**
       * @return the {@link Optional} containing a {@link SourcePath} representing the actual static
       *     PIC library.
       */
      @Override
      Optional<SourcePath> getStaticPicLibrary(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        return getStaticPicLibraryForSelectedVersions(cxxPlatform, graphBuilder, selectedVersions);
      }

      private Optional<SourcePath> getStaticPicLibraryForSelectedVersions(
          CxxPlatform cxxPlatform,
          ActionGraphBuilder graphBuilder,
          Optional<ImmutableMap<BuildTarget, Version>> versions) {
        Optional<SourcePath> staticPicLibraryPath =
            paths.getStaticPicLibrary(
                getProjectFilesystem(), graphBuilder, cellRoots, cxxPlatform, versions);
        // If a specific static-pic variant isn't available, then just use the static variant.
        return staticPicLibraryPath.isPresent()
            ? staticPicLibraryPath
            : getStaticLibraryForSelectedVersions(cxxPlatform, graphBuilder, versions);
      }

      @Override
      public Iterable<CxxPreprocessorDep> getCxxPreprocessorDeps(
          CxxPlatform cxxPlatform, BuildRuleResolver ruleResolver) {
        if (!isPlatformSupported(cxxPlatform)) {
          return ImmutableList.of();
        }
        return args.getCxxDeps().get(ruleResolver, cxxPlatform).stream()
            .filter(CxxPreprocessorDep.class::isInstance)
            .map(CxxPreprocessorDep.class::cast)
            .collect(ImmutableList.toImmutableList());
      }

      @Override
      public CxxPreprocessorInput getCxxPreprocessorInput(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        CxxPreprocessorInput.Builder builder = CxxPreprocessorInput.builder();

        if (hasHeaders(cxxPlatform)) {
          CxxPreprocessables.addHeaderSymlinkTree(
              builder,
              getBuildTarget(),
              graphBuilder,
              cxxPlatform,
              HeaderVisibility.PUBLIC,
              CxxPreprocessables.IncludeType.SYSTEM);
        }
        builder.putAllPreprocessorFlags(getExportedPreprocessorFlags(cxxPlatform, graphBuilder));
        builder.addAllFrameworks(args.getFrameworks());
        for (SourcePath includePath :
            paths.getIncludeDirs(
                projectFilesystem, graphBuilder, cellRoots, cxxPlatform, selectedVersions)) {
          builder.addIncludes(CxxHeadersDir.of(CxxPreprocessables.IncludeType.SYSTEM, includePath));
        }
        return builder.build();
      }

      @Override
      public ImmutableMap<BuildTarget, CxxPreprocessorInput> getTransitiveCxxPreprocessorInput(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        return transitiveCxxPreprocessorInputCache.getUnchecked(cxxPlatform, graphBuilder);
      }

      public ImmutableList<Arg> getExportedLinkerFlags(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        return PrebuiltCxxLibraryDescription.this.getExportedLinkerArgs(
            cxxPlatform, args, buildTarget, cellRoots, graphBuilder);
      }

      public ImmutableList<Arg> getExportedPostLinkerFlags(CxxPlatform cxxPlatform) {
        // TODO(cjhopman): Why wasn't this updated to handle macros correctly like
        // exported_linker_flags?
        return CxxFlags.getFlagsWithPlatformMacroExpansion(
                args.getExportedPostLinkerFlags(),
                args.getExportedPostPlatformLinkerFlags(),
                cxxPlatform)
            .stream()
            .map(s -> (Arg) StringArg.from(s))
            .collect(ImmutableList.toImmutableList());
      }

      @Override
      protected NativeLinkableInfo createNativeLinkable(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        if (!isPlatformSupported(cxxPlatform)) {
          return new NativeLinkableInfo(
              getBuildTarget(),
              getType(),
              ImmutableList.of(),
              ImmutableList.of(),
              Linkage.ANY,
              NativeLinkableInfo.fixedDelegate(NativeLinkableInput.of(), ImmutableMap.of()),
              NativeLinkableInfo.defaults());
        }

        ImmutableList<NativeLinkable> deps =
            args.getPrivateCxxDeps().get(graphBuilder, cxxPlatform).stream()
                .filter(NativeLinkableGroup.class::isInstance)
                .map(NativeLinkableGroup.class::cast)
                .map(g -> g.getNativeLinkable(cxxPlatform, graphBuilder))
                .collect(ImmutableList.toImmutableList());

        ImmutableList<NativeLinkable> exportedDeps =
            args.getExportedCxxDeps().get(graphBuilder, cxxPlatform).stream()
                .filter(NativeLinkableGroup.class::isInstance)
                .map(NativeLinkableGroup.class::cast)
                .map(g -> g.getNativeLinkable(cxxPlatform, graphBuilder))
                .collect(ImmutableList.toImmutableList());

        ImmutableList<Arg> exportedLinkerFlags = getExportedLinkerFlags(cxxPlatform, graphBuilder);
        ImmutableList<Arg> exportedPostLinkerFlags = getExportedPostLinkerFlags(cxxPlatform);

        Optional<NativeLinkTargetInfo> linkTargetInfo =
            getNativeLinkTargetInfo(
                cxxPlatform,
                graphBuilder,
                deps,
                exportedDeps,
                exportedLinkerFlags,
                exportedPostLinkerFlags);

        return new NativeLinkableInfo(
            getBuildTarget(),
            getType(),
            deps,
            exportedDeps,
            getPreferredLinkage(cxxPlatform),
            new NativeLinkableInfo.Delegate() {
              @Override
              public NativeLinkableInput computeInput(
                  ActionGraphBuilder graphBuilder,
                  Linker.LinkableDepType type,
                  boolean forceLinkWhole,
                  TargetConfiguration targetConfiguration) {
                return computeNativeLinkableInputUncached(
                    graphBuilder, cxxPlatform, type, forceLinkWhole);
              }

              @Override
              public ImmutableMap<String, SourcePath> getSharedLibraries(
                  ActionGraphBuilder graphBuilder) {
                return resolveSharedLibraries(cxxPlatform, graphBuilder);
              }

              @Override
              public boolean isPrebuiltSOForHaskellOmnibus(ActionGraphBuilder graphBuilder) {
                ImmutableMap<String, SourcePath> sharedLibraries = getSharedLibraries(graphBuilder);
                for (Map.Entry<String, SourcePath> ent : sharedLibraries.entrySet()) {
                  if (!(ent.getValue() instanceof PathSourcePath)) {
                    return false;
                  }
                }
                return true;
              }
            },
            NativeLinkableInfo.defaults()
                .setExportedLinkerFlags(exportedLinkerFlags)
                .setExportedPostLinkerFlags(exportedPostLinkerFlags)
                .setSupportsOmnibusLinking(supportsOmnibusLinking(cxxPlatform))
                .setHaskellOmnibusLinkingOptions(true, true)
                .setNativeLinkTarget(linkTargetInfo));
      }

      private NativeLinkableInput computeNativeLinkableInputUncached(
          ActionGraphBuilder graphBuilder,
          CxxPlatform cxxPlatform,
          Linker.LinkableDepType type,
          boolean forceLinkWhole) {
        Verify.verify(isPlatformSupported(cxxPlatform));
        NativeLinkable linkable = getNativeLinkable(cxxPlatform, graphBuilder);

        // Build the library path and linker arguments that we pass through the
        // {@link NativeLinkable} interface for linking.
        ImmutableList.Builder<Arg> linkerArgsBuilder = ImmutableList.builder();
        linkerArgsBuilder.addAll(linkable.getExportedLinkerFlags(graphBuilder));

        if (!args.isHeaderOnly()) {
          if (type == Linker.LinkableDepType.SHARED) {
            Preconditions.checkState(linkable.getPreferredLinkage() != Linkage.STATIC);
            Optional<SourcePath> importLibraryPath = getImportLibrary(cxxPlatform, graphBuilder);
            if (importLibraryPath.isPresent()
                && cxxPlatform.getLd().getType() == LinkerProvider.Type.WINDOWS) {
              SourcePathArg importLibrary =
                  SourcePathArg.of(
                      importLibraryPath.orElseThrow(
                          () ->
                              new HumanReadableException(
                                  "Could not find import library for %s.", getBuildTarget())));
              if (args.isLinkWhole() || forceLinkWhole) {
                throw new HumanReadableException(
                    "%s: whole linking is not supported for import libraries", getBuildTarget());
              } else {
                linkerArgsBuilder.add(FileListableLinkerInputArg.withSourcePathArg(importLibrary));
              }
            } else {
              SourcePath sharedLibrary = requireSharedLibrary(cxxPlatform, true, graphBuilder);
              if (args.getLinkWithoutSoname()) {
                if (!(sharedLibrary instanceof PathSourcePath)) {
                  throw new HumanReadableException(
                      "%s: can only link prebuilt DSOs without sonames", getBuildTarget());
                }
                linkerArgsBuilder.add(new RelativeLinkArg((PathSourcePath) sharedLibrary));
              } else {
                linkerArgsBuilder.add(
                    SourcePathArg.of(requireSharedLibrary(cxxPlatform, true, graphBuilder)));
              }
            }
          } else {
            Preconditions.checkState(linkable.getPreferredLinkage() != Linkage.SHARED);
            Optional<SourcePath> staticLibraryPath =
                type == Linker.LinkableDepType.STATIC_PIC
                    ? getStaticPicLibrary(cxxPlatform, graphBuilder)
                    : getStaticLibrary(cxxPlatform, graphBuilder);
            SourcePathArg staticLibrary =
                SourcePathArg.of(
                    staticLibraryPath.orElseThrow(
                        () ->
                            new HumanReadableException(
                                "Could not find static library for %s.", getBuildTarget())));
            if (args.isLinkWhole() || forceLinkWhole) {
              Linker linker =
                  cxxPlatform.getLd().resolve(graphBuilder, buildTarget.getTargetConfiguration());
              linkerArgsBuilder.addAll(
                  linker.linkWhole(
                      staticLibrary, context.getActionGraphBuilder().getSourcePathResolver()));
            } else {
              linkerArgsBuilder.add(FileListableLinkerInputArg.withSourcePathArg(staticLibrary));
            }
          }
        }

        // Add any post exported flags, if any.
        linkerArgsBuilder.addAll(linkable.getExportedPostLinkerFlags(graphBuilder));

        ImmutableList<Arg> linkerArgs = linkerArgsBuilder.build();

        return NativeLinkableInput.of(linkerArgs, args.getFrameworks(), args.getLibraries());
      }

      public Linkage getPreferredLinkage(CxxPlatform cxxPlatform) {
        if (args.isHeaderOnly()) {
          return Linkage.ANY;
        }
        if (cxxPlatform.getLd().getType() == LinkerProvider.Type.WINDOWS) {
          Optional<SourcePath> importLibraryPath = getImportLibrary(cxxPlatform, graphBuilder);
          if (importLibraryPath.isPresent()) {
            return Linkage.SHARED;
          }
        }
        if (args.isForceStatic()) {
          return Linkage.STATIC;
        }
        if (args.getPreferredLinkage().orElse(Linkage.ANY) != Linkage.ANY) {
          return args.getPreferredLinkage().get();
        }
        if (args.isProvided()) {
          return Linkage.SHARED;
        }
        Optional<Linkage> inferredLinkage =
            paths.getLinkage(projectFilesystem, cellRoots, cxxPlatform);
        return inferredLinkage.orElse(Linkage.ANY);
      }

      public boolean supportsOmnibusLinking(CxxPlatform cxxPlatform) {
        return args.getSupportsMergedLinking()
            .orElse(getPreferredLinkage(cxxPlatform) != Linkage.SHARED);
      }

      @Override
      public Iterable<AndroidPackageable> getRequiredPackageables(BuildRuleResolver ruleResolver) {
        return AndroidPackageableCollector.getPackageableRules(
            args.getCxxDeps().getForAllPlatforms(ruleResolver));
      }

      @Override
      public void addToCollector(AndroidPackageableCollector collector) {
        if (args.getCanBeAsset()) {
          collector.addNativeLinkableAsset(this);
        } else {
          collector.addNativeLinkable(this);
        }
      }

      public ImmutableMap<String, SourcePath> resolveSharedLibraries(
          CxxPlatform cxxPlatform, ActionGraphBuilder graphBuilder) {
        Verify.verify(isPlatformSupported(cxxPlatform));

        ImmutableMap.Builder<String, SourcePath> solibs = ImmutableMap.builder();
        if (!args.isHeaderOnly() && !args.isProvided()) {
          String resolvedSoname = getSoname(cxxPlatform, graphBuilder);
          SourcePath sharedLibrary = requireSharedLibrary(cxxPlatform, false, graphBuilder);
          solibs.put(resolvedSoname, sharedLibrary);
        }
        return solibs.build();
      }

      private Optional<NativeLinkTargetInfo> getNativeLinkTargetInfo(
          CxxPlatform cxxPlatform,
          ActionGraphBuilder graphBuilder,
          ImmutableList<NativeLinkable> deps,
          ImmutableList<NativeLinkable> exportedDeps,
          ImmutableList<Arg> exportedLinkerFlags,
          ImmutableList<Arg> exportedPostLinkerFlags) {
        if (getPreferredLinkage(cxxPlatform) == Linkage.SHARED) {
          return Optional.empty();
        }
        if (args.isHeaderOnly()) {
          return Optional.empty();
        }

        Optional<NativeLinkTargetInfo> linkTargetInfo = Optional.empty();
        if (getPreferredLinkage(cxxPlatform) != Linkage.SHARED) {
          Optional<SourcePath> staticPicLibrary = getStaticPicLibrary(cxxPlatform, graphBuilder);

          NativeLinkableInput linkableInput = null;
          if (staticPicLibrary.isPresent()) {
            linkableInput =
                NativeLinkableInput.builder()
                    .addAllArgs(exportedLinkerFlags)
                    .addAllArgs(
                        cxxPlatform
                            .getLd()
                            .resolve(graphBuilder, buildTarget.getTargetConfiguration())
                            .linkWhole(
                                SourcePathArg.of(staticPicLibrary.get()),
                                // TODO(cjhopman): We should only require SourcePathResolvers at the
                                // action execution stage.
                                graphBuilder.getSourcePathResolver()))
                    .addAllArgs(exportedPostLinkerFlags)
                    .build();
          }

          linkTargetInfo =
              Optional.of(
                  new NativeLinkTargetInfo(
                      getBuildTarget(),
                      NativeLinkTargetMode.library(getSoname(cxxPlatform, graphBuilder)),
                      Iterables.concat(deps, exportedDeps),
                      linkableInput,
                      Optional.empty()));
        }
        return linkTargetInfo;
      }
    };
  }