diff options
author | Googler <noreply@google.com> | 2016-03-18 17:33:12 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2016-03-21 09:34:21 +0000 |
commit | bb2f07124c7ebf5cb28c8cd4b57cf6156c1c7b0d (patch) | |
tree | ec63ded235fee12bd21b27b82376bf87fc9f568f /src/test/java/com/google/devtools | |
parent | 51a491b89a9cd5f15c9a093a5693bc37e696e6e1 (diff) |
Export cc build information in an aspect for IDE support.
--
MOS_MIGRATED_REVID=117560803
Diffstat (limited to 'src/test/java/com/google/devtools')
3 files changed, 622 insertions, 25 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java b/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java index 81b0badabc..02263568d8 100644 --- a/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java +++ b/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTest.java @@ -19,10 +19,13 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.ArtifactLocation; +import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.CRuleIdeInfo; +import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.CToolchainIdeInfo; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.JavaRuleIdeInfo; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.RuleIdeInfo; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.RuleIdeInfo.Kind; import com.google.devtools.build.lib.vfs.Path; +import com.google.protobuf.ProtocolStringList; import org.junit.Test; import org.junit.runner.RunWith; @@ -30,6 +33,7 @@ import org.junit.runners.JUnit4; import java.nio.file.Paths; import java.util.Map; +import java.util.Map.Entry; /** * Tests for {@link AndroidStudioInfoAspect} validating proto's contents. @@ -60,7 +64,7 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase } assertThat(ruleIdeInfo.getKind()).isEqualTo(Kind.JAVA_LIBRARY); assertThat(ruleIdeInfo.getDependenciesCount()).isEqualTo(0); - assertThat(relativePathsForSourcesOf(ruleIdeInfo)) + assertThat(relativePathsForJavaSourcesOf(ruleIdeInfo)) .containsExactly("com/google/example/simple/Simple.java"); assertThat( transform(ruleIdeInfo.getJavaRuleIdeInfo().getJarsList(), LIBRARY_ARTIFACT_TO_STRING)) @@ -119,7 +123,7 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase RuleIdeInfo complexRuleIdeInfo = getRuleInfoAndVerifyLabel( "//com/google/example:complex", ruleIdeInfos); - assertThat(relativePathsForSourcesOf(complexRuleIdeInfo)) + assertThat(relativePathsForJavaSourcesOf(complexRuleIdeInfo)) .containsExactly("com/google/example/complex/Complex.java"); assertThat(complexRuleIdeInfo.getDependenciesList()) .containsExactly("//com/google/example:simple"); @@ -152,7 +156,7 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase RuleIdeInfo extraComplexRuleIdeInfo = getRuleInfoAndVerifyLabel( "//com/google/example:extracomplex", ruleIdeInfos); - assertThat(relativePathsForSourcesOf(extraComplexRuleIdeInfo)) + assertThat(relativePathsForJavaSourcesOf(extraComplexRuleIdeInfo)) .containsExactly("com/google/example/extracomplex/ExtraComplex.java"); assertThat(extraComplexRuleIdeInfo.getDependenciesList()) .containsExactly("//com/google/example:complex"); @@ -203,7 +207,7 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase RuleIdeInfo extraComplexRuleIdeInfo = getRuleInfoAndVerifyLabel( "//com/google/example:extracomplex", ruleIdeInfos); - assertThat(relativePathsForSourcesOf(extraComplexRuleIdeInfo)) + assertThat(relativePathsForJavaSourcesOf(extraComplexRuleIdeInfo)) .containsExactly("com/google/example/extracomplex/ExtraComplex.java"); assertThat(extraComplexRuleIdeInfo.getDependenciesList()) .containsExactly("//com/google/example:complex", "//com/google/example:complex1"); @@ -291,7 +295,7 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase RuleIdeInfo megaComplexRuleIdeInfo = getRuleInfoAndVerifyLabel( "//com/google/example:megacomplex", ruleIdeInfos); - assertThat(relativePathsForSourcesOf(megaComplexRuleIdeInfo)) + assertThat(relativePathsForJavaSourcesOf(megaComplexRuleIdeInfo)) .containsExactly("com/google/example/megacomplex/MegaComplex.java"); assertThat(megaComplexRuleIdeInfo.getDependenciesList()) .containsExactly( @@ -467,10 +471,10 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase RuleIdeInfo testInfo = getRuleInfoAndVerifyLabel( "//java/com/google/example:FooBarTest", ruleIdeInfos); assertThat(testInfo.getKind()).isEqualTo(Kind.JAVA_TEST); - assertThat(relativePathsForSourcesOf(testInfo)) + assertThat(relativePathsForJavaSourcesOf(testInfo)) .containsExactly("java/com/google/example/FooBarTest.java"); - assertThat(testInfo.getDependenciesList()) - .containsExactly("//java/com/google/example:foobar"); + assertThat(testInfo.getDependenciesList()).contains("//java/com/google/example:foobar"); + assertThat(testInfo.getDependenciesList()).hasSize(2); assertThat(transform(testInfo.getJavaRuleIdeInfo().getJarsList(), LIBRARY_ARTIFACT_TO_STRING)) .containsExactly(jarString("java/com/google/example", "FooBarTest.jar", null, "FooBarTest-src.jar")); @@ -504,9 +508,10 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase RuleIdeInfo binaryInfo = getRuleInfoAndVerifyLabel( "//com/google/example:foobar-exe", ruleIdeInfos); assertThat(binaryInfo.getKind()).isEqualTo(Kind.JAVA_BINARY); - assertThat(relativePathsForSourcesOf(binaryInfo)) + assertThat(relativePathsForJavaSourcesOf(binaryInfo)) .containsExactly("com/google/example/FooBarMain.java"); - assertThat(binaryInfo.getDependenciesList()).containsExactly("//com/google/example:foobar"); + assertThat(binaryInfo.getDependenciesList()).contains("//com/google/example:foobar"); + assertThat(binaryInfo.getDependenciesList()).hasSize(2); assertThat(transform(binaryInfo.getJavaRuleIdeInfo().getJarsList(), LIBRARY_ARTIFACT_TO_STRING)) .containsExactly(jarString("com/google/example", "foobar-exe.jar", null, "foobar-exe-src.jar")); @@ -543,7 +548,7 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:l"); RuleIdeInfo ruleInfo = getRuleInfoAndVerifyLabel("//com/google/example:l", ruleIdeInfos); assertThat(ruleInfo.getKind()).isEqualTo(Kind.ANDROID_LIBRARY); - assertThat(relativePathsForSourcesOf(ruleInfo)).containsExactly("com/google/example/Main.java"); + assertThat(relativePathsForJavaSourcesOf(ruleInfo)).containsExactly("com/google/example/Main.java"); assertThat(transform(ruleInfo.getJavaRuleIdeInfo().getJarsList(), LIBRARY_ARTIFACT_TO_STRING)) .containsExactly( jarString("com/google/example", @@ -597,7 +602,7 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:b"); RuleIdeInfo ruleInfo = getRuleInfoAndVerifyLabel("//com/google/example:b", ruleIdeInfos); assertThat(ruleInfo.getKind()).isEqualTo(Kind.ANDROID_BINARY); - assertThat(relativePathsForSourcesOf(ruleInfo)).containsExactly("com/google/example/Main.java"); + assertThat(relativePathsForJavaSourcesOf(ruleInfo)).containsExactly("com/google/example/Main.java"); assertThat(transform(ruleInfo.getJavaRuleIdeInfo().getJarsList(), LIBRARY_ARTIFACT_TO_STRING)) .containsExactly( jarString("com/google/example", @@ -616,7 +621,8 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase .isEqualTo("com/google/example/b.apk"); - assertThat(ruleInfo.getDependenciesList()).containsExactly("//com/google/example:l1"); + assertThat(ruleInfo.getDependenciesList()).contains("//com/google/example:l1"); + assertThat(ruleInfo.getDependenciesList()).hasSize(2); assertThat(getIdeResolveFiles()).containsExactly( "com/google/example/libb.jar", @@ -690,7 +696,7 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase assertThat(LIBRARY_ARTIFACT_TO_STRING.apply(idlRuleInfo.getAndroidRuleIdeInfo().getIdlJar())) .isEqualTo(jarString("java/com/google/example", "libhas_idl-idl.jar", null, "libhas_idl-idl.srcjar")); - assertThat(relativePathsForSourcesOf(idlRuleInfo)) + assertThat(relativePathsForJavaSourcesOf(idlRuleInfo)) .isEmpty(); assertThat(getIdeResolveFiles()).containsExactly( "java/com/google/example/libhas_idl.jar", @@ -961,6 +967,467 @@ public class AndroidStudioInfoAspectTest extends AndroidStudioInfoAspectTestBase "libplugin.jar", "libplugin-ijar.jar", "libplugin-src.jar")); } + @Test + public void testSimpleCCLibraryForCCToolchainExistence() throws Exception { + Path buildFilePath = + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + " hdrs = ['simple/simple.h'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + assertThat(ruleIdeInfos.size()).isEqualTo(2); + RuleIdeInfo ruleInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", + ruleIdeInfos + ); + Entry<String, RuleIdeInfo> toolchainEntry = getCcToolchainRuleAndVerifyThereIsOnlyOne( + ruleIdeInfos); + RuleIdeInfo toolchainInfo = toolchainEntry.getValue(); + if (isNativeTest()) { + assertThat(ruleInfo.getBuildFile()).isEqualTo(buildFilePath.toString()); + ArtifactLocation location = ruleInfo.getBuildFileArtifactLocation(); + assertThat(Paths.get(location.getRootPath(), location.getRelativePath()).toString()) + .isEqualTo(buildFilePath.toString()); + assertThat(location.getRelativePath()).isEqualTo("com/google/example/BUILD"); + } + + assertThat(ruleInfo.hasCRuleIdeInfo()).isTrue(); + assertThat(ruleInfo.getDependenciesList()).hasSize(1); + assertThat(toolchainInfo.hasCToolchainIdeInfo()).isTrue(); + } + + @Test + public void testSimpleCCLibrary() throws Exception { + Path buildFilePath = + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + " hdrs = ['simple/simple.h'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + assertThat(ruleIdeInfos.size()).isEqualTo(2); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + if (isNativeTest()) { + assertThat(ruleIdeInfo.getBuildFile()).isEqualTo(buildFilePath.toString()); + ArtifactLocation location = ruleIdeInfo.getBuildFileArtifactLocation(); + assertThat(Paths.get(location.getRootPath(), location.getRelativePath()).toString()) + .isEqualTo(buildFilePath.toString()); + assertThat(location.getRelativePath()).isEqualTo("com/google/example/BUILD"); + } + assertThat(ruleIdeInfo.getKind()).isEqualTo(Kind.CC_LIBRARY); + assertThat(ruleIdeInfo.getDependenciesCount()).isEqualTo(1); + + assertThat(relativePathsForCSourcesOf(ruleIdeInfo)) + .containsExactly("com/google/example/simple/simple.cc"); + assertThat(relativePathsForExportedCHeadersOf(ruleIdeInfo)) + .containsExactly("com/google/example/simple/simple.h"); + + assertThat(ruleIdeInfo.hasCRuleIdeInfo()).isTrue(); + assertThat(ruleIdeInfo.hasJavaRuleIdeInfo()).isFalse(); + assertThat(ruleIdeInfo.hasAndroidRuleIdeInfo()).isFalse(); + CRuleIdeInfo cRuleIdeInfo = ruleIdeInfo.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleCoptList()).isEmpty(); + assertThat(cRuleIdeInfo.getRuleDefineList()).isEmpty(); + assertThat(cRuleIdeInfo.getRuleIncludeList()).isEmpty(); + + ProtocolStringList transQuoteIncludeDirList = + cRuleIdeInfo.getTransitiveQuoteIncludeDirectoryList(); + assertThat(transQuoteIncludeDirList).contains("."); + + assertThat(ruleIdeInfo.getJavaRuleIdeInfo().getJarsList()).isEmpty(); + + assertThat(getIdeResolveFiles()).isEmpty(); + } + + @Test + public void testSimpleCCLibraryWithIncludes() throws Exception { + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + " hdrs = ['simple/simple.h'],", + " includes = ['foo/bar'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + assertThat(ruleIdeInfos.size()).isEqualTo(2); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + + assertThat(ruleIdeInfo.hasCRuleIdeInfo()).isTrue(); + CRuleIdeInfo cRuleIdeInfo = ruleIdeInfo.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleIncludeList()).containsExactly("foo/bar"); + + // Make sure our understanding of where this attributes show up in other providers is correct. + Entry<String, RuleIdeInfo> toolchainEntry = getCcToolchainRuleAndVerifyThereIsOnlyOne( + ruleIdeInfos); + RuleIdeInfo toolchainInfo = toolchainEntry.getValue(); + assertThat(toolchainInfo.hasCToolchainIdeInfo()).isTrue(); + CToolchainIdeInfo cToolchainIdeInfo = toolchainInfo.getCToolchainIdeInfo(); + ProtocolStringList builtInIncludeDirectoryList = + cToolchainIdeInfo.getBuiltInIncludeDirectoryList(); + assertThat(builtInIncludeDirectoryList).doesNotContain("foo/bar"); + assertThat(builtInIncludeDirectoryList).doesNotContain("com/google/example/foo/bar"); + + ProtocolStringList transIncludeDirList = cRuleIdeInfo.getTransitiveIncludeDirectoryList(); + assertThat(transIncludeDirList).doesNotContain("foo/bar"); + assertThat(transIncludeDirList).doesNotContain("com/google/example/foo/bar"); + + ProtocolStringList transQuoteIncludeDirList = + cRuleIdeInfo.getTransitiveQuoteIncludeDirectoryList(); + assertThat(transQuoteIncludeDirList).doesNotContain("foo/bar"); + assertThat(transQuoteIncludeDirList).doesNotContain("com/google/example/foo/bar"); + + ProtocolStringList transSysIncludeDirList = + cRuleIdeInfo.getTransitiveSystemIncludeDirectoryList(); + assertThat(transSysIncludeDirList).doesNotContain("foo/bar"); + assertThat(transSysIncludeDirList).contains("com/google/example/foo/bar"); + } + + @Test + public void testSimpleCCLibraryWithCompilerFlags() throws Exception { + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + " hdrs = ['simple/simple.h'],", + " copts = ['-DGOPT', '-Ifoo/baz/'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + assertThat(ruleIdeInfos.size()).isEqualTo(2); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + + assertThat(ruleIdeInfo.hasCRuleIdeInfo()).isTrue(); + CRuleIdeInfo cRuleIdeInfo = ruleIdeInfo.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleCoptList()).containsExactly("-DGOPT", "-Ifoo/baz/"); + + // Make sure our understanding of where this attributes show up in other providers is correct. + Entry<String, RuleIdeInfo> toolchainEntry = getCcToolchainRuleAndVerifyThereIsOnlyOne( + ruleIdeInfos); + RuleIdeInfo toolchainInfo = toolchainEntry.getValue(); + assertThat(toolchainInfo.hasCToolchainIdeInfo()).isTrue(); + CToolchainIdeInfo cToolchainIdeInfo = toolchainInfo.getCToolchainIdeInfo(); + ProtocolStringList baseCompilerOptionList = cToolchainIdeInfo.getBaseCompilerOptionList(); + assertThat(baseCompilerOptionList).doesNotContain("-DGOPT"); + assertThat(baseCompilerOptionList).doesNotContain("-Ifoo/baz/"); + + ProtocolStringList cOptionList = cToolchainIdeInfo.getCOptionList(); + assertThat(cOptionList).doesNotContain("-DGOPT"); + assertThat(cOptionList).doesNotContain("-Ifoo/baz/"); + + ProtocolStringList cppOptionList = cToolchainIdeInfo.getCppOptionList(); + assertThat(cppOptionList).doesNotContain("-DGOPT"); + assertThat(cppOptionList).doesNotContain("-Ifoo/baz/"); + } + + @Test + public void testSimpleCCLibraryWithDefines() throws Exception { + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + " hdrs = ['simple/simple.h'],", + " defines = ['VERSION2'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + assertThat(ruleIdeInfos.size()).isEqualTo(2); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + + assertThat(ruleIdeInfo.hasCRuleIdeInfo()).isTrue(); + CRuleIdeInfo cRuleIdeInfo = ruleIdeInfo.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleDefineList()).containsExactly("VERSION2"); + + // Make sure our understanding of where this attributes show up in other providers is correct. + ProtocolStringList transDefineList = cRuleIdeInfo.getTransitiveDefineList(); + assertThat(transDefineList).contains("VERSION2"); + } + + @Test + public void testSimpleCCBinary() throws Exception { + Path buildFilePath = + scratch.file( + "com/google/example/BUILD", + "cc_binary(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + assertThat(ruleIdeInfos.size()).isEqualTo(2); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + if (isNativeTest()) { + assertThat(ruleIdeInfo.getBuildFile()).isEqualTo(buildFilePath.toString()); + ArtifactLocation location = ruleIdeInfo.getBuildFileArtifactLocation(); + assertThat(Paths.get(location.getRootPath(), location.getRelativePath()).toString()) + .isEqualTo(buildFilePath.toString()); + assertThat(location.getRelativePath()).isEqualTo("com/google/example/BUILD"); + } + assertThat(ruleIdeInfo.getKind()).isEqualTo(Kind.CC_BINARY); + assertThat(ruleIdeInfo.getDependenciesCount()).isEqualTo(1); + + assertThat(relativePathsForCSourcesOf(ruleIdeInfo)) + .containsExactly("com/google/example/simple/simple.cc"); + + assertThat(ruleIdeInfo.hasCRuleIdeInfo()).isTrue(); + assertThat(ruleIdeInfo.hasJavaRuleIdeInfo()).isFalse(); + assertThat(ruleIdeInfo.hasAndroidRuleIdeInfo()).isFalse(); + CRuleIdeInfo cRuleIdeInfo = ruleIdeInfo.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleCoptList()).isEmpty(); + assertThat(cRuleIdeInfo.getRuleDefineList()).isEmpty(); + assertThat(cRuleIdeInfo.getRuleIncludeList()).isEmpty(); + + assertThat(ruleIdeInfo.getJavaRuleIdeInfo().getJarsList()).isEmpty(); + + assertThat(getIdeResolveFiles()).isEmpty(); + } + + @Test + public void testSimpleCCTest() throws Exception { + Path buildFilePath = + scratch.file( + "com/google/example/BUILD", + "cc_test(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + assertThat(ruleIdeInfos.size()).isEqualTo(2); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + if (isNativeTest()) { + assertThat(ruleIdeInfo.getBuildFile()).isEqualTo(buildFilePath.toString()); + ArtifactLocation location = ruleIdeInfo.getBuildFileArtifactLocation(); + assertThat(Paths.get(location.getRootPath(), location.getRelativePath()).toString()) + .isEqualTo(buildFilePath.toString()); + assertThat(location.getRelativePath()).isEqualTo("com/google/example/BUILD"); + } + assertThat(ruleIdeInfo.getKind()).isEqualTo(Kind.CC_TEST); + assertThat(ruleIdeInfo.getDependenciesCount()).isEqualTo(1); + + assertThat(relativePathsForCSourcesOf(ruleIdeInfo)) + .containsExactly("com/google/example/simple/simple.cc"); + + assertThat(ruleIdeInfo.hasCRuleIdeInfo()).isTrue(); + assertThat(ruleIdeInfo.hasJavaRuleIdeInfo()).isFalse(); + assertThat(ruleIdeInfo.hasAndroidRuleIdeInfo()).isFalse(); + CRuleIdeInfo cRuleIdeInfo = ruleIdeInfo.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleCoptList()).isEmpty(); + assertThat(cRuleIdeInfo.getRuleDefineList()).isEmpty(); + assertThat(cRuleIdeInfo.getRuleIncludeList()).isEmpty(); + + assertThat(ruleIdeInfo.getJavaRuleIdeInfo().getJarsList()).isEmpty(); + + assertThat(getIdeResolveFiles()).isEmpty(); + } + + @Test + public void testSimpleCCLibraryWithDeps() throws Exception { + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'lib',", + " srcs = ['lib/lib.cc'],", + " hdrs = ['lib/lib.h'],", + ")", + "cc_library(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + " hdrs = ['simple/simple.h'],", + " deps = [':lib'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:simple"); + assertThat(ruleIdeInfos.size()).isEqualTo(3); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:simple", ruleIdeInfos); + + assertThat(ruleIdeInfo.getDependenciesList()).contains("//com/google/example:lib"); + assertThat(ruleIdeInfo.getDependenciesList()).hasSize(2); + } + + @Test + public void testSimpleAndroidBinaryThatDependsOnCCLibrary() throws Exception { + scratch.file( + "com/google/example/BUILD", + "android_library(", + " name = 'androidlib',", + " srcs = ['Lib.java'],", + " deps = ['simple'],", + ")", + "cc_library(", + " name = 'simple',", + " srcs = ['simple/simple.cc'],", + " hdrs = ['simple/simple.h'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:androidlib"); + assertThat(ruleIdeInfos.size()).isEqualTo(3); + RuleIdeInfo ruleIdeInfo = getRuleInfoAndVerifyLabel( + "//com/google/example:androidlib", ruleIdeInfos); + + assertThat(ruleIdeInfo.getDependenciesList()).containsExactly("//com/google/example:simple"); + } + + @Test + public void testTransitiveCCLibraryWithIncludes() throws Exception { + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'lib2',", + " srcs = ['lib2/lib2.cc'],", + " hdrs = ['lib2/lib2.h'],", + " includes = ['baz/lib'],", + ")", + "cc_library(", + " name = 'lib1',", + " srcs = ['lib1/lib1.cc'],", + " hdrs = ['lib1/lib1.h'],", + " includes = ['foo/bar'],", + " deps = [':lib2'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:lib1"); + assertThat(ruleIdeInfos.size()).isEqualTo(3); + RuleIdeInfo lib1 = getRuleInfoAndVerifyLabel( + "//com/google/example:lib1", ruleIdeInfos); + + assertThat(lib1.hasCRuleIdeInfo()).isTrue(); + CRuleIdeInfo cRuleIdeInfo = lib1.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleIncludeList()).containsExactly("foo/bar"); + + // Make sure our understanding of where this attributes show up in other providers is correct. + Entry<String, RuleIdeInfo> toolchainEntry = getCcToolchainRuleAndVerifyThereIsOnlyOne( + ruleIdeInfos); + RuleIdeInfo toolchainInfo = toolchainEntry.getValue(); + assertThat(toolchainInfo.hasCToolchainIdeInfo()).isTrue(); + CToolchainIdeInfo cToolchainIdeInfo = toolchainInfo.getCToolchainIdeInfo(); + ProtocolStringList builtInIncludeDirectoryList = + cToolchainIdeInfo.getBuiltInIncludeDirectoryList(); + assertThat(builtInIncludeDirectoryList).doesNotContain("foo/bar"); + assertThat(builtInIncludeDirectoryList).doesNotContain("baz/lib"); + assertThat(builtInIncludeDirectoryList).doesNotContain("com/google/example/foo/bar"); + assertThat(builtInIncludeDirectoryList).doesNotContain("com/google/example/baz/lib"); + + ProtocolStringList transIncludeDirList = cRuleIdeInfo.getTransitiveIncludeDirectoryList(); + assertThat(transIncludeDirList).doesNotContain("foo/bar"); + assertThat(transIncludeDirList).doesNotContain("baz/lib"); + assertThat(transIncludeDirList).doesNotContain("com/google/example/foo/bar"); + assertThat(transIncludeDirList).doesNotContain("com/google/example/baz/lib"); + + ProtocolStringList transQuoteIncludeDirList = + cRuleIdeInfo.getTransitiveQuoteIncludeDirectoryList(); + assertThat(transQuoteIncludeDirList).doesNotContain("foo/bar"); + assertThat(transQuoteIncludeDirList).doesNotContain("baz/lib"); + assertThat(transQuoteIncludeDirList).doesNotContain("com/google/example/foo/bar"); + assertThat(transQuoteIncludeDirList).doesNotContain("com/google/example/baz/lib"); + + ProtocolStringList transSysIncludeDirList = + cRuleIdeInfo.getTransitiveSystemIncludeDirectoryList(); + assertThat(transSysIncludeDirList).doesNotContain("foo/bar"); + assertThat(transSysIncludeDirList).doesNotContain("baz/lib"); + assertThat(transSysIncludeDirList).contains("com/google/example/foo/bar"); + assertThat(transSysIncludeDirList).contains("com/google/example/baz/lib"); + } + + @Test + public void testTransitiveCLibraryWithCompilerFlags() throws Exception { + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'lib2',", + " srcs = ['lib2/lib2.cc'],", + " hdrs = ['lib2/lib2.h'],", + " copts = ['-v23', '-DDEV'],", + ")", + "cc_library(", + " name = 'lib1',", + " srcs = ['lib1/lib1.cc'],", + " hdrs = ['lib1/lib1.h'],", + " copts = ['-DGOPT', '-Ifoo/baz/'],", + " deps = [':lib2'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:lib1"); + assertThat(ruleIdeInfos.size()).isEqualTo(3); + RuleIdeInfo lib1 = getRuleInfoAndVerifyLabel( + "//com/google/example:lib1", ruleIdeInfos); + + assertThat(lib1.hasCRuleIdeInfo()).isTrue(); + CRuleIdeInfo cRuleIdeInfo = lib1.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleCoptList()).containsExactly("-DGOPT", "-Ifoo/baz/"); + + // Make sure our understanding of where this attributes show up in other providers is correct. + Entry<String, RuleIdeInfo> toolchainEntry = getCcToolchainRuleAndVerifyThereIsOnlyOne( + ruleIdeInfos); + RuleIdeInfo toolchainInfo = toolchainEntry.getValue(); + assertThat(toolchainInfo.hasCToolchainIdeInfo()).isTrue(); + CToolchainIdeInfo cToolchainIdeInfo = toolchainInfo.getCToolchainIdeInfo(); + ProtocolStringList baseCompilerOptionList = cToolchainIdeInfo.getBaseCompilerOptionList(); + assertThat(baseCompilerOptionList).doesNotContain("-DGOPT"); + assertThat(baseCompilerOptionList).doesNotContain("-Ifoo/baz/"); + assertThat(baseCompilerOptionList).doesNotContain("-v23"); + assertThat(baseCompilerOptionList).doesNotContain("-DDEV"); + + ProtocolStringList cOptionList = cToolchainIdeInfo.getCOptionList(); + assertThat(cOptionList).doesNotContain("-DGOPT"); + assertThat(cOptionList).doesNotContain("-Ifoo/baz/"); + assertThat(cOptionList).doesNotContain("-v23"); + assertThat(cOptionList).doesNotContain("-DDEV"); + + ProtocolStringList cppOptionList = cToolchainIdeInfo.getCppOptionList(); + assertThat(cppOptionList).doesNotContain("-DGOPT"); + assertThat(cppOptionList).doesNotContain("-Ifoo/baz/"); + assertThat(cppOptionList).doesNotContain("-v23"); + assertThat(cppOptionList).doesNotContain("-DDEV"); + } + + @Test + public void testTransitiveCCLibraryWithDefines() throws Exception { + scratch.file( + "com/google/example/BUILD", + "cc_library(", + " name = 'lib2',", + " srcs = ['lib2/lib2.cc'],", + " hdrs = ['lib2/lib2.h'],", + " defines = ['COMPLEX_IMPL'],", + ")", + "cc_library(", + " name = 'lib1',", + " srcs = ['lib1/lib1.cc'],", + " hdrs = ['lib1/lib1.h'],", + " defines = ['VERSION2'],", + " deps = [':lib2'],", + ")"); + Map<String, RuleIdeInfo> ruleIdeInfos = buildRuleIdeInfo("//com/google/example:lib1"); + assertThat(ruleIdeInfos.size()).isEqualTo(3); + RuleIdeInfo lib1 = getRuleInfoAndVerifyLabel( + "//com/google/example:lib1", ruleIdeInfos); + + assertThat(lib1.hasCRuleIdeInfo()).isTrue(); + CRuleIdeInfo cRuleIdeInfo = lib1.getCRuleIdeInfo(); + + assertThat(cRuleIdeInfo.getRuleDefineList()).containsExactly("VERSION2"); + + // Make sure our understanding of where this attributes show up in other providers is correct. + ProtocolStringList transDefineList = cRuleIdeInfo.getTransitiveDefineList(); + assertThat(transDefineList).contains("VERSION2"); + assertThat(transDefineList).contains("COMPLEX_IMPL"); + } + /** * Returns true if we are testing the native aspect, not the Skylark one. * Eventually Skylark aspect will be equivalent to a native one, and this method diff --git a/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTestBase.java b/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTestBase.java index dca83cb61e..291b6be9e3 100644 --- a/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTestBase.java +++ b/src/test/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspectTestBase.java @@ -38,6 +38,7 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.ArtifactLocation; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.LibraryArtifact; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.RuleIdeInfo; +import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.RuleIdeInfo.Kind; import com.google.devtools.build.lib.skyframe.AspectValue; import com.google.protobuf.TextFormat; @@ -52,6 +53,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import javax.annotation.Nullable; @@ -112,8 +114,20 @@ abstract class AndroidStudioInfoAspectTestBase extends BuildViewTestCase { return sb.toString(); } - protected static Iterable<String> relativePathsForSourcesOf(RuleIdeInfo ruleIdeInfo) { - return transform(ruleIdeInfo.getJavaRuleIdeInfo().getSourcesList(), ARTIFACT_TO_RELATIVE_PATH); + protected static Iterable<String> relativePathsForJavaSourcesOf(RuleIdeInfo ruleIdeInfo) { + return relativePathsForSources(ruleIdeInfo.getJavaRuleIdeInfo().getSourcesList()); + } + + protected static Iterable<String> relativePathsForCSourcesOf(RuleIdeInfo ruleIdeInfo) { + return relativePathsForSources(ruleIdeInfo.getCRuleIdeInfo().getSourceList()); + } + + protected static Iterable<String> relativePathsForExportedCHeadersOf(RuleIdeInfo ruleIdeInfo) { + return relativePathsForSources(ruleIdeInfo.getCRuleIdeInfo().getExportedHeaderList()); + } + + private static Iterable<String> relativePathsForSources(List<ArtifactLocation> sourcesList) { + return transform(sourcesList, ARTIFACT_TO_RELATIVE_PATH); } protected RuleIdeInfo getRuleInfoAndVerifyLabel( @@ -124,6 +138,21 @@ abstract class AndroidStudioInfoAspectTestBase extends BuildViewTestCase { return ruleIdeInfo; } + protected Entry<String, RuleIdeInfo> getCcToolchainRuleAndVerifyThereIsOnlyOne( + Map<String, RuleIdeInfo> ruleIdeInfos) { + Entry<String, RuleIdeInfo> toolchainInfo = null; + for (Entry<String, RuleIdeInfo> entry : ruleIdeInfos.entrySet()) { + if (entry.getValue().getKind() == Kind.CC_TOOLCHAIN) { + // Make sure we only have 1. + assertThat(toolchainInfo).isNull(); + assertThat(entry.getValue().hasCToolchainIdeInfo()).isTrue(); + toolchainInfo = entry; + } + } + assertThat(toolchainInfo).isNotNull(); + return toolchainInfo; + } + protected void buildTarget(String target) throws Exception { AnalysisResult analysisResult = update( diff --git a/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl b/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl index f7dc921faf..03e66f2756 100644 --- a/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl +++ b/src/test/java/com/google/devtools/build/lib/ideinfo/intellij_info.bzl @@ -28,6 +28,11 @@ _kind_to_kind_id = { "android_sdk" : 9, "java_plugin" : 10, "android_resources" : 11, + "cc_library" : 12, + "cc_binary" : 13, + "cc_test" : 14, + "cc_inc_library" : 15, + "cc_toolchain": 16 } _unrecognized_rule = -1; @@ -45,6 +50,7 @@ DEPS = struct( "java_lib",# From proto_library "_proto1_java_lib", # From proto_library "_junit", # From android_robolectric_test + "_cc_toolchain", # From C rules ], label_list = [ "deps", @@ -100,7 +106,7 @@ def source_directory_tuple(resource_file): def all_unique_source_directories(resources): """ Builds a list of ArtifactLocation protos for all source directories for a list of Android resources. """ - # Sets can contain tuples, but cannot conntain structs. + # Sets can contain tuples, but cannot contain structs. # Use set of tuples to unquify source directories. source_directory_tuples = set([source_directory_tuple(file) for file in resources]) return [struct_omit_none(relative_path = relative_path, @@ -134,6 +140,7 @@ def annotation_processing_jars(annotation_processing): jar = artifact_location(annotation_processing.class_jar), source_jar = artifact_location(annotation_processing.source_jar), ) + def jars_from_output(output): """ Collect jars for ide-resolve-files from Java output. """ @@ -143,6 +150,94 @@ def jars_from_output(output): for jar in [output.class_jar, output.ijar, output.source_jar] if jar != None and not jar.is_source] +def c_rule_ide_info(target, ctx): + """ Build CRuleIdeInfo. + + Returns a pair of (CRuleIdeInfo proto, a set of ide-resolve-files). + (or (None, empty set) if the rule is not a C rule). + """ + if not hasattr(target, "cc"): + return (None, set()) + + sources = getSourcesFromRule(ctx) + + if hasattr(ctx.rule.attr, "hdrs"): + exported_headers = [artifact_location(file) + for hdr in ctx.rule.attr.hdrs + for file in hdr.files] + else: + exported_headers = [] + + rule_includes = [] + if hasattr(ctx.rule.attr, "includes"): + rule_includes = ctx.rule.attr.includes + rule_defines = [] + if hasattr(ctx.rule.attr, "defines"): + rule_defines = ctx.rule.attr.defines + rule_copts = [] + if hasattr(ctx.rule.attr, "copts"): + rule_copts = ctx.rule.attr.copts + + cc_provider = target.cc + + return (struct_omit_none( + source = sources, + exported_header = exported_headers, + rule_include = rule_includes, + rule_define = rule_defines, + rule_copt = rule_copts, + transitive_include_directory = cc_provider.include_directories, + transitive_quote_include_directory = cc_provider.quote_include_directories, + transitive_define = cc_provider.defines, + transitive_system_include_directory = cc_provider.system_include_directories + ), + set()) + +def c_toolchain_ide_info(target, ctx): + """ Build CToolchainIdeInfo. + + Returns a pair of (CToolchainIdeInfo proto, a set of ide-resolve-files). + (or (None, empty set) if the rule is not a cc_toolchain rule). + """ + + if ctx.rule.kind != "cc_toolchain": + return (None, set()) + + # This should exist because we requested it in our aspect definition. + cc_fragment = ctx.fragments.cpp + + return (struct_omit_none( + target_name = cc_fragment.target_gnu_system_name, + base_compiler_option = cc_fragment.compiler_options(ctx.features), + c_option = cc_fragment.c_options, + cpp_option = cc_fragment.cxx_options(ctx.features), + link_option = cc_fragment.link_options, + unfiltered_compiler_option = cc_fragment.unfiltered_compiler_options(ctx.features), + preprocessor_executable = + replaceEmptyPathWithDot(str(cc_fragment.preprocessor_executable)), + cpp_executable = str(cc_fragment.compiler_executable), + built_in_include_directory = [str(d) + for d in cc_fragment.built_in_include_directories] + ), + set()) + +# TODO(salguarnieri) Remove once skylark provides the path safe string from a PathFragment. +def replaceEmptyPathWithDot(pathString): + return "." if len(pathString) == 0 else pathString + +def getSourcesFromRule(context): + """ + Get the list of sources from a rule as artifact locations. + + Returns the list of sources as artifact locations for a rule or an empty list if no sources are + present. + """ + + if hasattr(context.rule.attr, "srcs"): + return [artifact_location(file) + for src in context.rule.attr.srcs + for file in src.files] + return [] def java_rule_ide_info(target, ctx): """ Build JavaRuleIdeInfo. @@ -152,12 +247,8 @@ def java_rule_ide_info(target, ctx): """ if not hasattr(target, "java"): return (None, set()) - if hasattr(ctx.rule.attr, "srcs"): - sources = [artifact_location(file) - for src in ctx.rule.attr.srcs - for file in src.files] - else: - sources = [] + + sources = getSourcesFromRule(ctx) jars = [library_artifact(output) for output in target.java.outputs.jars] ide_resolve_files = set([jar @@ -258,6 +349,13 @@ def _aspect_impl(target, ctx): ide_resolve_files = ide_resolve_files | dep.intellij_info_files.ide_resolve_files + # Collect C-specific information + (c_rule_ide_info, c_ide_resolve_files) = c_rule_ide_info(target, ctx) + ide_resolve_files = ide_resolve_files | c_ide_resolve_files + + (c_toolchain_ide_info, c_toolchain_ide_resolve_files) = c_toolchain_ide_info(target, ctx) + ide_resolve_files = ide_resolve_files | c_toolchain_ide_resolve_files + # Collect Java-specific information (java_rule_ide_info, java_ide_resolve_files) = java_rule_ide_info(target, ctx) ide_resolve_files = ide_resolve_files | java_ide_resolve_files @@ -282,6 +380,8 @@ def _aspect_impl(target, ctx): dependencies = list(compiletime_deps), runtime_deps = list(runtime_deps), build_file_artifact_location = build_file_artifact_location(ctx.build_file_path), + c_rule_ide_info = c_rule_ide_info, + c_toolchain_ide_info = c_toolchain_ide_info, java_rule_ide_info = java_rule_ide_info, android_rule_ide_info = android_rule_ide_info, tags = ctx.rule.attr.tags, @@ -305,6 +405,7 @@ def _aspect_impl(target, ctx): export_deps = export_deps, ) -intellij_info_aspect = aspect(implementation = _aspect_impl, - attr_aspects = ALL_DEPS.label + ALL_DEPS.label_list +intellij_info_aspect = aspect( + implementation = _aspect_impl, + attr_aspects = ALL_DEPS.label + ALL_DEPS.label_list, ) |