Search in sources :

Example 1 with BuildTargetSourcePath

use of com.facebook.buck.rules.BuildTargetSourcePath in project buck by facebook.

the class ProjectGenerator method resolveSourcePath.

private Path resolveSourcePath(SourcePath sourcePath) {
    if (sourcePath instanceof PathSourcePath) {
        return ((PathSourcePath) sourcePath).getRelativePath();
    }
    Preconditions.checkArgument(sourcePath instanceof BuildTargetSourcePath);
    BuildTargetSourcePath<?> buildTargetSourcePath = (BuildTargetSourcePath<?>) sourcePath;
    BuildTarget buildTarget = buildTargetSourcePath.getTarget();
    TargetNode<?, ?> node = targetGraph.get(buildTarget);
    Optional<TargetNode<ExportFileDescription.Arg, ?>> exportFileNode = node.castArg(ExportFileDescription.Arg.class);
    if (!exportFileNode.isPresent()) {
        BuildRuleResolver resolver = buildRuleResolverForNode.apply(node);
        SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
        SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
        Path output = pathResolver.getRelativePath(sourcePath);
        if (output == null) {
            throw new HumanReadableException("The target '%s' does not have an output.", node.getBuildTarget());
        }
        requiredBuildTargetsBuilder.add(buildTarget);
        return output;
    }
    Optional<SourcePath> src = exportFileNode.get().getConstructorArg().src;
    if (!src.isPresent()) {
        return buildTarget.getBasePath().resolve(buildTarget.getShortNameAndFlavorPostfix());
    }
    return resolveSourcePath(src.get());
}
Also used : SourceTreePath(com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath) Path(java.nio.file.Path) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) FrameworkPath(com.facebook.buck.rules.coercer.FrameworkPath) TargetNode(com.facebook.buck.rules.TargetNode) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) BuildRuleResolver(com.facebook.buck.rules.BuildRuleResolver) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) BuildTarget(com.facebook.buck.model.BuildTarget) UnflavoredBuildTarget(com.facebook.buck.model.UnflavoredBuildTarget) HumanReadableException(com.facebook.buck.util.HumanReadableException) ExportFileDescription(com.facebook.buck.shell.ExportFileDescription)

Example 2 with BuildTargetSourcePath

use of com.facebook.buck.rules.BuildTargetSourcePath in project buck by facebook.

the class CopyResourcesStep method buildSteps.

