aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/astinterpreter.py2
-rw-r--r--mesonbuild/build.py11
-rw-r--r--mesonbuild/environment.py2
-rw-r--r--mesonbuild/interpreter.py26
-rw-r--r--mesonbuild/modules/gnome.py23
-rw-r--r--mesonbuild/modules/i18n.py14
-rw-r--r--mesonbuild/scripts/meson_install.py140
-rw-r--r--test cases/common/131 custom target directory install/docgen.py12
-rw-r--r--test cases/common/131 custom target directory install/installed_files.txt3
-rw-r--r--test cases/common/131 custom target directory install/meson.build9
-rw-r--r--test cases/common/60 install script/meson.build8
-rw-r--r--test cases/common/60 install script/myinstall.py12
-rwxr-xr-xtest cases/common/60 install script/myinstall.sh10
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