aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/ninjabackend.py15
-rw-r--r--mesonbuild/build.py11
-rw-r--r--mesonbuild/interpreter.py25
-rw-r--r--mesonbuild/scripts/meson_install.py24
4 files changed, 51 insertions, 24 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index c7e194e..1aff06f 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -724,6 +724,7 @@ int dummy;
"Pass 'false' for outputs that should not be installed and 'true' for\n" \
'using the default installation directory for an output.'
raise MesonException(m.format(t.name, num_out, t.get_outputs(), num_outdirs))
+ install_mode = t.get_custom_install_mode()
# Install the target output(s)
if isinstance(t, build.BuildTarget):
should_strip = self.get_option_for_target('strip', t)
@@ -731,7 +732,7 @@ int dummy;
# Done separately because of strip/aliases/rpath
if outdirs[0] is not False:
i = [self.get_target_filename(t), outdirs[0],
- t.get_aliases(), should_strip, t.install_rpath]
+ t.get_aliases(), should_strip, t.install_rpath, install_mode]
d.targets.append(i)
# On toolchains/platforms that use an import library for
# linking (separate from the shared library with all the
@@ -749,7 +750,7 @@ int dummy;
implib_install_dir,
# It has no aliases, should not be stripped, and
# doesn't have an install_rpath
- {}, False, '']
+ {}, False, '', install_mode]
d.targets.append(i)
# Install secondary outputs. Only used for Vala right now.
if num_outdirs > 1:
@@ -758,7 +759,7 @@ int dummy;
if outdir is False:
continue
f = os.path.join(self.get_target_dir(t), output)
- d.targets.append([f, outdir, {}, False, None])
+ d.targets.append([f, outdir, {}, False, None, install_mode])
elif isinstance(t, build.CustomTarget):
# If only one install_dir is specified, assume that all
# outputs will be installed into it. This is for
@@ -770,14 +771,14 @@ int dummy;
if num_outdirs == 1 and num_out > 1:
for output in t.get_outputs():
f = os.path.join(self.get_target_dir(t), output)
- d.targets.append([f, outdirs[0], {}, False, None])
+ d.targets.append([f, outdirs[0], {}, False, None, install_mode])
else:
for output, outdir in zip(t.get_outputs(), outdirs):
# User requested that we not install this output
if outdir is False:
continue
f = os.path.join(self.get_target_dir(t), output)
- d.targets.append([f, outdir, {}, False, None])
+ d.targets.append([f, outdir, {}, False, None, install_mode])
def generate_custom_install_script(self, d):
result = []
@@ -809,7 +810,7 @@ int dummy;
msg = 'Invalid header type {!r} can\'t be installed'
raise MesonException(msg.format(f))
abspath = f.absolute_path(srcdir, builddir)
- i = [abspath, outdir]
+ i = [abspath, outdir, h.get_custom_install_mode()]
d.headers.append(i)
def generate_man_install(self, d):
@@ -823,7 +824,7 @@ int dummy;
subdir = os.path.join(manroot, 'man' + num)
srcabs = f.absolute_path(self.environment.get_source_dir(), self.environment.get_build_dir())
dstabs = os.path.join(subdir, os.path.basename(f.fname) + '.gz')
- i = [srcabs, dstabs]
+ i = [srcabs, dstabs, m.get_custom_install_mode()]
d.man.append(i)
def generate_data_install(self, d):
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 0bcb98f..1e7f5fe 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -64,6 +64,7 @@ buildtarget_kwargs = set([
'install',
'install_rpath',
'install_dir',
+ 'install_mode',
'name_prefix',
'name_suffix',
'native',
@@ -668,6 +669,9 @@ class BuildTarget(Target):
def get_custom_install_dir(self):
return self.install_dir
+ def get_custom_install_mode(self):
+ return self.install_mode
+
def process_kwargs(self, kwargs, environment):
super().process_kwargs(kwargs)
self.copy_kwargs(kwargs)
@@ -745,6 +749,7 @@ This will become a hard error in a future Meson release.''')
# the list index of that item will not be installed
self.install_dir = typeslistify(kwargs.get('install_dir', [None]),
(str, bool))
+ self.install_mode = kwargs.get('install_mode', None)
main_class = kwargs.get('main_class', '')
if not isinstance(main_class, str):
raise InvalidArguments('Main class must be a string')
@@ -1626,6 +1631,7 @@ class CustomTarget(Target):
'capture',
'install',
'install_dir',
+ 'install_mode',
'build_always',
'depends',
'depend_files',
@@ -1774,9 +1780,11 @@ class CustomTarget(Target):
# If an item in this list is False, the output corresponding to
# the list index of that item will not be installed
self.install_dir = typeslistify(kwargs['install_dir'], (str, bool))
+ self.install_mode = kwargs.get('install_mode', None)
else:
self.install = False
self.install_dir = [None]
+ self.install_mode = None
self.build_always = kwargs.get('build_always', False)
if not isinstance(self.build_always, bool):
raise InvalidArguments('Argument build_always must be a boolean.')
@@ -1803,6 +1811,9 @@ class CustomTarget(Target):
def get_custom_install_dir(self):
return self.install_dir
+ def get_custom_install_mode(self):
+ return self.install_mode
+
def get_outputs(self):
return self.outputs
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 93fd237..b596ddc 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -577,6 +577,7 @@ class Headers(InterpreterObject):
self.sources = sources
self.install_subdir = kwargs.get('subdir', '')
self.custom_install_dir = kwargs.get('install_dir', None)
+ self.custom_install_mode = kwargs.get('install_mode', None)
if self.custom_install_dir is not None:
if not isinstance(self.custom_install_dir, str):
raise InterpreterException('Custom_install_dir must be a string.')
@@ -593,6 +594,9 @@ class Headers(InterpreterObject):
def get_custom_install_dir(self):
return self.custom_install_dir
+ def get_custom_install_mode(self):
+ return self.custom_install_mode
+
class DataHolder(InterpreterObject, ObjectHolder):
def __init__(self, data):
InterpreterObject.__init__(self)
@@ -624,6 +628,7 @@ class Man(InterpreterObject):
self.sources = sources
self.validate_sources()
self.custom_install_dir = kwargs.get('install_dir', None)
+ self.custom_install_mode = kwargs.get('install_mode', None)
if self.custom_install_dir is not None and not isinstance(self.custom_install_dir, str):
raise InterpreterException('Custom_install_dir must be a string.')
@@ -639,6 +644,9 @@ class Man(InterpreterObject):
def get_custom_install_dir(self):
return self.custom_install_dir
+ def get_custom_install_mode(self):
+ return self.custom_install_mode
+
def get_sources(self):
return self.sources
@@ -1716,8 +1724,8 @@ permitted_kwargs = {'add_global_arguments': {'language'},
'add_test_setup': {'exe_wrapper', 'gdb', 'timeout_multiplier', 'env'},
'benchmark': {'args', 'env', 'should_fail', 'timeout', 'workdir', 'suite'},
'build_target': known_build_target_kwargs,
- 'configure_file': {'input', 'output', 'configuration', 'command', 'copy', 'install_dir', 'capture', 'install', 'format', 'output_format'},
- 'custom_target': {'input', 'output', 'command', 'install', 'install_dir', 'build_always', 'capture', 'depends', 'depend_files', 'depfile', 'build_by_default'},
+ 'configure_file': {'input', 'output', 'configuration', 'command', 'copy', 'install_dir', 'install_mode', 'capture', 'install', 'format', 'output_format'},
+ 'custom_target': {'input', 'output', 'command', 'install', 'install_dir', 'install_mode', 'build_always', 'capture', 'depends', 'depend_files', 'depfile', 'build_by_default'},
'dependency': {'default_options', 'fallback', 'language', 'main', 'method', 'modules', 'optional_modules', 'native', 'required', 'static', 'version', 'private_headers'},
'declare_dependency': {'include_directories', 'link_with', 'sources', 'dependencies', 'compile_args', 'link_args', 'link_whole', 'version'},
'executable': build.known_exe_kwargs,
@@ -1725,8 +1733,8 @@ permitted_kwargs = {'add_global_arguments': {'language'},
'generator': {'arguments', 'output', 'depfile', 'capture', 'preserve_path_from'},
'include_directories': {'is_system'},
'install_data': {'install_dir', 'install_mode', 'rename', 'sources'},
- 'install_headers': {'install_dir', 'subdir'},
- 'install_man': {'install_dir'},
+ 'install_headers': {'install_dir', 'install_mode', 'subdir'},
+ 'install_man': {'install_dir', 'install_mode'},
'install_subdir': {'exclude_files', 'exclude_directories', 'install_dir', 'install_mode', 'strip_directory'},
'jar': build.known_jar_kwargs,
'project': {'version', 'meson_version', 'default_options', 'license', 'subproject_dir'},
@@ -2932,6 +2940,7 @@ root and issuing %s.
if len(args) != 1:
raise InterpreterException('custom_target: Only one positional argument is allowed, and it must be a string name')
name = args[0]
+ kwargs['install_mode'] = self._get_kwarg_install_mode(kwargs)
tg = CustomTargetHolder(build.CustomTarget(name, self.subdir, self.subproject, kwargs), self)
self.add_target(name, tg.held_object)
return tg
@@ -3058,6 +3067,7 @@ root and issuing %s.
@permittedKwargs(permitted_kwargs['install_headers'])
def func_install_headers(self, node, args, kwargs):
source_files = self.source_strings_to_files(args)
+ kwargs['install_mode'] = self._get_kwarg_install_mode(kwargs)
h = Headers(source_files, kwargs)
self.build.headers.append(h)
return h
@@ -3065,6 +3075,7 @@ root and issuing %s.
@permittedKwargs(permitted_kwargs['install_man'])
def func_install_man(self, node, args, kwargs):
fargs = self.source_strings_to_files(args)
+ kwargs['install_mode'] = self._get_kwarg_install_mode(kwargs)
m = Man(fargs, kwargs)
self.build.man.append(m)
return m
@@ -3115,7 +3126,7 @@ root and issuing %s.
self.subdir = prev_subdir
def _get_kwarg_install_mode(self, kwargs):
- if 'install_mode' not in kwargs:
+ if kwargs.get('install_mode', None) is None:
return None
install_mode = []
mode = mesonlib.typeslistify(kwargs.get('install_mode', []), (str, int))
@@ -3358,7 +3369,8 @@ root and issuing %s.
idir = kwargs.get('install_dir', None)
if isinstance(idir, str) and idir:
cfile = mesonlib.File.from_built_file(ofile_path, ofile_fname)
- self.build.data.append(build.Data([cfile], idir))
+ install_mode = self._get_kwarg_install_mode(kwargs)
+ self.build.data.append(build.Data([cfile], idir, install_mode))
return mesonlib.File.from_built_file(self.subdir, output)
@permittedKwargs(permitted_kwargs['include_directories'])
@@ -3642,6 +3654,7 @@ different subdirectory.
sources = self.source_strings_to_files(sources)
objs = extract_as_list(kwargs, 'objects')
kwargs['dependencies'] = extract_as_list(kwargs, 'dependencies')
+ kwargs['install_mode'] = self._get_kwarg_install_mode(kwargs)
if 'extra_files' in kwargs:
ef = extract_as_list(kwargs, 'extra_files')
kwargs['extra_files'] = self.source_strings_to_files(ef)
diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py
index b51a351..eaa992b 100644
--- a/mesonbuild/scripts/meson_install.py
+++ b/mesonbuild/scripts/meson_install.py
@@ -148,7 +148,7 @@ def do_copyfile(from_file, to_file):
selinux_updates.append(to_file)
append_to_log(to_file)
-def do_copydir(data, src_dir, dst_dir, exclude):
+def do_copydir(data, src_dir, dst_dir, exclude, install_mode):
'''
Copies the contents of directory @src_dir into @dst_dir.
@@ -158,7 +158,7 @@ def do_copydir(data, src_dir, dst_dir, exclude):
excluded
foobar
file
- do_copydir(..., '/foo', '/dst/dir', {'bar/excluded'}) creates
+ do_copydir(..., '/foo', '/dst/dir', {'bar/excluded'}, None) creates
/dst/
dir/
bar/
@@ -170,6 +170,7 @@ def do_copydir(data, src_dir, dst_dir, exclude):
dst_dir: str, absolute path to the destination directory
exclude: (set(str), set(str)), tuple of (exclude_files, exclude_dirs),
each element of the set is a path relative to src_dir.
+ install_mode: FileMode object, or None to use defaults.
'''
if not os.path.isabs(src_dir):
raise ValueError('src_dir must be absolute, got %s' % src_dir)
@@ -212,7 +213,7 @@ def do_copydir(data, src_dir, dst_dir, exclude):
os.mkdir(parent_dir)
shutil.copystat(os.path.dirname(abs_src), parent_dir)
shutil.copy2(abs_src, abs_dst, follow_symlinks=False)
- sanitize_permissions(abs_dst, data.install_umask)
+ set_mode(abs_dst, install_mode, data.install_umask)
append_to_log(abs_dst)
def get_destdir_path(d, path):
@@ -263,8 +264,7 @@ def install_subdirs(d):
full_dst_dir = get_destdir_path(d, dst_dir)
print('Installing subdir %s to %s' % (src_dir, full_dst_dir))
d.dirmaker.makedirs(full_dst_dir, exist_ok=True)
- do_copydir(d, src_dir, full_dst_dir, exclude)
- set_mode(full_dst_dir, mode, d.install_umask)
+ do_copydir(d, src_dir, full_dst_dir, exclude, mode)
def install_data(d):
for i in d.data:
@@ -283,6 +283,7 @@ def install_man(d):
outfilename = get_destdir_path(d, m[1])
outdir = os.path.dirname(outfilename)
d.dirmaker.makedirs(outdir, exist_ok=True)
+ install_mode = m[2]
print('Installing %s to %s' % (full_source_filename, outdir))
if outfilename.endswith('.gz') and not full_source_filename.endswith('.gz'):
with open(outfilename, 'wb') as of:
@@ -294,7 +295,7 @@ def install_man(d):
append_to_log(outfilename)
else:
do_copyfile(full_source_filename, outfilename)
- sanitize_permissions(outfilename, d.install_umask)
+ set_mode(outfilename, install_mode, d.install_umask)
def install_headers(d):
for t in d.headers:
@@ -302,10 +303,11 @@ def install_headers(d):
fname = os.path.basename(fullfilename)
outdir = get_destdir_path(d, t[1])
outfilename = os.path.join(outdir, fname)
+ install_mode = t[2]
print('Installing %s to %s' % (fname, outdir))
d.dirmaker.makedirs(outdir, exist_ok=True)
do_copyfile(fullfilename, outfilename)
- sanitize_permissions(outfilename, d.install_umask)
+ set_mode(outfilename, install_mode, d.install_umask)
def run_install_script(d):
env = {'MESON_SOURCE_ROOT': d.source_dir,
@@ -364,13 +366,14 @@ def install_targets(d):
aliases = t[2]
should_strip = t[3]
install_rpath = t[4]
+ install_mode = t[5]
print('Installing %s to %s' % (fname, outname))
d.dirmaker.makedirs(outdir, exist_ok=True)
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)
- sanitize_permissions(outname, d.install_umask)
+ set_mode(outname, install_mode, d.install_umask)
if should_strip and d.strip_bin is not None:
if fname.endswith('.jar'):
print('Not stripping jar target:', os.path.basename(fname))
@@ -387,12 +390,11 @@ def install_targets(d):
pdb_outname = os.path.splitext(outname)[0] + '.pdb'
print('Installing pdb file %s to %s' % (pdb_filename, pdb_outname))
do_copyfile(pdb_filename, pdb_outname)
- sanitize_permissions(pdb_outname, d.install_umask)
+ set_mode(pdb_outname, install_mode, d.install_umask)
elif os.path.isdir(fname):
fname = os.path.join(d.build_dir, fname.rstrip('/'))
outname = os.path.join(outdir, os.path.basename(fname))
- do_copydir(d, fname, outname, None)
- sanitize_permissions(outname, d.install_umask)
+ do_copydir(d, fname, outname, None, install_mode)
else:
raise RuntimeError('Unknown file type for {!r}'.format(fname))
printed_symlink_error = False