summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2019-01-20 19:27:42 +0100
committerDaniel Mensinger <daniel@mensinger-ka.de>2019-01-22 16:09:35 +0100
commit08da3873ddf81a97cdce782d8cde4b904280d8f5 (patch)
treecc6ec4dfb01b2e640867e9a93ea62dbacf303075
parent005a62491b7f93c08dc471ee16d8f9e3b1888f55 (diff)
downloadmeson-08da3873ddf81a97cdce782d8cde4b904280d8f5.tar.gz
Added target AST Interpreter support
-rw-r--r--mesonbuild/ast/interpreter.py29
-rw-r--r--mesonbuild/ast/introspection.py94
2 files changed, 115 insertions, 8 deletions
diff --git a/mesonbuild/ast/interpreter.py b/mesonbuild/ast/interpreter.py
index 032337833..28f115039 100644
--- a/mesonbuild/ast/interpreter.py
+++ b/mesonbuild/ast/interpreter.py
@@ -170,16 +170,33 @@ class AstInterpreter(interpreterbase.InterpreterBase):
def assignment(self, node):
pass
- def flatten_args(self, args):
+ def flatten_args(self, args, include_unknown_args: bool = False):
# Resolve mparser.ArrayNode if needed
flattend_args = []
+ temp_args = []
if isinstance(args, mparser.ArrayNode):
- args = [x.value for x in args.args.arguments]
+ args = [x for x in args.args.arguments]
+ elif isinstance(args, mparser.ArgumentNode):
+ args = [x for x in args.arguments]
for i in args:
if isinstance(i, mparser.ArrayNode):
- flattend_args += [x.value for x in i.args.arguments]
- elif isinstance(i, str):
- flattend_args += [i]
+ temp_args += [x for x in i.args.arguments]
else:
- pass
+ temp_args += [i]
+ for i in temp_args:
+ if isinstance(i, mparser.ElementaryNode):
+ flattend_args += [i.value]
+ elif isinstance(i, (str, bool, int, float)) or include_unknown_args:
+ flattend_args += [i]
return flattend_args
+
+ def flatten_kwargs(self, kwargs: object, include_unknown_args: bool = False):
+ flattend_kwargs = {}
+ for key, val in kwargs.items():
+ if isinstance(val, mparser.ElementaryNode):
+ flattend_kwargs[key] = val.value
+ elif isinstance(val, (mparser.ArrayNode, mparser.ArgumentNode)):
+ flattend_kwargs[key] = self.flatten_args(val, include_unknown_args)
+ elif isinstance(val, (str, bool, int, float)) or include_unknown_args:
+ flattend_kwargs[key] = val
+ return flattend_kwargs
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index f21788c44..fde9cc176 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -19,8 +19,9 @@ from . import AstInterpreter
from .. import compilers, environment, mesonlib, mparser, optinterpreter
from .. import coredata as cdata
from ..interpreterbase import InvalidArguments
+from ..build import Executable, CustomTarget, Jar, RunTarget, SharedLibrary, SharedModule, StaticLibrary
-import os
+import sys, os
class IntrospectionHelper:
# mimic an argparse namespace
@@ -48,10 +49,18 @@ class IntrospectionInterpreter(AstInterpreter):
self.backend = backend
self.default_options = {'backend': self.backend}
self.project_data = {}
+ self.targets = []
self.funcs.update({
+ 'add_languages': self.func_add_languages,
+ 'executable': self.func_executable,
+ 'jar': self.func_jar,
+ 'library': self.func_library,
'project': self.func_project,
- 'add_languages': self.func_add_languages
+ 'shared_library': self.func_shared_lib,
+ 'shared_module': self.func_shared_module,
+ 'static_library': self.func_static_lib,
+ 'both_libraries': self.func_both_lib,
})
def func_project(self, node, args, kwargs):
@@ -115,6 +124,87 @@ class IntrospectionInterpreter(AstInterpreter):
if lang not in self.coredata.compilers:
self.environment.detect_compilers(lang, need_cross_compiler)
+ def build_target(self, node, args, kwargs, targetclass):
+ if not args:
+ return
+ args = self.flatten_args(args, True)
+ kwargs = self.flatten_kwargs(kwargs, True)
+ name = args[0]
+ sources = args[1:]
+ if 'sources' in kwargs:
+ sources += self.flatten_args(kwargs['sources'])
+
+ # Filter out kwargs from other target types. For example 'soversion'
+ # passed to library() when default_library == 'static'.
+ kwargs = {k: v for k, v in kwargs.items() if k in targetclass.known_kwargs}
+
+ is_cross = False
+ objects = []
+ target = targetclass(name, self.subdir, self.subproject, is_cross, sources, objects, self.environment, kwargs)
+
+ self.targets += [{
+ 'name': target.get_basename(),
+ 'id': target.get_id(),
+ 'type': target.get_typename(),
+ 'defined_in': os.path.normpath(os.path.join(self.source_root, self.subdir, environment.build_filename)),
+ 'subdir': self.subdir,
+ 'build_by_default': target.build_by_default,
+ 'sources': sources,
+ 'kwargs': kwargs,
+ 'node': node,
+ }]
+
+ return
+
+ def build_library(self, node, args, kwargs):
+ default_library = self.coredata.get_builtin_option('default_library')
+ if default_library == 'shared':
+ return self.build_target(node, args, kwargs, SharedLibrary)
+ elif default_library == 'static':
+ return self.build_target(node, args, kwargs, StaticLibrary)
+ elif default_library == 'both':
+ return self.build_target(node, args, kwargs, SharedLibrary)
+
+ def func_executable(self, node, args, kwargs):
+ return self.build_target(node, args, kwargs, Executable)
+
+ def func_static_lib(self, node, args, kwargs):
+ return self.build_target(node, args, kwargs, StaticLibrary)
+
+ def func_shared_lib(self, node, args, kwargs):
+ return self.build_target(node, args, kwargs, SharedLibrary)
+
+ def func_both_lib(self, node, args, kwargs):
+ return self.build_target(node, args, kwargs, SharedLibrary)
+
+ def func_shared_module(self, node, args, kwargs):
+ return self.build_target(node, args, kwargs, SharedModule)
+
+ def func_library(self, node, args, kwargs):
+ return self.build_library(node, args, kwargs)
+
+ def func_jar(self, node, args, kwargs):
+ return self.build_target(node, args, kwargs, Jar)
+
+ def func_build_target(self, node, args, kwargs):
+ if 'target_type' not in kwargs:
+ return
+ target_type = kwargs.pop('target_type')
+ if isinstance(target_type, mparser.ElementaryNode):
+ target_type = target_type.value
+ if target_type == 'executable':
+ return self.build_target(node, args, kwargs, Executable)
+ elif target_type == 'shared_library':
+ return self.build_target(node, args, kwargs, SharedLibrary)
+ elif target_type == 'static_library':
+ return self.build_target(node, args, kwargs, StaticLibrary)
+ elif target_type == 'both_libraries':
+ return self.build_target(node, args, kwargs, SharedLibrary)
+ elif target_type == 'library':
+ return self.build_library(node, args, kwargs)
+ elif target_type == 'jar':
+ return self.build_target(node, args, kwargs, Jar)
+
def is_subproject(self):
return self.subproject != ''