diff options
author | Mats Wichmann <mats@linux.com> | 2021-11-04 20:03:50 (GMT) |
---|---|---|
committer | Mats Wichmann <mats@linux.com> | 2021-11-04 22:30:05 (GMT) |
commit | 027c15f002610eae38212fe282963553a86a66ef (patch) | |
tree | ecfd9c0e3510e90a36c6b9e243097a3ec0996b9d /SCons/Tool/JavaCommon.py | |
parent | 1a04e66fdbe9dd5b088c337fa04f66f403dde2ad (diff) | |
download | SCons-027c15f002610eae38212fe282963553a86a66ef.zip SCons-027c15f002610eae38212fe282963553a86a66ef.tar.gz SCons-027c15f002610eae38212fe282963553a86a66ef.tar.bz2 |
Update Java support for more versions
* on Windows, detect more possible JDK locations.
* On all platforms, more Java versions (up to 17.0 now).
* Add some docu on version selection and on JavaH tool in light of javah
command dropped since 10.0.
* Try to be better about preserving user's passed-in JAVA* consvars.
Signed-off-by: Mats Wichmann <mats@linux.com>
Diffstat (limited to 'SCons/Tool/JavaCommon.py')
-rw-r--r-- | SCons/Tool/JavaCommon.py | 158 |
1 files changed, 113 insertions, 45 deletions
diff --git a/SCons/Tool/JavaCommon.py b/SCons/Tool/JavaCommon.py index d869b38..dac7d50 100644 --- a/SCons/Tool/JavaCommon.py +++ b/SCons/Tool/JavaCommon.py @@ -1,11 +1,6 @@ -"""SCons.Tool.JavaCommon - -Stuff for processing Java. - -""" - +# MIT License # -# __COPYRIGHT__ +# Copyright The SCons Foundation # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the @@ -25,16 +20,16 @@ Stuff for processing Java. # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# -__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" +"""Common routines for processing Java. """ import os -import os.path import re import glob +from pathlib import Path +from typing import List -java_parsing = 1 +java_parsing = True default_java_version = '1.4' @@ -43,13 +38,18 @@ default_java_version = '1.4' scopeStateVersions = ('1.8',) # Glob patterns for use in finding where the JDK is. -# These are pairs, *dir_glob used in the general case, -# *version_dir_glob if matching only a specific version. -# For now only used for Windows. -java_win32_dir_glob = 'C:/Program Files*/Java/jdk*/bin' +# +# These are pairs, (*dir_glob, *version_dir_glob) depending on whether +# a JDK version was requested or not. +# For now only used for Windows, which doesn't install JDK in a +# path that would be in env['ENV']['PATH']. The specific tool will +# add the discovered path to this. Since Oracle changed the rules, +# there are many possible vendors, we can't guess them all, but take a shot. +java_win32_dir_glob = 'C:/Program Files*/*/*jdk*/bin' + # On windows, since Java 9, there is a dash between 'jdk' and the version # string that wasn't there before. this glob should catch either way. -java_win32_version_dir_glob = 'C:/Program Files*/Java/jdk*%s*/bin' +java_win32_version_dir_glob = 'C:/Program Files*/*/*jdk*%s*/bin' # Glob patterns for use in finding where the JDK headers are. # These are pairs, *dir_glob used in the general case, @@ -98,9 +98,27 @@ if java_parsing: interfaces, and anonymous inner classes.""" def __init__(self, version=default_java_version): - - if version not in ('1.1', '1.2', '1.3', '1.4', '1.5', '1.6', '1.7', - '1.8', '5', '6', '9.0', '10.0', '11.0', '12.0'): + if version not in ( + '1.1', + '1.2', + '1.3', + '1.4', + '1.5', + '1.6', + '1.7', + '1.8', + '5', + '6', + '9.0', + '10.0', + '11.0', + '12.0', + '13.0', + '14.0', + '15.0', + '16.0', + '17.0', + ): msg = "Java version %s not supported" % version raise NotImplementedError(msg) @@ -207,7 +225,24 @@ if java_parsing: if self.version in ('1.1', '1.2', '1.3', '1.4'): clazz = self.listClasses[0] self.listOutputs.append('%s$%d' % (clazz, self.nextAnon)) - elif self.version in ('1.5', '1.6', '1.7', '1.8', '5', '6', '9.0', '10.0', '11.0', '12.0'): + # TODO: shouldn't need to repeat versions here and in OuterState + elif self.version in ( + '1.5', + '1.6', + '1.7', + '1.8', + '5', + '6', + '9.0', + '10.0', + '11.0', + '12.0', + '13.0', + '14.0', + '15.0', + '16.0', + '17.0', + ): self.stackAnonClassBrackets.append(self.brackets) className = [] className.extend(self.listClasses) @@ -443,49 +478,82 @@ else: return os.path.split(fn) -def get_java_install_dirs(platform, version=None): - """ - Find the java jdk installation directories. +def get_java_install_dirs(platform, version=None) -> List[str]: + """ Find possible java jdk installation directories. + + Returns a list for use as `default_paths` when looking up actual + java binaries with :meth:`SCons.Tool.find_program_path`. + The paths are sorted by version, latest first. - This list is intended to supply as "default paths" for use when looking - up actual java binaries. + Args: + platform: selector for search algorithm. + version: if not None, restrict the search to this version. - :param platform: selector for search algorithm. - :param version: If specified, only look for java sdk's of this version - :return: list of default paths for java. + Returns: + list of default paths for jdk. """ - paths = [] if platform == 'win32': + paths = [] if version: paths = glob.glob(java_win32_version_dir_glob % version) else: paths = glob.glob(java_win32_dir_glob) - else: - # other platforms, do nothing for now - pass - return sorted(paths) + def win32getvnum(java): + """ Generates a sort key for win32 jdk versions. + We'll have gotten a path like ...something/*jdk*/bin because + that is the pattern we glob for. To generate the sort key, + extracts the next-to-last component, then trims it further if + it had a complex name, like 'java-1.8.0-openjdk-1.8.0.312-1', + to try and put it on a common footing with the more common style, + which looks like 'jdk-11.0.2'. + + This is certainly fragile, and if someone has a 9.0 it won't + sort right since this will still be alphabetic, BUT 9.0 was + not an LTS release and is 30 mos out of support as this note + is written so just assume it will be okay. + """ + d = Path(java).parts[-2] + if not d.startswith('jdk'): + d = 'jdk' + d.rsplit('jdk', 1)[-1] + return d + + return sorted(paths, key=win32getvnum, reverse=True) + + # other platforms, do nothing for now: we expect the standard + # paths to be enough to find a jdk (e.g. use alternatives system) + return [] -def get_java_include_paths(env, javac, version): - """ - Find java include paths for JNI building. - :param env: construction environment, used to extract platform. - :param javac: path to detected javac. - :return: list of paths. +def get_java_include_paths(env, javac, version) -> List[str]: + """Find java include paths for JNI building. + + Cannot be called in isolation - `javac` refers to an already detected + compiler. Normally would would call :func:`get_java_install_dirs` first + and then do lookups on the paths it returns before calling us. + + Args: + env: construction environment, used to extract platform. + javac: path to detected javac. + version: if not None, restrict the search to this version. + + Returns: + list of include directory paths. """ - paths = [] if not javac: - # there are no paths if we've not detected javac. - pass - elif env['PLATFORM'] == 'win32': - # on Windows, we have the right path to javac, so look locally + return [] + + # on Windows, we have a path to the actual javac, so look locally + if env['PLATFORM'] == 'win32': javac_bin_dir = os.path.dirname(javac) java_inc_dir = os.path.normpath(os.path.join(javac_bin_dir, '..', 'include')) paths = [java_inc_dir, os.path.join(java_inc_dir, 'win32')] + + # for the others, we probably found something which isn't in the JDK dir, + # so use the predefined patterns to glob for an include directory. elif env['PLATFORM'] == 'darwin': if not version: paths = [java_macos_include_dir_glob] @@ -500,10 +568,10 @@ def get_java_include_paths(env, javac, version): for p in java_linux_version_include_dirs_glob: base_paths.extend(glob.glob(p % version)) + paths = [] for p in base_paths: paths.extend([p, os.path.join(p, 'linux')]) - # print("PATHS:%s"%paths) return paths # Local Variables: |