Moved even more stuff from interpreter to build.

pull/15/head
Jussi Pakkanen 12 years ago
parent a2959fd0f4
commit 08622ae644
  1. 116
      build.py
  2. 102
      interpreter.py

@ -13,7 +13,8 @@
# limitations under the License. # limitations under the License.
import coredata import coredata
import copy import copy, os
import environment
class InvalidArguments(coredata.MesonException): class InvalidArguments(coredata.MesonException):
pass pass
@ -73,6 +74,21 @@ class Build:
def get_global_flags(self, compiler): def get_global_flags(self, compiler):
return self.global_args.get(compiler.get_language(), []) return self.global_args.get(compiler.get_language(), [])
class IncludeDirs():
def __init__(self, curdir, dirs, kwargs):
self.curdir = curdir
self.incdirs = dirs
# Fixme: check that the directories actually exist.
# Also that they don't contain ".." or somesuch.
if len(kwargs) > 0:
raise InvalidCode('Includedirs function does not take keyword arguments.')
def get_curdir(self):
return self.curdir
def get_incdirs(self):
return self.incdirs
class BuildTarget(): class BuildTarget():
def __init__(self, name, subdir, is_cross, sources, environment, kwargs): def __init__(self, name, subdir, is_cross, sources, environment, kwargs):
self.name = name self.name = name
@ -114,6 +130,10 @@ class BuildTarget():
if not isinstance(llist, list): if not isinstance(llist, list):
llist = [llist] llist = [llist]
for linktarget in llist: for linktarget in llist:
# Sorry for this hack. Keyword targets are kept in holders
# in kwargs. Unpack here without looking at the exact type.
if hasattr(linktarget, "target"):
linktarget = linktarget.target
self.link(linktarget) self.link(linktarget)
c_pchlist = kwargs.get('c_pch', []) c_pchlist = kwargs.get('c_pch', [])
if not isinstance(c_pchlist, list): if not isinstance(c_pchlist, list):
@ -229,10 +249,15 @@ class BuildTarget():
self.pch[language] = pchlist self.pch[language] = pchlist
def add_include_dirs(self, args): def add_include_dirs(self, args):
ids = []
for a in args: for a in args:
# FIXME same hack, forcibly unpack from holder.
if hasattr(a, 'includedirs'):
a = a.includedirs
if not isinstance(a, IncludeDirs): if not isinstance(a, IncludeDirs):
raise InvalidArguments('Include directory to be added is not an include directory object.') raise InvalidArguments('Include directory to be added is not an include directory object.')
self.include_dirs += args ids.append(a)
self.include_dirs += ids
def add_compiler_args(self, language, flags): def add_compiler_args(self, language, flags):
for a in flags: for a in flags:
@ -246,6 +271,89 @@ class BuildTarget():
def get_aliaslist(self): def get_aliaslist(self):
return [] return []
class Generator():
def __init__(self, args, kwargs):
if len(args) != 1:
raise InvalidArguments('Generator requires one and only one positional argument')
if hasattr(args[0], 'target'):
exe = args[0].target
if not isinstance(exe, Executable):
raise InvalidArguments('First generator argument must be an executable.')
elif hasattr(args[0], 'ep'):
exe = args[0].ep
else:
print(args[0])
raise InvalidArguments('First generator argument must be an executable object.')
self.exe = exe
self.process_kwargs(kwargs)
def get_exe(self):
return self.exe
def process_kwargs(self, kwargs):
if 'arguments' not in kwargs:
raise InvalidArguments('Generator must have "arguments" keyword argument.')
args = kwargs['arguments']
if isinstance(args, str):
args = [args]
if not isinstance(args, list):
raise InvalidArguments('"Arguments" keyword argument must be a string or a list of strings.')
for a in args:
if not isinstance(a, str):
raise InvalidArguments('A non-string object in "arguments" keyword argument.')
self.arglist = args
if 'outputs' not in kwargs:
raise InvalidArguments('Generator must have "outputs" keyword argument.')
outputs = kwargs['outputs']
if not isinstance(outputs, list):
outputs = [outputs]
for rule in outputs:
if not isinstance(rule, str):
raise InvalidArguments('"outputs" may only contain strings.')
if not '@BASENAME@' in rule and not '@PLAINNAME@' in rule:
raise InvalidArguments('"outputs" must contain @BASENAME@ or @PLAINNAME@.')
if '/' in rule or '\\' in rule:
raise InvalidArguments('"outputs" must not contain a directory separator.')
self.outputs = outputs
def get_base_outnames(self, inname):
plainname = os.path.split(inname)[1]
basename = plainname.split('.')[0]
return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs]
def get_arglist(self):
return self.arglist
class GeneratedList():
def __init__(self, generator):
if hasattr(generator, 'generator'):
generator = generator.generator
self.generator = generator
self.infilelist = []
self.outfilelist = []
self.outmap = {}
def add_file(self, newfile):
self.infilelist.append(newfile)
outfiles = self.generator.get_base_outnames(newfile)
self.outfilelist += outfiles
self.outmap[newfile] = outfiles
def get_infilelist(self):
return self.infilelist
def get_outfilelist(self):
return self.outfilelist
def get_outputs_for(self, filename):
return self.outmap[filename]
def get_generator(self):
return self.generator
class Executable(BuildTarget): class Executable(BuildTarget):
def __init__(self, name, subdir, is_cross, sources, environment, kwargs): def __init__(self, name, subdir, is_cross, sources, environment, kwargs):
super().__init__(name, subdir, is_cross, sources, environment, kwargs) super().__init__(name, subdir, is_cross, sources, environment, kwargs)
@ -282,16 +390,12 @@ class SharedLibrary(BuildTarget):
return fname + '.' + self.version return fname + '.' + self.version
def set_version(self, version): def set_version(self, version):
if isinstance(version, nodes.StringStatement):
version = version.get_value()
if not isinstance(version, str): if not isinstance(version, str):
print(version) print(version)
raise InvalidArguments('Shared library version is not a string.') raise InvalidArguments('Shared library version is not a string.')
self.version = version self.version = version
def set_soversion(self, version): def set_soversion(self, version):
if isinstance(version, nodes.StringStatement) or isinstance(version, nodes.IntStatement):
version = version.get_value()
if isinstance(version, int): if isinstance(version, int):
version = str(version) version = str(version)
if not isinstance(version, str): if not isinstance(version, str):

