Commit fa725f1d authored by Matthias Braun's avatar Matthias Braun
Browse files

add a build.ninja generator

parent 9896f92e
/.ninja_deps
/.ninja_log
/aclocal.m4
/autom4te.cache/
/build
/build.ninja
/config.guess
/config.h.in
/config.mak
/config.sub
/configure
/depcomp
/firm-homepage
/install-sh
/ltmain.sh
/missing
......@@ -15,5 +18,4 @@
/win32/vc2010/firm.suo
/win32/vc2010/firm.vcxproj.user
/win32/vc2010/win32/
/firm-homepage
Makefile.in
#!/usr/bin/env python
# Create ninja build rules
from glob import glob
from os import chdir, environ
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)
variant = getenv("variant", "debug")
cflags_warnings = ["-Wall", "-W", "-Wextra", "-Wstrict-prototypes",
"-Wmissing-prototypes", "-Wwrite-strings"]
cflags_language = ["-std=c99"]
cflags_codegen = []
cflags = cflags_warnings + cflags_language + cflags_codegen
cppflags = []
linkflags = ["-lm"]
if variant == "debug":
cflags_codegen += ["-O0", "-g3"]
cppflags += ["-DDEBUG_libfirm"]
elif variant == "profile":
cflags_codegen += ["-O3", "-pg"]
linkflags += ["-pg"]
cppflags += ["-DNDEBUG"]
elif variant == "coverage":
cflags_codegen += ["-O0", "--coverage"]
linkflags += ["--coverage"]
cppflags += ["-DDEBUG_libfirm"]
elif variant == "optimize":
cflags_codegen += ["-O3", "-fomit-frame-pointer"]
cppflags += ["-DNDEBUG"]
else:
sys.stderr.write("Unknown build variant '%s' requested\n" % variant)
sys.exit(1)
srcdir = dirname(__file__)
if srcdir == "" or srcdir == ".":
srcdir = "."
builddir = "build/%s" % variant
else:
builddir = "."
dllext = ".dylib" if system() == "Darwin" else ".so"
chdir(srcdir)
sources = glob("ir/*/*.c")
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()]
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")
def var(name, value):
build_ninja.write("%s = %s\n" % (name, value))
var("ninja_required_version", "1.5")
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"]:
value = globals()[name]
# concatenate command lists
if not isinstance(value, basestring):
value = " ".join(value)
var(name, value)
# Write the rules
build_ninja.write('''
rule CC
command = $cc $cflags $cppflags -MP -MMD -c $cfile -o $out
description = CC $out
rule AR
command = rm -f $out
command = $ar -crsu $out $in
description = AR $out
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
description = GEN_IR $out
rule GEN
command = $perl $generator $specfile $outdir
description = GEN $out
rule CONFIGURE
command = $python $in
description = CONFIGURE $out
''')
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))
for (key,val) in keyvals.iteritems():
build_ninja.write(" %s = %s\n" % (key, val))
return targets
def build(rule, target, dependencies=[], **kevalys):
targets = multibuild(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=[]):
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)
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
def begen(generator, specfile, outs):
outdir = dirname(outs[0])
return multibuild("GEN", outs, ins=[generator, specfile], generator=generator, outdir=outdir, specfile=specfile)
backends = [ "TEMPLATE", "amd64", "arm", "ia32", "sparc" ]
for be in backends:
be_sources = glob("ir/be/%(be)s/*.c" % locals())
be_sources = map(lambda x: "$srcdir/" + x, be_sources)
spec = "$srcdir/ir/be/%(be)s/%(be)s_spec.pl" % locals()
be_generated = []
be_generated += begen("$srcdir/ir/be/scripts/generate_regalloc_if.pl", spec,
outs = [ "$gendir/ir/be/%(be)s/gen_%(be)s_regalloc_if.h" % locals(),
"$gendir/ir/be/%(be)s/gen_%(be)s_regalloc_if.c" % locals() ])
be_generated += begen("$srcdir/ir/be/scripts/generate_emitter.pl", spec,
outs = [ "$gendir/ir/be/%(be)s/gen_%(be)s_emitter.h" % locals(),
"$gendir/ir/be/%(be)s/gen_%(be)s_emitter.c" % locals() ])
be_generated += begen("$srcdir/ir/be/scripts/generate_new_opcodes.pl", spec,
outs = [ "$gendir/ir/be/%(be)s/gen_%(be)s_new_nodes.h" % locals(),
"$gendir/ir/be/%(be)s/gen_%(be)s_new_nodes.c.inl" % locals()])
be_sources += [x for x in be_generated if x.endswith(".c") ]
for f in be_sources:
objects += [ compile_c(f, extradeps=be_generated,
extra_flags=["-I$gendir/ir/be/%(be)s" % locals(),
"-I$srcdir/ir/be/%(be)s" % locals()]) ]
# Link
build("LINKLIB", libfirm_dll, objects)
build("AR", libfirm_a, objects)
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