aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2022-08-01 23:51:43 -0400
committerEli Schwartz <eschwartz@archlinux.org>2022-08-22 14:15:22 -0400
commit3e73d4d77d1d36b15d06c8b3c4a7ee6ad77847b6 (patch)
tree1657528ecf739758e226827e9e8f3eae1d3419c5
parente19e9ce6f196f7c127a2668b5df0ada1d50806df (diff)
downloadmeson-3e73d4d77d1d36b15d06c8b3c4a7ee6ad77847b6.zip
meson-3e73d4d77d1d36b15d06c8b3c4a7ee6ad77847b6.tar.gz
meson-3e73d4d77d1d36b15d06c8b3c4a7ee6ad77847b6.tar.bz2
introspection: untangle install_plan implemetation, fix a bunch of wrong ones
Generally plumb through the values of get_option() passed to install_dir, and use this to establish the install plan name. Fixes several odd cases, such as: - {datadir} being prepended to "share" or "include" - dissociating custom install directories and writing them out as {prefix}/share/foo or {prefix}/lib/python3.10/site-packages This is the second half of #9478 Fixes #10601
-rw-r--r--mesonbuild/backend/backends.py22
-rw-r--r--mesonbuild/build.py5
-rw-r--r--mesonbuild/interpreter/interpreter.py17
-rw-r--r--mesonbuild/mintro.py2
-rw-r--r--mesonbuild/modules/python.py21
-rw-r--r--unittests/allplatformstests.py34
6 files changed, 53 insertions, 48 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 67bc8bf..42f6255 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -1534,7 +1534,7 @@ class Backend:
for t in self.build.get_targets().values():
if not t.should_install():
continue
- outdirs, default_install_dir_name, custom_install_dir = t.get_install_dir()
+ outdirs, install_dir_names, custom_install_dir = t.get_install_dir()
# 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:
@@ -1544,7 +1544,9 @@ class Backend:
raise MesonException(m.format(t.name, num_out, t.get_outputs(), num_outdirs))
assert len(t.install_tag) == num_out
install_mode = t.get_custom_install_mode()
- first_outdir = outdirs[0] # because mypy get's confused type narrowing in lists
+ # because mypy get's confused type narrowing in lists
+ first_outdir = outdirs[0]
+ first_outdir_name = install_dir_names[0]
# Install the target output(s)
if isinstance(t, build.BuildTarget):
@@ -1570,7 +1572,7 @@ class Backend:
tag = t.install_tag[0] or ('devel' if isinstance(t, build.StaticLibrary) else 'runtime')
mappings = t.get_link_deps_mapping(d.prefix)
i = TargetInstallData(self.get_target_filename(t), first_outdir,
- default_install_dir_name,
+ first_outdir_name,
should_strip, mappings, t.rpath_dirs_to_remove,
t.install_rpath, install_mode, t.subproject,
tag=tag, can_strip=can_strip)
@@ -1595,7 +1597,7 @@ class Backend:
implib_install_dir = self.environment.get_import_lib_dir()
# Install the import library; may not exist for shared modules
i = TargetInstallData(self.get_target_filename_for_linking(t),
- implib_install_dir, default_install_dir_name,
+ implib_install_dir, first_outdir_name,
False, {}, set(), '', install_mode,
t.subproject, optional=isinstance(t, build.SharedModule),
tag='devel')
@@ -1604,19 +1606,19 @@ class Backend:
if not should_strip and t.get_debug_filename():
debug_file = os.path.join(self.get_target_dir(t), t.get_debug_filename())
i = TargetInstallData(debug_file, first_outdir,
- default_install_dir_name,
+ first_outdir_name,
False, {}, set(), '',
install_mode, t.subproject,
optional=True, tag='devel')
d.targets.append(i)
# Install secondary outputs. Only used for Vala right now.
if num_outdirs > 1:
- for output, outdir, tag in zip(t.get_outputs()[1:], outdirs[1:], t.install_tag[1:]):
+ for output, outdir, outdir_name, tag in zip(t.get_outputs()[1:], outdirs[1:], install_dir_names[1:], t.install_tag[1:]):
# User requested that we not install this output
if outdir is False:
continue
f = os.path.join(self.get_target_dir(t), output)
- i = TargetInstallData(f, outdir, default_install_dir_name, False, {}, set(), None,
+ i = TargetInstallData(f, outdir, outdir_name, False, {}, set(), None,
install_mode, t.subproject,
tag=tag)
d.targets.append(i)
@@ -1635,18 +1637,18 @@ class Backend:
if first_outdir is not False:
for output, tag in zip(t.get_outputs(), t.install_tag):
f = os.path.join(self.get_target_dir(t), output)
- i = TargetInstallData(f, first_outdir, default_install_dir_name,
+ i = TargetInstallData(f, first_outdir, first_outdir_name,
False, {}, set(), None, install_mode,
t.subproject, optional=not t.build_by_default,
tag=tag)
d.targets.append(i)
else:
- for output, outdir, tag in zip(t.get_outputs(), outdirs, t.install_tag):
+ for output, outdir, outdir_name, tag in zip(t.get_outputs(), outdirs, install_dir_names, t.install_tag):
# User requested that we not install this output
if outdir is False:
continue
f = os.path.join(self.get_target_dir(t), output)
- i = TargetInstallData(f, outdir, default_install_dir_name,
+ i = TargetInstallData(f, outdir, outdir_name,
False, {}, set(), None, install_mode,
t.subproject, optional=not t.build_by_default,
tag=tag)
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 2729373..c7f5997 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -628,7 +628,7 @@ class Target(HoldableObject):
# False (which means we want this specific output out of many
# outputs to not be installed).
custom_install_dir = True
- default_install_dir_name = None
+ install_dir_names = [getattr(i, 'optname', None) for i in outdirs]
else:
custom_install_dir = False
# if outdirs is empty we need to set to something, otherwise we set
@@ -637,8 +637,9 @@ class Target(HoldableObject):
outdirs[0] = default_install_dir
else:
outdirs = [default_install_dir]
+ install_dir_names = [default_install_dir_name] * len(outdirs)
- return outdirs, default_install_dir_name, custom_install_dir
+ return outdirs, install_dir_names, custom_install_dir
def get_basename(self) -> str:
return self.name
diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py
index 8caf010..131f073 100644
--- a/mesonbuild/interpreter/interpreter.py
+++ b/mesonbuild/interpreter/interpreter.py
@@ -2342,14 +2342,8 @@ class Interpreter(InterpreterBase, HoldableObject):
'"rename" and "sources" argument lists must be the same length if "rename" is given. '
f'Rename has {len(rename)} elements and sources has {len(sources)}.')
- install_dir_name = kwargs['install_dir']
- if install_dir_name:
- if not os.path.isabs(install_dir_name):
- install_dir_name = os.path.join('{datadir}', install_dir_name)
- else:
- install_dir_name = '{datadir}'
return self.install_data_impl(sources, kwargs['install_dir'], kwargs['install_mode'],
- rename, kwargs['install_tag'], install_dir_name,
+ rename, kwargs['install_tag'],
preserve_path=kwargs['preserve_path'])
def install_data_impl(self, sources: T.List[mesonlib.File], install_dir: T.Optional[str],
@@ -2361,7 +2355,9 @@ class Interpreter(InterpreterBase, HoldableObject):
"""Just the implementation with no validation."""
idir = install_dir or ''
- idir_name = install_dir_name or idir
+ idir_name = install_dir_name or idir or '{datadir}'
+ if isinstance(idir_name, P_OBJ.OptionString):
+ idir_name = idir_name.optname
dirs = collections.defaultdict(list)
ret_data = []
if preserve_path:
@@ -2594,10 +2590,13 @@ class Interpreter(InterpreterBase, HoldableObject):
if not idir:
raise InterpreterException(
'"install_dir" must be specified when "install" in a configure_file is true')
+ idir_name = idir
+ if isinstance(idir_name, P_OBJ.OptionString):
+ idir_name = idir_name.optname
cfile = mesonlib.File.from_built_file(ofile_path, ofile_fname)
install_mode = kwargs['install_mode']
install_tag = kwargs['install_tag']
- self.build.data.append(build.Data([cfile], idir, idir, install_mode, self.subproject,
+ self.build.data.append(build.Data([cfile], idir, idir_name, install_mode, self.subproject,
install_tag=install_tag, data_type='configure'))
return mesonlib.File.from_built_file(self.subdir, output)
diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py
index eee2e7c..fd5c16f 100644
--- a/mesonbuild/mintro.py
+++ b/mesonbuild/mintro.py
@@ -143,8 +143,6 @@ def list_install_plan(installdata: backends.InstallData) -> T.Dict[str, T.Dict[s
install_path_name = data.install_path_name
if key == 'headers': # in the headers, install_path_name is the directory
install_path_name = os.path.join(install_path_name, os.path.basename(data.path))
- elif data_type == 'configure':
- install_path_name = os.path.join('{prefix}', install_path_name)
plan[data_type] = plan.get(data_type, {})
plan[data_type][data.path] = {
diff --git a/mesonbuild/modules/python.py b/mesonbuild/modules/python.py
index 91443b8..9b50de4 100644
--- a/mesonbuild/modules/python.py
+++ b/mesonbuild/modules/python.py
@@ -30,6 +30,7 @@ from ..dependencies.base import process_method_kw
from ..dependencies.detect import get_dep_identifier
from ..environment import detect_cpu_family
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
+from ..interpreter import primitives as P_OBJ
from ..interpreter.type_checking import NoneType, PRESERVE_PATH_KW
from ..interpreterbase import (
noPosargs, noKwargs, permittedKwargs, ContainerTypeInfo,
@@ -514,7 +515,7 @@ class PythonInstallation(ExternalProgramHolder):
if not isinstance(subdir, str):
raise InvalidArguments('"subdir" argument must be a string.')
- kwargs['install_dir'] = os.path.join(self.platlib_install_path, subdir)
+ kwargs['install_dir'] = self._get_install_dir_impl(False, subdir)
new_deps = []
has_pydep = False
@@ -598,11 +599,12 @@ class PythonInstallation(ExternalProgramHolder):
def install_sources_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File]]],
kwargs: 'PyInstallKw') -> 'Data':
tag = kwargs['install_tag'] or 'runtime'
+ install_dir = self._get_install_dir_impl(kwargs['pure'], kwargs['subdir'])
return self.interpreter.install_data_impl(
self.interpreter.source_strings_to_files(args[0]),
- self._get_install_dir_impl(kwargs['pure'], kwargs['subdir']),
+ install_dir,
mesonlib.FileMode(), rename=None, tag=tag, install_data_type='python',
- install_dir_name=self._get_install_dir_name_impl(kwargs['pure'], kwargs['subdir']),
+ install_dir_name=install_dir.optname,
preserve_path=kwargs['preserve_path'])
@noPosargs
@@ -610,12 +612,15 @@ class PythonInstallation(ExternalProgramHolder):
def get_install_dir_method(self, args: T.List['TYPE_var'], kwargs: 'PyInstallKw') -> str:
return self._get_install_dir_impl(kwargs['pure'], kwargs['subdir'])
- def _get_install_dir_impl(self, pure: bool, subdir: str) -> str:
- return os.path.join(
- self.purelib_install_path if pure else self.platlib_install_path, subdir)
+ def _get_install_dir_impl(self, pure: bool, subdir: str) -> P_OBJ.OptionString:
+ if pure:
+ base = self.purelib_install_path
+ name = '{py_purelib}'
+ else:
+ base = self.platlib_install_path
+ name = '{py_platlib}'
- def _get_install_dir_name_impl(self, pure: bool, subdir: str) -> str:
- return os.path.join('{py_purelib}' if pure else '{py_platlib}', subdir)
+ return P_OBJ.OptionString(os.path.join(base, subdir), os.path.join(name, subdir))
@noPosargs
@noKwargs
diff --git a/unittests/allplatformstests.py b/unittests/allplatformstests.py
index 3238a39..824d97b 100644
--- a/unittests/allplatformstests.py
+++ b/unittests/allplatformstests.py
@@ -4145,11 +4145,11 @@ class AllPlatformTests(BasePlatformTests):
expected = {
'targets': {
f'{self.builddir}/out1-notag.txt': {
- 'destination': '{prefix}/share/out1-notag.txt',
+ 'destination': '{datadir}/out1-notag.txt',
'tag': None,
},
f'{self.builddir}/out2-notag.txt': {
- 'destination': '{prefix}/share/out2-notag.txt',
+ 'destination': '{datadir}/out2-notag.txt',
'tag': None,
},
f'{self.builddir}/libstatic.a': {
@@ -4197,67 +4197,67 @@ class AllPlatformTests(BasePlatformTests):
'tag': 'devel',
},
f'{self.builddir}/out1-custom.txt': {
- 'destination': '{prefix}/share/out1-custom.txt',
+ 'destination': '{datadir}/out1-custom.txt',
'tag': 'custom',
},
f'{self.builddir}/out2-custom.txt': {
- 'destination': '{prefix}/share/out2-custom.txt',
+ 'destination': '{datadir}/out2-custom.txt',
'tag': 'custom',
},
f'{self.builddir}/out3-custom.txt': {
- 'destination': '{prefix}/share/out3-custom.txt',
+ 'destination': '{datadir}/out3-custom.txt',
'tag': 'custom',
},
f'{self.builddir}/subdir/out1.txt': {
- 'destination': '{prefix}/share/out1.txt',
+ 'destination': '{datadir}/out1.txt',
'tag': None,
},
f'{self.builddir}/subdir/out2.txt': {
- 'destination': '{prefix}/share/out2.txt',
+ 'destination': '{datadir}/out2.txt',
'tag': None,
},
f'{self.builddir}/out-devel.h': {
- 'destination': '{prefix}/include/out-devel.h',
+ 'destination': '{includedir}/out-devel.h',
'tag': 'devel',
},
f'{self.builddir}/out3-notag.txt': {
- 'destination': '{prefix}/share/out3-notag.txt',
+ 'destination': '{datadir}/out3-notag.txt',
'tag': None,
},
},
'configure': {
f'{self.builddir}/foo-notag.h': {
- 'destination': '{prefix}/share/foo-notag.h',
+ 'destination': '{datadir}/foo-notag.h',
'tag': None,
},
f'{self.builddir}/foo2-devel.h': {
- 'destination': '{prefix}/include/foo2-devel.h',
+ 'destination': '{includedir}/foo2-devel.h',
'tag': 'devel',
},
f'{self.builddir}/foo-custom.h': {
- 'destination': '{prefix}/share/foo-custom.h',
+ 'destination': '{datadir}/foo-custom.h',
'tag': 'custom',
},
f'{self.builddir}/subdir/foo2.h': {
- 'destination': '{prefix}/share/foo2.h',
+ 'destination': '{datadir}/foo2.h',
'tag': None,
},
},
'data': {
f'{testdir}/bar-notag.txt': {
- 'destination': '{datadir}/share/bar-notag.txt',
+ 'destination': '{datadir}/bar-notag.txt',
'tag': None,
},
f'{testdir}/bar-devel.h': {
- 'destination': '{datadir}/include/bar-devel.h',
+ 'destination': '{includedir}/bar-devel.h',
'tag': 'devel',
},
f'{testdir}/bar-custom.txt': {
- 'destination': '{datadir}/share/bar-custom.txt',
+ 'destination': '{datadir}/bar-custom.txt',
'tag': 'custom',
},
f'{testdir}/subdir/bar2-devel.h': {
- 'destination': '{datadir}/include/bar2-devel.h',
+ 'destination': '{includedir}/bar2-devel.h',
'tag': 'devel',
},
},