aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbackends.py8
-rwxr-xr-xenvironment.py1
-rwxr-xr-xinterpreter.py38
-rw-r--r--test cases/common/31 find program/meson.build12
-rw-r--r--test cases/common/31 find program/source.in3
5 files changed, 57 insertions, 5 deletions
diff --git a/backends.py b/backends.py
index d237e76..cf116a2 100755
--- a/backends.py
+++ b/backends.py
@@ -442,7 +442,10 @@ class NinjaBackend(Backend):
outfilelist = genlist.get_outfilelist()
if len(infilelist) != len(outfilelist):
raise RuntimeError('Internal data structures broken.')
- exe_file = os.path.join(self.environment.get_build_dir(), self.get_target_filename(exe))
+ if isinstance(exe, interpreter.BuildTarget):
+ exe_file = os.path.join(self.environment.get_build_dir(), self.get_target_filename(exe))
+ else:
+ exe_file = exe.get_command()
base_args = generator.get_arglist()
for i in range(len(infilelist)):
infilename = os.path.join(self.build_to_src, infilelist[i])
@@ -452,7 +455,8 @@ class NinjaBackend(Backend):
cmdlist = [exe_file] + args
elem = NinjaBuildElement(outfilename, 'CUSTOM_COMMAND', infilename)
elem.add_item('DESC', 'Generating $out')
- elem.add_dep(self.get_target_filename(exe))
+ if isinstance(exe, interpreter.BuildTarget):
+ elem.add_dep(self.get_target_filename(exe))
elem.add_item('COMMAND', cmdlist)
elem.write(outfile)
diff --git a/environment.py b/environment.py
index b8fa5ce..28b2221 100755
--- a/environment.py
+++ b/environment.py
@@ -228,7 +228,6 @@ def is_osx():
return platform.system().lower() == 'darwin'
def is_windows():
- print(platform.system().lower())
return platform.system().lower() == 'windows'
header_suffixes = ['h', 'hh', 'hpp', 'hxx', 'H']
diff --git a/interpreter.py b/interpreter.py
index 4b95105..94b1c5c 100755
--- a/interpreter.py
+++ b/interpreter.py
@@ -18,6 +18,7 @@ import mparser
import nodes
import environment
import os, sys, platform
+import shutil
class InterpreterException(Exception):
pass
@@ -38,13 +39,33 @@ class InterpreterObject():
return self.methods[method_name](args, kwargs)
raise InvalidCode('Unknown method "%s" in object.' % method_name)
+class ExternalProgram(InterpreterObject):
+
+ def __init__(self, name, fullpath=None):
+ InterpreterObject.__init__(self)
+ self.name = name
+ self.fullpath = fullpath
+
+ def found(self):
+ return self.fullpath is not None
+
+ def found_method(self, args, kwargs):
+ return self.found()
+
+ def get_command(self):
+ return self.fullpath
+
+ def get_name(self):
+ return self.name
+
class Generator(InterpreterObject):
def __init__(self, args, kwargs):
InterpreterObject.__init__(self)
if len(args) != 1:
raise InvalidArguments('Generator requires one and only one positional argument')
- if not isinstance(args[0], Executable):
+ if not isinstance(args[0], Executable) and \
+ not isinstance(args[0], ExternalProgram):
raise InvalidArguments('First generator argument must be an executable object.')
self.exe = args[0]
self.methods.update({'process' : self.process_method})
@@ -244,7 +265,7 @@ class BuildTarget(InterpreterObject):
self.generated = []
self.process_sourcelist(sources)
self.process_kwargs(kwargs)
- if len(self.sources) == 0:
+ if len(self.sources) == 0 and len(self.generated) == 0:
raise InvalidArguments('Build target %s has no sources.' % name)
def process_sourcelist(self, sources):
@@ -474,6 +495,7 @@ class Interpreter():
'configure_file' : self.func_configure_file,
'include_directories' : self.func_include_directories,
'add_global_arguments' : self.func_add_global_arguments,
+ 'find_program' : self.func_find_program,
}
def get_build_def_files(self):
@@ -587,6 +609,18 @@ class Interpreter():
self.coredata.compilers[lang] = comp
self.build.compilers.append(comp)
+ def func_find_program(self, node, args, kwargs):
+ self.validate_arguments(args, 1, [str])
+ required = kwargs.get('required', False)
+ if not isinstance(required, bool):
+ raise InvalidArguments('Line %d: "required" argument must be a boolean.' % node.lineno())
+ exename = args[0]
+ result = shutil.which(exename) # Does .exe appending on Windows.
+ progobj = ExternalProgram(exename, result)
+ if required and not progobj.found():
+ raise InvalidArguments('Line %d: program "%s" not found.' % (node.lineno(), exename))
+ return progobj
+
def func_find_dep(self, node, args, kwargs):
self.validate_arguments(args, 1, [str])
name = args[0]
diff --git a/test cases/common/31 find program/meson.build b/test cases/common/31 find program/meson.build
new file mode 100644
index 0000000..61913e9
--- /dev/null
+++ b/test cases/common/31 find program/meson.build
@@ -0,0 +1,12 @@
+project('find program', 'c')
+
+cp = find_program('cp', required : true)
+
+
+gen = generator(cp, \
+ output_name : '@BASENAME@.c', \
+ arguments : ['@INPUT@', '@OUTPUT@'])
+
+generated = gen.process('source.in')
+e = executable('prog', generated)
+add_test('external exe', e)
diff --git a/test cases/common/31 find program/source.in b/test cases/common/31 find program/source.in
new file mode 100644
index 0000000..5c2fa9b
--- /dev/null
+++ b/test cases/common/31 find program/source.in
@@ -0,0 +1,3 @@
+int main(int argc, char **argv) {
+ return 0;
+}