From c38544a6ec3aaf8a160305a31684362ce7d450f9 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Sat, 29 Sep 2018 20:54:42 +0200 Subject: build: move default_install_dir to the Target classes there is a huge amount of isinstance calls, this reduces the amount of these calls while splitting up a rather big function. It also assosiates every target type with theire default install directory. --- mesonbuild/backend/backends.py | 31 ++----------------------------- mesonbuild/build.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 78c2877..e0a593f 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -970,33 +970,6 @@ class Backend: with open(install_data_file, 'wb') as ofile: pickle.dump(d, ofile) - def get_target_install_dirs(self, t): - # Find the installation directory. - if isinstance(t, build.SharedModule): - default_install_dir = self.environment.get_shared_module_dir() - elif isinstance(t, build.SharedLibrary): - default_install_dir = self.environment.get_shared_lib_dir() - elif isinstance(t, build.StaticLibrary): - default_install_dir = self.environment.get_static_lib_dir() - elif isinstance(t, build.Executable): - default_install_dir = self.environment.get_bindir() - elif isinstance(t, build.CustomTarget): - default_install_dir = None - else: - assert(isinstance(t, build.BuildTarget)) - # XXX: Add BuildTarget-specific install dir cases here - default_install_dir = self.environment.get_libdir() - outdirs = t.get_custom_install_dir() - if outdirs[0] is not None and outdirs[0] != default_install_dir and outdirs[0] is not True: - # Either the value is set to a non-default value, or is set to - # False (which means we want this specific output out of many - # outputs to not be installed). - custom_install_dir = True - else: - custom_install_dir = False - outdirs[0] = default_install_dir - return outdirs, custom_install_dir - def get_target_link_deps_mappings(self, t, prefix): ''' On macOS, we need to change the install names of all built libraries @@ -1015,7 +988,7 @@ class Backend: if old in result: continue fname = ld.get_filename() - outdirs, _ = self.get_target_install_dirs(ld) + outdirs, _ = ld.get_install_dir(self.environment) new = os.path.join(prefix, outdirs[0], fname) result.update({old: new}) return result @@ -1024,7 +997,7 @@ class Backend: for t in self.build.get_targets().values(): if not t.should_install(): continue - outdirs, custom_install_dir = self.get_target_install_dirs(t) + outdirs, custom_install_dir = t.get_install_dir(self.environment) # Sanity-check the outputs and install_dirs num_outdirs, num_out = len(outdirs), len(t.get_outputs()) if num_outdirs != 1 and num_outdirs != num_out: diff --git a/mesonbuild/build.py b/mesonbuild/build.py index eb0e294..9279590 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -324,6 +324,20 @@ a hard error in the future.''' % name) self.build_always_stale = False self.option_overrides = {} + def get_install_dir(self, environment): + # Find the installation directory. + default_install_dir = self.get_default_install_dir(environment) + outdirs = self.get_custom_install_dir() + if outdirs[0] is not None and outdirs[0] != default_install_dir and outdirs[0] is not True: + # Either the value is set to a non-default value, or is set to + # False (which means we want this specific output out of many + # outputs to not be installed). + custom_install_dir = True + else: + custom_install_dir = False + outdirs[0] = default_install_dir + return outdirs, custom_install_dir + def get_basename(self): return self.name @@ -686,6 +700,9 @@ class BuildTarget(Target): result.update(i.get_link_dep_subdirs()) return result + def get_default_install_dir(self, environment): + return environment.get_libdir() + def get_custom_install_dir(self): return self.install_dir @@ -1323,6 +1340,9 @@ class Executable(BuildTarget): # Only linkwithable if using export_dynamic self.is_linkwithable = self.export_dynamic + def get_default_install_dir(self, environment): + return environment.get_bindir() + def description(self): '''Human friendly description of the executable''' return self.name @@ -1384,6 +1404,9 @@ class StaticLibrary(BuildTarget): self.filename = self.prefix + self.name + '.' + self.suffix self.outputs = [self.filename] + def get_default_install_dir(self, environment): + return environment.get_static_lib_dir() + def type_suffix(self): return "@sta" @@ -1430,6 +1453,9 @@ class SharedLibrary(BuildTarget): self.basic_filename_tpl = '{0.prefix}{0.name}.{0.suffix}' self.determine_filenames(is_cross, environment) + def get_default_install_dir(self, environment): + return environment.get_shared_lib_dir() + def determine_filenames(self, is_cross, env): """ See https://github.com/mesonbuild/meson/pull/417 for details. @@ -1701,6 +1727,10 @@ class SharedModule(SharedLibrary): raise MesonException('Shared modules must not specify the soversion kwarg.') super().__init__(name, subdir, subproject, is_cross, sources, objects, environment, kwargs) + def get_default_install_dir(self, environment): + return environment.get_shared_module_dir() + + class CustomTarget(Target): known_kwargs = set([ 'input', @@ -1738,6 +1768,9 @@ class CustomTarget(Target): mlog.warning('Unknown keyword arguments in target %s: %s' % (self.name, ', '.join(unknowns))) + def get_default_install_dir(self, environment): + return None + def __lt__(self, other): return self.get_id() < other.get_id() -- cgit v1.1 From c53d35aa721e3c98590ef15c82a87b01ede9f628 Mon Sep 17 00:00:00 2001 From: Marcel Hollerbach Date: Sat, 29 Sep 2018 21:15:00 +0200 Subject: build: generate the mappings in the Targets Before, the mappings has been created over all the links, while it actaully only used the Shared or Static Targets. This structure now is tree like structured and cached, thus the results can be computed a lot faster. The generator step generate_install is now for EFL from 6 sec. down to 0.3s. Which improves the overall build time from ~20 sec. to ~14 sec. --- mesonbuild/backend/backends.py | 28 +--------------------------- mesonbuild/build.py | 35 ++++++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index e0a593f..0a28782 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -27,9 +27,6 @@ from collections import OrderedDict import shlex from functools import lru_cache -@lru_cache(maxsize=None) -def get_target_macos_dylib_install_name(ld): - return get_macos_dylib_install_name(ld.prefix, ld.name, ld.suffix, ld.soversion) class CleanTrees: @@ -970,29 +967,6 @@ class Backend: with open(install_data_file, 'wb') as ofile: pickle.dump(d, ofile) - def get_target_link_deps_mappings(self, t, prefix): - ''' - On macOS, we need to change the install names of all built libraries - that a target depends on using install_name_tool so that the target - continues to work after installation. For this, we need a dictionary - mapping of the install_name value to the new one, so we can change them - on install. - ''' - result = {} - if isinstance(t, build.StaticLibrary): - return result - for ld in t.get_all_link_deps(): - if ld is t or not isinstance(ld, build.SharedLibrary): - continue - old = get_target_macos_dylib_install_name(ld) - if old in result: - continue - fname = ld.get_filename() - outdirs, _ = ld.get_install_dir(self.environment) - new = os.path.join(prefix, outdirs[0], fname) - result.update({old: new}) - return result - def generate_target_install(self, d): for t in self.build.get_targets().values(): if not t.should_install(): @@ -1012,7 +986,7 @@ class Backend: # Install primary build output (library/executable/jar, etc) # Done separately because of strip/aliases/rpath if outdirs[0] is not False: - mappings = self.get_target_link_deps_mappings(t, d.prefix) + mappings = t.get_link_deps_mapping(d.prefix, self.environment) i = TargetInstallData(self.get_target_filename(t), outdirs[0], t.get_aliases(), should_strip, mappings, t.install_rpath, install_mode) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 9279590..9c7b6a4 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -25,7 +25,7 @@ from .mesonlib import File, MesonException, listify, extract_as_list, OrderedSet from .mesonlib import typeslistify, stringlistify, classify_unity_sources from .mesonlib import get_filenames_templates_dict, substitute_values from .mesonlib import for_windows, for_darwin, for_cygwin, for_android, has_path_sep -from .compilers import is_object, clink_langs, sort_clink, lang_suffixes +from .compilers import is_object, clink_langs, sort_clink, lang_suffixes, get_macos_dylib_install_name from .interpreterbase import FeatureNew pch_kwargs = set(['c_pch', 'cpp_pch']) @@ -89,6 +89,10 @@ known_shmod_kwargs = known_build_target_kwargs known_stlib_kwargs = known_build_target_kwargs | {'pic'} known_jar_kwargs = known_exe_kwargs | {'main_class'} +@lru_cache(maxsize=None) +def get_target_macos_dylib_install_name(ld): + return get_macos_dylib_install_name(ld.prefix, ld.name, ld.suffix, ld.soversion) + class InvalidArguments(MesonException): pass @@ -692,6 +696,20 @@ class BuildTarget(Target): result += i.get_all_link_deps() return result + def get_link_deps_mapping(self, prefix, environment): + return self.get_transitive_link_deps_mapping(prefix, environment) + + @lru_cache(maxsize=None) + def get_transitive_link_deps_mapping(self, prefix, environment): + result = {} + for i in self.link_targets: + mapping = i.get_link_deps_mapping(prefix, environment) + #we are merging two dictionaries, while keeping the earlier one dominant + result_tmp = mapping.copy() + result_tmp.update(result) + result = result_tmp + return result + @lru_cache(maxsize=None) def get_link_dep_subdirs(self): result = OrderedSet() @@ -1404,6 +1422,9 @@ class StaticLibrary(BuildTarget): self.filename = self.prefix + self.name + '.' + self.suffix self.outputs = [self.filename] + def get_link_deps_mapping(self, prefix, environment): + return {} + def get_default_install_dir(self, environment): return environment.get_static_lib_dir() @@ -1453,6 +1474,18 @@ class SharedLibrary(BuildTarget): self.basic_filename_tpl = '{0.prefix}{0.name}.{0.suffix}' self.determine_filenames(is_cross, environment) + def get_link_deps_mapping(self, prefix, environment): + result = {} + mappings = self.get_transitive_link_deps_mapping(prefix, environment) + old = get_target_macos_dylib_install_name(self) + if old not in mappings: + fname = self.get_filename() + outdirs, _ = self.get_install_dir(self.environment) + new = os.path.join(prefix, outdirs[0], fname) + result.update({old: new}) + mappings.update(result) + return mappings + def get_default_install_dir(self, environment): return environment.get_shared_lib_dir() -- cgit v1.1