From 4d0a35462cc21b1fb33e04196d0b75b515f7f458 Mon Sep 17 00:00:00 2001 From: Chris Novakovic Date: Sat, 6 Aug 2022 23:39:49 +0100 Subject: [PATCH] `java_library`: output JNI headers generated by `javac` The Java compiler outputs header files for Java sources that use the Java Native Interface (JNI), but there's currently no way for them to be consumed by the native-code components that depend on them, preventing them from being built. Provide the JNI headers as outputs of `java_library` when `cc_hdrs` is required. This allows native-code JNI components written in C/C++ to be built by including the `java_library` target as a dependency. --- rules/java_rules.build_defs | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/rules/java_rules.build_defs b/rules/java_rules.build_defs index 80a4ddbccb..9ccd9f7661 100644 --- a/rules/java_rules.build_defs +++ b/rules/java_rules.build_defs @@ -4,7 +4,10 @@ def java_library(name:str, srcs:list=None, src_dir:str=None, resources:list=[], deps:list=[], modular:bool=False, exported_deps:list=None, visibility:list=None, test_only:bool&testonly=False, javac_flags:list&javacopts=None, labels:list=[], toolchain:str=CONFIG.JAVA_TOOLCHAIN): - """Compiles Java source to a .jar which can be collected by other rules. + """Compiles Java source to a .jar which can be collected by other rules. If the source makes use of + the Java Native Interface (JNI), and the target is included as a dependency of a C/C++ rule, this + rule instead outputs the JNI headers generated by the Java compiler to allow the source of the + native-code component to be built. Args: name (str): Name of the rule @@ -84,6 +87,33 @@ def java_library(name:str, srcs:list=None, src_dir:str=None, resources:list=[], src_dir_label = [] if srcs else ['src_dir:'+src_dir] + def _jni_header_outputs(name, output): + for hdr_path in output: + if hdr_path != "": + add_out(name, hdr_path) + add_label(name, "cc:inc:" + join_path(package_name(), dirname(hdr_path))) + + jni_hdrs = build_rule( + name = name, + tag = "jni_hdrs", + srcs = { + "WORKER": srcs or [src_dir], + }, + cmd = " && ".join([ + "mkdir -p _jni", + f"{javac_cmd} -h _jni >/dev/null 2>&1", + "find _jni -type f -name '*.h' | sort", + ]), + post_build = _jni_header_outputs, + labels = labels, + tools = { + "javac": [javac], + }, + test_only = test_only, + visibility = visibility, + deps = deps, + ) + return build_rule( name=name, srcs={ @@ -99,6 +129,9 @@ def java_library(name:str, srcs:list=None, src_dir:str=None, resources:list=[], cmd=cmd, building_description="Compiling...", requires=['java'], + provides={ + "cc_hdrs": jni_hdrs, + }, labels = labels + ['rule:java_test_library' if test_only else 'rule:java_library'] + src_dir_label, test_only=test_only, tools={