Mercurial > hg > truffle
diff mxtool/mx.py @ 14763:a6c1c3eb20c4
transition to JDK8
- introduce support for more than one JDK in mx
- update version in annotiationprocessors
- update project definitions (truffle api is not part of the transition)
- fix style errors
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 26 Mar 2014 14:34:08 +0100 |
parents | 65b005b58825 |
children | 5823c399e28f |
line wrap: on
line diff
--- a/mxtool/mx.py Wed Mar 26 14:32:50 2014 +0100 +++ b/mxtool/mx.py Wed Mar 26 14:34:08 2014 +0100 @@ -54,7 +54,7 @@ _primary_suite_path = None _primary_suite = None _opts = None -_java = None +_java_homes = None _warn = False """ @@ -117,6 +117,13 @@ self.workingSets = workingSets self.dir = d + # Verify that a JDK exists for this project if its compliance level is + # less than the compliance level of the default JDK + jdk = java(self.javaCompliance) + if jdk is None and self.javaCompliance < java().javaCompliance: + abort('Cannot find ' + str(self.javaCompliance) + ' JDK required by ' + name + '. ' + + 'Specify it with --extra-java-homes option or EXTRA_JAVA_HOMES environment variable.') + # Create directories for projects that don't yet exist if not exists(d): os.mkdir(d) @@ -1036,7 +1043,8 @@ self.add_argument('--Jp', action='append', dest='java_args_pfx', help='prefix Java VM arguments (e.g. --Jp @-dsa)', metavar='@<args>', default=[]) self.add_argument('--Ja', action='append', dest='java_args_sfx', help='suffix Java VM arguments (e.g. --Ja @-dsa)', metavar='@<args>', default=[]) self.add_argument('--user-home', help='users home directory', metavar='<path>', default=os.path.expanduser('~')) - self.add_argument('--java-home', help='bootstrap JDK installation directory (must be JDK 6 or later)', metavar='<path>') + self.add_argument('--java-home', help='primary JDK directory (must be JDK 7 or later)', metavar='<path>') + self.add_argument('--extra-java-homes', help='secondary JDK directories separated by "' + os.pathsep + '"', metavar='<path>') self.add_argument('--ignore-project', action='append', dest='ignored_projects', help='name of project to ignore', metavar='<name>', default=[]) self.add_argument('--kill-with-sigquit', action='store_true', dest='killwithsigquit', help='send sigquit first before killing child processes') if get_os() != 'windows': @@ -1061,6 +1069,8 @@ if opts.java_home is None: opts.java_home = os.environ.get('JAVA_HOME') + if opts.extra_java_homes is None: + opts.extra_java_homes = os.environ.get('EXTRA_JAVA_HOMES') if opts.java_home is None or opts.java_home == '': opts.java_home = _handle_missing_java_home() @@ -1089,12 +1099,21 @@ msg += ' {0:<20} {1}\n'.format(cmd, doc.split('\n', 1)[0]) return msg + '\n' -def java(): +def java(requiredCompliance=None): """ Get a JavaConfig object containing Java commands launch details. + If requiredCompliance is None, the compliance level specified by --java-home/JAVA_HOME + is returned. Otherwise, the JavaConfig exactly matching requiredCompliance is returned + or None if there is no exact match. """ - assert _java is not None - return _java + assert _java_homes + if not requiredCompliance: + return _java_homes[0] + for java in _java_homes: + if java.javaCompliance == requiredCompliance: + return java + return None + def run_java(args, nonZeroIsFatal=True, out=None, err=None, cwd=None, addDefaultArgs=True): return run(java().format_cmd(args, addDefaultArgs), nonZeroIsFatal=nonZeroIsFatal, out=out, err=err, cwd=cwd) @@ -1350,9 +1369,9 @@ A JavaConfig object encapsulates info on how Java commands are run. """ class JavaConfig: - def __init__(self, opts): - self.jdk = opts.java_home - self.debug_port = opts.java_dbg_port + def __init__(self, java_home, java_dbg_port): + self.jdk = java_home + self.debug_port = java_dbg_port self.jar = exe_suffix(join(self.jdk, 'bin', 'jar')) self.java = exe_suffix(join(self.jdk, 'bin', 'java')) self.javac = exe_suffix(join(self.jdk, 'bin', 'javac')) @@ -1361,7 +1380,7 @@ self._bootclasspath = None if not exists(self.java): - abort('Java launcher derived from JAVA_HOME does not exist: ' + self.java) + abort('Java launcher does not exist: ' + self.java) def delAtAndSplit(s): return shlex.split(s.lstrip('@')) @@ -1389,6 +1408,14 @@ if self.debug_port is not None: self.java_args += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(self.debug_port)] + def __hash__(self): + return hash(self.jdk) + + def __cmp__(self, other): + if isinstance(other, JavaConfig): + return cmp(self.javaCompliance, other.javaCompliance) + raise TypeError() + def format_cmd(self, args, addDefaultArgs): if addDefaultArgs: return [self.java] + self.processArgs(args) @@ -1624,14 +1651,12 @@ if not suppliedParser: parser = ArgumentParser(prog='mx build') - javaCompliance = java().javaCompliance - defaultEcjPath = get_env('JDT', join(_primary_suite.mxDir, 'ecj.jar')) parser = parser if parser is not None else ArgumentParser(prog='mx build') parser.add_argument('-f', action='store_true', dest='force', help='force build (disables timestamp checking)') parser.add_argument('-c', action='store_true', dest='clean', help='removes existing build output') - parser.add_argument('--source', dest='compliance', help='Java compliance level for projects without an explicit one', default=str(javaCompliance)) + parser.add_argument('--source', dest='compliance', help='Java compliance level for projects without an explicit one') parser.add_argument('--Wapi', action='store_true', dest='warnAPI', help='show warnings about using internal APIs') parser.add_argument('--projects', action='store', help='comma separated projects to build (omit to build all projects)') parser.add_argument('--only', action='store', help='comma separated projects to build, without checking their dependencies (omit to build all projects)') @@ -1710,9 +1735,12 @@ continue # skip building this Java project if its Java compliance level is "higher" than the configured JDK - if javaCompliance < p.javaCompliance: - log('Excluding {0} from build (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) + requiredCompliance = p.javaCompliance if p.javaCompliance else JavaCompliance(args.compliance) if args.compliance else None + jdk = java(requiredCompliance) + if not jdk: + log('Excluding {0} from build (Java compliance level {1} required)'.format(p.name, requiredCompliance)) continue + compliance = str(jdk.javaCompliance) outputDir = prepareOutputDirs(p, args.clean) @@ -1817,14 +1845,11 @@ toBeDeleted = [argfileName] try: - compliance = str(p.javaCompliance) if p.javaCompliance is not None else args.compliance if jdtJar is None: log('Compiling Java sources for {0} with javac...'.format(p.name)) - - - javacCmd = [java().javac, '-g', '-J-Xmx1g', '-source', compliance, '-target', compliance, '-classpath', cp, '-d', outputDir] - if java().debug_port is not None: - javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] + javacCmd = [jdk.javac, '-g', '-J-Xmx1g', '-source', compliance, '-target', compliance, '-classpath', cp, '-d', outputDir] + if jdk.debug_port is not None: + javacCmd += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(jdk.debug_port)] javacCmd += processorArgs javacCmd += ['@' + argfile.name] @@ -1834,9 +1859,9 @@ else: log('Compiling Java sources for {0} with JDT...'.format(p.name)) - jdtArgs = [java().java, '-Xmx1g'] - if java().debug_port is not None: - jdtArgs += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] + jdtArgs = [jdk.java, '-Xmx1g'] + if jdk.debug_port is not None: + jdtArgs += ['-Xdebug', '-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(jdk.debug_port)] jdtArgs += ['-jar', jdtJar, '-' + compliance, @@ -1912,13 +1937,14 @@ projects = [project(name) for name in args.projects.split(',')] class Batch: - def __init__(self, settingsFile): + def __init__(self, settingsFile, javaCompliance): self.path = settingsFile + self.javaCompliance = javaCompliance self.javafiles = list() def settings(self): with open(self.path) as fp: - return fp.read() + return fp.read() + java(self.javaCompliance).java class FileInfo: def __init__(self, path): @@ -1943,7 +1969,7 @@ continue sourceDirs = p.source_dirs() - batch = Batch(join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs')) + batch = Batch(join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs'), p.javaCompliance) if not exists(batch.path): if _opts.verbose: @@ -1962,8 +1988,15 @@ if res is not batch: res.javafiles = res.javafiles + batch.javafiles + print "we have: " + str(len(batches)) + " batches" for batch in batches.itervalues(): - run([args.eclipse_exe, '-nosplash', '-application', 'org.eclipse.jdt.core.JavaCodeFormatter', '-config', batch.path] + [f.path for f in batch.javafiles]) + run([args.eclipse_exe, + '-nosplash', + '-application', + 'org.eclipse.jdt.core.JavaCodeFormatter', + '-vm', java(batch.javaCompliance).java, + '-config', batch.path] + + [f.path for f in batch.javafiles]) for fi in batch.javafiles: if fi.update(): modified.append(fi) @@ -2115,7 +2148,8 @@ else: p = dep # skip a Java project if its Java compliance level is "higher" than the configured JDK - if java().javaCompliance < p.javaCompliance: + jdk = java(p.javaCompliance) + if not jdk: log('Excluding {0} from {2} (Java compliance level {1} required)'.format(p.name, p.javaCompliance, d.path)) continue @@ -2296,7 +2330,8 @@ abort('ERROR: .checkstyle for Project {0} is missing'.format(p.name)) # skip checking this Java project if its Java compliance level is "higher" than the configured JDK - if java().javaCompliance < p.javaCompliance: + jdk = java(p.javaCompliance) + if not jdk: log('Excluding {0} from checking (Java compliance level {1} required)'.format(p.name, p.javaCompliance)) continue @@ -2720,6 +2755,10 @@ if p.native: continue + if not java(p.javaCompliance): + log('Excluding {0} (JDK with compliance level {1} not available)'.format(p.name, p.javaCompliance)) + continue + if not exists(p.dir): os.makedirs(p.dir) @@ -2964,7 +3003,7 @@ launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': consoleOn}) launchOut.open('mapAttribute', {'key' : 'org.eclipse.debug.core.environmentVariables'}) - launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 'value' : java().jdk}) + launchOut.element('mapEntry', {'key' : 'JAVA_HOME', 'value' : java(p.javaCompliance).jdk}) launchOut.close('mapAttribute') if refresh: @@ -3211,6 +3250,7 @@ updated = False files = [] libFiles = [] + jdks = set() for p in suite.projects: if p.native: continue @@ -3221,13 +3261,21 @@ if not exists(join(p.dir, 'nbproject')): os.makedirs(join(p.dir, 'nbproject')) + jdk = java(p.javaCompliance) + + if not jdk: + log('Excluding {0} (JDK with compliance level {1} not available)'.format(p.name, p.javaCompliance)) + continue + + jdks.add(jdk) + out = XMLDoc() out.open('project', {'name' : p.name, 'default' : 'default', 'basedir' : '.'}) out.element('description', data='Builds, tests, and runs the project ' + p.name + '.') out.element('import', {'file' : 'nbproject/build-impl.xml'}) out.open('target', {'name' : '-post-compile'}) out.open('exec', {'executable' : sys.executable}) - out.element('env', {'key' : 'JAVA_HOME', 'value' : java().jdk}) + out.element('env', {'key' : 'JAVA_HOME', 'value' : jdk.jdk}) out.element('arg', {'value' : os.path.abspath(__file__)}) out.element('arg', {'value' : 'archive'}) out.element('arg', {'value' : '@GRAAL'}) @@ -3282,7 +3330,7 @@ files.append(join(p.dir, 'nbproject', 'project.xml')) out = StringIO.StringIO() - jdkPlatform = 'JDK_' + str(java().version) + jdkPlatform = 'JDK_' + str(jdk.version) annotationProcessorEnabled = "false" annotationProcessorReferences = "" @@ -3345,7 +3393,7 @@ manifest.file=manifest.mf meta.inf.dir=${src.dir}/META-INF mkdist.disabled=false -platforms.""" + jdkPlatform + """.home=""" + java().jdk + """ +platforms.""" + jdkPlatform + """.home=""" + jdk.jdk + """ platform.active=""" + jdkPlatform + """ run.classpath=\\ ${javac.classpath}:\\ @@ -3425,7 +3473,9 @@ if updated: log('If using NetBeans:') - log(' 1. Ensure that a platform named "JDK_' + str(java().version) + '" is defined (Tools -> Java Platforms)') + log(' 1. Ensure that the following platform(s) are defined (Tools -> Java Platforms):') + for jdk in jdks: + log(' JDK_' + str(jdk.version)) log(' 2. Open/create a Project Group for the directory containing the projects (File -> Project Group -> New Group... -> Folder of Projects)') _zip_files(files, suite.dir, configZip.path) @@ -3596,7 +3646,7 @@ windowTitle = ['-windowtitle', p.name + ' javadoc'] try: log('Generating {2} for {0} in {1}'.format(p.name, out, docDir)) - run([java().javadoc, memory, + run([java(p.javaCompliance).javadoc, memory, '-XDignore.symbol.file', '-classpath', cp, '-quiet', @@ -3625,7 +3675,7 @@ sp += p.source_dirs() names.append(p.name) - links = ['-link', 'http://docs.oracle.com/javase/' + str(_java.javaCompliance.value) + '/docs/api/'] + links = ['-link', 'http://docs.oracle.com/javase/' + str(java().javaCompliance.value) + '/docs/api/'] out = join(_primary_suite.dir, docDir) if args.base is not None: out = join(args.base, docDir) @@ -4105,9 +4155,16 @@ opts, commandAndArgs = _argParser._parse_cmd_line() - global _opts, _java + global _opts, _java_homes _opts = opts - _java = JavaConfig(opts) + defaultJdk = JavaConfig(opts.java_home, opts.java_dbg_port) + _java_homes = [defaultJdk] + if opts.extra_java_homes: + for java_home in opts.extra_java_homes.split(os.pathsep): + extraJdk = JavaConfig(java_home, opts.java_dbg_port) + if extraJdk > defaultJdk: + abort('Secondary JDK ' + extraJdk.jdk + ' has higher compliance level than default JDK ' + defaultJdk.jdk) + _java_homes.append(extraJdk) for s in suites(): s._post_init(opts)