Mercurial > hg > graal-jvmci-8
comparison mxtool/mx.py @ 8131:83ec1df0a30f
added support for distributions to mx
added GRAAL distribution to create graal.jar in top level directory
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 06 Mar 2013 16:59:10 +0100 |
parents | c7d7d9936809 |
children | 6e3ebc6fd5a4 |
comparison
equal
deleted
inserted
replaced
8126:22bbd34705ed | 8131:83ec1df0a30f |
---|---|
141 | 141 |
142 DEFAULT_JAVA_ARGS = '-ea -Xss2m -Xmx1g' | 142 DEFAULT_JAVA_ARGS = '-ea -Xss2m -Xmx1g' |
143 | 143 |
144 _projects = dict() | 144 _projects = dict() |
145 _libs = dict() | 145 _libs = dict() |
146 _dists = dict() | |
146 _suites = dict() | 147 _suites = dict() |
147 _mainSuite = None | 148 _mainSuite = None |
148 _opts = None | 149 _opts = None |
149 _java = None | 150 _java = None |
150 | 151 |
152 """ | |
153 A distribution is a jar or zip file containing the output from one or more Java projects. | |
154 """ | |
155 class Distribution: | |
156 def __init__(self, suite, name, path, deps): | |
157 self.suite = suite | |
158 self.name = name | |
159 self.path = path.replace('/', os.sep) | |
160 if not isabs(self.path): | |
161 self.path = join(suite.dir, self.path) | |
162 self.deps = deps | |
163 | |
164 def __str__(self): | |
165 return self.name | |
166 | |
151 """ | 167 """ |
152 A dependency is a library or project specified in a suite. | 168 A dependency is a library or project specified in a suite. |
153 """ | 169 """ |
154 class Dependency: | 170 class Dependency: |
155 def __init__(self, suite, name): | 171 def __init__(self, suite, name): |
414 class Suite: | 430 class Suite: |
415 def __init__(self, d, primary): | 431 def __init__(self, d, primary): |
416 self.dir = d | 432 self.dir = d |
417 self.projects = [] | 433 self.projects = [] |
418 self.libs = [] | 434 self.libs = [] |
435 self.dists = [] | |
419 self.includes = [] | 436 self.includes = [] |
420 self.commands = None | 437 self.commands = None |
421 self.primary = primary | 438 self.primary = primary |
422 mxDir = join(d, 'mx') | 439 mxDir = join(d, 'mx') |
423 self._load_env(mxDir) | 440 self._load_env(mxDir) |
425 self._load_includes(mxDir) | 442 self._load_includes(mxDir) |
426 | 443 |
427 def _load_projects(self, mxDir): | 444 def _load_projects(self, mxDir): |
428 libsMap = dict() | 445 libsMap = dict() |
429 projsMap = dict() | 446 projsMap = dict() |
447 distsMap = dict() | |
430 projectsFile = join(mxDir, 'projects') | 448 projectsFile = join(mxDir, 'projects') |
431 if not exists(projectsFile): | 449 if not exists(projectsFile): |
432 return | 450 return |
433 with open(projectsFile) as f: | 451 with open(projectsFile) as f: |
434 for line in f: | 452 for line in f: |
445 kind, name, attr = parts | 463 kind, name, attr = parts |
446 if kind == 'project': | 464 if kind == 'project': |
447 m = projsMap | 465 m = projsMap |
448 elif kind == 'library': | 466 elif kind == 'library': |
449 m = libsMap | 467 m = libsMap |
468 elif kind == 'distribution': | |
469 m = distsMap | |
450 else: | 470 else: |
451 abort('Property name does not start with "project@" or "library@": ' + key) | 471 abort('Property name does not start with "project@", "library@" or "distribution@": ' + key) |
452 | 472 |
453 attrs = m.get(name) | 473 attrs = m.get(name) |
454 if attrs is None: | 474 if attrs is None: |
455 attrs = dict() | 475 attrs = dict() |
456 m[name] = attrs | 476 m[name] = attrs |
492 sourceUrls = pop_list(attrs, 'sourceUrls') | 512 sourceUrls = pop_list(attrs, 'sourceUrls') |
493 l = Library(self, name, path, mustExist, urls, sourcePath, sourceUrls) | 513 l = Library(self, name, path, mustExist, urls, sourcePath, sourceUrls) |
494 l.__dict__.update(attrs) | 514 l.__dict__.update(attrs) |
495 self.libs.append(l) | 515 self.libs.append(l) |
496 | 516 |
517 for name, attrs in distsMap.iteritems(): | |
518 path = attrs.pop('path') | |
519 deps = pop_list(attrs, 'dependencies') | |
520 d = Distribution(self, name, path, deps) | |
521 d.__dict__.update(attrs) | |
522 self.dists.append(d) | |
523 | |
497 def _load_commands(self, mxDir): | 524 def _load_commands(self, mxDir): |
498 commands = join(mxDir, 'commands.py') | 525 commands = join(mxDir, 'commands.py') |
499 if exists(commands): | 526 if exists(commands): |
500 # temporarily extend the Python path | 527 # temporarily extend the Python path |
501 sys.path.insert(0, mxDir) | 528 sys.path.insert(0, mxDir) |
547 for l in self.libs: | 574 for l in self.libs: |
548 existing = _libs.get(l.name) | 575 existing = _libs.get(l.name) |
549 if existing is not None: | 576 if existing is not None: |
550 abort('cannot redefine library ' + l.name) | 577 abort('cannot redefine library ' + l.name) |
551 _libs[l.name] = l | 578 _libs[l.name] = l |
579 for d in self.dists: | |
580 existing = _dists.get(l.name) | |
581 if existing is not None: | |
582 abort('cannot redefine distribution ' + d.name) | |
583 _dists[d.name] = d | |
552 | 584 |
553 class XMLElement(xml.dom.minidom.Element): | 585 class XMLElement(xml.dom.minidom.Element): |
554 def writexml(self, writer, indent="", addindent="", newl=""): | 586 def writexml(self, writer, indent="", addindent="", newl=""): |
555 writer.write(indent+"<" + self.tagName) | 587 writer.write(indent+"<" + self.tagName) |
556 | 588 |
650 def projects(): | 682 def projects(): |
651 """ | 683 """ |
652 Get the list of all loaded projects. | 684 Get the list of all loaded projects. |
653 """ | 685 """ |
654 return _projects.values() | 686 return _projects.values() |
687 | |
688 def distribution(name, fatalIfMissing=True): | |
689 """ | |
690 Get the distribution for a given name. This will abort if the named distribution does | |
691 not exist and 'fatalIfMissing' is true. | |
692 """ | |
693 d = _dists.get(name) | |
694 if d is None and fatalIfMissing: | |
695 abort('distribution named ' + name + ' not found') | |
696 return d | |
655 | 697 |
656 def project(name, fatalIfMissing=True): | 698 def project(name, fatalIfMissing=True): |
657 """ | 699 """ |
658 Get the project for a given name. This will abort if the named project does | 700 Get the project for a given name. This will abort if the named project does |
659 not exist and 'fatalIfMissing' is true. | 701 not exist and 'fatalIfMissing' is true. |
1475 jdtArgs.append('@' + argfile.name) | 1517 jdtArgs.append('@' + argfile.name) |
1476 run(jdtArgs) | 1518 run(jdtArgs) |
1477 finally: | 1519 finally: |
1478 for n in toBeDeleted: | 1520 for n in toBeDeleted: |
1479 os.remove(n) | 1521 os.remove(n) |
1522 | |
1523 for dist in _dists.values(): | |
1524 archive(['@' + dist.name]) | |
1480 | 1525 |
1481 if suppliedParser: | 1526 if suppliedParser: |
1482 return args | 1527 return args |
1483 return None | 1528 return None |
1484 | 1529 |
1576 | 1621 |
1577 def processorjars(): | 1622 def processorjars(): |
1578 projects = set() | 1623 projects = set() |
1579 | 1624 |
1580 for p in sorted_deps(): | 1625 for p in sorted_deps(): |
1581 if _needsEclipseJarBuild(p): | 1626 if _isAnnotationProcessorDependency(p): |
1582 projects.add(p) | 1627 projects.add(p) |
1583 | 1628 |
1584 if len(projects) <= 0: | 1629 if len(projects) <= 0: |
1585 return | 1630 return |
1586 | 1631 |
1587 pnames = [p.name for p in projects] | 1632 pnames = [p.name for p in projects] |
1588 build(['--projects', ",".join(pnames)]) | 1633 build(['--projects', ",".join(pnames)]) |
1589 jarprojects(pnames) | 1634 archive(pnames) |
1590 | 1635 |
1591 def jarprojects(args): | 1636 def archive(args): |
1592 """create jar files for the output of one or more projects""" | 1637 """create jar files for projects and distributions""" |
1593 parser = ArgumentParser(prog='mx jar'); | 1638 parser = ArgumentParser(prog='mx archive'); |
1594 parser.add_argument('-d', '--dest', help='single jar file to create') | 1639 parser.add_argument('names', nargs=REMAINDER, metavar='[<project>|@<distribution>]...') |
1595 parser.add_argument('projects', nargs=REMAINDER, metavar='projects...') | |
1596 args = parser.parse_args(args) | 1640 args = parser.parse_args(args) |
1597 | 1641 |
1598 if not args.projects: | 1642 for name in args.names: |
1599 args.projects = [p.name for p in projects()] | 1643 if name.startswith('@'): |
1600 | 1644 dname = name[1:] |
1601 if args.dest is not None: | 1645 d = distribution(dname) |
1602 zf = zipfile.ZipFile(args.dest, 'w') | 1646 zf = zipfile.ZipFile(d.path, 'w') |
1603 | 1647 for p in sorted_deps(d.deps): |
1604 for pname in args.projects: | 1648 outputDir = p.output_dir() |
1605 p = project(pname, fatalIfMissing=True) | 1649 for root, _, files in os.walk(outputDir): |
1606 if args.dest is None: | 1650 for f in files: |
1651 relpath = root[len(outputDir) + 1:] | |
1652 arcname = join(relpath, f).replace(os.sep, '/') | |
1653 zf.write(join(root, f), arcname) | |
1654 zf.close() | |
1655 else: | |
1656 p = project(name) | |
1657 outputDir = p.output_dir() | |
1607 jar = join(p.dir, p.name + '.jar') | 1658 jar = join(p.dir, p.name + '.jar') |
1608 zf = zipfile.ZipFile(jar, 'w') | 1659 zf = zipfile.ZipFile(jar, 'w') |
1609 outputDir = p.output_dir() | 1660 for root, _, files in os.walk(outputDir): |
1610 for root, _, files in os.walk(outputDir): | 1661 for f in files: |
1611 for f in files: | 1662 relpath = root[len(outputDir) + 1:] |
1612 relpath = root[len(outputDir) + 1:] | 1663 arcname = join(relpath, f).replace(os.sep, '/') |
1613 arcname = join(relpath, f).replace(os.sep, '/') | 1664 zf.write(join(root, f), arcname) |
1614 zf.write(join(root, f), arcname) | |
1615 if args.dest is None: | |
1616 zf.close() | 1665 zf.close() |
1617 | |
1618 if args.dest is not None: | |
1619 zf.close() | |
1620 | 1666 |
1621 def canonicalizeprojects(args): | 1667 def canonicalizeprojects(args): |
1622 """process all project files to canonicalize the dependencies | 1668 """process all project files to canonicalize the dependencies |
1623 | 1669 |
1624 The exit code of this command reflects how many files were updated.""" | 1670 The exit code of this command reflects how many files were updated.""" |
1994 suite = _mainSuite | 2040 suite = _mainSuite |
1995 | 2041 |
1996 if buildProcessorJars: | 2042 if buildProcessorJars: |
1997 processorjars() | 2043 processorjars() |
1998 | 2044 |
2045 projToDist = dict() | |
2046 for dist in _dists.values(): | |
2047 distDeps = sorted_deps(dist.deps) | |
2048 for p in distDeps: | |
2049 projToDist[p.name] = (dist, [dep.name for dep in distDeps]) | |
2050 | |
1999 for p in projects(): | 2051 for p in projects(): |
2000 if p.native: | 2052 if p.native: |
2001 continue | 2053 continue |
2002 | 2054 |
2003 if not exists(p.dir): | 2055 if not exists(p.dir): |
2108 out.open('buildCommand') | 2160 out.open('buildCommand') |
2109 out.element('name', data=buildCommand) | 2161 out.element('name', data=buildCommand) |
2110 out.element('arguments', data='') | 2162 out.element('arguments', data='') |
2111 out.close('buildCommand') | 2163 out.close('buildCommand') |
2112 | 2164 |
2113 if (_needsEclipseJarBuild(p)): | 2165 if _isAnnotationProcessorDependency(p): |
2114 targetValues = _genEclipseJarBuild(p); | 2166 _genEclipseBuilder(out, p, 'Jar.launch', 'archive ' + p.name, refresh = False, async = False) |
2115 for value in targetValues: | 2167 _genEclipseBuilder(out, p, 'Refresh.launch', '', refresh = True, async = True) |
2116 out.open('buildCommand') | 2168 |
2117 out.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder') | 2169 if projToDist.has_key(p.name): |
2118 out.element('triggers', data='auto,full,incremental,') | 2170 dist, distDeps = projToDist[p.name] |
2119 out.open('arguments') | 2171 _genEclipseBuilder(out, p, 'Create' + dist.name + 'Dist.launch', 'archive @' + dist.name, refresh=False, async=True) |
2120 out.open('dictionary') | 2172 |
2121 out.element('key', data = 'LaunchConfigHandle') | |
2122 out.element('value', data = value) | |
2123 out.close('dictionary') | |
2124 out.open('dictionary') | |
2125 out.element('key', data = 'incclean') | |
2126 out.element('value', data = 'true') | |
2127 out.close('dictionary') | |
2128 out.close('arguments') | |
2129 out.close('buildCommand') | |
2130 | |
2131 out.close('buildSpec') | 2173 out.close('buildSpec') |
2132 out.open('natures') | 2174 out.open('natures') |
2133 out.element('nature', data='org.eclipse.jdt.core.javanature') | 2175 out.element('nature', data='org.eclipse.jdt.core.javanature') |
2134 if exists(csConfig): | 2176 if exists(csConfig): |
2135 out.element('nature', data='net.sf.eclipsecs.core.CheckstyleNature') | 2177 out.element('nature', data='net.sf.eclipsecs.core.CheckstyleNature') |
2180 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) | 2222 update_file(join(p.dir, '.factorypath'), out.xml(indent='\t', newl='\n')) |
2181 | 2223 |
2182 make_eclipse_attach('localhost', '8000', deps=projects()) | 2224 make_eclipse_attach('localhost', '8000', deps=projects()) |
2183 | 2225 |
2184 | 2226 |
2185 def _needsEclipseJarBuild(p): | 2227 def _isAnnotationProcessorDependency(p): |
2186 processors = set([]) | 2228 """ |
2229 Determines if a given project is part of an annotation processor. | |
2230 """ | |
2231 processors = set() | |
2187 | 2232 |
2188 for otherProject in projects(): | 2233 for otherProject in projects(): |
2189 if hasattr(otherProject, 'annotationProcessors') and len(otherProject.annotationProcessors) > 0: | 2234 if hasattr(otherProject, 'annotationProcessors') and len(otherProject.annotationProcessors) > 0: |
2190 for processorName in otherProject.annotationProcessors: | 2235 for processorName in otherProject.annotationProcessors: |
2191 processors.add(project(processorName, fatalIfMissing=True)) | 2236 processors.add(project(processorName, fatalIfMissing=True)) |
2198 if p in deps: | 2243 if p in deps: |
2199 return True | 2244 return True |
2200 | 2245 |
2201 return False | 2246 return False |
2202 | 2247 |
2203 def _genEclipseJarBuild(p): | 2248 def _genEclipseBuilder(dotProjectDoc, p, name, mxCommand, refresh=True, async=False): |
2204 builders = [] | |
2205 builders.append(_genEclipseLaunch(p, 'Jar.launch', ''.join(['jarprojects ', p.name]), refresh = False, async = False)) | |
2206 builders.append(_genEclipseLaunch(p, 'Refresh.launch', '', refresh = True, async = True)) | |
2207 return builders | |
2208 | |
2209 def _genEclipseLaunch(p, name, mxCommand, refresh=True, async=False): | |
2210 launchOut = XMLDoc(); | 2249 launchOut = XMLDoc(); |
2211 launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) | 2250 launchOut.open('launchConfiguration', {'type' : 'org.eclipse.ui.externaltools.ProgramBuilderLaunchConfigurationType'}) |
2212 if refresh: | 2251 if refresh: |
2213 launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value': '${project}'}) | 2252 launchOut.element('stringAttribute', {'key' : 'org.eclipse.debug.core.ATTR_REFRESH_SCOPE', 'value': '${project}'}) |
2214 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': 'false'}) | 2253 launchOut.element('booleanAttribute', {'key' : 'org.eclipse.debug.core.capture_output', 'value': 'false'}) |
2234 | 2273 |
2235 if not exists(externalToolDir): | 2274 if not exists(externalToolDir): |
2236 os.makedirs(externalToolDir) | 2275 os.makedirs(externalToolDir) |
2237 update_file(join(externalToolDir, name), launchOut.xml(indent='\t', newl='\n')) | 2276 update_file(join(externalToolDir, name), launchOut.xml(indent='\t', newl='\n')) |
2238 | 2277 |
2239 return ''.join(["<project>/.externalToolBuilders/", name]) | 2278 dotProjectDoc.open('buildCommand') |
2240 | 2279 dotProjectDoc.element('name', data='org.eclipse.ui.externaltools.ExternalToolBuilder') |
2241 | 2280 dotProjectDoc.element('triggers', data='auto,full,incremental,') |
2281 dotProjectDoc.open('arguments') | |
2282 dotProjectDoc.open('dictionary') | |
2283 dotProjectDoc.element('key', data = 'LaunchConfigHandle') | |
2284 dotProjectDoc.element('value', data = '<project>/.externalToolBuilders/' + name) | |
2285 dotProjectDoc.close('dictionary') | |
2286 dotProjectDoc.open('dictionary') | |
2287 dotProjectDoc.element('key', data = 'incclean') | |
2288 dotProjectDoc.element('value', data = 'true') | |
2289 dotProjectDoc.close('dictionary') | |
2290 dotProjectDoc.close('arguments') | |
2291 dotProjectDoc.close('buildCommand') | |
2292 | |
2242 def netbeansinit(args, suite=None): | 2293 def netbeansinit(args, suite=None): |
2243 """(re)generate NetBeans project configurations""" | 2294 """(re)generate NetBeans project configurations""" |
2244 | 2295 |
2245 if suite is None: | 2296 if suite is None: |
2246 suite = _mainSuite | 2297 suite = _mainSuite |
2954 'findclass': [findclass, ''], | 3005 'findclass': [findclass, ''], |
2955 'fsckprojects': [fsckprojects, ''], | 3006 'fsckprojects': [fsckprojects, ''], |
2956 'help': [help_, '[command]'], | 3007 'help': [help_, '[command]'], |
2957 'ideclean': [ideclean, ''], | 3008 'ideclean': [ideclean, ''], |
2958 'ideinit': [ideinit, ''], | 3009 'ideinit': [ideinit, ''], |
2959 'jarprojects': [jarprojects, '[options]'], | 3010 'archive': [archive, '[options]'], |
2960 'projectgraph': [projectgraph, ''], | 3011 'projectgraph': [projectgraph, ''], |
2961 'javap': [javap, ''], | 3012 'javap': [javap, ''], |
2962 'javadoc': [javadoc, '[options]'], | 3013 'javadoc': [javadoc, '[options]'], |
2963 'site': [site, '[options]'], | 3014 'site': [site, '[options]'], |
2964 'netbeansinit': [netbeansinit, ''], | 3015 'netbeansinit': [netbeansinit, ''], |