# HG changeset patch # User Stefan Anzinger # Date 1432644392 -7200 # Node ID 6420ac0cbe3ce5508d6a3982e5d4fc70920f0373 # Parent 6b59a0656841eb421a1fe3b80857a7af5f399525 Add Makefile generator for building graal without mx diff -r 6b59a0656841 -r 6420ac0cbe3c mx/mx_graal.py --- a/mx/mx_graal.py Fri May 22 11:52:28 2015 +0200 +++ b/mx/mx_graal.py Tue May 26 14:46:32 2015 +0200 @@ -37,6 +37,7 @@ import itertools import json, textwrap import fnmatch +import mx_graal_makefile # This works because when mx loads this file, it makes sure __file__ gets an absolute path _graal_home = dirname(dirname(__file__)) @@ -2656,6 +2657,7 @@ 'longtests' : [longtests, ''], 'sl' : [sl, '[SL args|@VM options]'], 'jol' : [jol, ''], + 'makefile' : [mx_graal_makefile.build_makefile, 'build makefiles for JDK build'], } mx.add_argument('--jacoco', help='instruments com.oracle.* classes using JaCoCo', default='off', choices=['off', 'on', 'append']) diff -r 6b59a0656841 -r 6420ac0cbe3c mx/mx_graal_makefile.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mx/mx_graal_makefile.py Tue May 26 14:46:32 2015 +0200 @@ -0,0 +1,183 @@ +import mx, os, sys +# +# ---------------------------------------------------------------------------------------------------- +# +# Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# +# ---------------------------------------------------------------------------------------------------- +# + + +def build_makefile(args): + """Build a Makefile from the suitte.py to build graa.jar without python""" + if len(args) == 0 or args[0] == "-": + do_build_makefile(lambda l: sys.stdout.write(l + os.linesep)) + elif args[0] == "-o": + with open(args[1], "w") as f: + do_build_makefile(lambda l: f.write(l + os.linesep)) + +def relative_dep_path(d): + if isinstance(d, str): d = mx.dependency(d) + return os.path.basename(d.get_path(False)) + +def createMakeRule(p, bootClasspath): + def filterDeps(deps, t): + def typeFilter(project): # filters + if isinstance(project, str): + project = mx.dependency(project, True) + return isinstance(project, t) + return [d for d in deps if typeFilter(d)] + + + canonicalDeps = p.canonical_deps() + canonicalProjectDep = filterDeps(canonicalDeps, mx.Project) + canonicalProjectDepDirs = ['$(TARGET)/' +i for i in canonicalProjectDep] + canonicalLibDep = filterDeps(canonicalDeps, mx.Library) + canonicalLibDepJars = ["$(LIB)/" + relative_dep_path(d) for d in canonicalLibDep] + + allDep = p.all_deps([], True, False, includeAnnotationProcessors=True) + allProcessorDistNames = [x.definedAnnotationProcessorsDist.name for x in filterDeps(allDep, mx.Project) if x.definedAnnotationProcessors != None] + allProjectDep = filterDeps(allDep, mx.Project) + allProjectDepDir = ['$(TARGET)/' +i.name for i in allProjectDep] + allLibDep = filterDeps(allDep, mx.Library) + allLibDepJar = ["$(LIB)/" + relative_dep_path(d) for d in allLibDep] + + processor = p.annotation_processors_path() + if processor != None: processor = processor.replace(p.suite.dir, "$(TARGET)") + + cp = allLibDepJar +allProjectDepDir + props = { + 'name': p.name, + 'project_deps': ' '.join(canonicalProjectDepDirs + canonicalLibDepJars + allProcessorDistNames), + 'cp_deps': ('-cp ' + ':'.join(cp)) if len(cp) > 0 else '', + 'cp_boot': ('-bootclasspath ' + bootClasspath) if len(bootClasspath) > 0 else '', + 'processor': ('-processorpath ' + processor) if processor != None else '' + } + return """$(TARGET)/{name}: $(shell find graal/{name}/src/ -type f -name *.java) {project_deps} +\t$(eval TMP := $(shell mktemp -d)) +\ttest ! -d $(TARGET)/{name} || cp -Rp $(TARGET)/{name} $(TMP) +\t$(JAVAC) -d $(TMP) {cp_boot} {processor} {cp_deps} $(shell find graal/{name}/src/ -type f -name *.java) +\ttest ! -d graal/{name}/src/META-INF || (mkdir -p $(TARGET)/{name}/META-INF/ && cp -r graal/{name}/src/META-INF/ $(TARGET)/{name}/) +\tmkdir -p $(TARGET)/{name} +\tcp -r $(TMP)/* $(TARGET)/{name} +\ttouch $(TARGET)/{name} +\trm -r $(TMP) +""".format(**props) + +def createDistributionRule(dist): + depDirs = ' '.join(['$(TARGET)/' + i.name for i in dist.sorted_deps(False, True)]) + depDirsStar = ' '.join(['$(TARGET)/' + i.name + '/*' for i in dist.sorted_deps(False, True)]) + jarPath = os.path.relpath(dist.path, dist.suite.dir) + jarDir = os.path.dirname(jarPath) + props = { + 'dist_name': dist.name, + 'depDirs': depDirs, + 'depDirsStar': depDirsStar, + 'jar_path': jarPath, + 'jar_dir': jarDir, + 'providers_dir': '$(TMP)/META-INF/providers/ ', + 'services_dir': '$(TMP)/META-INF/services/' + } + return """{dist_name}: {depDirs} +\t$(eval TMP := $(shell mktemp -d)) +\tmkdir -p $(TARGET){jar_dir} +\ttouch $(TARGET)/{jar_path} +\tcp -r {depDirsStar} $(TMP) +\ttest -d {services_dir} || mkdir -p {services_dir} +\ttest ! -d {providers_dir} || (cd {providers_dir} && for i in $$(ls); do c=$$(cat $$i); echo $$i >> {services_dir}$$c; done) +\ttest ! -d {providers_dir} || rm -r {providers_dir} +\t$(JAR) cvf $(TARGET){jar_path} -C $(TMP) . +\trm -r $(TMP) +""".format(**props) + +def createDownloadRule(lib): + http_urls = [u for u in lib.urls if u.startswith("http")] + if len(http_urls) == 0: http_urls = [u for u in lib.urls if u.startswith("jar")] + if len(http_urls) == 0: raise BaseException("No http url specified for downloading library %s: available urls: %s" % (lib.name, lib.urls)) + url = http_urls[0] + tofile = '$(LIB)/' + relative_dep_path(lib) + if url.startswith("jar"): + props = { + 'url': url[url.find(":")+1:url.rfind("!")], + 'archive_file': url[url.rfind("!")+1:], + 'dest': tofile + } + dl = """\t$(eval TMP := $(shell mktemp -d)) +\tcd $(TMP) && $(WGET) -O dl.zip {url} && $(JAR) xf dl.zip +\tmv $(TMP)/{archive_file} {dest} +\trm -rf $(TMP)""".format(**props) + else: + dl = "\t$(WGET) -O {} {}".format(tofile, url) + return """{}:\n{}""".format(tofile, dl) + + +def create_suite_build(suite, out): + for p in suite.projects: + java = mx.java(p.javaCompliance) + bootClassPath = java.bootclasspath() + bootClassPath = bootClassPath.replace(java.jdk, "$(JDK)") + out(createMakeRule(p, bootClassPath)) + for l in suite.libs: + out(createDownloadRule(l)) + + distributionNames = [] + for d in suite.dists: + distributionNames.append(d.name) + out(createDistributionRule(d)) + out("{0}: {1}\n.PHONY: {1}".format(suite.name, " ".join(distributionNames))) + + +def do_build_makefile(out): + out("""VERBOSE= +TARGET=build/ +LIB=$(TARGET)/lib +JDK= + +WGET=wget +JAVAC=$(JDK)/bin/javac +JAR=$(JDK)/bin/jar + + +ifeq ($(JDK),) +$(error Variable JDK must be set to a JDK installation.) +endif +ifneq ($(VERBOSE),) +SHELL=sh -x +endif + +all: default + +$(TARGET): +\tmkdir -p $(TARGET) + +$(LIB): +\tmkdir -p $(LIB) +""") + suiteNames = [] + for s in mx.suites(): + suiteNames.append(s.name) + create_suite_build(s, out) + + out("""default: $(TARGET) $(LIB) {0} +.PHONY: {0} + """.format(" ".join(suiteNames))) +