/* * Copyright 2015-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may obtain * a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. */ package com.facebook.buck.cxx; import com.facebook.buck.android.AndroidPackageable; import com.facebook.buck.android.AndroidPackageableCollector; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.parser.NoSuchBuildTargetException; import com.facebook.buck.rules.BuildRule; import com.facebook.buck.rules.BuildRuleParams; import com.facebook.buck.rules.DefaultBuildTargetSourcePath; import com.facebook.buck.rules.NoopBuildRule; import com.facebook.buck.rules.PathSourcePath; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.args.SourcePathArg; import com.google.common.cache.LoadingCache; import com.google.common.collect.FluentIterable; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSortedSet; import java.nio.file.Path; import java.nio.file.Paths; /** Fake implementation of {@link CxxLibrary} for testing. */ public final class FakeCxxLibrary extends NoopBuildRule implements AbstractCxxLibrary, NativeTestable { private final BuildTarget publicHeaderTarget; private final BuildTarget publicHeaderSymlinkTreeTarget; private final BuildTarget privateHeaderTarget; private final BuildTarget privateHeaderSymlinkTreeTarget; private final BuildRule archive; private final BuildRule sharedLibrary; private final Path sharedLibraryOutput; private final String sharedLibrarySoname; private final ImmutableSortedSet<BuildTarget> tests; private final LoadingCache< CxxPreprocessables.CxxPreprocessorInputCacheKey, ImmutableMap<BuildTarget, CxxPreprocessorInput>> transitiveCxxPreprocessorInputCache = CxxPreprocessables.getTransitiveCxxPreprocessorInputCache(this); public FakeCxxLibrary( BuildRuleParams params, BuildTarget publicHeaderTarget, BuildTarget publicHeaderSymlinkTreeTarget, BuildTarget privateHeaderTarget, BuildTarget privateHeaderSymlinkTreeTarget, BuildRule archive, BuildRule sharedLibrary, Path sharedLibraryOutput, String sharedLibrarySoname, ImmutableSortedSet<BuildTarget> tests) { super(params); this.publicHeaderTarget = publicHeaderTarget; this.publicHeaderSymlinkTreeTarget = publicHeaderSymlinkTreeTarget; this.privateHeaderTarget = privateHeaderTarget; this.privateHeaderSymlinkTreeTarget = privateHeaderSymlinkTreeTarget; this.archive = archive; this.sharedLibrary = sharedLibrary; this.sharedLibraryOutput = sharedLibraryOutput; this.sharedLibrarySoname = sharedLibrarySoname; this.tests = tests; } @Override public Iterable<? extends CxxPreprocessorDep> getCxxPreprocessorDeps(CxxPlatform cxxPlatform) { return FluentIterable.from(getBuildDeps()).filter(CxxPreprocessorDep.class); } @Override public CxxPreprocessorInput getCxxPreprocessorInput( CxxPlatform cxxPlatform, HeaderVisibility headerVisibility) { switch (headerVisibility) { case PUBLIC: return CxxPreprocessorInput.builder() .addIncludes( CxxSymlinkTreeHeaders.builder() .setIncludeType(CxxPreprocessables.IncludeType.LOCAL) .putNameToPathMap( Paths.get("header.h"), new DefaultBuildTargetSourcePath(publicHeaderTarget)) .setRoot(new DefaultBuildTargetSourcePath(publicHeaderSymlinkTreeTarget)) .build()) .build(); case PRIVATE: return CxxPreprocessorInput.builder() .addIncludes( CxxSymlinkTreeHeaders.builder() .setIncludeType(CxxPreprocessables.IncludeType.LOCAL) .setRoot(new DefaultBuildTargetSourcePath(privateHeaderSymlinkTreeTarget)) .putNameToPathMap( Paths.get("header.h"), new DefaultBuildTargetSourcePath(privateHeaderTarget)) .build()) .build(); } throw new RuntimeException("Invalid header visibility value: " + headerVisibility); } @Override public ImmutableMap<BuildTarget, CxxPreprocessorInput> getTransitiveCxxPreprocessorInput( CxxPlatform cxxPlatform, HeaderVisibility headerVisibility) throws NoSuchBuildTargetException { return transitiveCxxPreprocessorInputCache.getUnchecked( ImmutableCxxPreprocessorInputCacheKey.of(cxxPlatform, headerVisibility)); } @Override public Iterable<NativeLinkable> getNativeLinkableDeps() { return FluentIterable.from(getDeclaredDeps()).filter(NativeLinkable.class); } @Override public Iterable<NativeLinkable> getNativeLinkableExportedDeps() { return FluentIterable.from(getDeclaredDeps()).filter(NativeLinkable.class); } @Override public NativeLinkableInput getNativeLinkableInput( CxxPlatform cxxPlatform, Linker.LinkableDepType type) { return type == Linker.LinkableDepType.STATIC ? NativeLinkableInput.of( ImmutableList.of(SourcePathArg.of(archive.getSourcePathToOutput())), ImmutableSet.of(), ImmutableSet.of()) : NativeLinkableInput.of( ImmutableList.of(SourcePathArg.of(sharedLibrary.getSourcePathToOutput())), ImmutableSet.of(), ImmutableSet.of()); } @Override public NativeLinkable.Linkage getPreferredLinkage(CxxPlatform cxxPlatform) { return Linkage.ANY; } @Override public Iterable<AndroidPackageable> getRequiredPackageables() { return ImmutableList.of(); } @Override public void addToCollector(AndroidPackageableCollector collector) {} @Override public ImmutableMap<String, SourcePath> getSharedLibraries(CxxPlatform cxxPlatform) { return ImmutableMap.of( sharedLibrarySoname, new PathSourcePath(getProjectFilesystem(), sharedLibraryOutput)); } @Override public boolean isTestedBy(BuildTarget testTarget) { return tests.contains(testTarget); } }