diff options
-rw-r--r-- | mesonbuild/astinterpreter.py | 2 | ||||
-rw-r--r-- | mesonbuild/build.py | 11 | ||||
-rw-r--r-- | mesonbuild/environment.py | 2 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 26 | ||||
-rw-r--r-- | mesonbuild/modules/gnome.py | 23 | ||||
-rw-r--r-- | mesonbuild/modules/i18n.py | 14 | ||||
-rw-r--r-- | mesonbuild/scripts/meson_install.py | 140 | ||||
-rw-r--r-- | test cases/common/131 custom target directory install/docgen.py | 12 | ||||
-rw-r--r-- | test cases/common/131 custom target directory install/installed_files.txt | 3 | ||||
-rw-r--r-- | test cases/common/131 custom target directory install/meson.build | 9 | ||||
-rw-r--r-- | test cases/common/60 install script/meson.build | 8 | ||||
-rw-r--r-- | test cases/common/60 install script/myinstall.py | 12 | ||||
-rwxr-xr-x | test cases/common/60 install script/myinstall.sh | 10 |
13 files changed, 154 insertions, 118 deletions
diff --git a/mesonbuild/astinterpreter.py b/mesonbuild/astinterpreter.py index 3691d64..7a83736 100644 --- a/mesonbuild/astinterpreter.py +++ b/mesonbuild/astinterpreter.py @@ -129,7 +129,7 @@ class AstInterpreter(interpreterbase.InterpreterBase): absname = os.path.join(self.source_root, buildfilename) if not os.path.isfile(absname): self.subdir = prev_subdir - raise InterpreterException('Nonexistant build def file %s.' % buildfilename) + raise InterpreterException('Nonexistent build def file %s.' % buildfilename) with open(absname, encoding='utf8') as f: code = f.read() assert(isinstance(code, str)) diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 1c3f4e8..db92858 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -1482,7 +1482,10 @@ class Data(): for s in self.sources: assert(isinstance(s, File)) -class InstallScript: - def __init__(self, cmd_arr): - assert(isinstance(cmd_arr, list)) - self.cmd_arr = cmd_arr +class InstallScript(dict): + def __init__(self, script, args): + super(InstallScript, self).__init__() + assert(isinstance(script, list)) + assert(isinstance(args, list)) + self['exe'] = script + self['args'] = args diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 44c5965..3231fa8 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -457,7 +457,7 @@ class Environment(): if 'PathScale EKOPath(tm)' in err: return PathScaleFortranCompiler([compiler], version, is_cross, exe_wrap) - if 'pgf90' in out: + if 'PGI Compilers' in out: return PGIFortranCompiler([compiler], version, is_cross, exe_wrap) if 'Open64 Compiler Suite' in err: diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index b586997..c92adaf 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1007,26 +1007,26 @@ class MesonMain(InterpreterObject): }) def add_install_script_method(self, args, kwargs): - if len(args) != 1: - raise InterpreterException('Set_install_script takes exactly one argument.') - check_stringlist(args) + 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] - scriptfile = os.path.join(self.interpreter.environment.source_dir, - self.interpreter.subdir, scriptbase) - if not os.path.isfile(scriptfile): - raise InterpreterException('Can not find install script %s.' % scriptbase) - self.build.install_scripts.append(build.InstallScript([scriptfile])) + 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}) def add_postconf_script_method(self, args, kwargs): if len(args) < 1: - raise InterpreterException('Not enough arguments') - check_stringlist(args, 'add_postconf_script arguments must be strings.') + 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) - exe = dependencies.ExternalProgram(scriptbase, search_dir=search_dir) + script = dependencies.ExternalProgram(scriptbase, search_dir=search_dir) extras = args[1:] - self.build.postconf_scripts.append({'exe': exe, 'args': extras}) + self.build.postconf_scripts.append({'exe': script, 'args': extras}) def current_source_dir_method(self, args, kwargs): src = self.interpreter.environment.source_dir @@ -2023,7 +2023,7 @@ requirements use the version keyword argument instead.''') absname = os.path.join(self.environment.get_source_dir(), buildfilename) if not os.path.isfile(absname): self.subdir = prev_subdir - raise InterpreterException('Nonexistant build def file %s.' % buildfilename) + raise InterpreterException('Nonexistent build def file %s.' % buildfilename) with open(absname, encoding='utf8') as f: code = f.read() assert(isinstance(code, str)) diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py index 7a3d51a..9b606f3 100644 --- a/mesonbuild/modules/gnome.py +++ b/mesonbuild/modules/gnome.py @@ -599,10 +599,8 @@ can not be used with the current version of glib-compiled-resources, due to if kwargs: raise MesonException('Unknown arguments passed: {}'.format(', '.join(kwargs.keys()))) - install_cmd = [ - sys.executable, - state.environment.get_build_command(), - '--internal', + script = [sys.executable, state.environment.get_build_command()] + args = ['--internal', 'yelphelper', 'install', '--subdir=' + state.subdir, @@ -611,12 +609,12 @@ can not be used with the current version of glib-compiled-resources, due to '--sources=' + source_str, ] if symlinks: - install_cmd.append('--symlinks=true') + args.append('--symlinks=true') if media: - install_cmd.append('--media=' + '@@'.join(media)) + args.append('--media=' + '@@'.join(media)) if langs: - install_cmd.append('--langs=' + '@@'.join(langs)) - inscript = build.InstallScript(install_cmd) + args.append('--langs=' + '@@'.join(langs)) + inscript = build.InstallScript(script, args) potargs = [state.environment.get_build_command(), '--internal', 'yelphelper', 'pot', '--subdir=' + state.subdir, @@ -654,7 +652,7 @@ can not be used with the current version of glib-compiled-resources, due to raise MesonException('You can only specify main_xml or main_sgml, not both.') main_file = main_xml targetname = modulename + '-doc' - command = [state.environment.get_build_command(), '--internal', 'gtkdoc'] + command = [sys.executable, state.environment.get_build_command()] namespace = kwargs.get('namespace', '') mode = kwargs.get('mode', 'auto') @@ -677,7 +675,8 @@ can not be used with the current version of glib-compiled-resources, due to else: header_dirs.append(src_dir) - args = ['--sourcedir=' + state.environment.get_source_dir(), + args = ['--internal', 'gtkdoc', + '--sourcedir=' + state.environment.get_source_dir(), '--builddir=' + state.environment.get_build_dir(), '--subdir=' + state.subdir, '--headerdirs=' + '@@'.join(header_dirs), @@ -697,9 +696,9 @@ can not be used with the current version of glib-compiled-resources, due to args += self._unpack_args('--ignore-headers=', 'ignore_headers', kwargs) args += self._unpack_args('--installdir=', 'install_dir', kwargs, state) args += self._get_build_args(kwargs, state) - res = [build.RunTarget(targetname, command[0], command[1:] + args, [], state.subdir)] + res = [build.RunTarget(targetname, command[0], command[1:] + sargs, [], state.subdir)] if kwargs.get('install', True): - res.append(build.InstallScript(command + args)) + res.append(build.InstallScript(command, args)) return res def _get_build_args(self, kwargs, state): diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index 29db960..eaeb0a3 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -102,14 +102,14 @@ class I18nModule: updatepoargs.append(extra_args) updatepotarget = build.RunTarget(packagename + '-update-po', sys.executable, updatepoargs, [], state.subdir) - installcmd = [sys.executable, state.environment.get_build_command(), - '--internal', 'gettext', 'install', - '--subdir=' + state.subdir, - '--localedir=' + state.environment.coredata.get_builtin_option('localedir'), - pkg_arg] + script = [sys.executable, state.environment.get_build_command()] + args = ['--internal', 'gettext', 'install', + '--subdir=' + state.subdir, + '--localedir=' + state.environment.coredata.get_builtin_option('localedir'), + pkg_arg] if lang_arg: - installcmd.append(lang_arg) - iscript = build.InstallScript(installcmd) + args.append(lang_arg) + iscript = build.InstallScript(script, args) return [pottarget, gmotarget, iscript, updatepotarget] diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py index f81bf89..0df79e3 100644 --- a/mesonbuild/scripts/meson_install.py +++ b/mesonbuild/scripts/meson_install.py @@ -26,16 +26,55 @@ def append_to_log(line): install_log_file.write('\n') install_log_file.flush() -def do_copy(from_file, to_file): - try: - # Python's copyfile fails if the target file already exists. +def do_copyfile(from_file, to_file): + if not os.path.isfile(from_file): + raise RuntimeError('Tried to install something that isn\'t a file:' + '{!r}'.format(from_file)) + # copyfile fails if the target file already exists, so remove it to + # allow overwriting a previous install. If the target is not a file, we + # want to give a readable error. + if os.path.exists(to_file): + if not os.path.isfile(to_file): + raise RuntimeError('Destination {!r} already exists and is not ' + 'a file'.format(to_file)) os.unlink(to_file) - except FileNotFoundError: - pass shutil.copyfile(from_file, to_file) shutil.copystat(from_file, to_file) append_to_log(to_file) +def do_copydir(src_prefix, src_dir, dst_dir): + ''' + Copies the directory @src_prefix (full path) into @dst_dir + + @src_dir is simply the parent directory of @src_prefix + ''' + for root, dirs, files in os.walk(src_prefix): + for d in dirs: + abs_src = os.path.join(src_dir, root, d) + filepart = abs_src[len(src_dir)+1:] + abs_dst = os.path.join(dst_dir, filepart) + if os.path.isdir(abs_dst): + continue + if os.path.exists(abs_dst): + print('Tried to copy directory %s but a file of that name already exists.' % abs_dst) + sys.exit(1) + os.makedirs(abs_dst) + shutil.copystat(abs_src, abs_dst) + for f in files: + abs_src = os.path.join(src_dir, root, f) + filepart = abs_src[len(src_dir)+1:] + abs_dst = os.path.join(dst_dir, filepart) + if os.path.isdir(abs_dst): + print('Tried to copy file %s but a directory of that name already exists.' % abs_dst) + if os.path.exists(abs_dst): + os.unlink(abs_dst) + parent_dir = os.path.split(abs_dst)[0] + if not os.path.isdir(parent_dir): + os.mkdir(parent_dir) + shutil.copystat(os.path.split(abs_src)[0], parent_dir) + shutil.copy2(abs_src, abs_dst, follow_symlinks=False) + append_to_log(abs_dst) + def get_destdir_path(d, path): if os.path.isabs(path): output = destdir_join(d.destdir, path) @@ -65,32 +104,7 @@ def install_subdirs(data): dst_dir = get_destdir_path(data, dst_dir) if not os.path.exists(dst_dir): os.makedirs(dst_dir) - for root, dirs, files in os.walk(src_prefix): - for d in dirs: - abs_src = os.path.join(src_dir, root, d) - filepart = abs_src[len(src_dir)+1:] - abs_dst = os.path.join(dst_dir, filepart) - if os.path.isdir(abs_dst): - continue - if os.path.exists(abs_dst): - print('Tried to copy directory %s but a file of that name already exists.' % abs_dst) - sys.exit(1) - os.makedirs(abs_dst) - shutil.copystat(abs_src, abs_dst) - for f in files: - abs_src = os.path.join(src_dir, root, f) - filepart = abs_src[len(src_dir)+1:] - abs_dst = os.path.join(dst_dir, filepart) - if os.path.isdir(abs_dst): - print('Tried to copy file %s but a directory of that name already exists.' % abs_dst) - if os.path.exists(abs_dst): - os.unlink(abs_dst) - parent_dir = os.path.split(abs_dst)[0] - if not os.path.isdir(parent_dir): - os.mkdir(parent_dir) - shutil.copystat(os.path.split(abs_src)[0], parent_dir) - shutil.copy2(abs_src, abs_dst, follow_symlinks=False) - append_to_log(abs_dst) + do_copydir(src_prefix, src_dir, dst_dir) def install_data(d): for i in d.data: @@ -99,7 +113,7 @@ def install_data(d): outdir = os.path.split(outfilename)[0] os.makedirs(outdir, exist_ok=True) print('Installing %s to %s.' % (fullfilename, outdir)) - do_copy(fullfilename, outfilename) + do_copyfile(fullfilename, outfilename) def install_man(d): for m in d.man: @@ -115,7 +129,7 @@ def install_man(d): shutil.copystat(full_source_filename, outfilename) append_to_log(outfilename) else: - do_copy(full_source_filename, outfilename) + do_copyfile(full_source_filename, outfilename) def install_headers(d): for t in d.headers: @@ -125,39 +139,28 @@ def install_headers(d): outfilename = os.path.join(outdir, fname) print('Installing %s to %s' % (fname, outdir)) os.makedirs(outdir, exist_ok=True) - do_copy(fullfilename, outfilename) + do_copyfile(fullfilename, outfilename) def run_install_script(d): env = {'MESON_SOURCE_ROOT' : d.source_dir, 'MESON_BUILD_ROOT' : d.build_dir, - 'MESON_INSTALL_PREFIX' : d.prefix + 'MESON_INSTALL_PREFIX' : d.prefix, + 'MESON_INSTALL_DESTDIR_PREFIX' : d.fullprefix, } child_env = os.environ.copy() child_env.update(env) for i in d.install_scripts: - final_command = i.cmd_arr - script = i.cmd_arr[0] - print('Running custom install script %s' % script) - suffix = os.path.splitext(script)[1].lower() - if platform.system().lower() == 'windows' and suffix != '.bat': - with open(script, encoding='latin_1', errors='ignore') as f: - first_line = f.readline().strip() - if first_line.startswith('#!'): - if shutil.which(first_line[2:]): - commands = [first_line[2:]] - else: - commands = first_line[2:].split('#')[0].strip().split() - commands[0] = shutil.which(commands[0].split('/')[-1]) - if commands[0] is None: - raise RuntimeError("Don't know how to run script %s." % script) - final_command = commands + [script] + i.cmd_arr[1:] + script = i['exe'] + args = i['args'] + name = ' '.join(script + args) + print('Running custom install script {!r}'.format(name)) try: - rc = subprocess.call(final_command, env=child_env) + rc = subprocess.call(script + args, env=child_env) if rc != 0: sys.exit(rc) except: - print('Failed to run install script:', *i.cmd_arr) + print('Failed to run install script {!r}'.format(name)) sys.exit(1) def is_elf_platform(): @@ -201,15 +204,23 @@ def install_targets(d): install_rpath = t[4] print('Installing %s to %s' % (fname, outname)) os.makedirs(outdir, exist_ok=True) - do_copy(fname, outname) - if should_strip: - print('Stripping target') - ps, stdo, stde = Popen_safe(['strip', outname]) - if ps.returncode != 0: - print('Could not strip file.\n') - print('Stdout:\n%s\n' % stdo) - print('Stderr:\n%s\n' % stde) - sys.exit(1) + if not os.path.exists(fname): + raise RuntimeError('File {!r} could not be found'.format(fname)) + elif os.path.isfile(fname): + do_copyfile(fname, outname) + if should_strip: + print('Stripping target {!r}'.format(fname)) + ps, stdo, stde = Popen_safe(['strip', outname]) + if ps.returncode != 0: + print('Could not strip file.\n') + print('Stdout:\n%s\n' % stdo) + print('Stderr:\n%s\n' % stde) + sys.exit(1) + elif os.path.isdir(fname): + fname = os.path.join(d.build_dir, fname.rstrip('/')) + do_copydir(fname, os.path.dirname(fname), outdir) + else: + raise RuntimeError('Unknown file type for {!r}'.format(fname)) printed_symlink_error = False for alias in aliases: try: @@ -222,9 +233,10 @@ def install_targets(d): append_to_log(symlinkfilename) except (NotImplementedError, OSError): if not printed_symlink_error: - print("Symlink creation does not work on this platform.") + print("Symlink creation does not work on this platform. " + "Skipping all symlinking.") printed_symlink_error = True - if is_elf_platform(): + if is_elf_platform() and os.path.isfile(outname): try: e = depfixer.Elf(outname, False) e.fix_rpath(install_rpath) diff --git a/test cases/common/131 custom target directory install/docgen.py b/test cases/common/131 custom target directory install/docgen.py new file mode 100644 index 0000000..245f370 --- /dev/null +++ b/test cases/common/131 custom target directory install/docgen.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python3 + +import os +import sys + +out = sys.argv[1] + +os.mkdir(out) + +for name in ('a', 'b', 'c'): + with open(os.path.join(out, name + '.html'), 'w') as f: + f.write(name) diff --git a/test cases/common/131 custom target directory install/installed_files.txt b/test cases/common/131 custom target directory install/installed_files.txt new file mode 100644 index 0000000..bcf20e0 --- /dev/null +++ b/test cases/common/131 custom target directory install/installed_files.txt @@ -0,0 +1,3 @@ +usr/share/doc/testpkgname/html/a.html +usr/share/doc/testpkgname/html/b.html +usr/share/doc/testpkgname/html/c.html diff --git a/test cases/common/131 custom target directory install/meson.build b/test cases/common/131 custom target directory install/meson.build new file mode 100644 index 0000000..ada9ae1 --- /dev/null +++ b/test cases/common/131 custom target directory install/meson.build @@ -0,0 +1,9 @@ +project('custom-target-dir-install', 'c') + +docgen = find_program('docgen.py') + +custom_target('docgen', + output : 'html', + command : [docgen, '@OUTPUT@'], + install : true, + install_dir : join_paths(get_option('datadir'), 'doc/testpkgname')) diff --git a/test cases/common/60 install script/meson.build b/test cases/common/60 install script/meson.build index 6cab840..7cbde8d 100644 --- a/test cases/common/60 install script/meson.build +++ b/test cases/common/60 install script/meson.build @@ -1,8 +1,4 @@ project('custom install script', 'c') -if meson.get_compiler('c').get_id() == 'msvc' - install_data('no-installed-files', install_dir : '') -else - meson.add_install_script('myinstall.sh') - executable('prog', 'prog.c', install : true) -endif +executable('prog', 'prog.c', install : true) +meson.add_install_script('myinstall.py', 'diiba/daaba', 'file.dat') diff --git a/test cases/common/60 install script/myinstall.py b/test cases/common/60 install script/myinstall.py new file mode 100644 index 0000000..969aba5 --- /dev/null +++ b/test cases/common/60 install script/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]), 'w') as f: + f.write('') diff --git a/test cases/common/60 install script/myinstall.sh b/test cases/common/60 install script/myinstall.sh deleted file mode 100755 index 79512c9..0000000 --- a/test cases/common/60 install script/myinstall.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -set -eu - -echo Starting custom installation step - -mkdir -p "${DESTDIR}${MESON_INSTALL_PREFIX}/diiba/daaba" -touch "${DESTDIR}${MESON_INSTALL_PREFIX}/diiba/daaba/file.dat" - -echo Finished custom install step |