/* * 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.cxx; import static org.junit.Assert.assertThat; import com.facebook.buck.model.BuildTarget; import com.facebook.buck.model.BuildTargetFactory; import com.facebook.buck.rules.BuildRule; import com.facebook.buck.rules.BuildRuleResolver; import com.facebook.buck.rules.DefaultBuildTargetSourcePath; import com.facebook.buck.rules.DefaultTargetNodeToBuildRuleTransformer; import com.facebook.buck.rules.FakeSourcePath; import com.facebook.buck.rules.PathSourcePath; 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.rules.coercer.PatternMatchedCollection; import com.facebook.buck.testutil.TargetGraphFactory; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSortedSet; import java.util.regex.Pattern; import org.hamcrest.Matchers; import org.junit.Test; public class PrebuiltCxxLibraryGroupDescriptionTest { @Test public void exportedPreprocessorFlags() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); BuildTarget target = BuildTargetFactory.newInstance("//:lib"); CxxPreprocessorDep lib = (CxxPreprocessorDep) new PrebuiltCxxLibraryGroupBuilder(target) .setExportedPreprocessorFlags(ImmutableList.of("-flag")) .build(resolver); assertThat( lib.getCxxPreprocessorInput(CxxPlatformUtils.DEFAULT_PLATFORM, HeaderVisibility.PUBLIC) .getPreprocessorFlags(), Matchers.equalTo( CxxFlags.getLanguageFlags( ImmutableList.of("-flag"), PatternMatchedCollection.of(), ImmutableMap.of(), CxxPlatformUtils.DEFAULT_PLATFORM))); } @Test public void includeDirs() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); BuildTarget target = BuildTargetFactory.newInstance("//:lib"); SourcePath includes = new FakeSourcePath("include"); CxxPreprocessorDep lib = (CxxPreprocessorDep) new PrebuiltCxxLibraryGroupBuilder(target) .setIncludeDirs(ImmutableList.of(includes)) .build(resolver); assertThat( lib.getCxxPreprocessorInput(CxxPlatformUtils.DEFAULT_PLATFORM, HeaderVisibility.PUBLIC) .getIncludes(), Matchers.equalTo( ImmutableList.<CxxHeaders>of( CxxHeadersDir.of(CxxPreprocessables.IncludeType.SYSTEM, includes)))); } @Test public void staticLink() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); BuildTarget target = BuildTargetFactory.newInstance("//:lib"); SourcePath path = new FakeSourcePath("include"); NativeLinkable lib = (NativeLinkable) new PrebuiltCxxLibraryGroupBuilder(target) .setStaticLink(ImmutableList.of("--something", "$(lib 0)", "--something-else")) .setStaticLibs(ImmutableList.of(path)) .build(resolver); assertThat( lib.getNativeLinkableInput( CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC), Matchers.equalTo( NativeLinkableInput.builder() .addArgs( StringArg.of("--something"), SourcePathArg.of(path), StringArg.of("--something-else")) .build())); } @Test public void staticPicLink() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); BuildTarget target = BuildTargetFactory.newInstance("//:lib"); SourcePath path = new FakeSourcePath("include"); NativeLinkable lib = (NativeLinkable) new PrebuiltCxxLibraryGroupBuilder(target) .setStaticPicLink(ImmutableList.of("--something", "$(lib 0)", "--something-else")) .setStaticPicLibs(ImmutableList.of(path)) .build(resolver); assertThat( lib.getNativeLinkableInput( CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC_PIC), Matchers.equalTo( NativeLinkableInput.builder() .addArgs( StringArg.of("--something"), SourcePathArg.of(path), StringArg.of("--something-else")) .build())); } @Test public void sharedLink() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); BuildTarget target = BuildTargetFactory.newInstance("//:lib"); SourcePath lib1 = new FakeSourcePath("dir/lib1.so"); PathSourcePath lib2 = new FakeSourcePath("dir/lib2.so"); NativeLinkable lib = (NativeLinkable) new PrebuiltCxxLibraryGroupBuilder(target) .setSharedLink( ImmutableList.of( "--something", "$(lib lib1.so)", "--something-else", "$(rel-lib lib2.so)")) .setSharedLibs(ImmutableMap.of("lib1.so", lib1, "lib2.so", lib2)) .build(resolver); assertThat( lib.getNativeLinkableInput( CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.SHARED), Matchers.equalTo( NativeLinkableInput.builder() .addArgs( StringArg.of("--something"), SourcePathArg.of(lib1), StringArg.of("--something-else"), new RelativeLinkArg(lib2)) .build())); } @Test public void exportedDeps() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); BuildTarget target = BuildTargetFactory.newInstance("//:lib"); CxxLibrary dep = (CxxLibrary) new CxxLibraryBuilder(BuildTargetFactory.newInstance("//:dep")).build(resolver); NativeLinkable lib = (NativeLinkable) new PrebuiltCxxLibraryGroupBuilder(target) .setExportedDeps(ImmutableSortedSet.of(dep.getBuildTarget())) .build(resolver); assertThat( lib.getNativeLinkableExportedDepsForPlatform(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.contains(dep)); } @Test public void providedSharedLibs() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); BuildTarget target = BuildTargetFactory.newInstance("//:lib"); SourcePath lib1 = new FakeSourcePath("dir/lib1.so"); SourcePath lib2 = new FakeSourcePath("dir/lib2.so"); NativeLinkable lib = (NativeLinkable) new PrebuiltCxxLibraryGroupBuilder(target) .setSharedLink(ImmutableList.of("$(lib lib1.so)", "$(lib lib2.so)")) .setSharedLibs(ImmutableMap.of("lib1.so", lib1)) .setProvidedSharedLibs(ImmutableMap.of("lib2.so", lib2)) .build(resolver); assertThat( lib.getNativeLinkableInput( CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.SHARED), Matchers.equalTo( NativeLinkableInput.builder() .addArgs(SourcePathArg.of(lib1), SourcePathArg.of(lib2)) .build())); assertThat( lib.getSharedLibraries(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.equalTo(ImmutableMap.of("lib1.so", lib1))); } @Test public void preferredLinkage() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); NativeLinkable any = (NativeLinkable) new PrebuiltCxxLibraryGroupBuilder(BuildTargetFactory.newInstance("//:any")) .setSharedLink(ImmutableList.of("-something")) .setStaticLink(ImmutableList.of("-something")) .build(resolver); assertThat( any.getPreferredLinkage(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.equalTo(NativeLinkable.Linkage.ANY)); NativeLinkable staticOnly = (NativeLinkable) new PrebuiltCxxLibraryGroupBuilder(BuildTargetFactory.newInstance("//:static-only")) .setStaticLink(ImmutableList.of("-something")) .build(resolver); assertThat( staticOnly.getPreferredLinkage(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.equalTo(NativeLinkable.Linkage.STATIC)); NativeLinkable sharedOnly = (NativeLinkable) new PrebuiltCxxLibraryGroupBuilder(BuildTargetFactory.newInstance("//:shared-only")) .setSharedLink(ImmutableList.of("-something")) .build(resolver); assertThat( sharedOnly.getPreferredLinkage(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.equalTo(NativeLinkable.Linkage.SHARED)); } @Test public void cxxGenruleLib() throws Exception { CxxGenruleBuilder cxxGenruleBuilder = new CxxGenruleBuilder(BuildTargetFactory.newInstance("//:dep")).setOut("libtest.so"); PrebuiltCxxLibraryGroupBuilder builder = new PrebuiltCxxLibraryGroupBuilder(BuildTargetFactory.newInstance("//:rule")) .setStaticLink(ImmutableList.of("$(lib 0)")) .setStaticLibs( ImmutableList.of(new DefaultBuildTargetSourcePath(cxxGenruleBuilder.getTarget()))); BuildRuleResolver resolver = new BuildRuleResolver( TargetGraphFactory.newInstance(cxxGenruleBuilder.build(), builder.build()), new DefaultTargetNodeToBuildRuleTransformer()); CxxGenrule cxxGenrule = (CxxGenrule) cxxGenruleBuilder.build(resolver); NativeLinkable library = (NativeLinkable) builder.build(resolver); NativeLinkableInput input = library.getNativeLinkableInput( CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.STATIC); SourcePath lib = cxxGenrule.getGenrule(CxxPlatformUtils.DEFAULT_PLATFORM); assertThat(input.getArgs(), Matchers.contains(SourcePathArg.of(lib))); } @Test public void supportedPlatforms() throws Exception { BuildRuleResolver resolver = new BuildRuleResolver(TargetGraph.EMPTY, new DefaultTargetNodeToBuildRuleTransformer()); CxxLibrary dep1 = (CxxLibrary) new CxxLibraryBuilder(BuildTargetFactory.newInstance("//:dep")).build(resolver); CxxLibrary dep2 = (CxxLibrary) new CxxLibraryBuilder(BuildTargetFactory.newInstance("//:dep2")).build(resolver); BuildTarget target = BuildTargetFactory.newInstance("//:lib"); SourcePath lib1 = new FakeSourcePath("dir/lib1.so"); SourcePath lib2 = new FakeSourcePath("dir/lib2.so"); BuildRule buildRule = new PrebuiltCxxLibraryGroupBuilder(target) .setSharedLink(ImmutableList.of("$(lib lib1.so)", "$(lib lib2.so)")) .setSharedLibs(ImmutableMap.of("lib1.so", lib1)) .setProvidedSharedLibs(ImmutableMap.of("lib2.so", lib2)) .setExportedDeps(ImmutableSortedSet.of(dep1.getBuildTarget())) .setDeps(ImmutableSortedSet.of(dep2.getBuildTarget())) .setSupportedPlatformsRegex(Pattern.compile("nothing")) .build(resolver); NativeLinkable lib = (NativeLinkable) buildRule; assertThat( lib.getNativeLinkableInput( CxxPlatformUtils.DEFAULT_PLATFORM, Linker.LinkableDepType.SHARED), Matchers.equalTo(NativeLinkableInput.of())); assertThat( lib.getNativeLinkableExportedDepsForPlatform(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.emptyIterable()); assertThat( lib.getNativeLinkableDepsForPlatform(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.emptyIterable()); assertThat(lib.getSharedLibraries(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.anEmptyMap()); CxxPreprocessorDep cxxPreprocessorDep = (CxxPreprocessorDep) buildRule; assertThat( cxxPreprocessorDep.getCxxPreprocessorDeps(CxxPlatformUtils.DEFAULT_PLATFORM), Matchers.emptyIterable()); } }