Commit 4bfcfc08 authored by Matthias Braun's avatar Matthias Braun
Browse files

further cleanup, improvements to build.ninja generator

parent b5479358
......@@ -6,21 +6,20 @@ from os.path import basename, dirname, realpath
from platform import system
import sys
# Open output
filename = "build.ninja"
sys.stdout.write("Creating %s\n" % (filename,))
build_ninja = open(filename, "w")
# Create settings, flags
def getenv(name, defaultval):
# TODO: remember value for subsequent generator runs
return environ.get(name, defaultval)
def quote(arglist):
arglist = map(lambda x: x.replace(' ', '$ ').replace(':', '$:'), arglist)
return " ".join(arglist)
# Settings, flags
variant = getenv("variant", "debug")
cflags_warnings = ["-Wall", "-W", "-Wextra", "-Wstrict-prototypes",
"-Wmissing-prototypes", "-Wwrite-strings"]
cflags_language = ["-std=c99"]
cflags_codegen = []
cflags_codegen = ["-fPIC"]
cflags = cflags_warnings + cflags_language + cflags_codegen
cppflags = []
linkflags = ["-lm"]
......@@ -42,13 +41,21 @@ else:
sys.stderr.write("Unknown build variant '%s' requested\n" % variant)
sys.exit(1)
# Determine directories, create output, collect files
srcdir = dirname(__file__)
if srcdir == "" or srcdir == ".":
srcdir = "."
builddir = "build/%s" % variant
top_builddir = "build"
builddir = "%s/%s" % (top_builddir, variant)
else:
builddir = "."
top_builddir = "."
builddir = top_builddir
dllext = ".dylib" if system() == "Darwin" else ".so"
gendir = top_builddir + '/gen'
filename = "build.ninja"
sys.stdout.write("Creating %s\n" % (filename,))
build_ninja = open(filename, "w")
chdir(srcdir)
sources = glob("ir/*/*.c")
......@@ -56,38 +63,30 @@ sources = map(lambda x: "$srcdir/%s" % x, sources)
libfirm_a = "$builddir/libfirm.a"
libfirm_dll = "$builddir/libfirm$dllext"
gendir = builddir + '/gen'
def unique(data):
return list(set(data))
includedirs = unique(map(dirname, sources))
includedirs += ['$srcdir/include/libfirm', '$srcdir/include/libfirm/adt']
includedirs += ['$gendir/include/libfirm' % globals(),
'$gendir/ir/ir' % globals()]
includedirs += [ '$srcdir/include/libfirm', '$srcdir/include/libfirm/adt',
'$gendir/include/libfirm', '$gendir/ir/ir' ]
cppflags += map(lambda x: "-I%s" % x, includedirs)
# TODO: correct quoting of spaces etc.
cflags = " ".join(cflags)
cppflags = " ".join(cppflags)
linkflags = " ".join(linkflags)
# Produce output
build_ninja.write("# Warning: automatically generated by %(__file__)s\n")
build_ninja.write("# Warning: automatically generated by %s\n" % __file__)
def var(name, value):
build_ninja.write("%s = %s\n" % (name, value))
var("ninja_required_version", "1.5")
var("ninja_required_version", "1.3")
var("cc", "cc")
var("link", "cc")
var("ar", "ar")
var("python", "python")
var("perl", "perl")
for name in ["dllext", "srcdir", "builddir", "gendir", "cflags", "cppflags",
"linkflags"]:
"linkflags"]:
value = globals()[name]
# concatenate command lists
# TODO: correct quoting
if not isinstance(value, basestring):
value = " ".join(value)
value = quote(value)
var(name, value)
# Write the rules
......@@ -102,27 +101,22 @@ rule AR
rule LINKLIB
command = $link -shared $in -o $out $linkflags
description = LINKLIB $out
rule MKDIR
command = mkdir -p $out
description = MKDIR $out
rule GEN_IR
command = $python $generator $specfile $template > $out
command = $python $generatortool $specfile $template > $out
description = GEN_IR $out
rule GEN
command = $perl $generator $specfile $outdir
command = $perl $generatortool $specfile $outdir
description = GEN $out
rule CONFIGURE
command = $python $in
description = CONFIGURE $out
generator = 1
''')
def multibuild(rule, targets, dependencies=[], **keyvals):
targets_joined = " ".join(targets)
dependencies_joined = " ".join(dependencies)
if extra_order_deps:
dependencies_joined += "|| " + " ".join(extra_order_deps)
build_ninja.write("build %s: %s %s\n" % (targets_joined, rule, dependencies_joined))
targets_q = quote(targets)
dependencies_q = quote(dependencies)
build_ninja.write("build %s: %s %s\n" % (targets_q, rule, dependencies_q))
for (key,val) in keyvals.iteritems():
build_ninja.write(" %s = %s\n" % (key, val))
return targets
......@@ -132,58 +126,53 @@ def build(rule, target, dependencies=[], **kevalys):
return targets[0]
extra_c_deps = []
extra_order_deps = []
# build.ninja regeneration
build("CONFIGURE", "build.ninja", ["$srcdir/%s" % basename(__file__)])
if builddir != ".":
bdtarget = build("MKDIR", "$builddir")
extra_order_deps += [ bdtarget ]
def compile_c(source, out=None, prepend_builddir=True, extradeps=[], extra_flags=[]):
# Generate files from node spec
def specgen(out, template=None):
if template is None:
template = "$srcdir/scripts/templates/" + basename(out)
generator = "$srcdir/scripts/gen_ir.py"
specfile = "$srcdir/scripts/ir_spec.py"
deps = [template, specfile, generator, "$srcdir/scripts/spec_util.py",
"$srcdir/scripts/filters.py"]
return build("GEN_IR", out, deps, specfile=specfile,
template=template, generatortool=generator)
generated = [ "$gendir/include/libfirm/nodes.h",
"$gendir/ir/ir/gen_irdump.c.inl", "$gendir/ir/ir/gen_irnode.h",
"$gendir/ir/ir/gen_irio.c.inl", "$gendir/ir/ir/gen_irnode.c" ]
generated = map(specgen, generated)
extra_c_deps += generated
# Compile C sources
def compile_c(source, out=None, extradeps=[], extra_flags=[]):
if out is None:
# TODO: make this more robust
out = source
out = out.replace("$srcdir/", "")
out = out.replace(".c", ".o")
if prepend_builddir:
out = "$builddir/" + out
deps = [source] + extradeps + extra_c_deps
args = dict()
args['cfile'] = source
args['depfile'] = out.replace(".o", ".d")
if extra_flags != []:
args['cflags'] = "$cflags " + " ".join(extra_flags)
args['cflags'] = "$cflags " + quote(extra_flags)
return build("CC", out, deps, **args)
# Generate files from node spec
def specgen(out, template=None, prepend_gendir=True):
if template is None:
template = "$srcdir/scripts/templates/" + basename(out)
if prepend_gendir:
out = "$gendir/" + out
generator = "$srcdir/scripts/gen_ir.py"
specfile = "$srcdir/scripts/ir_spec.py"
deps = [template, specfile, generator]
return build("GEN_IR", out, deps, specfile=specfile,
template=template, generator=generator)
gen_irnode = "ir/ir/gen_irnode.c"
generated = [ "include/libfirm/nodes.h", "ir/ir/gen_irdump.c.inl",
"ir/ir/gen_irnode.h", "ir/ir/gen_irio.c.inl", "ir/ir/gen_irnode.c" ]
generated = map(specgen, generated)
extra_c_deps += generated
# Compile normal source files
objects = map(compile_c, sources)
# Compile generated C files
for gen_cfile in [x for x in generated if x.endswith(".c")]:
objects += [ compile_c(gen_cfile) ]
# Rules for the backends
# Backend generators and compilation
def begen(generator, specfile, targets):
outdir = dirname(targets[0])
deps = [generator, specfile]
return multibuild("GEN", targets, deps, generator=generator, outdir=outdir, specfile=specfile)
return multibuild("GEN", targets, deps, generatortool=generator,
outdir=outdir, specfile=specfile)
backends = [ "TEMPLATE", "amd64", "arm", "ia32", "sparc" ]
for be in backends:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment