From 589a56e78f37861ddf920ae0aa4710b409131fb7 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Tue, 20 Dec 2016 02:01:24 +0530 Subject: [PATCH] Cache the scripts used for postconf and install phases Cache the absolute dir that the script is searched in and the name of the script. These are the only two things that change. Update the test to test for both #1235 and the case when a script of the same name is in a different directory (which also covers the subproject case). Closes #1235 --- mesonbuild/backend/backends.py | 2 +- mesonbuild/build.py | 4 +-- mesonbuild/interpreter.py | 34 ++++++++++++------- mesonbuild/modules/gnome.py | 4 +-- mesonbuild/modules/i18n.py | 2 +- .../60 install script/installed_files.txt | 2 ++ .../common/60 install script/meson.build | 3 ++ .../common/60 install script/src/meson.build | 1 + .../common/60 install script/src/myinstall.py | 12 +++++++ 9 files changed, 45 insertions(+), 19 deletions(-) create mode 100644 test cases/common/60 install script/src/meson.build create mode 100644 test cases/common/60 install script/src/myinstall.py diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 8b6d181ef..ca013faf0 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -641,7 +641,7 @@ class Backend(): child_env.update(env) for s in self.build.postconf_scripts: - cmd = s['exe'].get_command() + s['args'] + cmd = s['exe'] + s['args'] subprocess.check_call(cmd, env=child_env) # Subprojects of subprojects may cause the same dep args to be used diff --git a/mesonbuild/build.py b/mesonbuild/build.py index db92858e7..a9f10c5fc 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1482,9 +1482,9 @@ class Data(): for s in self.sources: assert(isinstance(s, File)) -class InstallScript(dict): +class RunScript(dict): def __init__(self, script, args): - super(InstallScript, self).__init__() + super().__init__() assert(isinstance(script, list)) assert(isinstance(args, list)) self['exe'] = script diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 2bef59508..7e55b8800 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -987,6 +987,7 @@ class MesonMain(InterpreterObject): InterpreterObject.__init__(self) self.build = build self.interpreter = interpreter + self._found_source_scripts = {} self.methods.update({'get_compiler': self.get_compiler_method, 'is_cross_build' : self.is_cross_build_method, 'has_exe_wrapper' : self.has_exe_wrapper_method, @@ -1006,27 +1007,34 @@ class MesonMain(InterpreterObject): 'backend' : self.backend_method, }) + def _find_source_script(self, name, args): + # Prefer scripts in the current source directory + search_dir = os.path.join(self.interpreter.environment.source_dir, + self.interpreter.subdir) + key = (name, search_dir) + if key in self._found_source_scripts: + found = self._found_source_scripts[key] + else: + found = dependencies.ExternalProgram(name, search_dir=search_dir) + if found: + self._found_source_scripts[key] = found + else: + raise InterpreterException('Script {!r} not found'.format(name)) + return build.RunScript(found.get_command(), args) + def add_install_script_method(self, args, kwargs): if len(args) < 1: raise InterpreterException('add_install_script takes one or more arguments') check_stringlist(args, 'add_install_script args must be strings') - scriptbase = args[0] - search_dir = os.path.join(self.interpreter.environment.source_dir, - self.interpreter.subdir) - script = dependencies.ExternalProgram(scriptbase, search_dir=search_dir) - extras = args[1:] - self.build.install_scripts.append({'exe': script.get_command(), 'args': extras}) + script = self._find_source_script(args[0], args[1:]) + self.build.install_scripts.append(script) def add_postconf_script_method(self, args, kwargs): if len(args) < 1: raise InterpreterException('add_postconf_script takes one or more arguments') check_stringlist(args, 'add_postconf_script arguments must be strings') - scriptbase = args[0] - search_dir = os.path.join(self.interpreter.environment.source_dir, - self.interpreter.subdir) - script = dependencies.ExternalProgram(scriptbase, search_dir=search_dir) - extras = args[1:] - self.build.postconf_scripts.append({'exe': script, 'args': extras}) + script = self._find_source_script(args[0], args[1:]) + self.build.postconf_scripts.append(script) def current_source_dir_method(self, args, kwargs): src = self.interpreter.environment.source_dir @@ -1236,7 +1244,7 @@ class Interpreter(InterpreterBase): outvalues.append(GeneratedListHolder(v)) elif isinstance(v, build.RunTarget): self.add_target(v.name, v) - elif isinstance(v, build.InstallScript): + elif isinstance(v, build.RunScript): self.build.install_scripts.append(v) elif isinstance(v, build.Data): self.build.data.append(v) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index dd4d40922..f72ddfaca 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -615,7 +615,7 @@ can not be used with the current version of glib-compiled-resources, due to args.append('--media=' + '@@'.join(media)) if langs: args.append('--langs=' + '@@'.join(langs)) - inscript = build.InstallScript(script, args) + inscript = build.RunScript(script, args) potargs = [state.environment.get_build_command(), '--internal', 'yelphelper', 'pot', '--subdir=' + state.subdir, @@ -699,7 +699,7 @@ can not be used with the current version of glib-compiled-resources, due to args += self._get_build_args(kwargs, state) res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir)] if kwargs.get('install', True): - res.append(build.InstallScript(command, args)) + res.append(build.RunScript(command, args)) return res def _get_build_args(self, kwargs, state): diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index eaeb0a3b7..4df62f238 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -109,7 +109,7 @@ class I18nModule: pkg_arg] if lang_arg: args.append(lang_arg) - iscript = build.InstallScript(script, args) + iscript = build.RunScript(script, args) return [pottarget, gmotarget, iscript, updatepotarget] diff --git a/test cases/common/60 install script/installed_files.txt b/test cases/common/60 install script/installed_files.txt index 94e3164f6..94c1fed2a 100644 --- a/test cases/common/60 install script/installed_files.txt +++ b/test cases/common/60 install script/installed_files.txt @@ -1,2 +1,4 @@ usr/bin/prog?exe usr/diiba/daaba/file.dat +usr/this/should/also-work.dat +usr/this/does/something-different.dat.in diff --git a/test cases/common/60 install script/meson.build b/test cases/common/60 install script/meson.build index 7cbde8d11..6351518fb 100644 --- a/test cases/common/60 install script/meson.build +++ b/test cases/common/60 install script/meson.build @@ -2,3 +2,6 @@ project('custom install script', 'c') executable('prog', 'prog.c', install : true) meson.add_install_script('myinstall.py', 'diiba/daaba', 'file.dat') +meson.add_install_script('myinstall.py', 'this/should', 'also-work.dat') + +subdir('src') diff --git a/test cases/common/60 install script/src/meson.build b/test cases/common/60 install script/src/meson.build new file mode 100644 index 000000000..b23574ac3 --- /dev/null +++ b/test cases/common/60 install script/src/meson.build @@ -0,0 +1 @@ +meson.add_install_script('myinstall.py', 'this/does', 'something-different.dat') diff --git a/test cases/common/60 install script/src/myinstall.py b/test cases/common/60 install script/src/myinstall.py new file mode 100644 index 000000000..d8a5714ac --- /dev/null +++ b/test cases/common/60 install script/src/myinstall.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import os +import sys + +prefix = os.environ['MESON_INSTALL_DESTDIR_PREFIX'] + +dirname = os.path.join(prefix, sys.argv[1]) + +os.makedirs(dirname) +with open(os.path.join(dirname, sys.argv[2] + '.in'), 'w') as f: + f.write('')