diff options
-rw-r--r-- | docs/markdown/Java-module.md | 47 | ||||
-rw-r--r-- | docs/markdown/snippets/java_generate_native_headers.md | 34 | ||||
-rw-r--r-- | mesonbuild/modules/java.py | 47 | ||||
-rw-r--r-- | test cases/java/9 jdk/lib/meson.build | 2 | ||||
-rw-r--r-- | test cases/java/9 jdk/src/com/mesonbuild/meson.build | 3 |
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('.') |