Mercurial > hg > graal-compiler
diff mxtool/mx.py @ 7313:570d8e4c6dfb
Merge.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Mon, 07 Jan 2013 13:04:04 +0100 |
parents | 57edf6b07d36 |
children | 442668d41bc2 |
line wrap: on
line diff
--- a/mxtool/mx.py Fri Dec 21 15:54:59 2012 +0100 +++ b/mxtool/mx.py Mon Jan 07 13:04:04 2013 +0100 @@ -188,14 +188,17 @@ if not exists(s): os.mkdir(s) - def all_deps(self, deps, includeLibs, includeSelf=True): + def all_deps(self, deps, includeLibs, includeSelf=True, includeAnnotationProcessors=False): """ Add the transitive set of dependencies for this project, including libraries if 'includeLibs' is true, to the 'deps' list. """ + childDeps = list(self.deps) + if includeAnnotationProcessors and hasattr(self, 'annotationProcessors') and len(self.annotationProcessors) > 0: + childDeps = self.annotationProcessors + childDeps if self in deps: return deps - for name in self.deps: + for name in childDeps: assert name != self.name dep = _libs.get(name, None) if dep is not None: @@ -208,7 +211,7 @@ abort('project named ' + name + ' required by ' + self.name + ' is ignored') abort('dependency named ' + name + ' required by ' + self.name + ' is not found') if not dep in deps: - dep.all_deps(deps, includeLibs) + dep.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) if not self in deps and includeSelf: deps.append(self) return deps @@ -464,7 +467,7 @@ srcDirs = pop_list(attrs, 'sourceDirs') deps = pop_list(attrs, 'dependencies') ap = pop_list(attrs, 'annotationProcessors') - deps += ap + #deps += ap javaCompliance = attrs.pop('javaCompliance', None) subDir = attrs.pop('subDir', None); if subDir is None: @@ -478,9 +481,6 @@ abort('javaCompliance property required for non-native project ' + name) if len(ap) > 0: p.annotationProcessors = ap - apc = pop_list(attrs, 'annotationProcessorClasses') - if len(apc) > 0: - p.annotationProcessorClasses = apc p.__dict__.update(attrs) self.projects.append(p) @@ -729,7 +729,7 @@ entryPath = zi.filename yield zf, entryPath -def sorted_deps(projectNames=None, includeLibs=False): +def sorted_deps(projectNames=None, includeLibs=False, includeAnnotationProcessors=False): """ Gets projects and libraries sorted such that dependencies are before the projects that depend on them. Unless 'includeLibs' is @@ -742,7 +742,7 @@ projects = [project(name) for name in projectNames] for p in projects: - p.all_deps(deps, includeLibs) + p.all_deps(deps, includeLibs=includeLibs, includeAnnotationProcessors=includeAnnotationProcessors) return deps class ArgParser(ArgumentParser): @@ -1296,7 +1296,7 @@ if args.only is not None: sortedProjects = [project(name) for name in args.only.split(',')] else: - sortedProjects = sorted_deps(projects) + sortedProjects = sorted_deps(projects, includeAnnotationProcessors=True) for p in sortedProjects: if p.native: @@ -1380,7 +1380,9 @@ log('could not file .class directive in Jasmin source: ' + src) else: dst = join(outputDir, src[len(sourceDir) + 1:]) - if exists(dirname(dst)) and (not exists(dst) or os.path.getmtime(dst) != os.path.getmtime(src)): + if not exists(dirname(dst)): + os.makedirs(dirname(dst)) + if exists(dirname(dst)) and (not exists(dst) or os.path.getmtime(dst) < os.path.getmtime(src)): shutil.copyfile(src, dst) if not mustBuild: @@ -1410,18 +1412,12 @@ javacArgs += ['-J-Xdebug', '-J-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=' + str(java().debug_port)] if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: - annotationProcessors = [] - for apProject in p.annotationProcessors: - apClasses = project(apProject).annotationProcessorClasses - if len(apClasses) == 0: - abort("Project " + p + " specifies " + apProject + " as an annotation processor but " + apProject + " does not specifiy any annotation processor class") - annotationProcessors += apClasses - + processorPath = classpath(p.annotationProcessors, resolve=True) genDir = p.source_gen_dir(); if exists(genDir): shutil.rmtree(genDir) os.mkdir(genDir) - javacArgs += ['-processor', ",".join(annotationProcessors), "-s", genDir] + javacArgs += ['-processorpath', join(processorPath), '-s', genDir] else: javacArgs += ['-proc:none'] @@ -1442,7 +1438,7 @@ jdtProperties = join(p.dir, '.settings', 'org.eclipse.jdt.core.prefs') if not exists(jdtProperties): # Try to fix a missing properties file by running eclipseinit - eclipseinit([]) + eclipseinit([], buildProcessorJars=False) if not exists(jdtProperties): log('JDT properties file {0} not found'.format(jdtProperties)) else: @@ -1467,37 +1463,61 @@ return args return None -def processorjars(args): - hasProcessorJars = [] +def processorjars(): + projects = set([]) for p in sorted_deps(): - if hasattr(p, 'annotationProcessorClasses') and len(p.annotationProcessorClasses) > 0: - hasProcessorJars.append(p) + if _needsEclipseJarBuild(p): + projects.add(p) - if len(hasProcessorJars) <= 0: + if len(projects) <= 0: return - build(['--projects', ",".join(map(lambda p: p.name, hasProcessorJars))]) - - for p in hasProcessorJars: - spDir = join(p.output_dir(), 'META-INF', 'services') - if not exists(spDir): - os.makedirs(spDir) - spFile = join(spDir, 'javax.annotation.processing.Processor') - with open(spFile, 'w') as fp: - fp.writelines(p.annotationProcessorClasses) - created = False - for dep in p.all_deps([], False): - if created: - cmd = 'uf' - else: - cmd = 'cf' - created = True - jarCmd = [java().jar, cmd, join(p.dir, p.name + 'AnnotationProcessor.jar'), '-C', dep.output_dir(), '.'] - subprocess.check_call(jarCmd) - log('added ' + dep.name + ' to ' + p.name + '.jar'); + build(['--projects', ",".join(map(lambda p: p.name, projects))]) + + for p in projects: + targetJar = join(p.dir, p.name + '.jar') + jar(targetJar, [p.output_dir()]) +def jar(destFileName, dirs): + latestMod = _latestModification(dirs) + + if exists(destFileName): + mod = os.path.getmtime(destFileName) + if int(round(latestMod*1000)) == int(round(mod*1000)): + # nothing todo + return + + if latestMod is None and exists(destFileName): + return + + jarCmd = [java().jar, 'cf', destFileName] + + for directory in dirs: + jarCmd += ['-C', directory, '.'] + + subprocess.check_call(jarCmd) + log('Written jar file {0}'.format(destFileName)) + + atime = os.path.getatime(destFileName) + os.utime(destFileName, (atime, latestMod)) + +def _latestModification(directories): + latestMod = None + for directory in directories: + if not os.path.exists (directory): + continue + for root, _, files in os.walk(directory): + for names in files: + filepath = os.path.join(root, names) + mod = os.path.getmtime(filepath) + if latestMod is None: + latestMod = mod + elif mod > latestMod: + latestMod = mod + return latestMod + def canonicalizeprojects(args): """process all project files to canonicalize the dependencies @@ -1860,13 +1880,14 @@ os.makedirs(eclipseLaunches) return update_file(join(eclipseLaunches, name + '.launch'), launch) -def eclipseinit(args, suite=None): +def eclipseinit(args, suite=None, buildProcessorJars=True): """(re)generate Eclipse project configurations""" if suite is None: suite = _mainSuite - processorjars([]) + if buildProcessorJars: + processorjars() for p in projects(): if p.native: @@ -1884,6 +1905,12 @@ os.mkdir(srcDir) out.element('classpathentry', {'kind' : 'src', 'path' : src}) + if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + genDir = p.source_gen_dir(); + if not exists(genDir): + os.mkdir(genDir) + out.element('classpathentry', {'kind' : 'src', 'path' : 'src_gen'}) + # Every Java program depends on the JRE out.element('classpathentry', {'kind' : 'con', 'path' : 'org.eclipse.jdt.launching.JRE_CONTAINER'}) @@ -1975,6 +2002,23 @@ out.element('name', data=buildCommand) out.element('arguments', data='') out.close('buildCommand') + + if (_needsEclipseJarBuild(p)): + out.open('buildCommand') + out.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder') + out.element('triggers', data='auto,full,incremental,') + out.open('arguments') + out.open('dictionary') + out.element('key', data = 'LaunchConfigHandle') + out.element('value', data = _genEclipseJarBuild(p)) + out.close('dictionary') + out.open('dictionary') + out.element('key', data = 'incclean') + out.element('value', data = 'true') + out.close('dictionary') + out.close('arguments') + out.close('buildCommand') + out.close('buildSpec') out.open('natures') out.element('nature', data='org.eclipse.jdt.core.javanature') @@ -2010,7 +2054,6 @@ out.element('factorypathentry', {'kind' : 'PLUGIN', 'id' : 'org.eclipse.jst.ws.annotations.core', 'enabled' : 'true', 'runInBatchMode' : 'false'}) for ap in p.annotationProcessors: apProject = project(ap) - out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + apProject.name + '/' + apProject.name + 'AnnotationProcessor.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) for dep in apProject.all_deps([], True): if dep.isLibrary(): if not hasattr(dep, 'eclipse.container') and not hasattr(dep, 'eclipse.project'): @@ -2022,11 +2065,65 @@ # safest to simply use absolute paths. path = join(suite.dir, path) out.element('factorypathentry', {'kind' : 'EXTJAR', 'id' : path, 'enabled' : 'true', 'runInBatchMode' : 'false'}) + else: + out.element('factorypathentry', {'kind' : 'WKSPJAR', 'id' : '/' + dep.name + '/' + dep.name + '.jar', 'enabled' : 'true', 'runInBatchMode' : 'false'}) out.close('factorypath') update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) make_eclipse_attach('localhost', '8000', deps=projects()) + +def _needsEclipseJarBuild(p): + processors = set([]) + + for otherProject in projects(): + if hasattr(otherProject, 'annotationProcessors') and len(otherProject.annotationProcessors) > 0: + for processorName in otherProject.annotationProcessors: + processors.add(project(processorName, fatalIfMissing=True)) + + if p in processors: + return True + + for otherProject in processors: + deps = otherProject.all_deps([], True) + if p in deps: + return True + + return False + +def _genEclipseJarBuild(p): + launchOut = XMLDoc(); + launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) + launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value': '${project}'}) + launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': 'false'}) + launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_CONSOLE_OUTPUT_ON', 'value': 'false'}) + launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND', 'value': 'true'}) + + baseDir = dirname(dirname(os.path.abspath(__file__))) + + cmd = 'mx.sh' + if get_os() == 'windows': + cmd = 'mx.cmd' + launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_LOCATION', 'value': join(baseDir, cmd) }) + launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS', 'value': 'auto,full,incremental'}) + launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TOOL_ARGUMENTS', 'value': ''.join(['jar', ' ', p.name])}) + launchOut.element('booleanAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED','value': 'true'}) + launchOut.element('stringAttribute', {'key' : 'org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY', 'value': baseDir}) + + + launchOut.close('launchConfiguration') + + externalToolDir = join(p.dir, '.externalToolBuilders') + + if not exists(externalToolDir): + os.makedirs(externalToolDir) + update_file(join(externalToolDir, 'Jar.launch'), launchOut.xml(indent='\t', newl='\n')) + + return "<project>/.externalToolBuilders/Jar.launch" + + + + def netbeansinit(args, suite=None): """(re)generate NetBeans project configurations""" @@ -2063,9 +2160,10 @@ out.element('explicit-platform', {'explicit-source-supported' : 'true'}) out.open('source-roots') out.element('root', {'id' : 'src.dir'}) + if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + out.element('root', {'id' : 'src.ap-source-output.dir'}) out.close('source-roots') out.open('test-roots') - out.element('root', {'id' : 'test.src.dir'}) out.close('test-roots') out.close('data') @@ -2099,12 +2197,18 @@ out = StringIO.StringIO() jdkPlatform = 'JDK_' + java().version + annotationProcessorEnabled = "false" + annotationProcessorReferences = "" + annotationProcessorSrcFolder = "" + if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + annotationProcessorEnabled = "true" + annotationProcessorSrcFolder = "src.ap-source-output.dir=${build.generated.sources.dir}/ap-source-output" + content = """ -annotation.processing.enabled=false -annotation.processing.enabled.in.editor=false +annotation.processing.enabled=""" + annotationProcessorEnabled + """ +annotation.processing.enabled.in.editor=""" + annotationProcessorEnabled + """ annotation.processing.processors.list= annotation.processing.run.all.processors=true -annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output application.title=""" + p.name + """ application.vendor=mx build.classes.dir=${build.dir} @@ -2134,15 +2238,11 @@ # Space-separated list of extra javac options javac.compilerargs= javac.deprecation=false -javac.processorpath=\\ - ${javac.classpath} javac.source=1.7 javac.target=1.7 javac.test.classpath=\\ ${javac.classpath}:\\ ${build.classes.dir} -javac.test.processorpath=\\ - ${javac.test.classpath} javadoc.additionalparam= javadoc.author=false javadoc.encoding=${source.encoding} @@ -2170,7 +2270,8 @@ run.test.classpath=\\ ${javac.test.classpath}:\\ ${build.test.classes.dir} -test.src.dir= +test.src.dir=./test +""" + annotationProcessorSrcFolder + """ source.encoding=UTF-8""".replace(':', os.pathsep).replace('/', os.sep) print >> out, content @@ -2188,7 +2289,19 @@ print >> out, 'src.' + src + '.dir=${' + ref + '}' javacClasspath = [] - for dep in p.all_deps([], True): + + deps = p.all_deps([], True) + annotationProcessorOnlyDeps = [] + if hasattr(p, 'annotationProcessors') and len(p.annotationProcessors) > 0: + for ap in p.annotationProcessors: + apProject = project(ap) + if not apProject in deps: + deps.append(apProject) + annotationProcessorOnlyDeps.append(apProject) + + annotationProcessorReferences = []; + + for dep in deps: if dep == p: continue; @@ -2208,11 +2321,16 @@ print >> out, 'project.' + n + '=' + relDepPath print >> out, ref + '=${project.' + n + '}/dist/' + dep.name + '.jar' - javacClasspath.append('${' + ref + '}') + if not dep in annotationProcessorOnlyDeps: + javacClasspath.append('${' + ref + '}') + else: + annotationProcessorReferences.append('${' + ref + '}') + annotationProcessorReferences += ":\\\n ${" + ref + "}" print >> out, 'javac.classpath=\\\n ' + (os.pathsep + '\\\n ').join(javacClasspath) - - + print >> out, 'javac.test.processorpath=${javac.test.classpath}\\\n ' + (os.pathsep + '\\\n ').join(annotationProcessorReferences) + print >> out, 'javac.processorpath=${javac.classpath}\\\n ' + (os.pathsep + '\\\n ').join(annotationProcessorReferences) + updated = update_file(join(p.dir, 'nbproject', 'project.properties'), out.getvalue()) or updated out.close() @@ -2223,7 +2341,6 @@ def ideclean(args, suite=None): """remove all Eclipse and NetBeans project configurations""" - def rm(path): if exists(path): os.remove(path) @@ -2233,10 +2350,17 @@ continue shutil.rmtree(join(p.dir, '.settings'), ignore_errors=True) + shutil.rmtree(join(p.dir, '.externalToolBuilders'), ignore_errors=True) shutil.rmtree(join(p.dir, 'nbproject'), ignore_errors=True) rm(join(p.dir, '.classpath')) rm(join(p.dir, '.project')) rm(join(p.dir, 'build.xml')) + rm(join(p.dir, 'eclipse-build.xml')) + try: + rm(join(p.dir, p.name + '.jar')) + except: + log("Error removing {0}".format(p.name + '.jar')) + def ideinit(args, suite=None): """(re)generate Eclipse and NetBeans project configurations"""