Skip to content

Commit

Permalink
Add Java runtime's static libraries as implicit dependencies for laun…
Browse files Browse the repository at this point in the history
…cher (similar to java_binary specified deps), if hermetic is enabled.

The static libraries are statically linked with the launcher in that case. With this change, we will be able to enable hermetic Java at build time with just java_binary target's hermetic attribute. Please see[]

#hermetic-java-static-linking

PiperOrigin-RevId: 468003715
Change-Id: Ic9da65cb524fbe55d63fb3a5b52e6dd3ed2112ea
  • Loading branch information
Googler authored and aiuto committed Oct 12, 2022
1 parent d04e79f commit ac2e776
Show file tree
Hide file tree
Showing 8 changed files with 107 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
package com.google.devtools.build.lib.rules.java;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.devtools.build.lib.packages.Type.BOOLEAN;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
Expand Down Expand Up @@ -566,6 +567,14 @@ public ImmutableList<? extends TransitiveInfoCollection> targetsTreatedAsDeps(
return targetsTreatedAsDeps.get(type);
}

public ImmutableList<CcInfo> hermeticStaticLibs() {
if (ruleContext.isAttrDefined("hermetic", BOOLEAN)
&& ruleContext.attributes().get("hermetic", BOOLEAN)) {
return JavaRuntimeInfo.from(ruleContext).hermeticStaticLibs();
}
return ImmutableList.of();
}

/** Returns the default dependencies for the given classpath context. */
public static ImmutableList<TransitiveInfoCollection> defaultDeps(
RuleContext ruleContext, JavaSemantics semantics, ClasspathType type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.MutableActionGraph.ActionConflictException;
Expand All @@ -32,6 +33,7 @@
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.util.OsUtils;
import com.google.devtools.build.lib.vfs.PathFragment;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -94,6 +96,9 @@ public ConfiguredTarget create(RuleContext ruleContext)

Artifact libModules = ruleContext.getPrerequisiteArtifact("lib_modules");

ImmutableList<CcInfo> hermeticStaticLibs =
ImmutableList.copyOf(ruleContext.getPrerequisites("hermetic_static_libs", CcInfo.PROVIDER));

NestedSet<Artifact> filesToBuild = filesBuilder.build();

// TODO(cushon): clean up uses of java_runtime in data deps and remove this
Expand All @@ -110,7 +115,8 @@ public ConfiguredTarget create(RuleContext ruleContext)
javaHomeRunfilesPath,
javaBinaryRunfilesPath,
hermeticInputs,
libModules);
libModules,
hermeticStaticLibs);

TemplateVariableInfo templateVariableInfo =
new TemplateVariableInfo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,20 @@

import static com.google.devtools.build.lib.rules.java.JavaRuleClasses.JAVA_RUNTIME_ATTRIBUTE_NAME;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.platform.ToolchainInfo;
import com.google.devtools.build.lib.collect.nestedset.Depset;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.packages.BuildType;
import com.google.devtools.build.lib.packages.BuiltinProvider;
import com.google.devtools.build.lib.packages.NativeInfo;
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.rules.cpp.LibraryToLink;
import com.google.devtools.build.lib.starlarkbuildapi.java.JavaRuntimeInfoApi;
import com.google.devtools.build.lib.vfs.PathFragment;
import javax.annotation.Nullable;
Expand All @@ -45,15 +49,17 @@ public static JavaRuntimeInfo create(
PathFragment javaHomeRunfilesPath,
PathFragment javaBinaryRunfilesPath,
NestedSet<Artifact> hermeticInputs,
@Nullable Artifact libModules) {
@Nullable Artifact libModules,
ImmutableList<CcInfo> hermeticStaticLibs) {
return new JavaRuntimeInfo(
javaBaseInputs,
javaHome,
javaBinaryExecPath,
javaHomeRunfilesPath,
javaBinaryRunfilesPath,
hermeticInputs,
libModules);
libModules,
hermeticStaticLibs);
}

