Expose DebugPackageProvider to Starlark as DebugPackageInfo PiperOrigin-RevId: 334455669
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java index eef35d4..316c5ad 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/CcRules.java
@@ -37,6 +37,7 @@ import com.google.devtools.build.lib.rules.cpp.CppRuleClasses.CcIncludeScanningRule; import com.google.devtools.build.lib.rules.cpp.CppRuleClasses.CcLinkingRule; import com.google.devtools.build.lib.rules.cpp.CpuTransformer; +import com.google.devtools.build.lib.rules.cpp.DebugPackageProvider; import com.google.devtools.build.lib.rules.cpp.FdoPrefetchHintsRule; import com.google.devtools.build.lib.rules.cpp.FdoProfileRule; import com.google.devtools.build.lib.rules.cpp.GoogleLegacyStubs; @@ -89,6 +90,7 @@ new CcBootstrap( new BazelCcModule(), CcInfo.PROVIDER, + DebugPackageProvider.PROVIDER, CcToolchainConfigInfo.PROVIDER, new GoogleLegacyStubs.PyWrapCcHelper(), new GoogleLegacyStubs.GoWrapCcHelper(),
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java index b588fa2..30b3b2e 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcBinary.java
@@ -661,8 +661,7 @@ CcStarlarkApiProvider.maybeAdd(ruleContext, ruleBuilder); ruleBuilder .addProvider(RunfilesProvider.class, RunfilesProvider.simple(runfiles)) - .addProvider( - DebugPackageProvider.class, + .addNativeDeclaredProvider( new DebugPackageProvider(ruleContext.getLabel(), strippedFile, binary, explicitDwpFile)) .setRunfilesSupport(runfilesSupport, binary) .addNativeDeclaredProvider(ccLauncherInfo);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/DebugPackageProvider.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/DebugPackageProvider.java index f287c5e..d610338 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/DebugPackageProvider.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/DebugPackageProvider.java
@@ -16,11 +16,15 @@ import com.google.common.base.Preconditions; import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.analysis.TransitiveInfoProvider; import com.google.devtools.build.lib.cmdline.Label; import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable; +import com.google.devtools.build.lib.packages.BuiltinProvider; +import com.google.devtools.build.lib.packages.NativeInfo; import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec; +import com.google.devtools.build.lib.starlarkbuildapi.cpp.DebugPackageInfoApi; import javax.annotation.Nullable; +import net.starlark.java.eval.EvalException; +import net.starlark.java.eval.Starlark; /** * Provides the binary artifact and its associated .dwp files, if fission is enabled. If Fission @@ -28,7 +32,10 @@ */ @Immutable @AutoCodec -public final class DebugPackageProvider implements TransitiveInfoProvider { +public final class DebugPackageProvider extends NativeInfo + implements DebugPackageInfoApi<Artifact> { + public static final Provider PROVIDER = new Provider(); + private final Label targetLabel; private final Artifact strippedArtifact; private final Artifact unstrippedArtifact; @@ -40,6 +47,7 @@ @Nullable Artifact strippedArtifact, Artifact unstrippedArtifact, @Nullable Artifact dwpArtifact) { + super(PROVIDER); Preconditions.checkNotNull(unstrippedArtifact); this.targetLabel = targetLabel; this.strippedArtifact = strippedArtifact; @@ -48,30 +56,54 @@ } /** Returns the label for the *_binary target. */ + @Override public final Label getTargetLabel() { return targetLabel; } - /** - * Returns the stripped file (the explicit ".stripped" target). - */ + /** Returns the stripped file (the explicit ".stripped" target). */ + @Override public final Artifact getStrippedArtifact() { return strippedArtifact; } - /** - * Returns the unstripped file (the default executable target). - */ + /** Returns the unstripped file (the default executable target). */ + @Override public final Artifact getUnstrippedArtifact() { return unstrippedArtifact; } - /** - * Returns the .dwp file (for fission builds) or null if --fission=no. - */ + /** Returns the .dwp file (for fission builds) or null if --fission=no. */ @Nullable + @Override public final Artifact getDwpArtifact() { return dwpArtifact; } + /** Provider class for {@link DebugPackageProvider} objects. */ + public static class Provider extends BuiltinProvider<DebugPackageProvider> + implements DebugPackageInfoApi.Provider<Artifact> { + private Provider() { + super(DebugPackageInfoApi.NAME, DebugPackageProvider.class); + } + + @Override + public DebugPackageProvider createDebugPackageInfo( + Label starlarkTargetLabel, + Artifact starlarkStrippedArtifact, + Artifact starlarkUnstrippedArtifact, + Object starlarkDwpArtifact) + throws EvalException { + return new DebugPackageProvider( + starlarkTargetLabel, + starlarkStrippedArtifact, + starlarkUnstrippedArtifact, + nullIfNone(starlarkDwpArtifact, Artifact.class)); + } + + @Nullable + private static <T> T nullIfNone(Object object, Class<T> type) { + return object != Starlark.NONE ? type.cast(object) : null; + } + } }
diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcBootstrap.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcBootstrap.java index 81a332b..2db806a 100644 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcBootstrap.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcBootstrap.java
@@ -43,6 +43,7 @@ ccModule; private final CcInfoApi.Provider<? extends FileApi> ccInfoProvider; + private final DebugPackageInfoApi.Provider<? extends FileApi> debugPackageInfoProvider; private final CcToolchainConfigInfoApi.Provider ccToolchainConfigInfoProvider; private final PyWrapCcHelperApi<?, ?, ?, ?, ?, ?, ?, ?, ?> pyWrapCcHelper; private final GoWrapCcHelperApi<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> goWrapCcHelper; @@ -67,6 +68,7 @@ ? extends CcCompilationOutputsApi<? extends FileApi>> ccModule, CcInfoApi.Provider<? extends FileApi> ccInfoProvider, + DebugPackageInfoApi.Provider<? extends FileApi> debugPackageInfoProvider, CcToolchainConfigInfoApi.Provider ccToolchainConfigInfoProvider, PyWrapCcHelperApi<?, ?, ?, ?, ?, ?, ?, ?, ?> pyWrapCcHelper, GoWrapCcHelperApi<?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?> goWrapCcHelper, @@ -74,6 +76,7 @@ PyCcLinkParamsProviderApi.Provider pyCcLinkInfoParamsInfoProvider) { this.ccModule = ccModule; this.ccInfoProvider = ccInfoProvider; + this.debugPackageInfoProvider = debugPackageInfoProvider; this.ccToolchainConfigInfoProvider = ccToolchainConfigInfoProvider; this.pyWrapCcHelper = pyWrapCcHelper; this.goWrapCcHelper = goWrapCcHelper; @@ -85,6 +88,7 @@ public void addBindingsToBuilder(ImmutableMap.Builder<String, Object> builder) { builder.put("cc_common", ccModule); builder.put("CcInfo", ccInfoProvider); + builder.put("DebugPackageInfo", debugPackageInfoProvider); builder.put("CcToolchainConfigInfo", ccToolchainConfigInfoProvider); builder.put( "py_wrap_cc_helper_do_not_use",
diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/DebugPackageInfoApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/DebugPackageInfoApi.java new file mode 100644 index 0000000..8612838 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/DebugPackageInfoApi.java
@@ -0,0 +1,110 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// 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.google.devtools.build.lib.starlarkbuildapi.cpp; + +import com.google.devtools.build.docgen.annot.DocCategory; +import com.google.devtools.build.docgen.annot.StarlarkConstructor; +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.starlarkbuildapi.FileApi; +import com.google.devtools.build.lib.starlarkbuildapi.core.ProviderApi; +import com.google.devtools.build.lib.starlarkbuildapi.core.StructApi; +import net.starlark.java.annot.Param; +import net.starlark.java.annot.ParamType; +import net.starlark.java.annot.StarlarkBuiltin; +import net.starlark.java.annot.StarlarkMethod; +import net.starlark.java.eval.EvalException; +import net.starlark.java.eval.NoneType; + +/** Wrapper for the native DebugPackageProvider. */ +@StarlarkBuiltin( + name = "DebugPackageInfo", + category = DocCategory.PROVIDER, + doc = + "A provider for the binary file and its associated .dwp files, if fission is enabled." + + "If Fission ({@url https://gcc.gnu.org/wiki/DebugFission}) is not enabled, the dwp " + + "file will be null.") +public interface DebugPackageInfoApi<FileT extends FileApi> extends StructApi { + String NAME = "DebugPackageInfo"; + + @StarlarkMethod( + name = "target_label", + doc = "Returns the label for the *_binary target", + structField = true) + Label getTargetLabel(); + + @StarlarkMethod( + name = "stripped_file", + doc = "Returns the stripped file (the explicit \".stripped\" target).", + structField = true) + FileT getStrippedArtifact(); + + @StarlarkMethod( + name = "unstripped_file", + doc = "Returns the unstripped file (the default executable target)", + structField = true) + FileT getUnstrippedArtifact(); + + @StarlarkMethod( + name = "dwp_file", + doc = "Returns the .dwp file (for fission builds) or null if --fission=no.", + structField = true, + allowReturnNones = true) + FileT getDwpArtifact(); + + /** The provider implementing this can construct DebugPackageInfo objects. */ + @StarlarkBuiltin(name = "Provider", doc = "", documented = false) + interface Provider<FileT extends FileApi> extends ProviderApi { + + @StarlarkMethod( + name = NAME, + doc = "The <code>DebugPackageInfo</code> constructor.", + parameters = { + @Param( + name = "target_label", + doc = "The label for the *_binary target", + positional = false, + named = true, + noneable = false, + allowedTypes = {@ParamType(type = Label.class)}), + @Param( + name = "stripped_file", + doc = "The stripped file (the explicit \".stripped\" target)", + positional = false, + named = true, + noneable = false, + allowedTypes = {@ParamType(type = FileApi.class)}), + @Param( + name = "unstripped_file", + doc = "The unstripped file (the default executable target).", + positional = false, + named = true, + noneable = false, + allowedTypes = {@ParamType(type = FileApi.class)}), + @Param( + name = "dwp_file", + doc = "The .dwp file (for fission builds) or null if --fission=no.", + positional = false, + named = true, + noneable = true, + defaultValue = "None", + allowedTypes = {@ParamType(type = FileApi.class), @ParamType(type = NoneType.class)}) + }, + selfCall = true) + @StarlarkConstructor + DebugPackageInfoApi<FileT> createDebugPackageInfo( + Label targetLabel, FileT strippedFile, FileT unstrippedFile, Object dwpFile) + throws EvalException; + } +}
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeApi.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeApi.java index 11ea82d..2d020f5 100644 --- a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeApi.java +++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/FakeApi.java
@@ -56,6 +56,7 @@ import com.google.devtools.build.skydoc.fakebuildapi.cpp.FakeCcInfo; import com.google.devtools.build.skydoc.fakebuildapi.cpp.FakeCcModule; import com.google.devtools.build.skydoc.fakebuildapi.cpp.FakeCcToolchainConfigInfo; +import com.google.devtools.build.skydoc.fakebuildapi.cpp.FakeDebugPackageInfo; import com.google.devtools.build.skydoc.fakebuildapi.cpp.FakeGoWrapCcHelper; import com.google.devtools.build.skydoc.fakebuildapi.cpp.FakePyCcLinkParamsProvider; import com.google.devtools.build.skydoc.fakebuildapi.cpp.FakePyWrapCcHelper; @@ -151,6 +152,7 @@ new CcBootstrap( new FakeCcModule(), new FakeCcInfo.Provider(), + new FakeDebugPackageInfo.Provider(), new FakeCcToolchainConfigInfo.Provider(), new FakePyWrapCcHelper(), new FakeGoWrapCcHelper(),
diff --git a/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeDebugPackageInfo.java b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeDebugPackageInfo.java new file mode 100644 index 0000000..084e116 --- /dev/null +++ b/src/main/java/com/google/devtools/build/skydoc/fakebuildapi/cpp/FakeDebugPackageInfo.java
@@ -0,0 +1,73 @@ +// Copyright 2020 The Bazel Authors. All rights reserved. +// +// 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.google.devtools.build.skydoc.fakebuildapi.cpp; + +import com.google.devtools.build.lib.cmdline.Label; +import com.google.devtools.build.lib.starlarkbuildapi.FileApi; +import com.google.devtools.build.lib.starlarkbuildapi.cpp.DebugPackageInfoApi; +import net.starlark.java.eval.EvalException; +import net.starlark.java.eval.Printer; + +/** Fake implementation of {@link DebugPackageInfoApi}. */ +public class FakeDebugPackageInfo implements DebugPackageInfoApi<FileApi> { + + @Override + public Label getTargetLabel() { + return null; + } + + @Override + public FileApi getStrippedArtifact() { + return null; + } + + @Override + public FileApi getUnstrippedArtifact() { + return null; + } + + /** Returns the .dwp file (for fission builds) or null if --fission=no. */ + @Override + public final FileApi getDwpArtifact() { + return null; + } + + @Override + public String toProto() throws EvalException { + return null; + } + + @Override + public String toJson() throws EvalException { + return null; + } + + @Override + public void repr(Printer printer) {} + + /** Fake implementation of {@link DebugPackageInfoApi.Provider}. */ + public static class Provider implements DebugPackageInfoApi.Provider<FileApi> { + + @Override + public DebugPackageInfoApi<FileApi> createDebugPackageInfo( + Label targetLabel, FileApi strippedArtifact, FileApi unstrippedArtifact, Object dwpArtifact) + throws EvalException { + return new FakeDebugPackageInfo(); + } + + @Override + public void repr(Printer printer) {} + } +}
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/StarlarkCcCommonTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/StarlarkCcCommonTest.java index 089d523..ceef382 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/StarlarkCcCommonTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/StarlarkCcCommonTest.java
@@ -6556,4 +6556,109 @@ "//b:import_objects_no_pic_lib", "If you pass 'pic_objects' you must also pass a 'pic_static_library'"); } + + private void setupDebugPackageProviderTest(String fission) throws Exception { + getAnalysisMock() + .ccSupport() + .setupCcToolchainConfig( + mockToolsConfig, + CcToolchainConfig.builder().withFeatures(CppRuleClasses.PER_OBJECT_DEBUG_INFO)); + useConfiguration(fission); + scratch.file( + "a/rule.bzl", + "def _impl(ctx):", + " out = ctx.actions.declare_file(ctx.label.name)", + " ctx.actions.run_shell(", + " inputs = [ctx.executable.cc_binary],", + " tools = [],", + " outputs = [out],", + " command = 'cp %s %s' % (ctx.executable.cc_binary.path, out.path),", + " )", + " wrapped_defaultinfo = ctx.attr.cc_binary[DefaultInfo]", + " runfiles = ctx.runfiles(files = [out])", + " wrapped_default_runfiles = wrapped_defaultinfo.default_runfiles.files.to_list()", + " if ctx.executable.cc_binary in wrapped_default_runfiles:", + " wrapped_default_runfiles.remove(ctx.executable.cc_binary)", + " result = [", + " DefaultInfo(", + " executable = out,", + " files = depset([out]),", + " runfiles = runfiles.merge(ctx.runfiles(files = wrapped_default_runfiles)),", + " ),", + " ]", + " if ctx.file.stripped_file:", + " wrapped_dbginfo = ctx.attr.cc_binary[DebugPackageInfo]", + " result.append(", + " DebugPackageInfo(", + " target_label = ctx.label,", + " stripped_file = ctx.file.stripped_file \\", + " if wrapped_dbginfo.stripped_file else None,", + " unstripped_file = out,", + " dwp_file = ctx.file.dwp_file if wrapped_dbginfo.dwp_file else None,", + " ),", + " )", + " return result", + "wrapped_binary = rule(", + " _impl,", + " attrs = {", + " 'cc_binary': attr.label(", + " allow_single_file = True,", + " mandatory = True,", + " executable = True,", + " cfg = 'target',", + " ),", + " 'stripped_file': attr.label(", + " allow_single_file = True,", + " default = None,", + " ),", + " 'dwp_file': attr.label(", + " allow_single_file = True,", + " default = None,", + " )", + " },", + " executable = True,", + ")"); + scratch.file( + "a/BUILD", + "load(':rule.bzl', 'wrapped_binary')", + "wrapped_binary(name = 'w',", + " cc_binary = ':native_binary',", + " stripped_file = ':w.stripped',", + " dwp_file = ':w.dwp',", + ")", + "wrapped_binary(name = 'w.stripped',", + " cc_binary = ':native_binary.stripped'", + ")", + "wrapped_binary(name = 'w.dwp',", + " cc_binary = ':native_binary.dwp'", + ")", + "cc_binary(name = 'native_binary',", + " srcs = ['main.cc']", + ")"); + scratch.file("a/main.cc", "int main() {}"); + } + + @Test + public void testDebugPackageProviderFissionDisabled() throws Exception { + setupDebugPackageProviderTest("--fission=no"); + ConfiguredTarget target = getConfiguredTarget("//a:w"); + assertNoEvents(); + assertThat(target).isNotNull(); + DebugPackageProvider debugPackageProvider = target.get(DebugPackageProvider.PROVIDER); + assertThat(debugPackageProvider.getStrippedArtifact().getFilename()).isEqualTo("w.stripped"); + assertThat(debugPackageProvider.getUnstrippedArtifact().getFilename()).isEqualTo("w"); + assertThat(debugPackageProvider.getDwpArtifact()).isNull(); + } + + @Test + public void testDebugPackageProviderFissionEnabled() throws Exception { + setupDebugPackageProviderTest("--fission=yes"); + ConfiguredTarget target = getConfiguredTarget("//a:w"); + assertNoEvents(); + assertThat(target).isNotNull(); + DebugPackageProvider debugPackageProvider = target.get(DebugPackageProvider.PROVIDER); + assertThat(debugPackageProvider.getStrippedArtifact().getFilename()).isEqualTo("w.stripped"); + assertThat(debugPackageProvider.getUnstrippedArtifact().getFilename()).isEqualTo("w"); + assertThat(debugPackageProvider.getDwpArtifact().getFilename()).isEqualTo("w.dwp"); + } }