Add modules kwarg to JNI system dep

This allows someone to link against libjvm.so and libjawt.so.
pull/10071/head
Tristan Partin 3 years ago committed by Eli Schwartz
parent e082f268bd
commit 498db2764c
  1. 17
      docs/markdown/Dependencies.md
  2. 10
      docs/markdown/snippets/jni-system-dep-modules.md
  3. 61
      mesonbuild/dependencies/dev.py
  4. 2
      test cases/java/9 jni/meson.build

@ -494,23 +494,34 @@ Deprecated name for JNI. `dependency('jdk')` instead of `dependency('jni')`.
*(added 0.62.0)*
`modules` is an optional list of strings containing any of `jvm` and `awt`.
Provides access to compiling with the Java Native Interface (JNI). The lookup
will first check if `JAVA_HOME` is set in the environment, and if not will use
the resolved path of `javac`. Systems will usually link your preferred JDK to
well known paths like `/usr/bin/javac` on Linux for instance. Using the path
from `JAVA_HOME` or the resolved `javac`, this dependency will place the JDK
installation's `include` directory and its platform-dependent subdirectory on
the compiler's include path.
the compiler's include path. If `modules` is non-empty, then the proper linker
arguments will also be added.
```meson
dep = dependency('jni', version: '>= 1.8.0')
dep = dependency('jni', version: '>= 1.8.0', modules: ['jvm'])
```
**Note**: Due to usage of a resolved path, upgrading the JDK may cause the
various headers to not be found. In that case, please reconfigure the build
various paths to not be found. In that case, please reconfigure the build
directory. One workaround is to explicitly set `JAVA_HOME` instead of relying on
the fallback `javac` resolved path behavior.
**Note**: Include paths might be broken on platforms other than `linux`,
`windows`, `darwin`, and `sunos`. Please submit a PR or open an issue in this
case.
**Note**: Use of the `modules` argument on a JDK `<= 1.8` may be broken if your
system is anything other than `x86_64`. Please submit a PR or open an issue in
this case.
## libgcrypt
*(added 0.49.0)*

@ -0,0 +1,10 @@
## JNI System Dependency Modules
The JNI system dependency now supports a `modules` keyword argument which is a
list containing any of the following: `jvm`, `awt`.
```meson
jni_dep = dependency('jni', version: '>= 1.8.0', modules: ['jvm', 'awt'])
```
This will add appropriate linker arguments to your target.

@ -15,6 +15,8 @@
# This file contains the detection logic for external dependencies useful for
# development purposes, such as testing, debugging, etc..
from __future__ import annotations
import glob
import os
import re
@ -38,6 +40,13 @@ from .pkgconfig import PkgConfigDependency
if T.TYPE_CHECKING:
from ..envconfig import MachineInfo
from .. environment import Environment
from typing_extensions import TypedDict
class JNISystemDependencyKW(TypedDict):
modules: T.List[str]
# FIXME: When dependency() moves to typed Kwargs, this should inherit
# from its TypedDict type.
version: T.Optional[str]
def get_shared_library_suffix(environment: 'Environment', for_machine: MachineChoice) -> str:
@ -500,8 +509,8 @@ class ZlibSystemDependency(SystemDependency):
class JNISystemDependency(SystemDependency):
def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
super().__init__('jni', environment, kwargs)
def __init__(self, environment: 'Environment', kwargs: JNISystemDependencyKW):
super().__init__('jni', environment, T.cast(T.Dict[str, T.Any], kwargs))
self.feature_since = ('0.62.0', '')
@ -512,6 +521,14 @@ class JNISystemDependency(SystemDependency):
self.javac = environment.coredata.compilers[self.for_machine]['java']
self.version = self.javac.version
modules: T.List[str] = mesonlib.listify(kwargs.get('modules', []))
for module in modules:
if module not in {'jvm', 'awt'}:
log = mlog.error if self.required else mlog.debug
log(f'Unknown JNI module ({module})')
self.is_found = False
return
if 'version' in kwargs and not version_compare(self.version, kwargs['version']):
mlog.error(f'Incorrect JDK version found ({self.version}), wanted {kwargs["version"]}')
self.is_found = False
@ -530,6 +547,44 @@ class JNISystemDependency(SystemDependency):
java_home_include = self.java_home / 'include'
self.compile_args.append(f'-I{java_home_include}')
self.compile_args.append(f'-I{java_home_include / platform_include_dir}')
if modules:
if m.is_windows():
java_home_lib = self.java_home / 'lib'
java_home_lib_server = java_home_lib
else:
if version_compare(self.version, '<= 1.8.0'):
# The JDK and Meson have a disagreement here, so translate it
# over. In the event more translation needs to be done, add to
# following dict.
def cpu_translate(cpu: str) -> str:
java_cpus = {
'x86_64': 'amd64',
}
return java_cpus.get(cpu, cpu)
java_home_lib = self.java_home / 'jre' / 'lib' / cpu_translate(m.cpu_family)
java_home_lib_server = java_home_lib / "server"
else:
java_home_lib = self.java_home / 'lib'
java_home_lib_server = java_home_lib / "server"
if 'jvm' in modules:
jvm = self.clib_compiler.find_library('jvm', environment, extra_dirs=[str(java_home_lib_server)])
if jvm is None:
mlog.debug('jvm library not found.')
self.is_found = False
else:
self.link_args.extend(jvm)
if 'awt' in modules:
jawt = self.clib_compiler.find_library('jawt', environment, extra_dirs=[str(java_home_lib)])
if jawt is None:
mlog.debug('jawt library not found.')
self.is_found = False
else:
self.link_args.extend(jawt)
self.is_found = True
@staticmethod
@ -553,7 +608,7 @@ class JNISystemDependency(SystemDependency):
class JDKSystemDependency(JNISystemDependency):
def __init__(self, environment: 'Environment', kwargs: T.Dict[str, T.Any]):
def __init__(self, environment: 'Environment', kwargs: JNISystemDependencyKW):
super().__init__(environment, kwargs)
self.feature_since = ('0.59.0', '')

@ -13,7 +13,7 @@ javamod = import('java')
java = find_program('java')
jni_dep = dependency('jni', version : '>=1.8')
jni_dep = dependency('jni', version : '>=1.8', modules: ['jvm', 'awt'])
# generate native headers
subdir('src/com/mesonbuild')

Loading…
Cancel
Save