aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Java-module.md47
-rw-r--r--docs/markdown/snippets/java_generate_native_headers.md34
-rw-r--r--mesonbuild/modules/java.py47
-rw-r--r--test cases/java/9 jdk/lib/meson.build2
-rw-r--r--test cases/java/9 jdk/src/com/mesonbuild/meson.build3
5 files changed, 127 insertions, 6 deletions
diff --git a/docs/markdown/Java-module.md b/docs/markdown/Java-module.md
index 9857de7..1665b7b 100644
--- a/docs/markdown/Java-module.md
+++ b/docs/markdown/Java-module.md
@@ -1,11 +1,13 @@
# Java Module
-*Added 0.60.0*
+*(added in 0.60.0)*
## Functions
### `generate_native_header()`
+*(deprecated in 0.62.0, use `generate_native_headers()`)*
+
This function will generate a header file for use in Java native module
development by reading the supplied Java file for `native` method declarations.
@@ -13,3 +15,46 @@ Keyword arguments:
- `package`: The [package](https://en.wikipedia.org/wiki/Java_package) of the
file. If left empty, Meson will assume that there is no package.
+
+### `generate_native_headers()`
+
+*(added in 0.62.0)*
+
+This function will generate native header files for use in Java native module
+development by reading the supplied Java files for `native` method declarations.
+
+Keyword arguments:
+
+- `classes`: The list of class names relative to the `package`, if it exists,
+which contain `native` method declarations. Use `.` separated class names.
+
+- `package`: The [package](https://en.wikipedia.org/wiki/Java_package) of the
+file. If left empty, Meson will assume that there is no package.
+
+Example:
+
+```java
+// Outer.java
+
+package com.mesonbuild;
+
+public class Outer {
+ private static native void outer();
+
+ public static class Inner {
+ private static native void inner();
+ }
+}
+```
+
+With the above file, an invocation would look like the following:
+
+```meson
+java = import('java')
+
+native_headers = java.generate_native_headers(
+ 'Outer.java',
+ package: 'com.mesonbuild',
+ classes: ['Outer', 'Outer.Inner']
+)
+```
diff --git a/docs/markdown/snippets/java_generate_native_headers.md b/docs/markdown/snippets/java_generate_native_headers.md
new file mode 100644
index 0000000..2a2a89e
--- /dev/null
+++ b/docs/markdown/snippets/java_generate_native_headers.md
@@ -0,0 +1,34 @@
+## Deprecated `java.generate_native_header()` in favor of the new `java.generate_native_headers()`
+
+`java.generate_native_header()` was only useful for the most basic of
+situations. It didn't take into account that in order to generate native
+headers, you had to have all the referenced Java files. It also didn't take
+into account inner classes. Do not use this function from `0.62.0` onward.
+
+`java.generate_native_headers()` has been added as a replacement which should account for the previous function's shortcomings.
+
+```java
+// Outer.java
+
+package com.mesonbuild;
+
+public class Outer {
+ private static native void outer();
+
+ public static class Inner {
+ private static native void inner();
+ }
+}
+```
+
+With the above file, an invocation would look like the following:
+
+```meson
+java = import('java')
+
+native_headers = java.generate_native_headers(
+ 'Outer.java',
+ package: 'com.mesonbuild',
+ classes: ['Outer', 'Outer.Inner']
+)
+```
diff --git a/mesonbuild/modules/java.py b/mesonbuild/modules/java.py
index 20cf3fd..dc660a7 100644
--- a/mesonbuild/modules/java.py
+++ b/mesonbuild/modules/java.py
@@ -15,9 +15,10 @@
import os
import pathlib
import typing as T
+from mesonbuild import mesonlib
from mesonbuild.build import CustomTarget
from mesonbuild.compilers import detect_compiler_for
-from mesonbuild.interpreterbase.decorators import FeatureNew, KwargInfo, typed_pos_args, typed_kwargs
+from mesonbuild.interpreterbase.decorators import ContainerTypeInfo, FeatureDeprecated, FeatureNew, KwargInfo, typed_pos_args, typed_kwargs
from mesonbuild.interpreter.interpreterobjects import FileHolder
from mesonbuild.mesonlib import version_compare, MachineChoice
from . import ExtensionModule, ModuleReturnValue, ModuleState
@@ -29,18 +30,18 @@ class JavaModule(ExtensionModule):
super().__init__(interpreter)
self.methods.update({
'generate_native_header': self.generate_native_header,
+ 'generate_native_headers': self.generate_native_headers,
})
if 'java' not in interpreter.environment.coredata.compilers[MachineChoice.BUILD]:
detect_compiler_for(interpreter.environment, 'java', MachineChoice.BUILD)
self.javac = interpreter.environment.coredata.compilers[MachineChoice.BUILD]['java']
+ @FeatureDeprecated('java.generate_native_header', '0.62.0', 'Use java.generate_native_headers instead')
@typed_pos_args('generate_native_header', (str, FileHolder))
@typed_kwargs('java.generate_native_header', KwargInfo('package', str, default=None))
def generate_native_header(self, state: ModuleState, args: T.Tuple[T.Union[str, FileHolder]],
kwargs: T.Dict[str, T.Optional[str]]) -> ModuleReturnValue:
- assert state.backend
-
package = kwargs.get('package')
file = self.interpreter.source_strings_to_files(
@@ -74,5 +75,45 @@ class JavaModule(ExtensionModule):
return ModuleReturnValue(target, [target])
+ @FeatureNew('java.generate_native_headers', '0.62.0')
+ @typed_pos_args('generate_native_headers', (str, mesonlib.File), min_varargs=1)
+ @typed_kwargs('java.generate_native_headers',
+ KwargInfo('classes', (ContainerTypeInfo(list, str)), default=[], listify=True,
+ required=True),
+ KwargInfo('package', str, default=None))
+ def generate_native_headers(self, state: ModuleState, args: T.List[mesonlib.FileOrString],
+ kwargs: T.Dict[str, T.Optional[str]]) -> ModuleReturnValue:
+ classes = T.cast(T.List[str], kwargs.get('classes'))
+ package = kwargs.get('package')
+
+ headers: T.List[str] = []
+ for clazz in classes:
+ underscore_clazz = clazz.replace(".", "_")
+ if package:
+ headers.append(f'{package.replace(".", "_")}_{underscore_clazz}.h')
+ else:
+ headers.append(f'{underscore_clazz}.h')
+
+ command = mesonlib.listify([
+ self.javac.exelist,
+ '-d',
+ '@PRIVATE_DIR@',
+ '-h',
+ state.subdir,
+ '@INPUT@',
+ ])
+
+ prefix = classes[0] if not package else package
+
+ target = CustomTarget(f'{prefix}-native-headers', state.subdir, state.subproject, command,
+ sources=list(args), outputs=headers, backend=state.backend)
+
+ # It is only known that 1.8.0 won't pre-create the directory. 11 and 16
+ # do not exhibit this behavior.
+ if version_compare(self.javac.version, '1.8.0'):
+ pathlib.Path(state.backend.get_target_private_dir_abs(target)).mkdir(parents=True, exist_ok=True)
+
+ return ModuleReturnValue(target, [target])
+
def initialize(*args: T.Any, **kwargs: T.Any) -> JavaModule:
return JavaModule(*args, **kwargs)
diff --git a/test cases/java/9 jdk/lib/meson.build b/test cases/java/9 jdk/lib/meson.build
index edffc1c..08407cf 100644
--- a/test cases/java/9 jdk/lib/meson.build
+++ b/test cases/java/9 jdk/lib/meson.build
@@ -3,7 +3,7 @@ sources = [
'native.c',
'com_mesonbuild_JdkTest.c',
),
- native_header
+ native_headers
]
jdkjava = shared_module(
diff --git a/test cases/java/9 jdk/src/com/mesonbuild/meson.build b/test cases/java/9 jdk/src/com/mesonbuild/meson.build
index 07daf51..0cce7f0 100644
--- a/test cases/java/9 jdk/src/com/mesonbuild/meson.build
+++ b/test cases/java/9 jdk/src/com/mesonbuild/meson.build
@@ -1,2 +1,3 @@
-native_header = javamod.generate_native_header('JdkTest.java', package: 'com.mesonbuild')
+native_headers = javamod.generate_native_headers(
+ 'JdkTest.java', package: 'com.mesonbuild', classes: ['JdkTest'])
native_header_includes = include_directories('.')