mirror of
https://github.com/Relintai/pandemonium_engine.git
synced 2025-01-22 00:57:17 +01:00
Removed java from scons.
This commit is contained in:
parent
53151b3437
commit
b7650adcea
@ -1,43 +0,0 @@
|
||||
# MIT License
|
||||
#
|
||||
# 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
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# 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.
|
||||
|
||||
import unittest
|
||||
|
||||
# Unit tests of various classes within SCons.Script.Main.py.
|
||||
#
|
||||
# Most of the tests of this functionality are actually end-to-end scripts
|
||||
# in the test/ hierarchy.
|
||||
#
|
||||
# This module is for specific bits of functionality that we can test
|
||||
# more effectively here, instead of in an end-to-end test that would
|
||||
# have to reach into SCons.Script.Main for various classes or other bits
|
||||
# of private functionality.
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
@ -1,584 +0,0 @@
|
||||
# MIT License
|
||||
#
|
||||
# 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
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# 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.
|
||||
|
||||
"""Common routines for processing Java. """
|
||||
|
||||
import os
|
||||
import re
|
||||
import glob
|
||||
from pathlib import Path
|
||||
from typing import List
|
||||
|
||||
java_parsing = True
|
||||
|
||||
default_java_version = '1.4'
|
||||
|
||||
# a switch for which jdk versions to use the Scope state for smarter
|
||||
# anonymous inner class parsing.
|
||||
scopeStateVersions = ('1.8',)
|
||||
|
||||
# Glob patterns for use in finding where the JDK is.
|
||||
#
|
||||
# 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*/*/*jdk*%s*/bin'
|
||||
|
||||
# Glob patterns for use in finding where the JDK headers are.
|
||||
# These are pairs, *dir_glob used in the general case,
|
||||
# *version_dir_glob if matching only a specific version.
|
||||
java_macos_include_dir_glob = '/System/Library/Frameworks/JavaVM.framework/Headers/'
|
||||
java_macos_version_include_dir_glob = '/System/Library/Frameworks/JavaVM.framework/Versions/%s*/Headers/'
|
||||
|
||||
java_linux_include_dirs_glob = [
|
||||
'/usr/lib/jvm/default-java/include',
|
||||
'/usr/lib/jvm/java-*/include',
|
||||
'/opt/oracle-jdk-bin-*/include',
|
||||
'/opt/openjdk-bin-*/include',
|
||||
'/usr/lib/openjdk-*/include',
|
||||
]
|
||||
# Need to match path like below (from Centos 7)
|
||||
# /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64/include/
|
||||
java_linux_version_include_dirs_glob = [
|
||||
'/usr/lib/jvm/java-*-sun-%s*/include',
|
||||
'/usr/lib/jvm/java-%s*-openjdk*/include',
|
||||
'/usr/java/jdk%s*/include',
|
||||
]
|
||||
|
||||
if java_parsing:
|
||||
# Parse Java files for class names.
|
||||
#
|
||||
# This is a really cool parser from Charles Crain
|
||||
# that finds appropriate class names in Java source.
|
||||
|
||||
# A regular expression that will find, in a java file:
|
||||
# newlines;
|
||||
# double-backslashes;
|
||||
# a single-line comment "//";
|
||||
# single or double quotes preceeded by a backslash;
|
||||
# single quotes, double quotes, open or close braces, semi-colons,
|
||||
# periods, open or close parentheses;
|
||||
# floating-point numbers;
|
||||
# any alphanumeric token (keyword, class name, specifier);
|
||||
# any alphanumeric token surrounded by angle brackets (generics);
|
||||
# the multi-line comment begin and end tokens /* and */;
|
||||
# array declarations "[]".
|
||||
# Lambda function symbols: ->
|
||||
_reToken = re.compile(r'(\n|\\\\|//|\\[\'"]|[\'"{\};.()]|' +
|
||||
r'\d*\.\d*|[A-Za-z_][\w$.]*|<[A-Za-z_]\w+>|' +
|
||||
r'/\*|\*/|\[\]|->)')
|
||||
|
||||
|
||||
class OuterState:
|
||||
"""The initial state for parsing a Java file for classes,
|
||||
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',
|
||||
'13.0',
|
||||
'14.0',
|
||||
'15.0',
|
||||
'16.0',
|
||||
'17.0',
|
||||
):
|
||||
msg = "Java version %s not supported" % version
|
||||
raise NotImplementedError(msg)
|
||||
|
||||
self.version = version
|
||||
self.listClasses = []
|
||||
self.listOutputs = []
|
||||
self.stackBrackets = []
|
||||
self.brackets = 0
|
||||
self.nextAnon = 1
|
||||
self.localClasses = []
|
||||
self.stackAnonClassBrackets = []
|
||||
self.anonStacksStack = [[0]]
|
||||
self.package = None
|
||||
|
||||
def trace(self):
|
||||
pass
|
||||
|
||||
def __getClassState(self):
|
||||
try:
|
||||
return self.classState
|
||||
except AttributeError:
|
||||
ret = ClassState(self)
|
||||
self.classState = ret
|
||||
return ret
|
||||
|
||||
def __getPackageState(self):
|
||||
try:
|
||||
return self.packageState
|
||||
except AttributeError:
|
||||
ret = PackageState(self)
|
||||
self.packageState = ret
|
||||
return ret
|
||||
|
||||
def __getAnonClassState(self):
|
||||
try:
|
||||
return self.anonState
|
||||
except AttributeError:
|
||||
self.outer_state = self
|
||||
ret = SkipState(1, AnonClassState(self))
|
||||
self.anonState = ret
|
||||
return ret
|
||||
|
||||
def __getSkipState(self):
|
||||
try:
|
||||
return self.skipState
|
||||
except AttributeError:
|
||||
ret = SkipState(1, self)
|
||||
self.skipState = ret
|
||||
return ret
|
||||
|
||||
def _getAnonStack(self):
|
||||
return self.anonStacksStack[-1]
|
||||
|
||||
def openBracket(self):
|
||||
self.brackets = self.brackets + 1
|
||||
|
||||
def closeBracket(self):
|
||||
self.brackets = self.brackets - 1
|
||||
if len(self.stackBrackets) and \
|
||||
self.brackets == self.stackBrackets[-1]:
|
||||
self.listOutputs.append('$'.join(self.listClasses))
|
||||
self.localClasses.pop()
|
||||
self.listClasses.pop()
|
||||
self.anonStacksStack.pop()
|
||||
self.stackBrackets.pop()
|
||||
if len(self.stackAnonClassBrackets) and \
|
||||
self.brackets == self.stackAnonClassBrackets[-1] and \
|
||||
self.version not in scopeStateVersions:
|
||||
self._getAnonStack().pop()
|
||||
self.stackAnonClassBrackets.pop()
|
||||
|
||||
def parseToken(self, token):
|
||||
if token[:2] == '//':
|
||||
return IgnoreState('\n', self)
|
||||
elif token == '/*':
|
||||
return IgnoreState('*/', self)
|
||||
elif token == '{':
|
||||
self.openBracket()
|
||||
elif token == '}':
|
||||
self.closeBracket()
|
||||
elif token in ['"', "'"]:
|
||||
return IgnoreState(token, self)
|
||||
elif token == "new":
|
||||
# anonymous inner class
|
||||
if len(self.listClasses) > 0:
|
||||
return self.__getAnonClassState()
|
||||
return self.__getSkipState() # Skip the class name
|
||||
elif token in ['class', 'interface', 'enum']:
|
||||
if len(self.listClasses) == 0:
|
||||
self.nextAnon = 1
|
||||
self.stackBrackets.append(self.brackets)
|
||||
return self.__getClassState()
|
||||
elif token == 'package':
|
||||
return self.__getPackageState()
|
||||
elif token == '.':
|
||||
# Skip the attribute, it might be named "class", in which
|
||||
# case we don't want to treat the following token as
|
||||
# an inner class name...
|
||||
return self.__getSkipState()
|
||||
return self
|
||||
|
||||
def addAnonClass(self):
|
||||
"""Add an anonymous inner class"""
|
||||
if self.version in ('1.1', '1.2', '1.3', '1.4'):
|
||||
clazz = self.listClasses[0]
|
||||
self.listOutputs.append('%s$%d' % (clazz, self.nextAnon))
|
||||
# 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)
|
||||
self._getAnonStack()[-1] = self._getAnonStack()[-1] + 1
|
||||
for anon in self._getAnonStack():
|
||||
className.append(str(anon))
|
||||
self.listOutputs.append('$'.join(className))
|
||||
|
||||
self.nextAnon = self.nextAnon + 1
|
||||
self._getAnonStack().append(0)
|
||||
|
||||
def setPackage(self, package):
|
||||
self.package = package
|
||||
|
||||
|
||||
class ScopeState:
|
||||
"""
|
||||
A state that parses code within a scope normally,
|
||||
within the confines of a scope.
|
||||
"""
|
||||
|
||||
def __init__(self, old_state):
|
||||
self.outer_state = old_state.outer_state
|
||||
self.old_state = old_state
|
||||
self.brackets = 0
|
||||
|
||||
def __getClassState(self):
|
||||
try:
|
||||
return self.classState
|
||||
except AttributeError:
|
||||
ret = ClassState(self)
|
||||
self.classState = ret
|
||||
return ret
|
||||
|
||||
def __getAnonClassState(self):
|
||||
try:
|
||||
return self.anonState
|
||||
except AttributeError:
|
||||
ret = SkipState(1, AnonClassState(self))
|
||||
self.anonState = ret
|
||||
return ret
|
||||
|
||||
def __getSkipState(self):
|
||||
try:
|
||||
return self.skipState
|
||||
except AttributeError:
|
||||
ret = SkipState(1, self)
|
||||
self.skipState = ret
|
||||
return ret
|
||||
|
||||
def openBracket(self):
|
||||
self.brackets = self.brackets + 1
|
||||
|
||||
def closeBracket(self):
|
||||
self.brackets = self.brackets - 1
|
||||
|
||||
def parseToken(self, token):
|
||||
# if self.brackets == 0:
|
||||
# return self.old_state.parseToken(token)
|
||||
if token[:2] == '//':
|
||||
return IgnoreState('\n', self)
|
||||
elif token == '/*':
|
||||
return IgnoreState('*/', self)
|
||||
elif token == '{':
|
||||
self.openBracket()
|
||||
elif token == '}':
|
||||
self.closeBracket()
|
||||
if self.brackets == 0:
|
||||
self.outer_state._getAnonStack().pop()
|
||||
return self.old_state
|
||||
elif token in ['"', "'"]:
|
||||
return IgnoreState(token, self)
|
||||
elif token == "new":
|
||||
# anonymous inner class
|
||||
return self.__getAnonClassState()
|
||||
elif token == '.':
|
||||
# Skip the attribute, it might be named "class", in which
|
||||
# case we don't want to treat the following token as
|
||||
# an inner class name...
|
||||
return self.__getSkipState()
|
||||
return self
|
||||
|
||||
|
||||
class AnonClassState:
|
||||
"""A state that looks for anonymous inner classes."""
|
||||
|
||||
def __init__(self, old_state):
|
||||
# outer_state is always an instance of OuterState
|
||||
self.outer_state = old_state.outer_state
|
||||
self.old_state = old_state
|
||||
self.brace_level = 0
|
||||
|
||||
def parseToken(self, token):
|
||||
# This is an anonymous class if and only if the next
|
||||
# non-whitespace token is a bracket. Everything between
|
||||
# braces should be parsed as normal java code.
|
||||
if token[:2] == '//':
|
||||
return IgnoreState('\n', self)
|
||||
elif token == '/*':
|
||||
return IgnoreState('*/', self)
|
||||
elif token == '\n':
|
||||
return self
|
||||
elif token[0] == '<' and token[-1] == '>':
|
||||
return self
|
||||
elif token == '(':
|
||||
self.brace_level = self.brace_level + 1
|
||||
return self
|
||||
if self.brace_level > 0:
|
||||
if token == 'new':
|
||||
# look further for anonymous inner class
|
||||
return SkipState(1, AnonClassState(self))
|
||||
elif token in ['"', "'"]:
|
||||
return IgnoreState(token, self)
|
||||
elif token == ')':
|
||||
self.brace_level = self.brace_level - 1
|
||||
return self
|
||||
if token == '{':
|
||||
self.outer_state.addAnonClass()
|
||||
if self.outer_state.version in scopeStateVersions:
|
||||
return ScopeState(old_state=self.old_state).parseToken(token)
|
||||
return self.old_state.parseToken(token)
|
||||
|
||||
|
||||
class SkipState:
|
||||
"""A state that will skip a specified number of tokens before
|
||||
reverting to the previous state."""
|
||||
|
||||
def __init__(self, tokens_to_skip, old_state):
|
||||
self.tokens_to_skip = tokens_to_skip
|
||||
self.old_state = old_state
|
||||
|
||||
def parseToken(self, token):
|
||||
self.tokens_to_skip = self.tokens_to_skip - 1
|
||||
if self.tokens_to_skip < 1:
|
||||
return self.old_state
|
||||
return self
|
||||
|
||||
|
||||
class ClassState:
|
||||
"""A state we go into when we hit a class or interface keyword."""
|
||||
|
||||
def __init__(self, outer_state):
|
||||
# outer_state is always an instance of OuterState
|
||||
self.outer_state = outer_state
|
||||
|
||||
def parseToken(self, token):
|
||||
# the next non-whitespace token should be the name of the class
|
||||
if token == '\n':
|
||||
return self
|
||||
# If that's an inner class which is declared in a method, it
|
||||
# requires an index prepended to the class-name, e.g.
|
||||
# 'Foo$1Inner'
|
||||
# https://github.com/SCons/scons/issues/2087
|
||||
if self.outer_state.localClasses and \
|
||||
self.outer_state.stackBrackets[-1] > \
|
||||
self.outer_state.stackBrackets[-2] + 1:
|
||||
locals = self.outer_state.localClasses[-1]
|
||||
try:
|
||||
idx = locals[token]
|
||||
locals[token] = locals[token] + 1
|
||||
except KeyError:
|
||||
locals[token] = 1
|
||||
token = str(locals[token]) + token
|
||||
self.outer_state.localClasses.append({})
|
||||
self.outer_state.listClasses.append(token)
|
||||
self.outer_state.anonStacksStack.append([0])
|
||||
return self.outer_state
|
||||
|
||||
|
||||
class IgnoreState:
|
||||
"""A state that will ignore all tokens until it gets to a
|
||||
specified token."""
|
||||
|
||||
def __init__(self, ignore_until, old_state):
|
||||
self.ignore_until = ignore_until
|
||||
self.old_state = old_state
|
||||
|
||||
def parseToken(self, token):
|
||||
if self.ignore_until == token:
|
||||
return self.old_state
|
||||
return self
|
||||
|
||||
|
||||
class PackageState:
|
||||
"""The state we enter when we encounter the package keyword.
|
||||
We assume the next token will be the package name."""
|
||||
|
||||
def __init__(self, outer_state):
|
||||
# outer_state is always an instance of OuterState
|
||||
self.outer_state = outer_state
|
||||
|
||||
def parseToken(self, token):
|
||||
self.outer_state.setPackage(token)
|
||||
return self.outer_state
|
||||
|
||||
|
||||
def parse_java_file(fn, version=default_java_version):
|
||||
with open(fn, 'r', encoding='utf-8') as f:
|
||||
data = f.read()
|
||||
return parse_java(data, version)
|
||||
|
||||
|
||||
def parse_java(contents, version=default_java_version, trace=None):
|
||||
"""Parse a .java file and return a double of package directory,
|
||||
plus a list of .class files that compiling that .java file will
|
||||
produce"""
|
||||
package = None
|
||||
initial = OuterState(version)
|
||||
currstate = initial
|
||||
for token in _reToken.findall(contents):
|
||||
# The regex produces a bunch of groups, but only one will
|
||||
# have anything in it.
|
||||
currstate = currstate.parseToken(token)
|
||||
if trace: trace(token, currstate)
|
||||
if initial.package:
|
||||
package = initial.package.replace('.', os.sep)
|
||||
return (package, initial.listOutputs)
|
||||
|
||||
else:
|
||||
# Don't actually parse Java files for class names.
|
||||
#
|
||||
# We might make this a configurable option in the future if
|
||||
# Java-file parsing takes too long (although it shouldn't relative
|
||||
# to how long the Java compiler itself seems to take...).
|
||||
|
||||
def parse_java_file(fn):
|
||||
""" "Parse" a .java file.
|
||||
|
||||
This actually just splits the file name, so the assumption here
|
||||
is that the file name matches the public class name, and that
|
||||
the path to the file is the same as the package name.
|
||||
"""
|
||||
return os.path.split(fn)
|
||||
|
||||
|
||||
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.
|
||||
|
||||
Args:
|
||||
platform: selector for search algorithm.
|
||||
version: if not None, restrict the search to this version.
|
||||
|
||||
Returns:
|
||||
list of default paths for jdk.
|
||||
"""
|
||||
|
||||
if platform == 'win32':
|
||||
paths = []
|
||||
if version:
|
||||
paths = glob.glob(java_win32_version_dir_glob % version)
|
||||
else:
|
||||
paths = glob.glob(java_win32_dir_glob)
|
||||
|
||||
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) -> 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.
|
||||
"""
|
||||
|
||||
if not javac:
|
||||
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]
|
||||
else:
|
||||
paths = sorted(glob.glob(java_macos_version_include_dir_glob % version))
|
||||
else:
|
||||
base_paths = []
|
||||
if not version:
|
||||
for p in java_linux_include_dirs_glob:
|
||||
base_paths.extend(glob.glob(p))
|
||||
else:
|
||||
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')])
|
||||
|
||||
return paths
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
@ -1,783 +0,0 @@
|
||||
# MIT License
|
||||
#
|
||||
# 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
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# 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.
|
||||
|
||||
import os.path
|
||||
import unittest
|
||||
import fnmatch
|
||||
|
||||
import SCons.Scanner.IDL
|
||||
import SCons.Tool.JavaCommon
|
||||
|
||||
import TestSCons
|
||||
|
||||
# Adding trace=trace to any of the parse_jave() calls below will cause
|
||||
# the parser to spit out trace messages of the tokens it sees and the
|
||||
# attendant transitions.
|
||||
|
||||
def trace(token, newstate):
|
||||
from SCons.Debug import Trace
|
||||
statename = newstate.__class__.__name__
|
||||
Trace('token = %s, state = %s\n' % (repr(token), statename))
|
||||
|
||||
class parse_javaTestCase(unittest.TestCase):
|
||||
|
||||
def test_bare_bones(self):
|
||||
"""Test a bare-bones class"""
|
||||
|
||||
input = """\
|
||||
package com.sub.bar;
|
||||
|
||||
public class Foo
|
||||
{
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
|
||||
/* This tests a former bug where strings would eat later code. */
|
||||
String hello1 = new String("Hello, world!");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
"""
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir == os.path.join('com', 'sub', 'bar'), pkg_dir
|
||||
assert classes == ['Foo'], classes
|
||||
|
||||
|
||||
def test_file_parser(self):
|
||||
"""Test the file parser"""
|
||||
input = """\
|
||||
package com.sub.bar;
|
||||
|
||||
public class Foo
|
||||
{
|
||||
public static void main(String[] args)
|
||||
{
|
||||
/* This tests that unicde is handled . */
|
||||
String hello1 = new String("ఎత్తువెడల్పు");
|
||||
}
|
||||
}
|
||||
"""
|
||||
file_name = 'test_file_parser.java'
|
||||
with open(file_name, 'w', encoding='UTF-8') as jf:
|
||||
print(input, file=jf)
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java_file(file_name)
|
||||
if os.path.exists(file_name):
|
||||
os.remove(file_name)
|
||||
assert pkg_dir == os.path.join('com', 'sub', 'bar'), pkg_dir
|
||||
assert classes == ['Foo'], classes
|
||||
|
||||
|
||||
def test_dollar_sign(self):
|
||||
"""Test class names with $ in them"""
|
||||
|
||||
input = """\
|
||||
public class BadDep {
|
||||
public void new$rand () {}
|
||||
}
|
||||
"""
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir is None, pkg_dir
|
||||
assert classes == ['BadDep'], classes
|
||||
|
||||
|
||||
|
||||
def test_inner_classes(self):
|
||||
"""Test parsing various forms of inner classes"""
|
||||
|
||||
input = """\
|
||||
class Empty {
|
||||
}
|
||||
|
||||
interface Listener {
|
||||
public void execute();
|
||||
}
|
||||
|
||||
public
|
||||
class
|
||||
Test implements Listener {
|
||||
class Inner {
|
||||
void go() {
|
||||
use(new Listener() {
|
||||
public void execute() {
|
||||
System.out.println("In Inner");
|
||||
}
|
||||
});
|
||||
}
|
||||
String s1 = "class A";
|
||||
String s2 = "new Listener() { }";
|
||||
/* class B */
|
||||
/* new Listener() { } */
|
||||
}
|
||||
|
||||
class Inner2 {
|
||||
Inner2() { Listener l = new Listener(); }
|
||||
}
|
||||
|
||||
/* Make sure this class doesn't get interpreted as an inner class of the previous one, when "new" is used in the previous class. */
|
||||
class Inner3 {
|
||||
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Test().run();
|
||||
}
|
||||
|
||||
void run() {
|
||||
use(new Listener() {
|
||||
public void execute() {
|
||||
use(new Listener( ) {
|
||||
public void execute() {
|
||||
System.out.println("Inside execute()");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
new Inner().go();
|
||||
}
|
||||
|
||||
void use(Listener l) {
|
||||
l.execute();
|
||||
}
|
||||
}
|
||||
|
||||
class Private {
|
||||
void run() {
|
||||
new Listener() {
|
||||
public void execute() {
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
|
||||
assert pkg_dir is None, pkg_dir
|
||||
expect = [
|
||||
'Empty',
|
||||
'Listener',
|
||||
'Test$1',
|
||||
'Test$Inner',
|
||||
'Test$Inner2',
|
||||
'Test$Inner3',
|
||||
'Test$2',
|
||||
'Test$3',
|
||||
'Test',
|
||||
'Private$1',
|
||||
'Private',
|
||||
]
|
||||
assert classes == expect, classes
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
|
||||
assert pkg_dir is None, pkg_dir
|
||||
expect = [
|
||||
'Empty',
|
||||
'Listener',
|
||||
'Test$Inner$1',
|
||||
'Test$Inner',
|
||||
'Test$Inner2',
|
||||
'Test$Inner3',
|
||||
'Test$1',
|
||||
'Test$1$1',
|
||||
'Test',
|
||||
'Private$1',
|
||||
'Private',
|
||||
]
|
||||
assert classes == expect, (expect, classes)
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '5')
|
||||
assert pkg_dir is None, pkg_dir
|
||||
expect = [
|
||||
'Empty',
|
||||
'Listener',
|
||||
'Test$Inner$1',
|
||||
'Test$Inner',
|
||||
'Test$Inner2',
|
||||
'Test$Inner3',
|
||||
'Test$1',
|
||||
'Test$1$1',
|
||||
'Test',
|
||||
'Private$1',
|
||||
'Private',
|
||||
]
|
||||
assert classes == expect, (expect, classes)
|
||||
|
||||
|
||||
|
||||
def test_comments(self):
|
||||
"""Test a class with comments"""
|
||||
|
||||
input = """\
|
||||
package com.sub.foo;
|
||||
|
||||
import java.rmi.Naming;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.RMISecurityManager;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class Example1 extends UnicastRemoteObject implements Hello {
|
||||
|
||||
public Example1() throws RemoteException {
|
||||
super();
|
||||
}
|
||||
|
||||
public String sayHello() {
|
||||
return "Hello World!";
|
||||
}
|
||||
|
||||
public static void main(String args[]) {
|
||||
if (System.getSecurityManager() == null) {
|
||||
System.setSecurityManager(new RMISecurityManager());
|
||||
}
|
||||
// a comment
|
||||
try {
|
||||
Example1 obj = new Example1();
|
||||
|
||||
Naming.rebind("//myhost/HelloServer", obj);
|
||||
|
||||
System.out.println("HelloServer bound in registry");
|
||||
} catch (Exception e) {
|
||||
System.out.println("Example1 err: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir == os.path.join('com', 'sub', 'foo'), pkg_dir
|
||||
assert classes == ['Example1'], classes
|
||||
|
||||
|
||||
def test_arrays(self):
|
||||
"""Test arrays of class instances"""
|
||||
|
||||
input = """\
|
||||
public class Test {
|
||||
MyClass abc = new MyClass();
|
||||
MyClass xyz = new MyClass();
|
||||
MyClass _array[] = new MyClass[] {
|
||||
abc,
|
||||
xyz
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir is None, pkg_dir
|
||||
assert classes == ['Test'], classes
|
||||
|
||||
|
||||
|
||||
def test_backslash(self):
|
||||
"""Test backslash handling"""
|
||||
|
||||
input = """\
|
||||
public class MyTabs
|
||||
{
|
||||
private class MyInternal
|
||||
{
|
||||
}
|
||||
private final static String PATH = "images\\\\";
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir is None, pkg_dir
|
||||
assert classes == ['MyTabs$MyInternal', 'MyTabs'], classes
|
||||
|
||||
|
||||
def test_enum(self):
|
||||
"""Test the Java 1.5 enum keyword"""
|
||||
|
||||
input = """\
|
||||
package p;
|
||||
public enum a {}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir == 'p', pkg_dir
|
||||
assert classes == ['a'], classes
|
||||
|
||||
|
||||
def test_anon_classes(self):
|
||||
"""Test anonymous classes"""
|
||||
|
||||
input = """\
|
||||
public abstract class TestClass
|
||||
{
|
||||
public void completed()
|
||||
{
|
||||
new Thread()
|
||||
{
|
||||
}.start();
|
||||
|
||||
new Thread()
|
||||
{
|
||||
}.start();
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir is None, pkg_dir
|
||||
assert classes == ['TestClass$1', 'TestClass$2', 'TestClass'], classes
|
||||
|
||||
|
||||
def test_closing_bracket(self):
|
||||
"""Test finding a closing bracket instead of an anonymous class"""
|
||||
|
||||
input = """\
|
||||
class TestSCons {
|
||||
public static void main(String[] args) {
|
||||
Foo[] fooArray = new Foo[] { new Foo() };
|
||||
}
|
||||
}
|
||||
|
||||
class Foo { }
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir is None, pkg_dir
|
||||
assert classes == ['TestSCons', 'Foo'], classes
|
||||
|
||||
|
||||
def test_dot_class_attributes(self):
|
||||
"""Test handling ".class" attributes"""
|
||||
|
||||
input = """\
|
||||
public class Test extends Object
|
||||
{
|
||||
static {
|
||||
Class c = Object[].class;
|
||||
Object[] s = new Object[] {};
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert classes == ['Test'], classes
|
||||
|
||||
input = """\
|
||||
public class A {
|
||||
public class B {
|
||||
public void F(Object[] o) {
|
||||
F(new Object[] {Object[].class});
|
||||
}
|
||||
public void G(Object[] o) {
|
||||
F(new Object[] {});
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input)
|
||||
assert pkg_dir is None, pkg_dir
|
||||
assert classes == ['A$B', 'A'], classes
|
||||
|
||||
def test_anonymous_classes_with_parentheses(self):
|
||||
"""Test finding anonymous classes marked by parentheses"""
|
||||
|
||||
input = """\
|
||||
import java.io.File;
|
||||
|
||||
public class Foo {
|
||||
public static void main(String[] args) {
|
||||
File f = new File(
|
||||
new File("a") {
|
||||
public String toString() {
|
||||
return "b";
|
||||
}
|
||||
} to String()
|
||||
) {
|
||||
public String toString() {
|
||||
return "c";
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
|
||||
assert classes == ['Foo$1', 'Foo$2', 'Foo'], classes
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
|
||||
assert classes == ['Foo$1', 'Foo$1$1', 'Foo'], classes
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '6')
|
||||
assert classes == ['Foo$1', 'Foo$1$1', 'Foo'], classes
|
||||
|
||||
|
||||
|
||||
def test_nested_anonymous_inner_classes(self):
|
||||
"""Test finding nested anonymous inner classes"""
|
||||
|
||||
input = """\
|
||||
// import java.util.*;
|
||||
|
||||
public class NestedExample
|
||||
{
|
||||
public NestedExample()
|
||||
{
|
||||
Thread t = new Thread() {
|
||||
public void start()
|
||||
{
|
||||
Thread t = new Thread() {
|
||||
public void start()
|
||||
{
|
||||
try {Thread.sleep(200);}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
};
|
||||
while (true)
|
||||
{
|
||||
try {Thread.sleep(200);}
|
||||
catch (Exception e) {}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public static void main(String argv[])
|
||||
{
|
||||
NestedExample e = new NestedExample();
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
|
||||
expect = [ 'NestedExample$1', 'NestedExample$2', 'NestedExample' ]
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
|
||||
expect = [ 'NestedExample$1', 'NestedExample$1$1', 'NestedExample' ]
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '6')
|
||||
expect = [ 'NestedExample$1', 'NestedExample$1$1', 'NestedExample' ]
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
def test_lambda_after_new(self):
|
||||
"""Test lamdas after new"""
|
||||
|
||||
input = """\
|
||||
// import java.util.*;
|
||||
|
||||
public class LamdaExample
|
||||
{
|
||||
|
||||
public void testFunc (int arg1, String arg2, Runnable lambda){
|
||||
}
|
||||
public LamdaExample()
|
||||
{
|
||||
testFunc(
|
||||
5,
|
||||
new String("test"),
|
||||
// Lambda symbol is after new, and used curly braces so
|
||||
// we should not parse this as a new class.
|
||||
() -> {}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public static void main(String argv[])
|
||||
{
|
||||
LamdaExample e = new LamdaExample();
|
||||
}
|
||||
}
|
||||
"""
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
|
||||
expect = [ 'LamdaExample' ]
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.8')
|
||||
expect = [ 'LamdaExample' ]
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
def test_private_inner_class_instantiation(self):
|
||||
"""Test anonymous inner class generated by private instantiation"""
|
||||
|
||||
input = """\
|
||||
class test
|
||||
{
|
||||
test()
|
||||
{
|
||||
super();
|
||||
new inner();
|
||||
}
|
||||
|
||||
static class inner
|
||||
{
|
||||
private inner() {}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
# This is what we *should* generate, apparently due to the
|
||||
# private instantiation of the inner class, but don't today.
|
||||
#expect = [ 'test$1', 'test$inner', 'test' ]
|
||||
|
||||
# What our parser currently generates, which doesn't match
|
||||
# what the Java compiler actually generates.
|
||||
expect = [ 'test$inner', 'test' ]
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
def test_floating_point_numbers(self):
|
||||
"""Test floating-point numbers in the input stream"""
|
||||
input = """
|
||||
// Broken.java
|
||||
class Broken
|
||||
{
|
||||
/**
|
||||
* Detected.
|
||||
*/
|
||||
Object anonymousInnerOK = new Runnable() { public void run () {} };
|
||||
|
||||
/**
|
||||
* Detected.
|
||||
*/
|
||||
class InnerOK { InnerOK () { } }
|
||||
|
||||
{
|
||||
System.out.println("a number: " + 1000.0 + "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Not detected.
|
||||
*/
|
||||
Object anonymousInnerBAD = new Runnable() { public void run () {} };
|
||||
|
||||
/**
|
||||
* Not detected.
|
||||
*/
|
||||
class InnerBAD { InnerBAD () { } }
|
||||
}
|
||||
"""
|
||||
|
||||
expect = ['Broken$1', 'Broken$InnerOK', 'Broken$2', 'Broken$InnerBAD', 'Broken']
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.4')
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5')
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
|
||||
def test_genercis(self):
|
||||
"""Test that generics don't interfere with detecting anonymous classes"""
|
||||
|
||||
input = """\
|
||||
import java.util.Date;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class Foo
|
||||
{
|
||||
public void foo()
|
||||
{
|
||||
Comparator<Date> comp = new Comparator<Date>()
|
||||
{
|
||||
static final long serialVersionUID = 1L;
|
||||
public int compare(Date lhs, Date rhs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
expect = [ 'Foo$1', 'Foo' ]
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.6')
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '6')
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
|
||||
def test_in_function_class_declaration(self):
|
||||
"""
|
||||
Test that implementing a class in a function call doesn't confuse SCons.
|
||||
"""
|
||||
|
||||
input = """
|
||||
package com.Matthew;
|
||||
|
||||
public class AnonDemo {
|
||||
|
||||
public static void main(String[] args) {
|
||||
new AnonDemo().execute();
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
Foo bar = new Foo(new Foo() {
|
||||
@Override
|
||||
public int getX() { return this.x; }
|
||||
}) {
|
||||
@Override
|
||||
public int getX() { return this.x; }
|
||||
};
|
||||
}
|
||||
|
||||
public abstract class Foo {
|
||||
public int x;
|
||||
public abstract int getX();
|
||||
|
||||
public Foo(Foo f) {
|
||||
this.x = f.x;
|
||||
}
|
||||
|
||||
public Foo() {}
|
||||
}
|
||||
}
|
||||
"""
|
||||
expect = ['AnonDemo$1',
|
||||
'AnonDemo$2',
|
||||
'AnonDemo$Foo',
|
||||
'AnonDemo']
|
||||
pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.8')
|
||||
assert expect == classes, (expect, classes)
|
||||
|
||||
def test_jdk_globs(self):
|
||||
"""
|
||||
Verify that the java path globs work with specific examples.
|
||||
:return:
|
||||
"""
|
||||
from SCons.Tool.JavaCommon import (
|
||||
java_linux_include_dirs_glob,
|
||||
java_linux_version_include_dirs_glob,
|
||||
java_win32_dir_glob,
|
||||
java_win32_version_dir_glob,
|
||||
java_macos_include_dir_glob,
|
||||
java_macos_version_include_dir_glob,
|
||||
)
|
||||
|
||||
# Test windows globs
|
||||
win_java_dirs = [
|
||||
(r'C:/Program Files/Java/jdk1.8.0_201/bin', '1.8.0'),
|
||||
(r'C:/Program Files/Java/jdk-11.0.2/bin', '11.0.2'),
|
||||
(r'C:/Program Files/AdoptOpenJDK/jdk-16.0.1.9-hotspot/bin', '16.0.1'),
|
||||
(r'C:/Program Files/Microsoft/jdk-17.0.0.35-hotspot/bin', '17.0.0'),
|
||||
(r'C:/Program Files/OpenJDK/openjdk-11.0.13_8/bin', '11.0.13'),
|
||||
(r'C:/Program Files/RedHat/java-1.8.0-openjdk-1.8.0.312-1/bin', '1.8.0'),
|
||||
(r'C:/Program Files/RedHat/java-11-openjdk-11.0.13-1/bin', '11.0.13'),
|
||||
]
|
||||
|
||||
for (wjd, version) in win_java_dirs:
|
||||
if not fnmatch.fnmatch(wjd, java_win32_dir_glob):
|
||||
self.fail(
|
||||
"Didn't properly match %s with pattern %s"
|
||||
% (wjd, java_win32_dir_glob)
|
||||
)
|
||||
if not fnmatch.fnmatch(wjd, java_win32_version_dir_glob % version):
|
||||
self.fail(
|
||||
"Didn't properly match %s with version (%s) specific pattern %s"
|
||||
% (wjd, version, java_win32_version_dir_glob % version)
|
||||
)
|
||||
|
||||
non_win_java_include_dirs = [
|
||||
(
|
||||
'/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.191.b12-0.el7_5.x86_64/include',
|
||||
'1.8.0',
|
||||
),
|
||||
('/usr/lib/jvm/java-1.8.0-openjdk-amd64/include', '1.8.0'),
|
||||
('/usr/lib/jvm/java-8-openjdk-amd64/include', '8'),
|
||||
]
|
||||
|
||||
# Test non-windows/non-macos globs
|
||||
for (wjd, version) in non_win_java_include_dirs:
|
||||
match = False
|
||||
globs_tried = []
|
||||
for jlig in java_linux_include_dirs_glob:
|
||||
globs_tried.append(jlig)
|
||||
|
||||
if fnmatch.fnmatch(wjd, jlig):
|
||||
match = True
|
||||
break
|
||||
|
||||
if not match:
|
||||
self.fail(
|
||||
"Didn't properly match %s with pattern %s" % (wjd, globs_tried)
|
||||
)
|
||||
|
||||
match = False
|
||||
globs_tried = []
|
||||
for jlvig in java_linux_version_include_dirs_glob:
|
||||
globs_tried.append(jlvig % version)
|
||||
if fnmatch.fnmatch(wjd, jlvig % version):
|
||||
match = True
|
||||
break
|
||||
|
||||
if not match:
|
||||
self.fail(
|
||||
"Didn't properly match %s with version (%s) specific pattern %s"
|
||||
% (wjd, version, globs_tried)
|
||||
)
|
||||
|
||||
# Test macos globs
|
||||
# Test windows globs
|
||||
macos_java_dirs = [
|
||||
# ('/System/Library/Frameworks/JavaVM.framework/Headers/', None),
|
||||
(
|
||||
'/System/Library/Frameworks/JavaVM.framework/Versions/11.0.2/Headers/',
|
||||
'11.0.2',
|
||||
),
|
||||
]
|
||||
|
||||
if not fnmatch.fnmatch(
|
||||
'/System/Library/Frameworks/JavaVM.framework/Headers/',
|
||||
java_macos_include_dir_glob,
|
||||
):
|
||||
self.fail(
|
||||
"Didn't properly match %s with pattern %s"
|
||||
% (
|
||||
'/System/Library/Frameworks/JavaVM.framework/Headers/',
|
||||
java_macos_include_dir_glob,
|
||||
)
|
||||
)
|
||||
|
||||
for (wjd, version) in macos_java_dirs:
|
||||
if not fnmatch.fnmatch(wjd, java_macos_version_include_dir_glob % version):
|
||||
self.fail(
|
||||
"Didn't properly match %s with version (%s) specific pattern %s"
|
||||
% (wjd, version, java_macos_version_include_dir_glob % version)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
@ -774,8 +774,6 @@ def tool_list(platform, env):
|
||||
'lex', 'yacc',
|
||||
# Foreign function interface
|
||||
'rpcgen', 'swig',
|
||||
# Java
|
||||
'jar', 'javac', 'javah', 'rmic',
|
||||
# Archivers
|
||||
'tar', 'zip',
|
||||
# File builders (text)
|
||||
|
@ -1,256 +0,0 @@
|
||||
# MIT License
|
||||
#
|
||||
# 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
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# 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.
|
||||
|
||||
"""Tool-specific initialization for jar.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
"""
|
||||
|
||||
import os
|
||||
from typing import List
|
||||
|
||||
import SCons.Node
|
||||
import SCons.Node.FS
|
||||
import SCons.Subst
|
||||
import SCons.Tool
|
||||
import SCons.Util
|
||||
import SCons.Warnings
|
||||
from SCons.Node.FS import _my_normcase
|
||||
from SCons.Tool.JavaCommon import get_java_install_dirs
|
||||
|
||||
|
||||
def jarSources(target, source, env, for_signature) -> List[str]:
|
||||
"""Only include sources that are not a manifest file."""
|
||||
try:
|
||||
env['JARCHDIR']
|
||||
except KeyError:
|
||||
jarchdir_set = False
|
||||
else:
|
||||
jarchdir_set = True
|
||||
jarchdir = env.subst('$JARCHDIR', target=target, source=source)
|
||||
if jarchdir:
|
||||
jarchdir = env.fs.Dir(jarchdir)
|
||||
result = []
|
||||
for src in source:
|
||||
contents = src.get_text_contents()
|
||||
if contents.startswith("Manifest-Version"):
|
||||
continue
|
||||
if jarchdir_set:
|
||||
_chdir = jarchdir
|
||||
else:
|
||||
try:
|
||||
_chdir = src.attributes.java_classdir
|
||||
except AttributeError:
|
||||
_chdir = None
|
||||
if _chdir:
|
||||
# If we are changing the dir with -C, then sources should
|
||||
# be relative to that directory.
|
||||
src = SCons.Subst.Literal(src.get_path(_chdir))
|
||||
result.append('-C')
|
||||
result.append(_chdir)
|
||||
result.append(src)
|
||||
return result
|
||||
|
||||
def jarManifest(target, source, env, for_signature):
|
||||
"""Look in sources for a manifest file, if any."""
|
||||
for src in source:
|
||||
contents = src.get_text_contents()
|
||||
if contents.startswith("Manifest-Version"):
|
||||
return src
|
||||
return ''
|
||||
|
||||
def jarFlags(target, source, env, for_signature) -> str:
|
||||
"""If we have a manifest, make sure that the 'm'
|
||||
flag is specified."""
|
||||
jarflags = env.subst('$JARFLAGS', target=target, source=source)
|
||||
for src in source:
|
||||
contents = src.get_text_contents()
|
||||
if contents.startswith("Manifest-Version"):
|
||||
if 'm' not in jarflags:
|
||||
return jarflags + 'm'
|
||||
break
|
||||
return jarflags
|
||||
|
||||
def Jar(env, target=None, source=[], *args, **kw):
|
||||
"""The Jar Builder.
|
||||
|
||||
This is a pseudo-Builder wrapper around the separate jar builders
|
||||
depending on whether the sources are a file list or a directory.
|
||||
"""
|
||||
# TODO: W1113: Keyword argument before variable positional arguments list in the definition of Jar function
|
||||
# TODO: W0102: Dangerous default value [] as argument
|
||||
|
||||
# jar target should not be a list so assume they passed
|
||||
# no target and want implicit target to be made and the arg
|
||||
# was actaully the list of sources
|
||||
if SCons.Util.is_List(target) and source == []:
|
||||
SCons.Warnings.warn(
|
||||
SCons.Warnings.SConsWarning,
|
||||
"Making implicit target jar file, and treating the list as sources"
|
||||
)
|
||||
source = target
|
||||
target = None
|
||||
|
||||
# mutiple targets passed so build each target the same from the
|
||||
# same source
|
||||
#TODO Maybe this should only be done once, and the result copied
|
||||
# for each target since it should result in the same?
|
||||
if SCons.Util.is_List(target) and SCons.Util.is_List(source):
|
||||
jars = []
|
||||
for single_target in target:
|
||||
jars += env.Jar(target=single_target, source=source, *args, **kw)
|
||||
return jars
|
||||
|
||||
# they passed no target so make a target implicitly
|
||||
if target is None:
|
||||
try:
|
||||
# make target from the first source file
|
||||
target = os.path.splitext(str(source[0]))[0] + env.subst('$JARSUFFIX')
|
||||
except:
|
||||
# TODO: W0702: No exception type(s) specified
|
||||
# something strange is happening but attempt anyways
|
||||
SCons.Warnings.warn(
|
||||
SCons.Warnings.SConsWarning,
|
||||
"Could not make implicit target from sources, using directory"
|
||||
)
|
||||
target = os.path.basename(str(env.Dir('.'))) + env.subst('$JARSUFFIX')
|
||||
|
||||
# make lists out of our target and sources
|
||||
if not SCons.Util.is_List(target):
|
||||
target = [target]
|
||||
if not SCons.Util.is_List(source):
|
||||
source = [source]
|
||||
|
||||
# setup for checking through all the sources and handle accordingly
|
||||
java_class_suffix = env.subst('$JAVACLASSSUFFIX')
|
||||
java_suffix = env.subst('$JAVASUFFIX')
|
||||
target_nodes = []
|
||||
|
||||
# function for determining what to do with a file and not a directory
|
||||
# if its already a class file then it can be used as a
|
||||
# source for jar, otherwise turn it into a class file then
|
||||
# return the source
|
||||
def file_to_class(src):
|
||||
if _my_normcase(str(src)).endswith(java_suffix):
|
||||
return env.JavaClassFile(source=src, *args, **kw)
|
||||
return [env.fs.File(src)]
|
||||
|
||||
# function for calling the JavaClassDir builder if a directory is
|
||||
# passed as a source to Jar builder. The JavaClassDir builder will
|
||||
# return an empty list if there were no target classes built from
|
||||
# the directory, in this case assume the user wanted the directory
|
||||
# copied into the jar as is (it contains other files such as
|
||||
# resources or class files compiled from prior commands)
|
||||
# TODO: investigate the expexcted behavior for directories that
|
||||
# have mixed content, such as Java files along side other files
|
||||
# files.
|
||||
def dir_to_class(src):
|
||||
dir_targets = env.JavaClassDir(source=src, *args, **kw)
|
||||
if dir_targets == []:
|
||||
# no classes files could be built from the source dir
|
||||
# so pass the dir as is.
|
||||
return [env.fs.Dir(src)]
|
||||
return dir_targets
|
||||
|
||||
# loop through the sources and handle each accordingly
|
||||
# the goal here is to get all the source files into a class
|
||||
# file or a directory that contains class files
|
||||
for src in SCons.Util.flatten(source):
|
||||
src = env.subst(src)
|
||||
if isinstance(src, SCons.Node.FS.Base):
|
||||
if isinstance(src, SCons.Node.FS.File):
|
||||
# found a file so make sure its a class file
|
||||
target_nodes.extend(file_to_class(src))
|
||||
else:
|
||||
# found a dir so get the class files out of it
|
||||
target_nodes.extend(dir_to_class(src))
|
||||
else:
|
||||
try:
|
||||
# source is string try to convert it to file
|
||||
target_nodes.extend(file_to_class(env.fs.File(src)))
|
||||
continue
|
||||
except:
|
||||
# TODO: W0702: No exception type(s) specified
|
||||
pass
|
||||
|
||||
try:
|
||||
# source is string try to covnert it to dir
|
||||
target_nodes.extend(dir_to_class(env.fs.Dir(src)))
|
||||
continue
|
||||
except:
|
||||
# TODO: W0702: No exception type(s) specified
|
||||
pass
|
||||
|
||||
SCons.Warnings.warn(
|
||||
SCons.Warnings.SConsWarning,
|
||||
("File: " + str(src)
|
||||
+ " could not be identified as File or Directory, skipping.")
|
||||
)
|
||||
|
||||
# at this point all our sources have been converted to classes or
|
||||
# directories of class so pass it to the Jar builder
|
||||
return env.JarFile(target=target, source=target_nodes, *args, **kw)
|
||||
|
||||
def generate(env) -> None:
|
||||
"""Add Builders and construction variables for jar to an Environment."""
|
||||
SCons.Tool.CreateJarBuilder(env)
|
||||
|
||||
SCons.Tool.CreateJavaFileBuilder(env)
|
||||
SCons.Tool.CreateJavaClassFileBuilder(env)
|
||||
SCons.Tool.CreateJavaClassDirBuilder(env)
|
||||
|
||||
env.AddMethod(Jar)
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
# Ensure that we have a proper path for jar
|
||||
paths = get_java_install_dirs('win32')
|
||||
jar = SCons.Tool.find_program_path(env, 'jar', default_paths=paths)
|
||||
if jar:
|
||||
jar_bin_dir = os.path.dirname(jar)
|
||||
env.AppendENVPath('PATH', jar_bin_dir)
|
||||
|
||||
env['JAR'] = 'jar'
|
||||
env['JARFLAGS'] = SCons.Util.CLVar('cf')
|
||||
env['_JARFLAGS'] = jarFlags
|
||||
env['_JARMANIFEST'] = jarManifest
|
||||
env['_JARSOURCES'] = jarSources
|
||||
env['_JARCOM'] = '$JAR $_JARFLAGS $TARGET $_JARMANIFEST $_JARSOURCES'
|
||||
env['JARCOM'] = "${TEMPFILE('$_JARCOM','$JARCOMSTR')}"
|
||||
env['JARSUFFIX'] = '.jar'
|
||||
|
||||
def exists(env):
|
||||
# As reported by Jan Nijtmans in issue #2730, the simple
|
||||
# return env.Detect('jar')
|
||||
# doesn't always work during initialization. For now, we
|
||||
# stop trying to detect an executable (analogous to the
|
||||
# javac Builder).
|
||||
# TODO: Come up with a proper detect() routine...and enable it.
|
||||
return True
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
@ -1,249 +0,0 @@
|
||||
# MIT License
|
||||
#
|
||||
# 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
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# 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.
|
||||
|
||||
"""SCons.Tool.javac
|
||||
|
||||
Tool-specific initialization for javac.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
import os.path
|
||||
from collections import OrderedDict
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
from SCons.Node.FS import _my_normcase
|
||||
from SCons.Tool.JavaCommon import parse_java_file, get_java_install_dirs, get_java_include_paths
|
||||
import SCons.Util
|
||||
|
||||
def classname(path):
|
||||
"""Turn a string (path name) into a Java class name."""
|
||||
return os.path.normpath(path).replace(os.sep, '.')
|
||||
|
||||
def emit_java_classes(target, source, env):
|
||||
"""Create and return lists of source java files
|
||||
and their corresponding target class files.
|
||||
"""
|
||||
java_suffix = env.get('JAVASUFFIX', '.java')
|
||||
class_suffix = env.get('JAVACLASSSUFFIX', '.class')
|
||||
|
||||
target[0].must_be_same(SCons.Node.FS.Dir)
|
||||
classdir = target[0]
|
||||
|
||||
s = source[0].rentry().disambiguate()
|
||||
if isinstance(s, SCons.Node.FS.File):
|
||||
sourcedir = s.dir.rdir()
|
||||
elif isinstance(s, SCons.Node.FS.Dir):
|
||||
sourcedir = s.rdir()
|
||||
else:
|
||||
raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % s.__class__)
|
||||
|
||||
slist = []
|
||||
js = _my_normcase(java_suffix)
|
||||
for entry in source:
|
||||
entry = entry.rentry().disambiguate()
|
||||
if isinstance(entry, SCons.Node.FS.File):
|
||||
slist.append(entry)
|
||||
elif isinstance(entry, SCons.Node.FS.Dir):
|
||||
result = OrderedDict()
|
||||
dirnode = entry.rdir()
|
||||
def find_java_files(arg, dirpath, filenames):
|
||||
java_files = sorted([n for n in filenames
|
||||
if _my_normcase(n).endswith(js)])
|
||||
mydir = dirnode.Dir(dirpath)
|
||||
java_paths = [mydir.File(f) for f in java_files]
|
||||
for jp in java_paths:
|
||||
arg[jp] = True
|
||||
for dirpath, dirnames, filenames in os.walk(dirnode.get_abspath()):
|
||||
find_java_files(result, dirpath, filenames)
|
||||
entry.walk(find_java_files, result)
|
||||
|
||||
slist.extend(list(result.keys()))
|
||||
else:
|
||||
raise SCons.Errors.UserError("Java source must be File or Dir, not '%s'" % entry.__class__)
|
||||
|
||||
version = env.get('JAVAVERSION', '1.4')
|
||||
full_tlist = []
|
||||
for f in slist:
|
||||
tlist = []
|
||||
source_file_based = True
|
||||
pkg_dir = None
|
||||
if not f.is_derived():
|
||||
pkg_dir, classes = parse_java_file(f.rfile().get_abspath(), version)
|
||||
if classes:
|
||||
source_file_based = False
|
||||
if pkg_dir:
|
||||
d = target[0].Dir(pkg_dir)
|
||||
p = pkg_dir + os.sep
|
||||
else:
|
||||
d = target[0]
|
||||
p = ''
|
||||
for c in classes:
|
||||
t = d.File(c + class_suffix)
|
||||
t.attributes.java_classdir = classdir
|
||||
t.attributes.java_sourcedir = sourcedir
|
||||
t.attributes.java_classname = classname(p + c)
|
||||
tlist.append(t)
|
||||
|
||||
if source_file_based:
|
||||
base = f.name[:-len(java_suffix)]
|
||||
if pkg_dir:
|
||||
t = target[0].Dir(pkg_dir).File(base + class_suffix)
|
||||
else:
|
||||
t = target[0].File(base + class_suffix)
|
||||
t.attributes.java_classdir = classdir
|
||||
t.attributes.java_sourcedir = f.dir
|
||||
t.attributes.java_classname = classname(base)
|
||||
tlist.append(t)
|
||||
|
||||
for t in tlist:
|
||||
t.set_specific_source([f])
|
||||
|
||||
full_tlist.extend(tlist)
|
||||
|
||||
return full_tlist, slist
|
||||
|
||||
JavaAction = SCons.Action.Action('$JAVACCOM', '$JAVACCOMSTR')
|
||||
|
||||
JavaBuilder = SCons.Builder.Builder(action = JavaAction,
|
||||
emitter = emit_java_classes,
|
||||
target_factory = SCons.Node.FS.Entry,
|
||||
source_factory = SCons.Node.FS.Entry)
|
||||
|
||||
class pathopt:
|
||||
"""
|
||||
Callable object for generating javac-style path options from
|
||||
a construction variable (e.g. -classpath, -sourcepath).
|
||||
"""
|
||||
def __init__(self, opt, var, default=None):
|
||||
self.opt = opt
|
||||
self.var = var
|
||||
self.default = default
|
||||
|
||||
def __call__(self, target, source, env, for_signature):
|
||||
path = env[self.var]
|
||||
if path and not SCons.Util.is_List(path):
|
||||
path = [path]
|
||||
if self.default:
|
||||
default = env[self.default]
|
||||
if default:
|
||||
if not SCons.Util.is_List(default):
|
||||
default = [default]
|
||||
path = path + default
|
||||
if path:
|
||||
return [self.opt, os.pathsep.join(map(str, path))]
|
||||
else:
|
||||
return []
|
||||
|
||||
def Java(env, target, source, *args, **kw):
|
||||
"""
|
||||
A pseudo-Builder wrapper around the separate JavaClass{File,Dir}
|
||||
Builders.
|
||||
"""
|
||||
if not SCons.Util.is_List(target):
|
||||
target = [target]
|
||||
if not SCons.Util.is_List(source):
|
||||
source = [source]
|
||||
|
||||
# Pad the target list with repetitions of the last element in the
|
||||
# list so we have a target for every source element.
|
||||
target = target + ([target[-1]] * (len(source) - len(target)))
|
||||
|
||||
java_suffix = env.subst('$JAVASUFFIX')
|
||||
result = []
|
||||
|
||||
for t, s in zip(target, source):
|
||||
if isinstance(s, SCons.Node.FS.Base):
|
||||
if isinstance(s, SCons.Node.FS.File):
|
||||
b = env.JavaClassFile
|
||||
else:
|
||||
b = env.JavaClassDir
|
||||
else:
|
||||
if os.path.isfile(s):
|
||||
b = env.JavaClassFile
|
||||
elif os.path.isdir(s):
|
||||
b = env.JavaClassDir
|
||||
elif s[-len(java_suffix):] == java_suffix:
|
||||
b = env.JavaClassFile
|
||||
else:
|
||||
b = env.JavaClassDir
|
||||
result.extend(b(t, s, *args, **kw))
|
||||
|
||||
return result
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for javac to an Environment."""
|
||||
java_file = SCons.Tool.CreateJavaFileBuilder(env)
|
||||
java_class = SCons.Tool.CreateJavaClassFileBuilder(env)
|
||||
java_class_dir = SCons.Tool.CreateJavaClassDirBuilder(env)
|
||||
java_class.add_emitter(None, emit_java_classes)
|
||||
java_class.add_emitter(env.subst('$JAVASUFFIX'), emit_java_classes)
|
||||
java_class_dir.emitter = emit_java_classes
|
||||
|
||||
env.AddMethod(Java)
|
||||
|
||||
version = env.get('JAVAVERSION', None)
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
# Ensure that we have a proper path for javac
|
||||
paths = get_java_install_dirs('win32', version=version)
|
||||
javac = SCons.Tool.find_program_path(env, 'javac', default_paths=paths)
|
||||
if javac:
|
||||
javac_bin_dir = os.path.dirname(javac)
|
||||
env.AppendENVPath('PATH', javac_bin_dir)
|
||||
else:
|
||||
javac = SCons.Tool.find_program_path(env, 'javac')
|
||||
|
||||
|
||||
env.SetDefault(
|
||||
JAVAC='javac',
|
||||
JAVACFLAGS=SCons.Util.CLVar(''),
|
||||
JAVAINCLUDES=get_java_include_paths(env, javac, version),
|
||||
JAVACLASSSUFFIX='.class',
|
||||
JAVASUFFIX='.java',
|
||||
JAVABOOTCLASSPATH=[],
|
||||
JAVACLASSPATH=[],
|
||||
JAVASOURCEPATH=[],
|
||||
)
|
||||
env['_javapathopt'] = pathopt
|
||||
env['_JAVABOOTCLASSPATH'] = '${_javapathopt("-bootclasspath", "JAVABOOTCLASSPATH")} '
|
||||
env['_JAVACLASSPATH'] = '${_javapathopt("-classpath", "JAVACLASSPATH")} '
|
||||
env['_JAVASOURCEPATH'] = '${_javapathopt("-sourcepath", "JAVASOURCEPATH", "_JAVASOURCEPATHDEFAULT")} '
|
||||
env['_JAVASOURCEPATHDEFAULT'] = '${TARGET.attributes.java_sourcedir}'
|
||||
env['_JAVACCOM'] = '$JAVAC $JAVACFLAGS $_JAVABOOTCLASSPATH $_JAVACLASSPATH -d ${TARGET.attributes.java_classdir} $_JAVASOURCEPATH $SOURCES'
|
||||
env['JAVACCOM'] = "${TEMPFILE('$_JAVACCOM','$JAVACCOMSTR')}"
|
||||
|
||||
def exists(env):
|
||||
return 1
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
@ -1,102 +0,0 @@
|
||||
#
|
||||
# __COPYRIGHT__
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# 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.
|
||||
#
|
||||
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import SCons.Tool.javac
|
||||
|
||||
class DummyNode:
|
||||
def __init__(self, val):
|
||||
self.val = val
|
||||
|
||||
def __str__(self):
|
||||
return str(self.val)
|
||||
|
||||
class pathoptTestCase(unittest.TestCase):
|
||||
def assert_pathopt(self, expect, path):
|
||||
popt = SCons.Tool.javac.pathopt('-foopath', 'FOOPATH')
|
||||
env = {'FOOPATH': path}
|
||||
actual = popt(None, None, env, None)
|
||||
self.assertEqual(expect, actual)
|
||||
|
||||
def assert_pathopt_default(self, expect, path, default):
|
||||
popt = SCons.Tool.javac.pathopt('-foopath', 'FOOPATH', default='DPATH')
|
||||
env = {'FOOPATH': path,
|
||||
'DPATH': default}
|
||||
actual = popt(None, None, env, None)
|
||||
self.assertEqual(expect, actual)
|
||||
|
||||
def test_unset(self):
|
||||
self.assert_pathopt([], None)
|
||||
self.assert_pathopt([], '')
|
||||
|
||||
def test_str(self):
|
||||
self.assert_pathopt(['-foopath', '/foo/bar'],
|
||||
'/foo/bar')
|
||||
|
||||
def test_list_str(self):
|
||||
self.assert_pathopt(['-foopath', '/foo%s/bar' % os.pathsep],
|
||||
['/foo', '/bar'])
|
||||
|
||||
def test_uses_pathsep(self):
|
||||
save = os.pathsep
|
||||
try:
|
||||
os.pathsep = '!'
|
||||
self.assert_pathopt(['-foopath', 'foo!bar'],
|
||||
['foo', 'bar'])
|
||||
finally:
|
||||
os.pathsep = save
|
||||
|
||||
def test_node(self):
|
||||
self.assert_pathopt(['-foopath', '/foo'],
|
||||
DummyNode('/foo'))
|
||||
|
||||
def test_list_node(self):
|
||||
self.assert_pathopt(['-foopath', os.pathsep.join(['/foo','/bar'])],
|
||||
['/foo', DummyNode('/bar')])
|
||||
|
||||
def test_default_str(self):
|
||||
self.assert_pathopt_default(
|
||||
['-foopath', os.pathsep.join(['/foo','/bar','/baz'])],
|
||||
['/foo', '/bar'],
|
||||
'/baz')
|
||||
|
||||
def test_default_list(self):
|
||||
self.assert_pathopt_default(
|
||||
['-foopath', os.pathsep.join(['/foo','/bar','/baz'])],
|
||||
['/foo', '/bar'],
|
||||
['/baz'])
|
||||
|
||||
def test_default_unset(self):
|
||||
self.assert_pathopt_default(
|
||||
['-foopath', '/foo'],
|
||||
'/foo',
|
||||
None)
|
||||
self.assert_pathopt_default(
|
||||
['-foopath', '/foo'],
|
||||
'/foo',
|
||||
'')
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
@ -1,148 +0,0 @@
|
||||
# MIT License
|
||||
#
|
||||
# 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
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# 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.
|
||||
"""SCons.Tool.javah
|
||||
|
||||
Tool-specific initialization for javah.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
import os.path
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Node.FS
|
||||
import SCons.Tool.javac
|
||||
import SCons.Util
|
||||
from SCons.Tool.JavaCommon import get_java_install_dirs
|
||||
|
||||
|
||||
def emit_java_headers(target, source, env):
|
||||
"""Create and return lists of Java stub header files that will
|
||||
be created from a set of class files.
|
||||
"""
|
||||
class_suffix = env.get('JAVACLASSSUFFIX', '.class')
|
||||
classdir = env.get('JAVACLASSDIR')
|
||||
|
||||
if not classdir:
|
||||
try:
|
||||
s = source[0]
|
||||
except IndexError:
|
||||
classdir = '.'
|
||||
else:
|
||||
try:
|
||||
classdir = s.attributes.java_classdir
|
||||
except AttributeError:
|
||||
classdir = '.'
|
||||
classdir = env.Dir(classdir).rdir()
|
||||
|
||||
if str(classdir) == '.':
|
||||
c_ = None
|
||||
else:
|
||||
c_ = str(classdir) + os.sep
|
||||
|
||||
slist = []
|
||||
for src in source:
|
||||
try:
|
||||
classname = src.attributes.java_classname
|
||||
except AttributeError:
|
||||
classname = str(src)
|
||||
if c_ and classname[:len(c_)] == c_:
|
||||
classname = classname[len(c_):]
|
||||
if class_suffix and classname[-len(class_suffix):] == class_suffix:
|
||||
classname = classname[:-len(class_suffix)]
|
||||
classname = SCons.Tool.javac.classname(classname)
|
||||
s = src.rfile()
|
||||
s.attributes.java_classname = classname
|
||||
slist.append(s)
|
||||
|
||||
s = source[0].rfile()
|
||||
if not hasattr(s.attributes, 'java_classdir'):
|
||||
s.attributes.java_classdir = classdir
|
||||
|
||||
if target[0].__class__ is SCons.Node.FS.File:
|
||||
tlist = target
|
||||
else:
|
||||
if not isinstance(target[0], SCons.Node.FS.Dir):
|
||||
target[0].__class__ = SCons.Node.FS.Dir
|
||||
target[0]._morph()
|
||||
tlist = []
|
||||
for s in source:
|
||||
fname = s.attributes.java_classname.replace('.', '_') + '.h'
|
||||
t = target[0].File(fname)
|
||||
t.attributes.java_lookupdir = target[0]
|
||||
tlist.append(t)
|
||||
|
||||
return tlist, source
|
||||
|
||||
def JavaHOutFlagGenerator(target, source, env, for_signature):
|
||||
try:
|
||||
t = target[0]
|
||||
except (AttributeError, IndexError, TypeError):
|
||||
t = target
|
||||
try:
|
||||
return '-d ' + str(t.attributes.java_lookupdir)
|
||||
except AttributeError:
|
||||
return '-o ' + str(t)
|
||||
|
||||
def getJavaHClassPath(env,target, source, for_signature):
|
||||
path = "${SOURCE.attributes.java_classdir}"
|
||||
if 'JAVACLASSPATH' in env and env['JAVACLASSPATH']:
|
||||
path = SCons.Util.AppendPath(path, env['JAVACLASSPATH'])
|
||||
return "-classpath %s" % path
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for javah to an Environment."""
|
||||
java_javah = SCons.Tool.CreateJavaHBuilder(env)
|
||||
java_javah.emitter = emit_java_headers
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
# Ensure that we have a proper path for javah
|
||||
paths = get_java_install_dirs('win32')
|
||||
javah = SCons.Tool.find_program_path(env, 'javah', default_paths=paths)
|
||||
if javah:
|
||||
javah_bin_dir = os.path.dirname(javah)
|
||||
env.AppendENVPath('PATH', javah_bin_dir)
|
||||
|
||||
env.SetDefault(
|
||||
JAVAH='javah',
|
||||
JAVAHFLAGS=SCons.Util.CLVar(''),
|
||||
JAVACLASSSUFFIX='.class',
|
||||
JAVASUFFIX='.java',
|
||||
)
|
||||
env['_JAVAHOUTFLAG'] = JavaHOutFlagGenerator
|
||||
env['_JAVAHCLASSPATH'] = getJavaHClassPath
|
||||
env['JAVAHCOM'] = '$JAVAH $JAVAHFLAGS $_JAVAHOUTFLAG $_JAVAHCLASSPATH ${SOURCES.attributes.java_classname}'
|
||||
|
||||
def exists(env):
|
||||
return env.Detect('javah')
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
@ -1,139 +0,0 @@
|
||||
"""SCons.Tool.rmic
|
||||
|
||||
Tool-specific initialization for rmic.
|
||||
|
||||
There normally shouldn't be any need to import this module directly.
|
||||
It will usually be imported through the generic SCons.Tool.Tool()
|
||||
selection method.
|
||||
|
||||
"""
|
||||
|
||||
#
|
||||
# __COPYRIGHT__
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining
|
||||
# a copy of this software and associated documentation files (the
|
||||
# "Software"), to deal in the Software without restriction, including
|
||||
# without limitation the rights to use, copy, modify, merge, publish,
|
||||
# distribute, sublicense, and/or sell copies of the Software, and to
|
||||
# permit persons to whom the Software is furnished to do so, subject to
|
||||
# the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included
|
||||
# in all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
|
||||
# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||||
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
# 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__"
|
||||
|
||||
import os.path
|
||||
|
||||
import SCons.Action
|
||||
import SCons.Builder
|
||||
import SCons.Node.FS
|
||||
import SCons.Util
|
||||
|
||||
from SCons.Tool.JavaCommon import get_java_install_dirs
|
||||
|
||||
|
||||
def emit_rmic_classes(target, source, env):
|
||||
"""Create and return lists of Java RMI stub and skeleton
|
||||
class files to be created from a set of class files.
|
||||
"""
|
||||
class_suffix = env.get('JAVACLASSSUFFIX', '.class')
|
||||
classdir = env.get('JAVACLASSDIR')
|
||||
|
||||
if not classdir:
|
||||
try:
|
||||
s = source[0]
|
||||
except IndexError:
|
||||
classdir = '.'
|
||||
else:
|
||||
try:
|
||||
classdir = s.attributes.java_classdir
|
||||
except AttributeError:
|
||||
classdir = '.'
|
||||
classdir = env.Dir(classdir).rdir()
|
||||
if str(classdir) == '.':
|
||||
c_ = None
|
||||
else:
|
||||
c_ = str(classdir) + os.sep
|
||||
|
||||
slist = []
|
||||
for src in source:
|
||||
try:
|
||||
classname = src.attributes.java_classname
|
||||
except AttributeError:
|
||||
classname = str(src)
|
||||
if c_ and classname[:len(c_)] == c_:
|
||||
classname = classname[len(c_):]
|
||||
if class_suffix and classname[:-len(class_suffix)] == class_suffix:
|
||||
classname = classname[-len(class_suffix):]
|
||||
s = src.rfile()
|
||||
s.attributes.java_classdir = classdir
|
||||
s.attributes.java_classname = classname
|
||||
slist.append(s)
|
||||
|
||||
stub_suffixes = ['_Stub']
|
||||
if env.get('JAVAVERSION') == '1.4':
|
||||
stub_suffixes.append('_Skel')
|
||||
|
||||
tlist = []
|
||||
for s in source:
|
||||
for suff in stub_suffixes:
|
||||
fname = s.attributes.java_classname.replace('.', os.sep) + \
|
||||
suff + class_suffix
|
||||
t = target[0].File(fname)
|
||||
t.attributes.java_lookupdir = target[0]
|
||||
tlist.append(t)
|
||||
|
||||
return tlist, source
|
||||
|
||||
RMICAction = SCons.Action.Action('$RMICCOM', '$RMICCOMSTR')
|
||||
|
||||
RMICBuilder = SCons.Builder.Builder(action = RMICAction,
|
||||
emitter = emit_rmic_classes,
|
||||
src_suffix = '$JAVACLASSSUFFIX',
|
||||
target_factory = SCons.Node.FS.Dir,
|
||||
source_factory = SCons.Node.FS.File)
|
||||
|
||||
def generate(env):
|
||||
"""Add Builders and construction variables for rmic to an Environment."""
|
||||
env['BUILDERS']['RMIC'] = RMICBuilder
|
||||
|
||||
if env['PLATFORM'] == 'win32':
|
||||
version = env.get('JAVAVERSION', None)
|
||||
# Ensure that we have a proper path for rmic
|
||||
paths = get_java_install_dirs('win32', version=version)
|
||||
rmic = SCons.Tool.find_program_path(env, 'rmic', default_paths=paths)
|
||||
# print("RMIC: %s"%rmic)
|
||||
if rmic:
|
||||
rmic_bin_dir = os.path.dirname(rmic)
|
||||
env.AppendENVPath('PATH', rmic_bin_dir)
|
||||
|
||||
env['RMIC'] = 'rmic'
|
||||
env['RMICFLAGS'] = SCons.Util.CLVar('')
|
||||
env['RMICCOM'] = '$RMIC $RMICFLAGS -d ${TARGET.attributes.java_lookupdir} -classpath ${SOURCE.attributes.java_classdir} ${SOURCES.attributes.java_classname}'
|
||||
env['JAVACLASSSUFFIX'] = '.class'
|
||||
|
||||
def exists(env):
|
||||
# As reported by Jan Nijtmans in issue #2730, the simple
|
||||
# return env.Detect('rmic')
|
||||
# doesn't always work during initialization. For now, we
|
||||
# stop trying to detect an executable (analogous to the
|
||||
# javac Builder).
|
||||
# TODO: Come up with a proper detect() routine...and enable it.
|
||||
return 1
|
||||
|
||||
# Local Variables:
|
||||
# tab-width:4
|
||||
# indent-tabs-mode:nil
|
||||
# End:
|
||||
# vim: set expandtab tabstop=4 shiftwidth=4:
|
Loading…
Reference in New Issue
Block a user