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/main/java/com/google | |
parent | 51a491b89a9cd5f15c9a093a5693bc37e696e6e1 (diff) |
Export cc build information in an aspect for IDE support.
--
MOS_MIGRATED_REVID=117560803
Diffstat (limited to 'src/main/java/com/google')
4 files changed, 205 insertions, 0 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/BUILD b/src/main/java/com/google/devtools/build/lib/BUILD index 2cfeea3cba..c1f5bc5486 100644 --- a/src/main/java/com/google/devtools/build/lib/BUILD +++ b/src/main/java/com/google/devtools/build/lib/BUILD @@ -786,6 +786,7 @@ java_library( ":util", ":vfs", "//src/main/java/com/google/devtools/build/lib/actions", + "//src/main/java/com/google/devtools/build/lib/rules/cpp", "//src/main/protobuf:android_studio_ide_info_java_proto", "//third_party:guava", "//third_party:jsr305", diff --git a/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java b/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java index feef789e8a..6e352c08e4 100644 --- a/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java +++ b/src/main/java/com/google/devtools/build/lib/ideinfo/AndroidStudioInfoAspect.java @@ -50,6 +50,8 @@ import com.google.devtools.build.lib.collect.nestedset.NestedSet; import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.AndroidRuleIdeInfo; 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.LibraryArtifact; import com.google.devtools.build.lib.ideinfo.androidstudio.AndroidStudioIdeInfo.RuleIdeInfo; @@ -62,6 +64,8 @@ import com.google.devtools.build.lib.packages.Rule; import com.google.devtools.build.lib.rules.android.AndroidIdeInfoProvider; import com.google.devtools.build.lib.rules.android.AndroidIdeInfoProvider.SourceDirectory; import com.google.devtools.build.lib.rules.android.AndroidSdkProvider; +import com.google.devtools.build.lib.rules.cpp.CppCompilationContext; +import com.google.devtools.build.lib.rules.cpp.CppConfiguration; import com.google.devtools.build.lib.rules.java.JavaExportsProvider; import com.google.devtools.build.lib.rules.java.JavaGenJarsProvider; import com.google.devtools.build.lib.rules.java.JavaRuleOutputJarsProvider; @@ -79,6 +83,7 @@ import java.util.Set; import javax.annotation.Nullable; + /** * Generates ide-build information for Android Studio. */ @@ -107,6 +112,7 @@ public class AndroidStudioInfoAspect implements ConfiguredNativeAspectFactory { new PrerequisiteAttr("binary_under_test", BuildType.LABEL), // From android_test new PrerequisiteAttr("java_lib", BuildType.LABEL), // From proto_library new PrerequisiteAttr("$proto1_java_lib", BuildType.LABEL), // From proto_library + new PrerequisiteAttr(":cc_toolchain", BuildType.LABEL) // from cc_* rules }; // File suffixes. @@ -326,6 +332,19 @@ public class AndroidStudioInfoAspect implements ConfiguredNativeAspectFactory { base, ruleContext, ideResolveArtifacts, packageManifest); outputBuilder.setJavaRuleIdeInfo(javaRuleIdeInfo); } + if (ruleKind == Kind.CC_BINARY + || ruleKind == Kind.CC_LIBRARY + || ruleKind == Kind.CC_TEST + || ruleKind == Kind.CC_INC_LIBRARY) { + CRuleIdeInfo cRuleIdeInfo = makeCRuleIdeInfo(base, ruleContext); + outputBuilder.setCRuleIdeInfo(cRuleIdeInfo); + } + if (ruleKind == Kind.CC_TOOLCHAIN) { + CToolchainIdeInfo cToolchainIdeInfo = makeCToolchainIdeInfo(base, ruleContext); + if (cToolchainIdeInfo != null) { + outputBuilder.setCToolchainIdeInfo(cToolchainIdeInfo); + } + } if (ruleKind == Kind.ANDROID_LIBRARY || ruleKind == Kind.ANDROID_BINARY || ruleKind == Kind.ANDROID_TEST @@ -553,6 +572,86 @@ public class AndroidStudioInfoAspect implements ConfiguredNativeAspectFactory { return builder.build(); } + private static CRuleIdeInfo makeCRuleIdeInfo(ConfiguredTarget base, RuleContext ruleContext) { + CRuleIdeInfo.Builder builder = CRuleIdeInfo.newBuilder(); + + Collection<Artifact> sourceFiles = getSources(ruleContext); + for (Artifact sourceFile : sourceFiles) { + builder.addSource(makeArtifactLocation(sourceFile)); + } + + Collection<Artifact> exportedHeaderFiles = getExportedHeaders(ruleContext); + for (Artifact exportedHeaderFile : exportedHeaderFiles) { + builder.addExportedHeader(makeArtifactLocation(exportedHeaderFile)); + } + + builder.addAllRuleInclude(getIncludes(ruleContext)); + builder.addAllRuleDefine(getDefines(ruleContext)); + builder.addAllRuleCopt(getCopts(ruleContext)); + + CppCompilationContext cppCompilationContext = base.getProvider(CppCompilationContext.class); + if (cppCompilationContext != null) { + // Get information about from the transitive closure + ImmutableList<PathFragment> transitiveIncludeDirectories = + cppCompilationContext.getIncludeDirs(); + for (PathFragment pathFragment : transitiveIncludeDirectories) { + builder.addTransitiveIncludeDirectory(pathFragment.getSafePathString()); + } + ImmutableList<PathFragment> transitiveQuoteIncludeDirectories = + cppCompilationContext.getQuoteIncludeDirs(); + for (PathFragment pathFragment : transitiveQuoteIncludeDirectories) { + builder.addTransitiveQuoteIncludeDirectory(pathFragment.getSafePathString()); + } + ImmutableList<String> transitiveDefines = cppCompilationContext.getDefines(); + for (String transitiveDefine : transitiveDefines) { + builder.addTransitiveDefine(transitiveDefine); + } + ImmutableList<PathFragment> transitiveSystemIncludeDirectories = + cppCompilationContext.getSystemIncludeDirs(); + for (PathFragment pathFragment : transitiveSystemIncludeDirectories) { + builder.addTransitiveSystemIncludeDirectory(pathFragment.getSafePathString()); + } + } + + return builder.build(); + } + + @Nullable + private static CToolchainIdeInfo makeCToolchainIdeInfo(ConfiguredTarget base, + RuleContext ruleContext) { + BuildConfiguration configuration = base.getConfiguration(); + if (configuration != null) { + CppConfiguration cppConfiguration = configuration.getFragment(CppConfiguration.class); + if (cppConfiguration != null) { + CToolchainIdeInfo.Builder builder = CToolchainIdeInfo.newBuilder(); + ImmutableSet<String> features = ruleContext.getFeatures(); + builder.setTargetName(cppConfiguration.getTargetGnuSystemName()); + + builder.addAllBaseCompilerOption(cppConfiguration.getCompilerOptions(features)); + builder.addAllCOption(cppConfiguration.getCOptions()); + builder.addAllCppOption(cppConfiguration.getCxxOptions(features)); + builder.addAllLinkOption(cppConfiguration.getLinkOptions()); + + // This includes options such as system includes from toolchains. + builder.addAllUnfilteredCompilerOption( + cppConfiguration.getUnfilteredCompilerOptions(features)); + + builder.setPreprocessorExecutable( + cppConfiguration.getCpreprocessorExecutable().getSafePathString()); + builder.setCppExecutable(cppConfiguration.getCppExecutable().getSafePathString()); + + List<PathFragment> builtInIncludeDirectories = cppConfiguration + .getBuiltInIncludeDirectories(); + for (PathFragment builtInIncludeDirectory : builtInIncludeDirectories) { + builder.addBuiltInIncludeDirectory(builtInIncludeDirectory.getSafePathString()); + } + return builder.build(); + } + } + + return null; + } + private static void collectJarsFromOutputJarsProvider( JavaRuleIdeInfo.Builder builder, NestedSetBuilder<Artifact> ideResolveArtifacts, @@ -634,6 +733,30 @@ public class AndroidStudioInfoAspect implements ConfiguredNativeAspectFactory { : ImmutableList.<Artifact>of(); } + private static Collection<Artifact> getExportedHeaders(RuleContext ruleContext) { + return ruleContext.attributes().has("hdrs", BuildType.LABEL_LIST) + ? ruleContext.getPrerequisiteArtifacts("hdrs", Mode.TARGET).list() + : ImmutableList.<Artifact>of(); + } + + private static Collection<String> getIncludes(RuleContext ruleContext) { + return ruleContext.attributes().has("includes", Type.STRING_LIST) + ? ruleContext.attributes().get("includes", Type.STRING_LIST) + : ImmutableList.<String>of(); + } + + private static Collection<String> getDefines(RuleContext ruleContext) { + return ruleContext.attributes().has("defines", Type.STRING_LIST) + ? ruleContext.attributes().get("defines", Type.STRING_LIST) + : ImmutableList.<String>of(); + } + + private static Collection<String> getCopts(RuleContext ruleContext) { + return ruleContext.attributes().has("copts", Type.STRING_LIST) + ? ruleContext.attributes().get("copts", Type.STRING_LIST) + : ImmutableList.<String>of(); + } + private static PathFragment getOutputFilePath(ConfiguredTarget base, RuleContext ruleContext, String suffix) { PathFragment packagePathFragment = @@ -666,6 +789,16 @@ public class AndroidStudioInfoAspect implements ConfiguredNativeAspectFactory { return Kind.JAVA_PLUGIN; case "android_resources": return Kind.ANDROID_RESOURCES; + case "cc_library": + return Kind.CC_LIBRARY; + case "cc_binary": + return Kind.CC_BINARY; + case "cc_test": + return Kind.CC_TEST; + case "cc_inc_library": + return Kind.CC_INC_LIBRARY; + case "cc_toolchain": + return Kind.CC_TOOLCHAIN; default: { if (base.getProvider(AndroidSdkProvider.class) != null) { diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java index 674e68c6ca..4f250b7b18 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcSkylarkApiProvider.java @@ -81,6 +81,71 @@ public final class CcSkylarkApiProvider extends SkylarkApiProvider { } @SkylarkCallable( + name = "defines", + structField = true, + doc = + "Returns the immutable set of defines used to compile this target " + + "(possibly empty but never None).") + public ImmutableList<String> getDefines() { + CppCompilationContext ccContext = getInfo().getProvider(CppCompilationContext.class); + return ccContext == null ? ImmutableList.<String>of() : ccContext.getDefines(); + } + + @SkylarkCallable( + name = "system_include_directories", + structField = true, + doc = + "Returns the immutable set of system include directories used to compile this target " + + "(possibly empty but never None).") + public ImmutableList<String> getSystemIncludeDirs() { + CppCompilationContext ccContext = getInfo().getProvider(CppCompilationContext.class); + if (ccContext == null) { + return ImmutableList.of(); + } + ImmutableList.Builder<String> builder = ImmutableList.builder(); + for (PathFragment path : ccContext.getSystemIncludeDirs()) { + builder.add(path.getSafePathString()); + } + return builder.build(); + } + + @SkylarkCallable( + name = "include_directories", + structField = true, + doc = + "Returns the immutable set of include directories used to compile this target " + + "(possibly empty but never None).") + public ImmutableList<String> getIncludeDirs() { + CppCompilationContext ccContext = getInfo().getProvider(CppCompilationContext.class); + if (ccContext == null) { + return ImmutableList.of(); + } + ImmutableList.Builder<String> builder = ImmutableList.builder(); + for (PathFragment path : ccContext.getIncludeDirs()) { + builder.add(path.getSafePathString()); + } + return builder.build(); + } + + @SkylarkCallable( + name = "quote_include_directories", + structField = true, + doc = + "Returns the immutable set of quote include directories used to compile this target " + + "(possibly empty but never None).") + public ImmutableList<String> getQuoteIncludeDirs() { + CppCompilationContext ccContext = getInfo().getProvider(CppCompilationContext.class); + if (ccContext == null) { + return ImmutableList.of(); + } + ImmutableList.Builder<String> builder = ImmutableList.builder(); + for (PathFragment path : ccContext.getQuoteIncludeDirs()) { + builder.add(path.getSafePathString()); + } + return builder.build(); + } + + @SkylarkCallable( name = "compile_flags", structField = true, doc = diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java index e46d1f76d6..f1adbe878b 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CppConfiguration.java @@ -1193,6 +1193,10 @@ public class CppConfiguration extends BuildConfiguration.Fragment { * They may be absolute if they are also installed on the remote build nodes or * for local compilation. */ + @SkylarkCallable(name = "built_in_include_directories", structField = true, + doc = "Built-in system include paths for the toolchain compiler. All paths in this list" + + " should be relative to the exec directory. They may be absolute if they are also installed" + + " on the remote build nodes or for local compilation.") public List<PathFragment> getBuiltInIncludeDirectories() { return builtInIncludeDirectories; } @@ -1699,6 +1703,8 @@ public class CppConfiguration extends BuildConfiguration.Fragment { * Returns the path to the GNU binutils 'cpp' binary that should be used * by this build. Relative paths are relative to the execution root. */ + @SkylarkCallable(name = "preprocessor_executable", structField = true, + doc = "Path to C/C++ preprocessor binary") public PathFragment getCpreprocessorExecutable() { return getToolPathFragment(CppConfiguration.Tool.CPP); } |