Try to find the jni dependency when javac is a Darwin stub

Darwin-based systems, at least macOS, provide various JDK executable
stubs in
/System/Library/Frameworks/JavaVM.framework/Versions/*/Commands.
These stubs are placed in such a way that they break the heuristics of
the JNI system dependency. If a javac being analyzed to find a Java home
is a stub, use /usr/libexec/java_home.

See https://stackoverflow.com/a/15133344/7572728 for more details.

Closes #11173
pull/11181/head
Tristan Partin 2 years ago
parent f287cac862
commit 7254db36a7
No known key found for this signature in database
GPG Key ID: 5AD0476101F9899D
  1. 36
      mesonbuild/dependencies/dev.py
  2. 6
      test cases/java/9 jni/meson.build

@ -22,6 +22,7 @@ import os
import re
import pathlib
import shutil
import subprocess
import typing as T
from mesonbuild.interpreterbase.decorators import FeatureDeprecated
@ -546,6 +547,17 @@ class JNISystemDependency(SystemDependency):
self.java_home = environment.properties[self.for_machine].get_java_home()
if not self.java_home:
self.java_home = pathlib.Path(shutil.which(self.javac.exelist[0])).resolve().parents[1]
if m.is_darwin():
problem_java_prefix = pathlib.Path('/System/Library/Frameworks/JavaVM.framework/Versions')
if problem_java_prefix in self.java_home.parents:
res = subprocess.run(['/usr/libexec/java_home', '--failfast', '--arch', m.cpu_family],
stdout=subprocess.PIPE)
if res.returncode != 0:
log = mlog.error if self.required else mlog.debug
log('JAVA_HOME could not be discovered on the system. Please set it explicitly.')
self.is_found = False
return
self.java_home = pathlib.Path(res.stdout.decode().strip())
platform_include_dir = self.__machine_info_to_platform_include_dir(m)
if platform_include_dir is None:
@ -563,17 +575,7 @@ class JNISystemDependency(SystemDependency):
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 = self.java_home / 'jre' / 'lib' / self.__cpu_translate(m.cpu_family)
else:
java_home_lib = self.java_home / 'lib'
@ -596,6 +598,18 @@ class JNISystemDependency(SystemDependency):
self.is_found = True
@staticmethod
def __cpu_translate(cpu: str) -> str:
'''
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.
'''
java_cpus = {
'x86_64': 'amd64',
}
return java_cpus.get(cpu, cpu)
@staticmethod
def __machine_info_to_platform_include_dir(m: 'MachineInfo') -> T.Optional[str]:
"""Translates the machine information to the platform-dependent include directory

@ -11,10 +11,16 @@ endif
fs = import('fs')
javamod = import('java')
cc = meson.get_compiler('c')
java = find_program('java')
jni_dep = dependency('jni', version : '>=1.8', modules: ['jvm', 'awt'])
# Assert that the header can actually be found with the dependency.
cc.has_header('jni.h', dependencies: [jni_dep])
# Assert that the platform-specific include directory is included in the compiler arguments.
cc.has_header('jni_md.h', dependencies: [jni_dep])
# generate native headers
subdir('src')
subdir('lib')

Loading…
Cancel
Save