@VisibleForTesting
ImmutableList<Step> buildSteps() {
    ImmutableList.Builder<Step> allSteps = ImmutableList.builder();
    if (resources.isEmpty()) {
        return allSteps.build();
    }
    String targetPackageDir = javaPackageFinder.findJavaPackage(target);
    for (SourcePath rawResource : resources) {
        // If the path to the file defining this rule were:
        // "first-party/orca/lib-http/tests/com/facebook/orca/BUCK"
        //
        // And the value of resource were:
        // "first-party/orca/lib-http/tests/com/facebook/orca/protocol/base/batch_exception1.txt"
        //
        // Assuming that `src_roots = tests` were in the [java] section of the .buckconfig file,
        // then javaPackageAsPath would be:
        // "com/facebook/orca/protocol/base/"
        //
        // And the path that we would want to copy to the classes directory would be:
        // "com/facebook/orca/protocol/base/batch_exception1.txt"
        //
        // Therefore, some path-wrangling is required to produce the correct string.
        Optional<BuildRule> underlyingRule = ruleFinder.getRule(rawResource);
        Path relativePathToResource = resolver.getRelativePath(rawResource);
        String resource;
        if (underlyingRule.isPresent()) {
            BuildTarget underlyingTarget = underlyingRule.get().getBuildTarget();
            if (underlyingRule.get() instanceof HasOutputName) {
                resource = MorePaths.pathWithUnixSeparators(underlyingTarget.getBasePath().resolve(((HasOutputName) underlyingRule.get()).getOutputName()));
            } else {
                Path genOutputParent = BuildTargets.getGenPath(filesystem, underlyingTarget, "%s").getParent();
                Path scratchOutputParent = BuildTargets.getScratchPath(filesystem, underlyingTarget, "%s").getParent();
                Optional<Path> outputPath = MorePaths.stripPrefix(relativePathToResource, genOutputParent).map(Optional::of).orElse(MorePaths.stripPrefix(relativePathToResource, scratchOutputParent));
                Preconditions.checkState(outputPath.isPresent(), "%s is used as a resource but does not output to a default output directory", underlyingTarget.getFullyQualifiedName());
                resource = MorePaths.pathWithUnixSeparators(underlyingTarget.getBasePath().resolve(outputPath.get()));
            }
        } else {
            resource = MorePaths.pathWithUnixSeparators(relativePathToResource);
        }
        Path javaPackageAsPath = javaPackageFinder.findJavaPackageFolder(outputDirectory.getFileSystem().getPath(resource));
        Path relativeSymlinkPath;
        if ("".equals(javaPackageAsPath.toString())) {
            // In this case, the project root is acting as the default package, so the resource path
            // works fine.
            relativeSymlinkPath = relativePathToResource.getFileName();
        } else {
            int lastIndex = resource.lastIndexOf(MorePaths.pathWithUnixSeparatorsAndTrailingSlash(javaPackageAsPath));
            if (lastIndex < 0) {
                Preconditions.checkState(rawResource instanceof BuildTargetSourcePath, "If resource path %s does not contain %s, then it must be a BuildTargetSourcePath.", relativePathToResource, javaPackageAsPath);
                // Handle the case where we depend on the output of another BuildRule. In that case, just
                // grab the output and put in the same package as this target would be in.
                relativeSymlinkPath = outputDirectory.getFileSystem().getPath(String.format("%s%s%s", targetPackageDir, targetPackageDir.isEmpty() ? "" : "/", resolver.getRelativePath(rawResource).getFileName()));
            } else {
                relativeSymlinkPath = outputDirectory.getFileSystem().getPath(resource.substring(lastIndex));
            }
        }
        Path target = outputDirectory.resolve(relativeSymlinkPath);
        MkdirAndSymlinkFileStep link = new MkdirAndSymlinkFileStep(filesystem, resolver.getAbsolutePath(rawResource), target);
        allSteps.add(link);
    }
    return allSteps.build();
}
Also used : SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) Path(java.nio.file.Path) HasOutputName(com.facebook.buck.model.HasOutputName) ImmutableList(com.google.common.collect.ImmutableList) Step(com.facebook.buck.step.Step) MkdirAndSymlinkFileStep(com.facebook.buck.step.fs.MkdirAndSymlinkFileStep) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) BuildTarget(com.facebook.buck.model.BuildTarget) BuildRule(com.facebook.buck.rules.BuildRule) MkdirAndSymlinkFileStep(com.facebook.buck.step.fs.MkdirAndSymlinkFileStep) VisibleForTesting(com.google.common.annotations.VisibleForTesting)

Example 3 with BuildTargetSourcePath

use of com.facebook.buck.rules.BuildTargetSourcePath in project buck by facebook.

the class AppleDescriptions method createAppleBundle.