@ -191,53 +191,11 @@ class ExternalLibraryHolder(InterpreterObject):
def get_exe_flags(self): def get_exe_flags(self):
return self.el.get_exe_flags() return self.el.get_exe_flags()
class Generator(InterpreterObject): class GeneratorHolder(InterpreterObject):
def __init__(self, args, kwargs): def __init__(self, args, kwargs):
InterpreterObject.__init__(self) super().__init__()
if len(args) != 1: self.generator = build.Generator(args, kwargs)
raise InvalidArguments('Generator requires one and only one positional argument')
if not isinstance(args[0], Executable) and \
not isinstance(args[0], ExternalProgramHolder):
raise InvalidArguments('First generator argument must be an executable object.')
self.exe = args[0]
self.methods.update({'process' : self.process_method}) self.methods.update({'process' : self.process_method})
self.process_kwargs(kwargs)
def get_exe(self):
return self.exe
def process_kwargs(self, kwargs):
if 'arguments' not in kwargs:
raise InvalidArguments('Generator must have "arguments" keyword argument.')
args = kwargs['arguments']
if isinstance(args, str):
args = [args]
if not isinstance(args, list):
raise InvalidArguments('"Arguments" keyword argument must be a string or a list of strings.')
for a in args:
if not isinstance(a, str):
raise InvalidArguments('A non-string object in "arguments" keyword argument.')
self.arglist = args
if 'outputs' not in kwargs:
raise InvalidArguments('Generator must have "outputs" keyword argument.')
outputs = kwargs['outputs']
if not isinstance(outputs, list):
outputs = [outputs]
for rule in outputs:
if not isinstance(rule, str):
raise InvalidArguments('"outputs" may only contain strings.')
if not '@BASENAME@' in rule and not '@PLAINNAME@' in rule:
raise InvalidArguments('"outputs" must contain @BASENAME@ or @PLAINNAME@.')
if '/' in rule or '\\' in rule:
raise InvalidArguments('"outputs" must not contain a directory separator.')
self.outputs = outputs
def get_base_outnames(self, inname):
plainname = os.path.split(inname)[1]
basename = plainname.split('.')[0]
return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.outputs]
def process_method(self, args, kwargs): def process_method(self, args, kwargs):
if len(kwargs) > 0: if len(kwargs) > 0:
@ -249,38 +207,17 @@ class Generator(InterpreterObject):
for a in args: for a in args:
if not isinstance(a, str): if not isinstance(a, str):
raise InvalidArguments('A non-string object in "process" arguments.') raise InvalidArguments('A non-string object in "process" arguments.')
gl = GeneratedList(self) gl = GeneratedListHolder(self)
[gl.add_file(a) for a in args] [gl.add_file(a) for a in args]
return gl return gl
def get_arglist(self): class GeneratedListHolder(InterpreterObject):
return self.arglist
class GeneratedList(InterpreterObject):
def __init__(self, generator): def __init__(self, generator):
InterpreterObject.__init__(self) super().__init__()
self.generator = generator self.glist = build.GeneratedList(generator)
self.infilelist = []
self.outfilelist = []
self.outmap = {}
def add_file(self, newfile):
self.infilelist.append(newfile)
outfiles = self.generator.get_base_outnames(newfile)
self.outfilelist += outfiles
self.outmap[newfile] = outfiles
def get_infilelist(self):
return self.infilelist
def get_outfilelist(self):
return self.outfilelist
def get_outputs_for(self, filename):
return self.outmap[filename]
def get_generator(self): def add_file(self, a):
return self.generator self.glist.add_file(a)
class Build(InterpreterObject): class Build(InterpreterObject):
def __init__(self): def __init__(self):
@ -316,21 +253,10 @@ class Host(InterpreterObject):
def is_big_endian_method(self, args, kwargs): def is_big_endian_method(self, args, kwargs):
return sys.byteorder != 'little' return sys.byteorder != 'little'
class IncludeDirs(InterpreterObject): class IncludeDirsHolder(InterpreterObject):
def __init__(self, curdir, dirs, kwargs): def __init__(self, curdir, dirs, kwargs):
InterpreterObject.__init__(self) super().__init__()
self.curdir = curdir self.includedirs = build.IncludeDirs(curdir, dirs, kwargs)
self.incdirs = dirs
# Fixme: check that the directories actually exist.
# Also that they don't contain ".." or somesuch.
if len(kwargs) > 0:
raise InvalidCode('Includedirs function does not take keyword arguments.')
def get_curdir(self):
return self.curdir
def get_incdirs(self):
return self.incdirs
class Headers(InterpreterObject): class Headers(InterpreterObject):
@ -898,7 +824,7 @@ class Interpreter():
return self.build_target(node, args, kwargs, SharedLibraryHolder) return self.build_target(node, args, kwargs, SharedLibraryHolder)
def func_generator(self, node, args, kwargs): def func_generator(self, node, args, kwargs):
gen = Generator(args, kwargs) gen = GeneratorHolder(args, kwargs)
self.generators.append(gen) self.generators.append(gen)
return gen return gen
@ -989,7 +915,7 @@ class Interpreter():
for a in args: for a in args:
if not isinstance(a, str): if not isinstance(a, str):
raise InvalidArguments('Argument %s is not a string.' % str(a)) raise InvalidArguments('Argument %s is not a string.' % str(a))
i = IncludeDirs(self.subdir, args, kwargs) i = IncludeDirsHolder(self.subdir, args, kwargs)
return i return i
def func_add_global_arguments(self, node, args, kwargs): def func_add_global_arguments(self, node, args, kwargs):

Loading…
Cancel
Save