aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Mensinger <daniel@mensinger-ka.de>2018-11-28 19:40:16 +0100
committerDaniel Mensinger <daniel@mensinger-ka.de>2019-01-06 12:19:28 +0100
commita5be893b19daf9e1f08eacc5d7f01389f6e40956 (patch)
tree1497e3a6e6d0d3efc172160f99306852ccc73ca4
parent74274e23ca42260e9be24c3cfaf7550c6c1505d2 (diff)
downloadmeson-a5be893b19daf9e1f08eacc5d7f01389f6e40956.zip
meson-a5be893b19daf9e1f08eacc5d7f01389f6e40956.tar.gz
meson-a5be893b19daf9e1f08eacc5d7f01389f6e40956.tar.bz2
Some code cleanup
-rw-r--r--mesonbuild/backend/backends.py95
-rw-r--r--mesonbuild/build.py12
-rw-r--r--mesonbuild/mintro.py31
-rw-r--r--mesonbuild/msetup.py6
4 files changed, 98 insertions, 46 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index d0c3e0a..9a377d4 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -159,6 +159,7 @@ class Backend:
self.processed_targets = {}
self.build_to_src = mesonlib.relpath(self.environment.get_source_dir(),
self.environment.get_build_dir())
+ self.introspect_data_cache = None # Cache to speed up get_introspection_data
def get_target_filename(self, t):
if isinstance(t, build.CustomTarget):
@@ -1165,20 +1166,10 @@ class Backend:
This is a limited fallback / reference implementation. The backend should override this method.
'''
- def include_dirs_to_path(inc_dirs, src_root, build_root):
- result = []
- if isinstance(inc_dirs, build.IncludeDirs):
- for i in inc_dirs.get_incdirs():
- abs_src = os.path.join(src_root, inc_dirs.get_curdir(), i)
- abs_build = os.path.join(build_root, inc_dirs.get_curdir(), i)
+ if not self.introspect_data_cache:
+ self.introspect_data_cache = {'targets': {}, 'dependencies': {}}
- if os.path.isdir(abs_src):
- result += [abs_src]
-
- if os.path.isdir(abs_build):
- result += [abs_build]
-
- return result
+ reg = re.compile(r'-I(.*)')
def extract_dependency_infromation(dep):
inc_dirs = []
@@ -1194,21 +1185,64 @@ class Backend:
return inc_dirs, args
- def climb_stack(tgt, inc_dirs, extra_args, dep_args):
+ def process_target(tgt, src_root, build_root):
if isinstance(tgt, build.BuildTarget):
+ # First check if the target is cached
+ tgtid = tgt.get_id()
+ if tgtid in self.introspect_data_cache['targets']:
+ c_tgt = self.introspect_data_cache['targets'][tgtid]
+ return c_tgt['inc_dirs'], c_tgt['dep_args'], c_tgt['extra_args']
+
# The build directory is always in the include directories
absbase_src = os.path.join(src_root, tgt.subdir)
absbase_build = os.path.join(build_root, tgt.subdir)
- inc_dirs += [absbase_src, absbase_build]
+ inc_dirs = [absbase_src, absbase_build]
+ dep_args = []
+ extra_args = {}
+ # Handle include directories
for i in tgt.include_dirs:
- inc_dirs += include_dirs_to_path(i, src_root, build_root)
+ if isinstance(i, build.IncludeDirs):
+ for j in i.get_incdirs():
+ abs_src = os.path.join(absbase_src, i.get_curdir(), j)
+ abs_build = os.path.join(absbase_build, i.get_curdir(), j)
+
+ if os.path.isdir(abs_src):
+ inc_dirs += [abs_src]
+
+ if os.path.isdir(abs_build):
+ inc_dirs += [abs_build]
+ # Handle dependencies
for i in tgt.external_deps:
- dep_inc_dirs, args = extract_dependency_infromation(i)
+ if not isinstance(i, base.Dependency):
+ continue
+
+ did = id(i)
+ if did in self.introspect_data_cache['dependencies']:
+ c_entry = self.introspect_data_cache['dependencies'][did]
+ inc_dirs += c_entry['dep_inc_dirs']
+ dep_args += c_entry['dep_cur_args']
+ continue
+
+ dep_inc_dirs = []
+ dep_cur_args = []
+
+ for i in i.get_compile_args():
+ match = reg.match(i)
+ if match:
+ dep_inc_dirs += [match.group(1)]
+ else:
+ dep_cur_args += [i]
+
+ self.introspect_data_cache['dependencies'][did] = {
+ 'dep_inc_dirs': dep_inc_dirs,
+ 'dep_cur_args': dep_cur_args
+ }
inc_dirs += dep_inc_dirs
- dep_args += args
+ dep_args += dep_cur_args
+ # Check for language specific extra args
for i, comp in tgt.compilers.items():
if isinstance(comp, compilers.Compiler):
if i not in extra_args:
@@ -1218,19 +1252,32 @@ class Backend:
extra_args[i] += self.build.get_global_args(comp, tgt.is_cross)
extra_args[i] += self.build.get_project_args(comp, tgt.subproject, tgt.is_cross)
+ # Recursively check the other targets
for i in tgt.link_targets:
- climb_stack(i, inc_dirs, extra_args, dep_args)
+ t_inc_dirs, t_dep_args, t_extra_args = process_target(i, src_root, build_root)
+ inc_dirs += t_inc_dirs
+ dep_args += t_dep_args
+ for ind, arglist in t_extra_args.items():
+ if ind in extra_args:
+ extra_args[ind] += arglist
+ else:
+ extra_args[ind] = arglist
+
+ # Update the cache
+ self.introspect_data_cache['targets'][tgtid] = {
+ 'inc_dirs': inc_dirs,
+ 'dep_args': dep_args,
+ 'extra_args': extra_args
+ }
+
+ return inc_dirs, dep_args, extra_args
src_root = self.build.environment.get_source_dir()
build_root = self.build.environment.get_build_dir()
-
- inc_dirs = []
- extra_args = {}
- dep_args = []
sources = {}
if isinstance(target, build.BuildTarget):
- climb_stack(target, inc_dirs, extra_args, dep_args)
+ inc_dirs, dep_args, extra_args = process_target(target, src_root, build_root)
# Add the dep_args, sort and remove duplicates
for i in extra_args:
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 5d0fefa..1054451 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -345,6 +345,7 @@ a hard error in the future.''' % name)
self.install = False
self.build_always_stale = False
self.option_overrides = {}
+ self.typename = 'unknown target'
def get_install_dir(self, environment):
# Find the installation directory.
@@ -366,6 +367,9 @@ a hard error in the future.''' % name)
def get_subdir(self):
return self.subdir
+ def get_typename(self):
+ return self.typename
+
@staticmethod
def _get_id_hash(target_id):
# We don't really need cryptographic security here.
@@ -1364,6 +1368,7 @@ class Executable(BuildTarget):
if 'pie' not in kwargs and 'b_pie' in environment.coredata.base_options:
kwargs['pie'] = environment.coredata.base_options['b_pie'].value
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
+ self.typename = 'executable'
# Unless overridden, executables have no suffix or prefix. Except on
# Windows and with C#/Mono executables where the suffix is 'exe'
if not hasattr(self, 'prefix'):
@@ -1453,6 +1458,7 @@ class StaticLibrary(BuildTarget):
if 'pic' not in kwargs and 'b_staticpic' in environment.coredata.base_options:
kwargs['pic'] = environment.coredata.base_options['b_staticpic'].value
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
+ self.typename = 'static library'
if 'cs' in self.compilers:
raise InvalidArguments('Static libraries not supported for C#.')
if 'rust' in self.compilers:
@@ -1509,6 +1515,7 @@ class SharedLibrary(BuildTarget):
known_kwargs = known_shlib_kwargs
def __init__(self, name, subdir, subproject, is_cross, sources, objects, environment, kwargs):
+ self.typename = 'shared library'
self.soversion = None
self.ltversion = None
# Max length 2, first element is compatibility_version, second is current_version
@@ -1817,6 +1824,7 @@ class SharedModule(SharedLibrary):
if 'soversion' in kwargs:
raise MesonException('Shared modules must not specify the soversion kwarg.')
super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs)
+ self.typename = 'shared module'
def get_default_install_dir(self, environment):
return environment.get_shared_module_dir()
@@ -1843,6 +1851,7 @@ class CustomTarget(Target):
def __init__(self, name, subdir, subproject, kwargs, absolute_paths=False):
super().__init__(name, subdir, subproject, False)
+ self.typename = 'custom'
self.dependencies = []
self.extra_depends = []
self.depend_files = [] # Files that this target depends on but are not on the command line.
@@ -2084,6 +2093,7 @@ class CustomTarget(Target):
class RunTarget(Target):
def __init__(self, name, command, args, dependencies, subdir, subproject):
super().__init__(name, subdir, subproject, False)
+ self.typename = 'run'
self.command = command
self.args = args
self.dependencies = dependencies
@@ -2124,6 +2134,7 @@ class Jar(BuildTarget):
for t in self.link_targets:
if not isinstance(t, Jar):
raise InvalidArguments('Link target %s is not a jar target.' % t)
+ self.typename = 'jar'
self.filename = self.name + '.jar'
self.outputs = [self.filename]
self.java_args = kwargs.get('java_args', [])
@@ -2160,6 +2171,7 @@ class CustomTargetIndex:
"""
def __init__(self, target, output):
+ self.typename = 'custom'
self.target = target
self.output = output
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index 449220c..6768070 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -104,37 +104,26 @@ def list_targets(builddata: build.Build, installdata, backend: backends.Backend)
if not isinstance(target, build.Target):
raise RuntimeError('Something weird happened. File a bug.')
- if isinstance(backend, backends.Backend):
- sources = backend.get_introspection_data(idname, target)
- else:
- raise RuntimeError('Parameter backend has an invalid type. This is a bug.')
-
- t = {'name': target.get_basename(), 'id': idname, 'sources': sources}
fname = target.get_filename()
if isinstance(fname, list):
fname = [os.path.join(target.subdir, x) for x in fname]
else:
fname = os.path.join(target.subdir, fname)
- t['filename'] = fname
- if isinstance(target, build.Executable):
- typename = 'executable'
- elif isinstance(target, build.SharedLibrary):
- typename = 'shared library'
- elif isinstance(target, build.StaticLibrary):
- typename = 'static library'
- elif isinstance(target, build.CustomTarget):
- typename = 'custom'
- elif isinstance(target, build.RunTarget):
- typename = 'run'
- else:
- typename = 'unknown'
- t['type'] = typename
+
+ t = {
+ 'name': target.get_basename(),
+ 'id': idname,
+ 'type': target.get_typename(),
+ 'filename': fname,
+ 'build_by_default': target.build_by_default,
+ 'sources': backend.get_introspection_data(idname, target)
+ }
+
if installdata and target.should_install():
t['installed'] = True
t['install_filename'] = determine_installed_path(target, installdata)
else:
t['installed'] = False
- t['build_by_default'] = target.build_by_default
tlist.append(t)
return ('targets', tlist)
diff --git a/mesonbuild/msetup.py b/mesonbuild/msetup.py
index 88c9251..491ea2f 100644
--- a/mesonbuild/msetup.py
+++ b/mesonbuild/msetup.py
@@ -221,7 +221,11 @@ class MesonApp:
intro_tests = intr.backend.create_test_serialisation(b.get_tests())
intro_benchmarks = intr.backend.create_test_serialisation(b.get_benchmarks())
intro_install = intr.backend.create_install_data()
- mintro.generate_introspection_file(b, intr.backend)
+ if self.options.profile:
+ fname = os.path.join(self.build_dir, 'meson-private', 'profile-introspector.log')
+ profile.runctx('mintro.generate_introspection_file(b, intr.backend)', globals(), locals(), filename=fname)
+ else:
+ mintro.generate_introspection_file(b, intr.backend)
except:
if 'cdf' in locals():
old_cdf = cdf + '.prev'