static AppleBundle createAppleBundle(FlavorDomain<CxxPlatform> cxxPlatformFlavorDomain, CxxPlatform defaultCxxPlatform, FlavorDomain<AppleCxxPlatform> appleCxxPlatforms, TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, CodeSignIdentityStore codeSignIdentityStore, ProvisioningProfileStore provisioningProfileStore, BuildTarget binary, Either<AppleBundleExtension, String> extension, Optional<String> productName, final SourcePath infoPlist, ImmutableMap<String, String> infoPlistSubstitutions, ImmutableSortedSet<BuildTarget> deps, ImmutableSortedSet<BuildTarget> tests, AppleDebugFormat debugFormat, boolean dryRunCodeSigning, boolean cacheable) throws NoSuchBuildTargetException {
    AppleCxxPlatform appleCxxPlatform = ApplePlatforms.getAppleCxxPlatformForBuildTarget(cxxPlatformFlavorDomain, defaultCxxPlatform, appleCxxPlatforms, params.getBuildTarget(), MultiarchFileInfos.create(appleCxxPlatforms, params.getBuildTarget()));
    AppleBundleDestinations destinations;
    if (extension.isLeft() && extension.getLeft().equals(AppleBundleExtension.FRAMEWORK)) {
        destinations = AppleBundleDestinations.platformFrameworkDestinations(appleCxxPlatform.getAppleSdk().getApplePlatform());
    } else {
        destinations = AppleBundleDestinations.platformDestinations(appleCxxPlatform.getAppleSdk().getApplePlatform());
    }
    AppleBundleResources collectedResources = AppleResources.collectResourceDirsAndFiles(targetGraph, Optional.empty(), targetGraph.get(params.getBuildTarget()));
    ImmutableSet.Builder<SourcePath> frameworksBuilder = ImmutableSet.builder();
    if (INCLUDE_FRAMEWORKS.getRequiredValue(params.getBuildTarget())) {
        for (BuildTarget dep : deps) {
            Optional<FrameworkDependencies> frameworkDependencies = resolver.requireMetadata(BuildTarget.builder(dep).addFlavors(FRAMEWORK_FLAVOR).addFlavors(NO_INCLUDE_FRAMEWORKS_FLAVOR).addFlavors(appleCxxPlatform.getCxxPlatform().getFlavor()).build(), FrameworkDependencies.class);
            if (frameworkDependencies.isPresent()) {
                frameworksBuilder.addAll(frameworkDependencies.get().getSourcePaths());
            }
        }
    }
    ImmutableSet<SourcePath> frameworks = frameworksBuilder.build();
    SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(resolver);
    SourcePathResolver sourcePathResolver = new SourcePathResolver(ruleFinder);
    BuildRuleParams paramsWithoutBundleSpecificFlavors = stripBundleSpecificFlavors(params);
    Optional<AppleAssetCatalog> assetCatalog = createBuildRuleForTransitiveAssetCatalogDependencies(targetGraph, paramsWithoutBundleSpecificFlavors, sourcePathResolver, appleCxxPlatform.getAppleSdk().getApplePlatform(), appleCxxPlatform.getActool());
    addToIndex(resolver, assetCatalog);
    Optional<CoreDataModel> coreDataModel = createBuildRulesForCoreDataDependencies(targetGraph, paramsWithoutBundleSpecificFlavors, AppleBundle.getBinaryName(params.getBuildTarget(), productName), appleCxxPlatform);
    addToIndex(resolver, coreDataModel);
    Optional<SceneKitAssets> sceneKitAssets = createBuildRulesForSceneKitAssetsDependencies(targetGraph, paramsWithoutBundleSpecificFlavors, appleCxxPlatform);
    addToIndex(resolver, sceneKitAssets);
    // TODO(bhamiltoncx): Sort through the changes needed to make project generation work with
    // binary being optional.
    BuildRule flavoredBinaryRule = getFlavoredBinaryRule(cxxPlatformFlavorDomain, defaultCxxPlatform, targetGraph, paramsWithoutBundleSpecificFlavors.getBuildTarget().getFlavors(), resolver, binary);
    if (!AppleDebuggableBinary.isBuildRuleDebuggable(flavoredBinaryRule)) {
        debugFormat = AppleDebugFormat.NONE;
    }
    BuildTarget unstrippedTarget = flavoredBinaryRule.getBuildTarget().withoutFlavors(CxxStrip.RULE_FLAVOR, AppleDebuggableBinary.RULE_FLAVOR, AppleBinaryDescription.APP_FLAVOR).withoutFlavors(StripStyle.FLAVOR_DOMAIN.getFlavors()).withoutFlavors(AppleDebugFormat.FLAVOR_DOMAIN.getFlavors()).withoutFlavors(AppleDebuggableBinary.RULE_FLAVOR).withoutFlavors(ImmutableSet.of(AppleBinaryDescription.APP_FLAVOR));
    Optional<LinkerMapMode> linkerMapMode = LinkerMapMode.FLAVOR_DOMAIN.getValue(params.getBuildTarget());
    if (linkerMapMode.isPresent()) {
        unstrippedTarget = unstrippedTarget.withAppendedFlavors(linkerMapMode.get().getFlavor());
    }
    BuildRule unstrippedBinaryRule = resolver.requireRule(unstrippedTarget);
    BuildRule targetDebuggableBinaryRule;
    Optional<AppleDsym> appleDsym;
    if (unstrippedBinaryRule instanceof ProvidesLinkedBinaryDeps) {
        BuildTarget binaryBuildTarget = getBinaryFromBuildRuleWithBinary(flavoredBinaryRule).getBuildTarget().withoutFlavors(AppleDebugFormat.FLAVOR_DOMAIN.getFlavors());
        BuildRuleParams binaryParams = params.withBuildTarget(binaryBuildTarget);
        targetDebuggableBinaryRule = createAppleDebuggableBinary(binaryParams, resolver, getBinaryFromBuildRuleWithBinary(flavoredBinaryRule), (ProvidesLinkedBinaryDeps) unstrippedBinaryRule, debugFormat, cxxPlatformFlavorDomain, defaultCxxPlatform, appleCxxPlatforms);
        appleDsym = createAppleDsymForDebugFormat(debugFormat, binaryParams, resolver, (ProvidesLinkedBinaryDeps) unstrippedBinaryRule, cxxPlatformFlavorDomain, defaultCxxPlatform, appleCxxPlatforms);
    } else {
        targetDebuggableBinaryRule = unstrippedBinaryRule;
        appleDsym = Optional.empty();
    }
    BuildRuleParams bundleParamsWithFlavoredBinaryDep = getBundleParamsWithUpdatedDeps(params, binary, ImmutableSet.<BuildRule>builder().add(targetDebuggableBinaryRule).addAll(OptionalCompat.asSet(assetCatalog)).addAll(OptionalCompat.asSet(coreDataModel)).addAll(OptionalCompat.asSet(sceneKitAssets)).addAll(BuildRules.toBuildRulesFor(params.getBuildTarget(), resolver, RichStream.from(collectedResources.getAll()).concat(frameworks.stream()).filter(BuildTargetSourcePath.class).map(BuildTargetSourcePath::getTarget).collect(MoreCollectors.toImmutableSet()))).addAll(OptionalCompat.asSet(appleDsym)).build());
    ImmutableMap<SourcePath, String> extensionBundlePaths = collectFirstLevelAppleDependencyBundles(params.getDeps(), destinations);
    return new AppleBundle(bundleParamsWithFlavoredBinaryDep, resolver, extension, productName, infoPlist, infoPlistSubstitutions, Optional.of(getBinaryFromBuildRuleWithBinary(flavoredBinaryRule)), appleDsym, destinations, collectedResources, extensionBundlePaths, frameworks, appleCxxPlatform, assetCatalog, coreDataModel, sceneKitAssets, tests, codeSignIdentityStore, provisioningProfileStore, dryRunCodeSigning, cacheable);
}
Also used : FrameworkDependencies(com.facebook.buck.cxx.FrameworkDependencies) LinkerMapMode(com.facebook.buck.cxx.LinkerMapMode) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) ImmutableSet(com.google.common.collect.ImmutableSet) BuildTarget(com.facebook.buck.model.BuildTarget) BuildRule(com.facebook.buck.rules.BuildRule) ProvidesLinkedBinaryDeps(com.facebook.buck.cxx.ProvidesLinkedBinaryDeps) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) BuildRuleParams(com.facebook.buck.rules.BuildRuleParams)

