aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2014-05-19 00:59:35 +0300
committerJussi Pakkanen <jpakkane@gmail.com>2014-05-19 00:59:35 +0300
commit2ecd2ea65a3c3a81e83d298ed815984b4107b9da (patch)
tree5523c690552a8478cbde77be5d3736aecd33f70b
parentbc9444e1e0bbdc5d4ac86d678de2c626eac41b78 (diff)
downloadmeson-2ecd2ea65a3c3a81e83d298ed815984b4107b9da.zip
meson-2ecd2ea65a3c3a81e83d298ed815984b4107b9da.tar.gz
meson-2ecd2ea65a3c3a81e83d298ed815984b4107b9da.tar.bz2
Can define custom targets.
-rw-r--r--backends.py2
-rw-r--r--build.py63
-rw-r--r--interpreter.py27
-rw-r--r--ninjabackend.py7
-rw-r--r--test cases/common/56 custom target/data_source.txt1
-rw-r--r--test cases/common/56 custom target/installed_files.txt1
-rw-r--r--test cases/common/56 custom target/meson.build14
-rwxr-xr-xtest cases/common/56 custom target/my_compiler.py14
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:
diff --git a/build.py b/build.py
index 2bc715a..8640e8b 100644
--- a/build.py
+++ b/build.py
@@ -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')