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