Can define custom targets.

pull/15/head
Jussi Pakkanen 11 years ago
parent bc9444e1e0
commit 2ecd2ea65a
  1. 2
      backends.py
  2. 63
      build.py
  3. 27
      interpreter.py
  4. 7
      ninjabackend.py
  5. 1
      test cases/common/56 custom target/data_source.txt
  6. 1
      test cases/common/56 custom target/installed_files.txt
  7. 14
      test cases/common/56 custom target/meson.build
  8. 14
      test cases/common/56 custom target/my_compiler.py

@ -186,6 +186,8 @@ class Backend():
return False
def generate_target(self, target, outfile):
if isinstance(target, build.CustomTarget):
self.generate_custom_target(target, outfile)
name = target.get_basename()
gen_src_deps = []
if name in self.processed_targets:

@ -563,6 +563,69 @@ class SharedLibrary(BuildTarget):
aliases.append(self.get_shbase())
return aliases
class CustomTarget:
def __init__(self, name, subdir, kwargs):
self.name = name
self.subdir = subdir
self.process_kwargs(kwargs)
def process_kwargs(self, kwargs):
if 'output' not in kwargs:
raise InvalidArguments('Missing keyword argument "output".')
self.output = kwargs['output']
if not(isinstance(self.output, str)):
raise InvalidArguments('Output argument not a string.')
if '/' in self.output:
raise InvalidArguments('Output must not contain a path segment.')
if 'command' not in kwargs:
raise InvalidArguments('Missing keyword argument "command".')
cmd = kwargs['command']
if not(isinstance(cmd, list)):
cmd = [cmd]
final_cmd = []
for i, c in enumerate(cmd):
if hasattr(c, 'ep'):
c = c.ep
if isinstance(c, str):
final_cmd.append(c)
elif isinstance(c, dependencies.ExternalProgram):
final_cmd.append(c.get_command())
else:
raise InvalidArguments('Argument %s in "command" is invalid.' % i)
self.command = final_cmd
if 'install' in kwargs:
self.install = kwargs['install']
if not isinstance(self.install, bool):
raise InvalidArguments('"install" must be boolean.')
if 'install_dir' not in kwargs:
raise InvalidArguments('"install_dir" not specified.')
self.install_dir = kwargs['install_dir']
if not(isinstance(self.install_dir, str)):
raise InvalidArguments('"install_dir" must be a string.')
else:
self.install = False
def get_basename(self):
return self.name
def get_dependencies(self):
return []
def should_install(self):
return self.install
def get_custom_install_dir(self):
return self.install_dir
def get_subdir(self):
return self.subdir
def get_filename(self):
return self.output
def get_aliaslist(self):
return []
class Jar(BuildTarget):
def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs):
super().__init__(name, subdir, is_cross, sources, objects, environment, kwargs);

@ -372,6 +372,17 @@ class JarHolder(BuildTargetHolder):
def __init__(self, name, subdir, is_cross, sources, objects, environment, kwargs):
super().__init__(build.Jar, name, subdir, is_cross, sources, objects, environment, kwargs)
class CustomTargetHolder(InterpreterObject):
def __init__(self, name, subdir, kwargs):
self.held_object = build.CustomTarget(name, subdir, kwargs)
def is_cross(self):
return self.held_object.is_cross()
def extract_objects_method(self, args, kwargs):
gobjs = self.held_object.extract_objects(args)
return GeneratedObjectsHolder(gobjs)
class Test(InterpreterObject):
def __init__(self, name, exe, is_parallel, cmd_args, env):
InterpreterObject.__init__(self)
@ -647,6 +658,7 @@ class Interpreter():
'static_library' : self.func_static_lib,
'shared_library' : self.func_shared_lib,
'jar' : self.func_jar,
'custom_target' : self.func_custom_target,
'generator' : self.func_generator,
'test' : self.func_test,
'headers' : self.func_headers,
@ -1008,6 +1020,21 @@ class Interpreter():
def func_jar(self, node, args, kwargs):
return self.build_target(node, args, kwargs, JarHolder)
def func_custom_target(self, node, args, kwargs):
if len(args) != 1:
raise InterpreterException('Incorrect number of arguments')
name = args[0]
if not isinstance(name, str):
raise InterpreterException('Argument must be a string.')
if name in coredata.forbidden_target_names:
raise InvalidArguments('Target name "%s" is reserved for Meson\'s internal use. Please rename.'\
% name)
if name in self.build.targets:
raise InvalidCode('Tried to create target "%s", but a target of that name already exists.' % name)
tg = CustomTargetHolder(name, self.subdir, kwargs)
self.build.targets[name] = tg.held_object
return tg
def func_generator(self, node, args, kwargs):
gen = GeneratorHolder(args, kwargs)
self.generators.append(gen)

@ -134,6 +134,13 @@ class NinjaBackend(backends.Backend):
outfile.close()
os.replace(tempfilename, outfilename)
def generate_custom_target(self, target, outfile):
ofilename = os.path.join(target.subdir, target.output)
elem = NinjaBuildElement(ofilename, 'CUSTOM_COMMAND', '')
elem.add_item('COMMAND', target.command)
elem.write(outfile)
self.processed_targets[target.name] = True
def generate_po(self, outfile):
for p in self.build.pot:
(packagename, languages, subdir) = p

@ -0,0 +1 @@
This is a text only input file.

@ -0,0 +1,14 @@
project('custom target', 'c')
python = find_program('python3')
comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
infile = '@0@/@1@'.format(meson.current_source_dir(), 'data_source.txt')
outfile = '@0@/@1@'.format(meson.current_build_dir(), 'data.dat')
mytarget = custom_target('bindat',
output : 'data.dat',
command : [python, comp, infile, outfile],
install : true,
install_dir : 'subdir'
)

@ -0,0 +1,14 @@
#!/usr/bin/python3
import sys
if __name__ == '__main__':
if len(sys.argv) != 3:
print(sys.argv[0], 'input_file output_file')
sys.exit(1)
ifile = open(sys.argv[1]).read()
if ifile != 'This is a text only input file.\n':
print('Malformed input')
sys.exit(1)
ofile = open(sys.argv[2], 'w')
ofile.write('This is a binary output file.\n')
Loading…
Cancel
Save