diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2014-05-19 00:59:35 +0300 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2014-05-19 00:59:35 +0300 |
commit | 2ecd2ea65a3c3a81e83d298ed815984b4107b9da (patch) | |
tree | 5523c690552a8478cbde77be5d3736aecd33f70b | |
parent | bc9444e1e0bbdc5d4ac86d678de2c626eac41b78 (diff) | |
download | meson-2ecd2ea65a3c3a81e83d298ed815984b4107b9da.zip meson-2ecd2ea65a3c3a81e83d298ed815984b4107b9da.tar.gz meson-2ecd2ea65a3c3a81e83d298ed815984b4107b9da.tar.bz2 |
Can define custom targets.
-rw-r--r-- | backends.py | 2 | ||||
-rw-r--r-- | build.py | 63 | ||||
-rw-r--r-- | interpreter.py | 27 | ||||
-rw-r--r-- | ninjabackend.py | 7 | ||||
-rw-r--r-- | test cases/common/56 custom target/data_source.txt | 1 | ||||
-rw-r--r-- | test cases/common/56 custom target/installed_files.txt | 1 | ||||
-rw-r--r-- | test cases/common/56 custom target/meson.build | 14 | ||||
-rwxr-xr-x | test cases/common/56 custom target/my_compiler.py | 14 |
8 files changed, 129 insertions, 0 deletions
diff --git a/backends.py b/backends.py index 9edb62d..30a8aa3 100644 --- a/backends.py +++ b/backends.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); diff --git a/interpreter.py b/interpreter.py index f732923..03ee59d 100644 --- a/interpreter.py +++ b/interpreter.py @@ -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, @@ -1007,6 +1019,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) diff --git a/ninjabackend.py b/ninjabackend.py index 48dfaf1..ff491b7 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -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 diff --git a/test cases/common/56 custom target/data_source.txt b/test cases/common/56 custom target/data_source.txt new file mode 100644 index 0000000..0c23cc0 --- /dev/null +++ b/test cases/common/56 custom target/data_source.txt @@ -0,0 +1 @@ +This is a text only input file. diff --git a/test cases/common/56 custom target/installed_files.txt b/test cases/common/56 custom target/installed_files.txt new file mode 100644 index 0000000..6baed14 --- /dev/null +++ b/test cases/common/56 custom target/installed_files.txt @@ -0,0 +1 @@ +subdir/data.dat diff --git a/test cases/common/56 custom target/meson.build b/test cases/common/56 custom target/meson.build new file mode 100644 index 0000000..c53dda2 --- /dev/null +++ b/test cases/common/56 custom target/meson.build @@ -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' +) diff --git a/test cases/common/56 custom target/my_compiler.py b/test cases/common/56 custom target/my_compiler.py new file mode 100755 index 0000000..3165cf8 --- /dev/null +++ b/test cases/common/56 custom target/my_compiler.py @@ -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') |