public static CxxLinkAndCompileRules createBuildRulesForCxxBinary()

in src/com/facebook/buck/cxx/CxxDescriptionEnhancer.java [1346:1542]


  public static CxxLinkAndCompileRules createBuildRulesForCxxBinary(
      BuildTarget target,
      ProjectFilesystem projectFilesystem,
      ActionGraphBuilder graphBuilder,
      CellPathResolver cellRoots,
      CxxBuckConfig cxxBuckConfig,
      CxxPlatform cxxPlatform,
      ImmutableMap<String, CxxSource> srcs,
      ImmutableMap<Path, SourcePath> headers,
      SortedSet<BuildRule> deps,
      ImmutableSet<BuildTarget> linkWholeDeps,
      Optional<StripStyle> stripStyle,
      Optional<LinkerMapMode> flavoredLinkerMapMode,
      LinkableDepType linkStyle,
      Optional<LinkableListFilter> linkableListFilter,
      CxxLinkOptions linkOptions,
      ImmutableList<StringWithMacros> preprocessorFlags,
      PatternMatchedCollection<ImmutableList<StringWithMacros>> platformPreprocessorFlags,
      ImmutableMap<Type, ImmutableList<StringWithMacros>> langPreprocessorFlags,
      ImmutableMap<Type, PatternMatchedCollection<ImmutableList<StringWithMacros>>>
          langPlatformPreprocessorFlags,
      ImmutableSortedSet<FrameworkPath> frameworks,
      ImmutableSortedSet<FrameworkPath> libraries,
      ImmutableList<StringWithMacros> compilerFlags,
      ImmutableMap<Type, ImmutableList<StringWithMacros>> langCompilerFlags,
      PatternMatchedCollection<ImmutableList<StringWithMacros>> platformCompilerFlags,
      ImmutableMap<Type, PatternMatchedCollection<ImmutableList<StringWithMacros>>>
          langPlatformCompilerFlags,
      Optional<SourcePath> prefixHeader,
      Optional<SourcePath> precompiledHeader,
      ImmutableList<StringWithMacros> linkerFlags,
      ImmutableList<String> linkerExtraOutputs,
      PatternMatchedCollection<ImmutableList<StringWithMacros>> platformLinkerFlags,
      Optional<CxxRuntimeType> cxxRuntimeType,
      ImmutableSortedSet<SourcePath> rawHeaders,
      ImmutableSortedSet<String> includeDirectories,
      Optional<String> outputRootName) {
    //    TODO(beefon): should be:
    //    Path linkOutput = getLinkOutputPath(
    //        createCxxLinkTarget(params.getBuildTarget(), flavoredLinkerMapMode),
    //        projectFilesystem);

    ImmutableMap<CxxPreprocessAndCompile, SourcePath> objects =
        createCompileRulesForCxxBinary(
            target,
            projectFilesystem,
            graphBuilder,
            cellRoots,
            cxxBuckConfig,
            cxxPlatform,
            srcs,
            headers,
            deps,
            linkStyle,
            linkOptions,
            preprocessorFlags,
            platformPreprocessorFlags,
            langPreprocessorFlags,
            langPlatformPreprocessorFlags,
            frameworks,
            compilerFlags,
            langCompilerFlags,
            platformCompilerFlags,
            langPlatformCompilerFlags,
            prefixHeader,
            precompiledHeader,
            rawHeaders,
            includeDirectories);

    CommandTool.Builder executableBuilder = new CommandTool.Builder();
    Linker linker = cxxPlatform.getLd().resolve(graphBuilder, target.getTargetConfiguration());
    BuildTarget linkRuleTarget = createCxxLinkTarget(target, flavoredLinkerMapMode);

    Path linkOutput =
        getBinaryOutputPath(
            flavoredLinkerMapMode.isPresent()
                ? target.withAppendedFlavors(flavoredLinkerMapMode.get().getFlavor())
                : target,
            projectFilesystem,
            cxxPlatform.getBinaryExtension(),
            outputRootName);

    ImmutableList<Arg> args =
        createLinkArgsForCxxBinary(
            linkRuleTarget,
            projectFilesystem,
            graphBuilder,
            cellRoots,
            cxxPlatform,
            objects,
            deps,
            executableBuilder,
            linker,
            linkStyle,
            linkOutput,
            linkerFlags,
            platformLinkerFlags);

    CxxLink cxxLink =
        (CxxLink)
            graphBuilder.computeIfAbsent(
                linkRuleTarget,
                ignored ->
                    // Generate the final link rule.  We use the top-level target as the link rule's
                    // target, so that it corresponds to the actual binary we build.
                    CxxLinkableEnhancer.createCxxLinkableBuildRule(
                        cxxBuckConfig,
                        cxxPlatform,
                        projectFilesystem,
                        graphBuilder,
                        linkRuleTarget,
                        Linker.LinkType.EXECUTABLE,
                        Optional.empty(),
                        linkOutput,
                        linkerExtraOutputs,
                        linkStyle,
                        linkableListFilter,
                        linkOptions,
                        RichStream.from(deps)
                            .filter(NativeLinkableGroup.class)
                            .map(g -> g.getNativeLinkable(cxxPlatform, graphBuilder))
                            .toImmutableList(),
                        cxxRuntimeType,
                        Optional.empty(),
                        ImmutableSet.of(),
                        linkWholeDeps,
                        NativeLinkableInput.builder()
                            .setArgs(args)
                            .setFrameworks(frameworks)
                            .setLibraries(libraries)
                            .build(),
                        Optional.empty(),
                        cellRoots));

    BuildRule binaryRuleForExecutable;
    Optional<CxxStrip> cxxStrip = Optional.empty();
    if (stripStyle.isPresent()) {
      BuildTarget cxxTarget = target;
      if (flavoredLinkerMapMode.isPresent()) {
        cxxTarget = cxxTarget.withAppendedFlavors(flavoredLinkerMapMode.get().getFlavor());
      }
      CxxStrip stripRule =
          createCxxStripRule(
              cxxTarget,
              projectFilesystem,
              graphBuilder,
              stripStyle.get(),
              cxxBuckConfig.shouldCacheStrip(),
              cxxLink,
              cxxPlatform,
              outputRootName);
      cxxStrip = Optional.of(stripRule);
      binaryRuleForExecutable = stripRule;
    } else {
      binaryRuleForExecutable = cxxLink;
    }

    SourcePath sourcePathToExecutable = binaryRuleForExecutable.getSourcePathToOutput();

    // Special handling for dynamically linked binaries requiring dependencies to be in the same
    // directory
    if (linkStyle == Linker.LinkableDepType.SHARED
        && linker.getSharedLibraryLoadingType()
            == Linker.SharedLibraryLoadingType.THE_SAME_DIRECTORY) {
      Path binaryName = linkOutput.getFileName();
      BuildTarget binaryWithSharedLibrariesTarget =
          createBinaryWithSharedLibrariesSymlinkTreeTarget(target, cxxPlatform.getFlavor());
      Path symlinkTreeRoot =
          getBinaryWithSharedLibrariesSymlinkTreePath(
              projectFilesystem, binaryWithSharedLibrariesTarget, cxxPlatform.getFlavor());
      Path appPath = symlinkTreeRoot.resolve(binaryName);
      MappedSymlinkTree binaryWithSharedLibraries =
          requireBinaryWithSharedLibrariesSymlinkTree(
              target,
              projectFilesystem,
              graphBuilder,
              cxxPlatform,
              deps,
              binaryName,
              sourcePathToExecutable);

      executableBuilder.addNonHashableInput(binaryWithSharedLibraries.getRootSourcePath());
      executableBuilder.addInputs(binaryWithSharedLibraries.getLinks().values());
      sourcePathToExecutable =
          ExplicitBuildTargetSourcePath.of(binaryWithSharedLibrariesTarget, appPath);
    }

    // Add the output of the link as the lone argument needed to invoke this binary as a tool.
    executableBuilder.addArg(SourcePathArg.of(sourcePathToExecutable));

    return new CxxLinkAndCompileRules(
        cxxLink,
        cxxStrip,
        ImmutableSortedSet.copyOf(objects.keySet()),
        executableBuilder.build(),
        deps);
  }