Example 4 with BuildTargetSourcePath

use of com.facebook.buck.rules.BuildTargetSourcePath in project buck by facebook.

the class PrebuiltCxxLibraryDescription method requireSharedLibrary.

/**
   * 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(BuildTarget target, BuildRuleResolver resolver, SourcePathResolver pathResolver, CellPathResolver cellRoots, ProjectFilesystem filesystem, CxxPlatform cxxPlatform, Optional<String> versionSubdir, Arg args) throws NoSuchBuildTargetException {
    SourcePath sharedLibraryPath = PrebuiltCxxLibraryDescription.getSharedLibraryPath(target, cellRoots, filesystem, resolver, cxxPlatform, versionSubdir, args.libDir, args.libName);
    // produced. This is preventing distributed build loading files lazily.
    if (sharedLibraryPath instanceof BuildTargetSourcePath || filesystem.exists(pathResolver.getAbsolutePath(sharedLibraryPath))) {
        return sharedLibraryPath;
    }
    // Otherwise, generate it's build rule.
    CxxLink sharedLibrary = (CxxLink) resolver.requireRule(target.withAppendedFlavors(cxxPlatform.getFlavor(), CxxDescriptionEnhancer.SHARED_FLAVOR));
    return sharedLibrary.getSourcePathToOutput();
}
Also used : PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) ExplicitBuildTargetSourcePath(com.facebook.buck.rules.ExplicitBuildTargetSourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) ExplicitBuildTargetSourcePath(com.facebook.buck.rules.ExplicitBuildTargetSourcePath)

Example 5 with BuildTargetSourcePath

use of com.facebook.buck.rules.BuildTargetSourcePath in project buck by facebook.

the class RuleKeyBuilderTest method newBuilder.

private RuleKeyBuilder<RuleKey> newBuilder() {
    Map<BuildTarget, BuildRule> ruleMap = ImmutableMap.of(TARGET_1, RULE_1, TARGET_2, RULE_2);
    Map<BuildRule, RuleKey> ruleKeyMap = ImmutableMap.of(RULE_1, RULE_KEY_1, RULE_2, RULE_KEY_2);
    Map<RuleKeyAppendable, RuleKey> appendableKeys = ImmutableMap.of(APPENDABLE_1, RULE_KEY_1, APPENDABLE_2, RULE_KEY_2);
    BuildRuleResolver ruleResolver = new FakeBuildRuleResolver(ruleMap);
    SourcePathRuleFinder ruleFinder = new SourcePathRuleFinder(ruleResolver);
    SourcePathResolver pathResolver = new SourcePathResolver(ruleFinder);
    FakeFileHashCache hashCache = new FakeFileHashCache(ImmutableMap.of(FILESYSTEM.resolve(PATH_1), HashCode.fromInt(0), FILESYSTEM.resolve(PATH_2), HashCode.fromInt(42)), ImmutableMap.of(pathResolver.getAbsoluteArchiveMemberPath(ARCHIVE_PATH_1), HashCode.fromInt(0), pathResolver.getAbsoluteArchiveMemberPath(ARCHIVE_PATH_2), HashCode.fromInt(42)), ImmutableMap.of());
    RuleKeyHasher<HashCode> hasher = new GuavaRuleKeyHasher(Hashing.sha1().newHasher());
    return new RuleKeyBuilder<RuleKey>(ruleFinder, pathResolver, hashCache, hasher) {

        @Override
        protected RuleKeyBuilder<RuleKey> setBuildRule(BuildRule rule) {
            if (rule == IGNORED_RULE) {
                return this;
            }
            return setBuildRuleKey(ruleKeyMap.get(rule));
        }

        @Override
        public RuleKeyBuilder<RuleKey> setAppendableRuleKey(RuleKeyAppendable appendable) {
            if (appendable == IGNORED_APPENDABLE) {
                return this;
            }
            return setAppendableRuleKey(appendableKeys.get(appendable));
        }

        @Override
        protected RuleKeyBuilder<RuleKey> setSourcePath(SourcePath sourcePath) throws IOException {
            if (sourcePath instanceof BuildTargetSourcePath) {
                return setSourcePathAsRule((BuildTargetSourcePath<?>) sourcePath);
            } else {
                return setSourcePathDirectly(sourcePath);
            }
        }

        @Override
        protected RuleKeyBuilder<RuleKey> setNonHashingSourcePath(SourcePath sourcePath) {
            return setNonHashingSourcePathDirectly(sourcePath);
        }

        @Override
        public RuleKey build() {
            return buildRuleKey();
        }
    };
}
Also used : RuleKey(com.facebook.buck.rules.RuleKey) FakeFileHashCache(com.facebook.buck.testutil.FakeFileHashCache) SourcePathRuleFinder(com.facebook.buck.rules.SourcePathRuleFinder) SourcePathResolver(com.facebook.buck.rules.SourcePathResolver) BuildRuleResolver(com.facebook.buck.rules.BuildRuleResolver) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) DefaultBuildTargetSourcePath(com.facebook.buck.rules.DefaultBuildTargetSourcePath) ArchiveMemberSourcePath(com.facebook.buck.rules.ArchiveMemberSourcePath) PathSourcePath(com.facebook.buck.rules.PathSourcePath) SourcePath(com.facebook.buck.rules.SourcePath) BuildTargetSourcePath(com.facebook.buck.rules.BuildTargetSourcePath) DefaultBuildTargetSourcePath(com.facebook.buck.rules.DefaultBuildTargetSourcePath) Sha1HashCode(com.facebook.buck.util.sha1.Sha1HashCode) HashCode(com.google.common.hash.HashCode) BuildTarget(com.facebook.buck.model.BuildTarget) BuildRule(com.facebook.buck.rules.BuildRule) RuleKeyAppendable(com.facebook.buck.rules.RuleKeyAppendable)

Aggregations

BuildTargetSourcePath (com.facebook.buck.rules.BuildTargetSourcePath)10 SourcePath (com.facebook.buck.rules.SourcePath)8 BuildTarget (com.facebook.buck.model.BuildTarget)7 BuildRule (com.facebook.buck.rules.BuildRule)7 PathSourcePath (com.facebook.buck.rules.PathSourcePath)5 BuildRuleResolver (com.facebook.buck.rules.BuildRuleResolver)4 SourcePathResolver (com.facebook.buck.rules.SourcePathResolver)4 SourcePathRuleFinder (com.facebook.buck.rules.SourcePathRuleFinder)4 UnflavoredBuildTarget (com.facebook.buck.model.UnflavoredBuildTarget)2 BuildRuleParams (com.facebook.buck.rules.BuildRuleParams)2 DefaultBuildTargetSourcePath (com.facebook.buck.rules.DefaultBuildTargetSourcePath)2 DefaultTargetNodeToBuildRuleTransformer (com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer)2 ExplicitBuildTargetSourcePath (com.facebook.buck.rules.ExplicitBuildTargetSourcePath)2 RuleKey (com.facebook.buck.rules.RuleKey)2 RuleKeyAppendable (com.facebook.buck.rules.RuleKeyAppendable)2 Path (java.nio.file.Path)2 Test (org.junit.Test)2 SourceTreePath (com.facebook.buck.apple.xcode.xcodeproj.SourceTreePath)1 CxxLibraryBuilder (com.facebook.buck.cxx.CxxLibraryBuilder)1 CxxLink (com.facebook.buck.cxx.CxxLink)1