/*
* 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 static org.junit.Assert.assertThat;
import com.facebook.buck.cxx.CxxHeadersDir;
import com.facebook.buck.cxx.CxxPlatformUtils;
import com.facebook.buck.cxx.CxxPreprocessables;
import com.facebook.buck.cxx.CxxPreprocessorInput;
import com.facebook.buck.cxx.HeaderVisibility;
import com.facebook.buck.cxx.Linker;
import com.facebook.buck.cxx.NativeLinkableInput;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.rules.BuildRuleResolver;
import com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer;
import com.facebook.buck.rules.FakeSourcePath;
import com.facebook.buck.rules.PathSourcePath;
import com.facebook.buck.rules.SourcePathResolver;
import com.facebook.buck.rules.SourcePathRuleFinder;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.rules.args.Arg;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.facebook.buck.testutil.TargetGraphFactory;
import com.facebook.buck.util.RichStream;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSortedSet;
import org.hamcrest.Matchers;
import org.junit.Test;
public class HaskellPrebuiltLibraryDescriptionTest {
@Test
public void staticLibraries() throws Exception {
PathSourcePath lib = new FakeSourcePath("libfoo.a");
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
PrebuiltHaskellLibraryBuilder builder =
new PrebuiltHaskellLibraryBuilder(target)
.setVersion("1.0.0")
.setDb(new FakeSourcePath("package.conf.d"))
.setStaticLibs(ImmutableList.of(lib));
TargetGraph targetGraph = TargetGraphFactory.newInstance(builder.build());
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver =
new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
PrebuiltHaskellLibrary library = builder.build(resolver, filesystem, targetGraph);
NativeLinkableInput input =
library.getNativeLinkableInput(
CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC);
assertThat(
RichStream.from(input.getArgs()).flatMap(a -> a.getInputs().stream()).toImmutableSet(),
Matchers.contains(lib));
}
@Test
public void sharedLibraries() throws Exception {
PathSourcePath lib = new FakeSourcePath("libfoo.so");
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
PrebuiltHaskellLibraryBuilder builder =
new PrebuiltHaskellLibraryBuilder(target)
.setVersion("1.0.0")
.setDb(new FakeSourcePath("package.conf.d"))
.setSharedLibs(ImmutableMap.of("libfoo.so", lib));
TargetGraph targetGraph = TargetGraphFactory.newInstance(builder.build());
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver =
new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
PrebuiltHaskellLibrary library = builder.build(resolver, filesystem, targetGraph);
NativeLinkableInput input =
library.getNativeLinkableInput(
CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.SHARED);
assertThat(
RichStream.from(input.getArgs()).flatMap(a -> a.getInputs().stream()).toImmutableSet(),
Matchers.contains(lib));
}
@Test
public void interfaces() throws Exception {
PathSourcePath interfaces = new FakeSourcePath("interfaces");
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
PrebuiltHaskellLibraryBuilder builder =
new PrebuiltHaskellLibraryBuilder(target)
.setVersion("1.0.0")
.setDb(new FakeSourcePath("package.conf.d"))
.setImportDirs(ImmutableList.of(interfaces));
TargetGraph targetGraph = TargetGraphFactory.newInstance(builder.build());
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver =
new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
PrebuiltHaskellLibrary library = builder.build(resolver, filesystem, targetGraph);
HaskellCompileInput input =
library.getCompileInput(CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC);
assertThat(input.getPackages().get(0).getInterfaces(), Matchers.contains(interfaces));
}
@Test
public void packageDb() throws Exception {
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
PathSourcePath db = new FakeSourcePath("package.conf.d");
PrebuiltHaskellLibraryBuilder builder =
new PrebuiltHaskellLibraryBuilder(target).setVersion("1.0.0").setDb(db);
TargetGraph targetGraph = TargetGraphFactory.newInstance(builder.build());
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver =
new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
PrebuiltHaskellLibrary library = builder.build(resolver, filesystem, targetGraph);
HaskellCompileInput input =
library.getCompileInput(CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC);
assertThat(input.getPackages().get(0).getPackageDb(), Matchers.equalTo(db));
}
@Test
public void packageInfo() throws Exception {
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
PrebuiltHaskellLibraryBuilder builder =
new PrebuiltHaskellLibraryBuilder(target)
.setVersion("1.0.0")
.setDb(new FakeSourcePath("package.conf.d"))
.setId("id");
TargetGraph targetGraph = TargetGraphFactory.newInstance(builder.build());
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver =
new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
PrebuiltHaskellLibrary library = builder.build(resolver, filesystem, targetGraph);
HaskellCompileInput input =
library.getCompileInput(CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC);
assertThat(
input.getPackages().get(0).getInfo(),
Matchers.equalTo(HaskellPackageInfo.of("rule", "1.0.0", "id")));
}
@Test
public void exportedLinkerFlags() throws Exception {
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
String flag = "-exported-linker-flags";
PrebuiltHaskellLibraryBuilder builder =
new PrebuiltHaskellLibraryBuilder(target)
.setVersion("1.0.0")
.setDb(new FakeSourcePath("package.conf.d"))
.setExportedLinkerFlags(ImmutableList.of(flag));
TargetGraph targetGraph = TargetGraphFactory.newInstance(builder.build());
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver =
new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
SourcePathResolver pathResolver = new SourcePathResolver(new SourcePathRuleFinder(resolver));
PrebuiltHaskellLibrary library = builder.build(resolver, filesystem, targetGraph);
NativeLinkableInput staticInput =
library.getNativeLinkableInput(
CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC);
assertThat(Arg.stringify(staticInput.getArgs(), pathResolver), Matchers.contains(flag));
NativeLinkableInput sharedInput =
library.getNativeLinkableInput(
CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.SHARED);
assertThat(Arg.stringify(sharedInput.getArgs(), pathResolver), Matchers.contains(flag));
}
@Test
public void exportedCompilerFlags() throws Exception {
String flag = "-exported-compiler-flags";
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
PrebuiltHaskellLibraryBuilder builder =
new PrebuiltHaskellLibraryBuilder(target)
.setVersion("1.0.0")
.setDb(new FakeSourcePath("package.conf.d"))
.setExportedCompilerFlags(ImmutableList.of(flag));
TargetGraph targetGraph = TargetGraphFactory.newInstance(builder.build());
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver =
new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
PrebuiltHaskellLibrary library = builder.build(resolver, filesystem, targetGraph);
HaskellCompileInput staticInput =
library.getCompileInput(CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC);
assertThat(staticInput.getFlags(), Matchers.contains(flag));
HaskellCompileInput sharedInput =
library.getCompileInput(
CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC_PIC);
assertThat(sharedInput.getFlags(), Matchers.contains(flag));
}
@Test
public void cxxHeaderDirs() throws Exception {
PathSourcePath interfaces = new FakeSourcePath("interfaces");
BuildTarget target = BuildTargetFactory.newInstance("//:rule");
PathSourcePath path = new FakeSourcePath("include_dir");
PrebuiltHaskellLibraryBuilder builder =
new PrebuiltHaskellLibraryBuilder(target)
.setVersion("1.0.0")
.setDb(new FakeSourcePath("package.conf.d"))
.setImportDirs(ImmutableList.of(interfaces))
.setCxxHeaderDirs(ImmutableSortedSet.of(path));
TargetGraph targetGraph = TargetGraphFactory.newInstance(builder.build());
ProjectFilesystem filesystem = new FakeProjectFilesystem();
BuildRuleResolver resolver =
new BuildRuleResolver(targetGraph, new DefaultTargetNodeToBuildRuleTransformer());
PrebuiltHaskellLibrary library = builder.build(resolver, filesystem, targetGraph);
assertThat(
library.getCxxPreprocessorInput(CxxPlatformUtils.DEFAULT_PLATFORM, HeaderVisibility.PUBLIC),
Matchers.equalTo(
CxxPreprocessorInput.builder()
.addIncludes(CxxHeadersDir.of(CxxPreprocessables.IncludeType.SYSTEM, path))
.build()));
}
}