xref: /aosp_15_r20/external/bazelbuild-rules_java/java/java_single_jar.bzl (revision abe8e1b943c923005d847f1e3cf6637de4ed1a1f)
1*abe8e1b9SSadaf Ebrahimi""" Definition of _java_single_jar. """
2*abe8e1b9SSadaf Ebrahimi
3*abe8e1b9SSadaf Ebrahimiload("//java/common:java_common.bzl", "java_common")
4*abe8e1b9SSadaf Ebrahimiload("//java/common:java_info.bzl", "JavaInfo")
5*abe8e1b9SSadaf Ebrahimi
6*abe8e1b9SSadaf Ebrahimidef _java_single_jar(ctx):
7*abe8e1b9SSadaf Ebrahimi    transitive_inputs = []
8*abe8e1b9SSadaf Ebrahimi    for dep in ctx.attr.deps:
9*abe8e1b9SSadaf Ebrahimi        if JavaInfo in dep:
10*abe8e1b9SSadaf Ebrahimi            info = dep[JavaInfo]
11*abe8e1b9SSadaf Ebrahimi            transitive_inputs.append(info.transitive_runtime_jars)
12*abe8e1b9SSadaf Ebrahimi            if hasattr(info, "compilation_info"):
13*abe8e1b9SSadaf Ebrahimi                compilation_info = info.compilation_info
14*abe8e1b9SSadaf Ebrahimi                if hasattr(compilation_info, "runtime_classpath"):
15*abe8e1b9SSadaf Ebrahimi                    transitive_inputs.append(compilation_info.runtime_classpath)
16*abe8e1b9SSadaf Ebrahimi        else:
17*abe8e1b9SSadaf Ebrahimi            files = []
18*abe8e1b9SSadaf Ebrahimi            for f in dep[DefaultInfo].files.to_list():
19*abe8e1b9SSadaf Ebrahimi                if not f.extension == "jar":
20*abe8e1b9SSadaf Ebrahimi                    fail("unexpected file type in java_single_jar.deps: %s" % f.path)
21*abe8e1b9SSadaf Ebrahimi                files.append(f)
22*abe8e1b9SSadaf Ebrahimi            transitive_inputs.append(depset(files))
23*abe8e1b9SSadaf Ebrahimi    inputs = depset(transitive = transitive_inputs)
24*abe8e1b9SSadaf Ebrahimi
25*abe8e1b9SSadaf Ebrahimi    if hasattr(java_common, "JavaRuntimeClasspathInfo"):
26*abe8e1b9SSadaf Ebrahimi        deploy_env_jars = depset(transitive = [
27*abe8e1b9SSadaf Ebrahimi            dep[java_common.JavaRuntimeClasspathInfo].runtime_classpath
28*abe8e1b9SSadaf Ebrahimi            for dep in ctx.attr.deploy_env
29*abe8e1b9SSadaf Ebrahimi        ])
30*abe8e1b9SSadaf Ebrahimi        excluded_jars = {jar: None for jar in deploy_env_jars.to_list()}
31*abe8e1b9SSadaf Ebrahimi        if excluded_jars:
32*abe8e1b9SSadaf Ebrahimi            inputs = depset([jar for jar in inputs.to_list() if jar not in excluded_jars])
33*abe8e1b9SSadaf Ebrahimi
34*abe8e1b9SSadaf Ebrahimi    args = ctx.actions.args()
35*abe8e1b9SSadaf Ebrahimi    args.add_all("--sources", inputs)
36*abe8e1b9SSadaf Ebrahimi    args.use_param_file("@%s")
37*abe8e1b9SSadaf Ebrahimi    args.set_param_file_format("multiline")
38*abe8e1b9SSadaf Ebrahimi    args.add_all("--deploy_manifest_lines", ctx.attr.deploy_manifest_lines)
39*abe8e1b9SSadaf Ebrahimi    args.add("--output", ctx.outputs.jar)
40*abe8e1b9SSadaf Ebrahimi    args.add("--normalize")
41*abe8e1b9SSadaf Ebrahimi
42*abe8e1b9SSadaf Ebrahimi    # Deal with limitation of singlejar flags: tool's default behavior is
43*abe8e1b9SSadaf Ebrahimi    # "no", but you get that behavior only by absence of compression flags.
44*abe8e1b9SSadaf Ebrahimi    if ctx.attr.compress == "preserve":
45*abe8e1b9SSadaf Ebrahimi        args.add("--dont_change_compression")
46*abe8e1b9SSadaf Ebrahimi    elif ctx.attr.compress == "yes":
47*abe8e1b9SSadaf Ebrahimi        args.add("--compression")
48*abe8e1b9SSadaf Ebrahimi    elif ctx.attr.compress == "no":
49*abe8e1b9SSadaf Ebrahimi        pass
50*abe8e1b9SSadaf Ebrahimi    else:
51*abe8e1b9SSadaf Ebrahimi        fail("\"compress\" attribute (%s) must be: yes, no, preserve." % ctx.attr.compress)
52*abe8e1b9SSadaf Ebrahimi
53*abe8e1b9SSadaf Ebrahimi    if ctx.attr.exclude_build_data:
54*abe8e1b9SSadaf Ebrahimi        args.add("--exclude_build_data")
55*abe8e1b9SSadaf Ebrahimi    if ctx.attr.multi_release:
56*abe8e1b9SSadaf Ebrahimi        args.add("--multi_release")
57*abe8e1b9SSadaf Ebrahimi
58*abe8e1b9SSadaf Ebrahimi    ctx.actions.run(
59*abe8e1b9SSadaf Ebrahimi        inputs = inputs,
60*abe8e1b9SSadaf Ebrahimi        outputs = [ctx.outputs.jar],
61*abe8e1b9SSadaf Ebrahimi        arguments = [args],
62*abe8e1b9SSadaf Ebrahimi        progress_message = "Merging into %s" % ctx.outputs.jar.short_path,
63*abe8e1b9SSadaf Ebrahimi        mnemonic = "JavaSingleJar",
64*abe8e1b9SSadaf Ebrahimi        executable = ctx.executable._singlejar,
65*abe8e1b9SSadaf Ebrahimi    )
66*abe8e1b9SSadaf Ebrahimi
67*abe8e1b9SSadaf Ebrahimi    files = depset([ctx.outputs.jar])
68*abe8e1b9SSadaf Ebrahimi    providers = [DefaultInfo(
69*abe8e1b9SSadaf Ebrahimi        files = files,
70*abe8e1b9SSadaf Ebrahimi        runfiles = ctx.runfiles(transitive_files = files),
71*abe8e1b9SSadaf Ebrahimi    )]
72*abe8e1b9SSadaf Ebrahimi    if hasattr(java_common, "JavaRuntimeClasspathInfo"):
73*abe8e1b9SSadaf Ebrahimi        providers.append(java_common.JavaRuntimeClasspathInfo(runtime_classpath = inputs))
74*abe8e1b9SSadaf Ebrahimi    return providers
75*abe8e1b9SSadaf Ebrahimi
76*abe8e1b9SSadaf Ebrahimijava_single_jar = rule(
77*abe8e1b9SSadaf Ebrahimi    attrs = {
78*abe8e1b9SSadaf Ebrahimi        "deps": attr.label_list(
79*abe8e1b9SSadaf Ebrahimi            allow_files = True,
80*abe8e1b9SSadaf Ebrahimi            doc = """
81*abe8e1b9SSadaf Ebrahimi                The Java targets (including java_import and java_library) to collect
82*abe8e1b9SSadaf Ebrahimi                transitive dependencies from. Runtime dependencies are collected via
83*abe8e1b9SSadaf Ebrahimi                deps, exports, and runtime_deps. Resources are also collected.
84*abe8e1b9SSadaf Ebrahimi                Native cc_library or java_wrap_cc dependencies are not.""",
85*abe8e1b9SSadaf Ebrahimi        ),
86*abe8e1b9SSadaf Ebrahimi        "deploy_manifest_lines": attr.string_list(doc = """
87*abe8e1b9SSadaf Ebrahimi          A list of lines to add to the <code>META-INF/manifest.mf</code> file."""),
88*abe8e1b9SSadaf Ebrahimi        "deploy_env": attr.label_list(
89*abe8e1b9SSadaf Ebrahimi            providers = [java_common.JavaRuntimeClasspathInfo] if hasattr(java_common, "JavaRuntimeClasspathInfo") else [],
90*abe8e1b9SSadaf Ebrahimi            allow_files = False,
91*abe8e1b9SSadaf Ebrahimi            doc = """
92*abe8e1b9SSadaf Ebrahimi            A list of `java_binary` or `java_single_jar` targets which represent
93*abe8e1b9SSadaf Ebrahimi            the deployment environment for this binary.
94*abe8e1b9SSadaf Ebrahimi
95*abe8e1b9SSadaf Ebrahimi            Set this attribute when building a plugin which will be loaded by another
96*abe8e1b9SSadaf Ebrahimi            `java_binary`.
97*abe8e1b9SSadaf Ebrahimi
98*abe8e1b9SSadaf Ebrahimi            `deploy_env` dependencies are excluded from the jar built by this rule.""",
99*abe8e1b9SSadaf Ebrahimi        ),
100*abe8e1b9SSadaf Ebrahimi        "compress": attr.string(default = "preserve", doc = """
101*abe8e1b9SSadaf Ebrahimi            Whether to always deflate ("yes"), always store ("no"), or pass
102*abe8e1b9SSadaf Ebrahimi            through unmodified ("preserve"). The default is "preserve", and is the
103*abe8e1b9SSadaf Ebrahimi            most efficient option -- no extra work is done to inflate or deflate."""),
104*abe8e1b9SSadaf Ebrahimi        "exclude_build_data": attr.bool(default = True, doc = """
105*abe8e1b9SSadaf Ebrahimi            Whether to omit the build-data.properties file generated
106*abe8e1b9SSadaf Ebrahimi            by default."""),
107*abe8e1b9SSadaf Ebrahimi        "multi_release": attr.bool(default = True, doc = """Whether to enable Multi-Release output jars."""),
108*abe8e1b9SSadaf Ebrahimi        "_singlejar": attr.label(
109*abe8e1b9SSadaf Ebrahimi            default = Label("//toolchains:singlejar"),
110*abe8e1b9SSadaf Ebrahimi            cfg = "exec",
111*abe8e1b9SSadaf Ebrahimi            allow_single_file = True,
112*abe8e1b9SSadaf Ebrahimi            executable = True,
113*abe8e1b9SSadaf Ebrahimi        ),
114*abe8e1b9SSadaf Ebrahimi    },
115*abe8e1b9SSadaf Ebrahimi    outputs = {
116*abe8e1b9SSadaf Ebrahimi        "jar": "%{name}.jar",
117*abe8e1b9SSadaf Ebrahimi    },
118*abe8e1b9SSadaf Ebrahimi    implementation = _java_single_jar,
119*abe8e1b9SSadaf Ebrahimi    doc = """
120*abe8e1b9SSadaf EbrahimiCollects Java dependencies and jar files into a single jar
121*abe8e1b9SSadaf Ebrahimi
122*abe8e1b9SSadaf Ebrahimi`java_single_jar` collects Java dependencies and jar files into a single jar.
123*abe8e1b9SSadaf EbrahimiThis is similar to java_binary with everything related to executables disabled,
124*abe8e1b9SSadaf Ebrahimiand provides an alternative to the java_binary "deploy jar hack".
125*abe8e1b9SSadaf Ebrahimi
126*abe8e1b9SSadaf Ebrahimi## Example
127*abe8e1b9SSadaf Ebrahimi
128*abe8e1b9SSadaf Ebrahimi```skylark
129*abe8e1b9SSadaf Ebrahimiload("//tools/build_defs/java_single_jar:java_single_jar.bzl", "java_single_jar")
130*abe8e1b9SSadaf Ebrahimi
131*abe8e1b9SSadaf Ebrahimijava_single_jar(
132*abe8e1b9SSadaf Ebrahimi    name = "my_single_jar",
133*abe8e1b9SSadaf Ebrahimi    deps = [
134*abe8e1b9SSadaf Ebrahimi        "//java/com/google/foo",
135*abe8e1b9SSadaf Ebrahimi        "//java/com/google/bar",
136*abe8e1b9SSadaf Ebrahimi    ],
137*abe8e1b9SSadaf Ebrahimi)
138*abe8e1b9SSadaf Ebrahimi```
139*abe8e1b9SSadaf Ebrahimi
140*abe8e1b9SSadaf EbrahimiOutputs:
141*abe8e1b9SSadaf Ebrahimi  {name}.jar: A single jar containing all of the inputs.
142*abe8e1b9SSadaf Ebrahimi""",
143*abe8e1b9SSadaf Ebrahimi)
144