@Override
Expand Down Expand Up @@ -104,6 +110,7 @@ public static JavaRuntimeInfo from(RuleContext ruleContext, String attributeName
private final PathFragment javaBinaryRunfilesPath;
private final NestedSet<Artifact> hermeticInputs;
@Nullable private final Artifact libModules;
private final ImmutableList<CcInfo> hermeticStaticLibs;

private JavaRuntimeInfo(
NestedSet<Artifact> javaBaseInputs,
Expand All @@ -112,14 +119,16 @@ private JavaRuntimeInfo(
PathFragment javaHomeRunfilesPath,
PathFragment javaBinaryRunfilesPath,
NestedSet<Artifact> hermeticInputs,
@Nullable Artifact libModules) {
@Nullable Artifact libModules,
ImmutableList<CcInfo> hermeticStaticLibs) {
this.javaBaseInputs = javaBaseInputs;
this.javaHome = javaHome;
this.javaBinaryExecPath = javaBinaryExecPath;
this.javaHomeRunfilesPath = javaHomeRunfilesPath;
this.javaBinaryRunfilesPath = javaBinaryRunfilesPath;
this.hermeticInputs = hermeticInputs;
this.libModules = libModules;
this.hermeticStaticLibs = hermeticStaticLibs;
}

/** All input artifacts in the javabase. */
Expand Down Expand Up @@ -179,6 +188,23 @@ public Artifact libModules() {
return libModules;
}

public ImmutableList<CcInfo> hermeticStaticLibs() {
return hermeticStaticLibs;
}

public NestedSet<LibraryToLink> collectHermeticStaticLibrariesToLink() {
NestedSetBuilder<LibraryToLink> result = NestedSetBuilder.stableOrder();
for (CcInfo lib : hermeticStaticLibs()) {
result.addTransitive(lib.getCcLinkingContext().getLibraries());
}
return result.build();
}

@Override
public Depset starlarkHermeticStaticLibs() {
return Depset.of(LibraryToLink.TYPE, collectHermeticStaticLibrariesToLink());
}

@Override
public Depset starlarkJavaBaseInputs() {
return Depset.of(Artifact.TYPE, javaBaseInputs());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
import com.google.devtools.build.lib.analysis.TemplateVariableInfo;
import com.google.devtools.build.lib.analysis.config.ConfigAwareRuleClassBuilder;
import com.google.devtools.build.lib.packages.RuleClass;
import com.google.devtools.build.lib.packages.StarlarkProviderIdentifier;
import com.google.devtools.build.lib.rules.cpp.CcInfo;
import com.google.devtools.build.lib.util.FileTypeSet;

/** Rule definition for {@code java_runtime} */
Expand Down Expand Up @@ -54,6 +56,10 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env)
.singleArtifact()
.allowedFileTypes(FileTypeSet.ANY_FILE)
.exec())
.add(
attr("hermetic_static_libs", LABEL_LIST)
.mandatoryProviders(StarlarkProviderIdentifier.forKey(CcInfo.PROVIDER.getKey()))
.allowedFileTypes())
/* <!-- #BLAZE_RULE(java_runtime).ATTRIBUTE(java) -->
The path to the java executable.
<!-- #END_BLAZE_RULE.ATTRIBUTE --> */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,11 @@ public interface JavaRuntimeInfoApi extends StructApi {
allowReturnNones = true)
@Nullable
FileApi libModules();

/** The JDK static libraries needed for hermetic deployments. */
@StarlarkMethod(
name = "hermetic_static_libs",
doc = "Returns the JDK static libraries.",
structField = true)
Depset starlarkHermeticStaticLibs();
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ java_test(
"//src/main/java/com/google/devtools/build/lib/collect/nestedset",
"//src/main/java/com/google/devtools/build/lib/rules/java:java-compilation",
"//src/main/java/com/google/devtools/build/lib/vfs:pathfragment",
"//third_party:guava",
"//third_party:guava-testlib",
"//third_party:junit4",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

package com.google.devtools.build.lib.rules.java;

import com.google.common.collect.ImmutableList;
import com.google.common.testing.EqualsTester;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
Expand All @@ -35,7 +36,8 @@ public void equalityIsObjectIdentity() {
PathFragment.create(""),
PathFragment.create(""),
NestedSetBuilder.emptySet(Order.STABLE_ORDER),
null);
null,
ImmutableList.of());
JavaRuntimeInfo b =
JavaRuntimeInfo.create(
NestedSetBuilder.emptySet(Order.STABLE_ORDER),
Expand All @@ -44,7 +46,8 @@ public void equalityIsObjectIdentity() {
PathFragment.create(""),
PathFragment.create(""),
NestedSetBuilder.emptySet(Order.STABLE_ORDER),
null);
null,
ImmutableList.of());

new EqualsTester().addEqualityGroup(a).addEqualityGroup(b).testEquals();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3307,4 +3307,47 @@ public void mergeAddExports() throws Exception {
private InstrumentedFilesInfo getInstrumentedFilesProvider(String label) throws Exception {
return getConfiguredTarget(label).get(InstrumentedFilesInfo.STARLARK_CONSTRUCTOR);
}

@Test
public void hermeticStaticLibs() throws Exception {
scratch.file("a/libStatic.a");
scratch.file(
"a/BUILD",
"load(':rule.bzl', 'jrule')",
"load('"
+ TestConstants.TOOLS_REPOSITORY
+ "//tools/jdk:java_toolchain_alias.bzl', 'java_runtime_alias')",
"genrule(name='gen', cmd='', outs=['foo/bar/bin/java'])",
"cc_import(name='libs', static_library = 'libStatic.a')",
"cc_library(name = 'jdk_static_libs00', data = ['libStatic.a'], linkstatic = 1)",
"java_runtime(name='jvm', srcs=[], java='foo/bar/bin/java', hermetic_static_libs ="
+ " ['libs'])",
"java_runtime_alias(name='alias')",
"jrule(name='r')",
"toolchain(",
" name = 'java_runtime_toolchain',",
" toolchain = ':jvm',",
" toolchain_type = '"
+ TestConstants.TOOLS_REPOSITORY
+ "//tools/jdk:runtime_toolchain_type',",
")");
scratch.file(
"a/rule.bzl",
"load('//myinfo:myinfo.bzl', 'MyInfo')",
"def _impl(ctx):",
" provider = ctx.attr._java_runtime[java_common.JavaRuntimeInfo]",
" return MyInfo(",
" hermetic_static_libs = provider.hermetic_static_libs,",
" )",
"jrule = rule(_impl, attrs = { '_java_runtime': attr.label(default=Label('//a:alias'))})");

useConfiguration("--extra_toolchains=//a:all");
ConfiguredTarget ct = getConfiguredTarget("//a:r");
StructImpl myInfo = getMyInfoFromTarget(ct);
Depset hermeticStaticLibs = (Depset) myInfo.getValue("hermetic_static_libs");
assertThat(
hermeticStaticLibs.getSet(LibraryToLink.class).toList().stream()
.map(LibraryToLink::getLibraryIdentifier))
.containsExactly("a/libStatic");
}
}

0 comments on commit ac2e776

Please sign in to comment.