/* * Copyright 2016-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.haskell; import com.facebook.buck.cxx.CxxHeadersDir; import com.facebook.buck.cxx.CxxPlatform; import com.facebook.buck.cxx.CxxPreprocessables; import com.facebook.buck.cxx.CxxPreprocessorDep; import com.facebook.buck.cxx.CxxPreprocessorInput; import com.facebook.buck.cxx.HeaderVisibility; import com.facebook.buck.cxx.ImmutableCxxPreprocessorInputCacheKey; import com.facebook.buck.cxx.Linker; import com.facebook.buck.cxx.NativeLinkable; import com.facebook.buck.cxx.NativeLinkableInput; 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.BuildRuleResolver; import com.facebook.buck.rules.CellPathResolver; import com.facebook.buck.rules.CommonDescriptionArg; import com.facebook.buck.rules.Description; import com.facebook.buck.rules.HasDeclaredDeps; import com.facebook.buck.rules.SourcePath; import com.facebook.buck.rules.TargetGraph; import com.facebook.buck.rules.args.SourcePathArg; import com.facebook.buck.rules.args.StringArg; import com.facebook.buck.util.RichStream; import com.facebook.buck.util.immutables.BuckStyleImmutable; import com.facebook.buck.versions.VersionPropagator; 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.ImmutableSortedSet; import org.immutables.value.Value; public class HaskellPrebuiltLibraryDescription implements Description<HaskellPrebuiltLibraryDescriptionArg>, VersionPropagator<HaskellPrebuiltLibraryDescriptionArg> { @Override public Class<HaskellPrebuiltLibraryDescriptionArg> getConstructorArgType() { return HaskellPrebuiltLibraryDescriptionArg.class; } @Override public BuildRule createBuildRule( TargetGraph targetGraph, BuildRuleParams params, BuildRuleResolver resolver, CellPathResolver cellRoots, final HaskellPrebuiltLibraryDescriptionArg args) throws NoSuchBuildTargetException { return new PrebuiltHaskellLibrary(params) { private final LoadingCache< CxxPreprocessables.CxxPreprocessorInputCacheKey, ImmutableMap<BuildTarget, CxxPreprocessorInput>> transitiveCxxPreprocessorInputCache = CxxPreprocessables.getTransitiveCxxPreprocessorInputCache(this); @Override public Iterable<BuildRule> getCompileDeps(CxxPlatform cxxPlatform) { return RichStream.from(args.getDeps()) .map(resolver::getRule) .filter(HaskellCompileDep.class::isInstance) .toImmutableList(); } @Override public HaskellCompileInput getCompileInput( CxxPlatform cxxPlatform, Linker.LinkableDepType depType) throws NoSuchBuildTargetException { return HaskellCompileInput.builder() .addAllFlags(args.getExportedCompilerFlags()) .addPackages( HaskellPackage.builder() .setInfo( HaskellPackageInfo.of( getBuildTarget().getShortName(), args.getVersion(), args.getId())) .setPackageDb(args.getDb()) .addAllInterfaces(args.getImportDirs()) .addAllLibraries( depType == Linker.LinkableDepType.SHARED ? args.getSharedLibs().values() : args.getStaticLibs()) .build()) .build(); } @Override public Iterable<? extends NativeLinkable> getNativeLinkableDeps() { return ImmutableList.of(); } @Override public Iterable<? extends NativeLinkable> getNativeLinkableExportedDeps() { return FluentIterable.from(getDeclaredDeps()).filter(NativeLinkable.class); } @Override public NativeLinkableInput getNativeLinkableInput( CxxPlatform cxxPlatform, Linker.LinkableDepType type) { NativeLinkableInput.Builder builder = NativeLinkableInput.builder(); builder.addAllArgs(StringArg.from(args.getExportedLinkerFlags())); if (type == Linker.LinkableDepType.SHARED) { builder.addAllArgs(SourcePathArg.from(args.getSharedLibs().values())); } else { builder.addAllArgs(SourcePathArg.from(args.getStaticLibs())); } return builder.build(); } @Override public Linkage getPreferredLinkage(CxxPlatform cxxPlatform) { return Linkage.ANY; } @Override public ImmutableMap<String, SourcePath> getSharedLibraries(CxxPlatform cxxPlatform) { return args.getSharedLibs(); } @Override public Iterable<? extends CxxPreprocessorDep> getCxxPreprocessorDeps( CxxPlatform cxxPlatform) { return FluentIterable.from(getBuildDeps()).filter(CxxPreprocessorDep.class); } @Override public CxxPreprocessorInput getCxxPreprocessorInput( CxxPlatform cxxPlatform, HeaderVisibility headerVisibility) throws NoSuchBuildTargetException { CxxPreprocessorInput.Builder builder = CxxPreprocessorInput.builder(); for (SourcePath headerDir : args.getCxxHeaderDirs()) { builder.addIncludes(CxxHeadersDir.of(CxxPreprocessables.IncludeType.SYSTEM, headerDir)); } return builder.build(); } @Override public ImmutableMap<BuildTarget, CxxPreprocessorInput> getTransitiveCxxPreprocessorInput( CxxPlatform cxxPlatform, HeaderVisibility headerVisibility) throws NoSuchBuildTargetException { return transitiveCxxPreprocessorInputCache.getUnchecked( ImmutableCxxPreprocessorInputCacheKey.of(cxxPlatform, headerVisibility)); } }; } @BuckStyleImmutable @Value.Immutable interface AbstractHaskellPrebuiltLibraryDescriptionArg extends CommonDescriptionArg, HasDeclaredDeps { String getVersion(); @Value.Default default String getId() { return String.format("%s-%s", getName(), getVersion()); } SourcePath getDb(); ImmutableList<SourcePath> getImportDirs(); ImmutableList<SourcePath> getStaticLibs(); ImmutableMap<String, SourcePath> getSharedLibs(); ImmutableList<String> getExportedLinkerFlags(); ImmutableList<String> getExportedCompilerFlags(); @Value.NaturalOrder ImmutableSortedSet<SourcePath> getCxxHeaderDirs(); } }