Skip to content

Commit 23c8a09

Browse files
eli-schwartznirbheek
authored andcommitted
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 (cherry picked from commit 3e73d4d)
1 parent 89fa141 commit 23c8a09

File tree

6 files changed

+54
-48
lines changed

6 files changed

+54
-48
lines changed

mesonbuild/backend/backends.py

+12-10
Original file line numberDiff line numberDiff line change
@@ -1542,7 +1542,7 @@ def generate_target_install(self, d: InstallData) -> None:
15421542
for t in self.build.get_targets().values():
15431543
if not t.should_install():
15441544
continue
1545-
outdirs, default_install_dir_name, custom_install_dir = t.get_install_dir()
1545+
outdirs, install_dir_names, custom_install_dir = t.get_install_dir()
15461546
# Sanity-check the outputs and install_dirs
15471547
num_outdirs, num_out = len(outdirs), len(t.get_outputs())
15481548
if num_outdirs != 1 and num_outdirs != num_out:
@@ -1552,7 +1552,9 @@ def generate_target_install(self, d: InstallData) -> None:
15521552
raise MesonException(m.format(t.name, num_out, t.get_outputs(), num_outdirs))
15531553
assert len(t.install_tag) == num_out
15541554
install_mode = t.get_custom_install_mode()
1555-
first_outdir = outdirs[0] # because mypy get's confused type narrowing in lists
1555+
# because mypy get's confused type narrowing in lists
1556+
first_outdir = outdirs[0]
1557+
first_outdir_name = install_dir_names[0]
15561558

15571559
# Install the target output(s)
15581560
if isinstance(t, build.BuildTarget):
@@ -1578,7 +1580,7 @@ def generate_target_install(self, d: InstallData) -> None:
15781580
tag = t.install_tag[0] or ('devel' if isinstance(t, build.StaticLibrary) else 'runtime')
15791581
mappings = t.get_link_deps_mapping(d.prefix)
15801582
i = TargetInstallData(self.get_target_filename(t), first_outdir,
1581-
default_install_dir_name,
1583+
first_outdir_name,
15821584
should_strip, mappings, t.rpath_dirs_to_remove,
15831585
t.install_rpath, install_mode, t.subproject,
15841586
tag=tag, can_strip=can_strip)
@@ -1603,7 +1605,7 @@ def generate_target_install(self, d: InstallData) -> None:
16031605
implib_install_dir = self.environment.get_import_lib_dir()
16041606
# Install the import library; may not exist for shared modules
16051607
i = TargetInstallData(self.get_target_filename_for_linking(t),
1606-
implib_install_dir, default_install_dir_name,
1608+
implib_install_dir, first_outdir_name,
16071609
False, {}, set(), '', install_mode,
16081610
t.subproject, optional=isinstance(t, build.SharedModule),
16091611
tag='devel')
@@ -1612,19 +1614,19 @@ def generate_target_install(self, d: InstallData) -> None:
16121614
if not should_strip and t.get_debug_filename():
16131615
debug_file = os.path.join(self.get_target_dir(t), t.get_debug_filename())
16141616
i = TargetInstallData(debug_file, first_outdir,
1615-
default_install_dir_name,
1617+
first_outdir_name,
16161618
False, {}, set(), '',
16171619
install_mode, t.subproject,
16181620
optional=True, tag='devel')
16191621
d.targets.append(i)
16201622
# Install secondary outputs. Only used for Vala right now.
16211623
if num_outdirs > 1:
1622-
for output, outdir, tag in zip(t.get_outputs()[1:], outdirs[1:], t.install_tag[1:]):
1624+
for output, outdir, outdir_name, tag in zip(t.get_outputs()[1:], outdirs[1:], install_dir_names[1:], t.install_tag[1:]):
16231625
# User requested that we not install this output
16241626
if outdir is False:
16251627
continue
16261628
f = os.path.join(self.get_target_dir(t), output)
1627-
i = TargetInstallData(f, outdir, default_install_dir_name, False, {}, set(), None,
1629+
i = TargetInstallData(f, outdir, outdir_name, False, {}, set(), None,
16281630
install_mode, t.subproject,
16291631
tag=tag)
16301632
d.targets.append(i)
@@ -1643,18 +1645,18 @@ def generate_target_install(self, d: InstallData) -> None:
16431645
if first_outdir is not False:
16441646
for output, tag in zip(t.get_outputs(), t.install_tag):
16451647
f = os.path.join(self.get_target_dir(t), output)
1646-
i = TargetInstallData(f, first_outdir, default_install_dir_name,
1648+
i = TargetInstallData(f, first_outdir, first_outdir_name,
16471649
False, {}, set(), None, install_mode,
16481650
t.subproject, optional=not t.build_by_default,
16491651
tag=tag)
16501652
d.targets.append(i)
16511653
else:
1652-
for output, outdir, tag in zip(t.get_outputs(), outdirs, t.install_tag):
1654+
for output, outdir, outdir_name, tag in zip(t.get_outputs(), outdirs, install_dir_names, t.install_tag):
16531655
# User requested that we not install this output
16541656
if outdir is False:
16551657
continue
16561658
f = os.path.join(self.get_target_dir(t), output)
1657-
i = TargetInstallData(f, outdir, default_install_dir_name,
1659+
i = TargetInstallData(f, outdir, outdir_name,
16581660
False, {}, set(), None, install_mode,
16591661
t.subproject, optional=not t.build_by_default,
16601662
tag=tag)

mesonbuild/build.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -627,7 +627,7 @@ def get_install_dir(self) -> T.Tuple[T.List[T.Union[str, Literal[False]]], str,
627627
# False (which means we want this specific output out of many
628628
# outputs to not be installed).
629629
custom_install_dir = True
630-
default_install_dir_name = None
630+
install_dir_names = [getattr(i, 'optname', None) for i in outdirs]
631631
else:
632632
custom_install_dir = False
633633
# if outdirs is empty we need to set to something, otherwise we set
@@ -636,8 +636,9 @@ def get_install_dir(self) -> T.Tuple[T.List[T.Union[str, Literal[False]]], str,
636636
outdirs[0] = default_install_dir
637637
else:
638638
outdirs = [default_install_dir]
639+
install_dir_names = [default_install_dir_name] * len(outdirs)
639640

640-
return outdirs, default_install_dir_name, custom_install_dir
641+
return outdirs, install_dir_names, custom_install_dir
641642

642643
def get_basename(self) -> str:
643644
return self.name

mesonbuild/interpreter/interpreter.py

+9-9
Original file line numberDiff line numberDiff line change
@@ -2340,14 +2340,8 @@ def func_install_data(self, node: mparser.BaseNode,
23402340
'"rename" and "sources" argument lists must be the same length if "rename" is given. '
23412341
f'Rename has {len(rename)} elements and sources has {len(sources)}.')
23422342

2343-
install_dir_name = kwargs['install_dir']
2344-
if install_dir_name:
2345-
if not os.path.isabs(install_dir_name):
2346-
install_dir_name = os.path.join('{datadir}', install_dir_name)
2347-
else:
2348-
install_dir_name = '{datadir}'
23492343
return self.install_data_impl(sources, kwargs['install_dir'], kwargs['install_mode'],
2350-
rename, kwargs['install_tag'], install_dir_name)
2344+
rename, kwargs['install_tag'])
23512345

23522346
def install_data_impl(self, sources: T.List[mesonlib.File], install_dir: str,
23532347
install_mode: FileMode, rename: T.Optional[str],
@@ -2356,7 +2350,10 @@ def install_data_impl(self, sources: T.List[mesonlib.File], install_dir: str,
23562350
install_data_type: T.Optional[str] = None) -> build.Data:
23572351

23582352
"""Just the implementation with no validation."""
2359-
data = build.Data(sources, install_dir, install_dir_name or install_dir, install_mode,
2353+
idir_name = install_dir_name or install_dir or '{datadir}'
2354+
if isinstance(idir_name, P_OBJ.OptionString):
2355+
idir_name = idir_name.optname
2356+
data = build.Data(sources, install_dir, idir_name, install_mode,
23602357
self.subproject, rename, tag, install_data_type)
23612358
self.build.data.append(data)
23622359
return data
@@ -2573,10 +2570,13 @@ def func_configure_file(self, node: mparser.BaseNode, args: T.List[TYPE_var],
25732570
if not idir:
25742571
raise InterpreterException(
25752572
'"install_dir" must be specified when "install" in a configure_file is true')
2573+
idir_name = idir
2574+
if isinstance(idir_name, P_OBJ.OptionString):
2575+
idir_name = idir_name.optname
25762576
cfile = mesonlib.File.from_built_file(ofile_path, ofile_fname)
25772577
install_mode = kwargs['install_mode']
25782578
install_tag = kwargs['install_tag']
2579-
self.build.data.append(build.Data([cfile], idir, idir, install_mode, self.subproject,
2579+
self.build.data.append(build.Data([cfile], idir, idir_name, install_mode, self.subproject,
25802580
install_tag=install_tag, data_type='configure'))
25812581
return mesonlib.File.from_built_file(self.subdir, output)
25822582

mesonbuild/mintro.py

-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,6 @@ def list_install_plan(installdata: backends.InstallData) -> T.Dict[str, T.Dict[s
140140
install_path_name = data.install_path_name
141141
if key == 'headers': # in the headers, install_path_name is the directory
142142
install_path_name = os.path.join(install_path_name, os.path.basename(data.path))
143-
elif data_type == 'configure':
144-
install_path_name = os.path.join('{prefix}', install_path_name)
145143

146144
plan[data_type] = plan.get(data_type, {})
147145
plan[data_type][data.path] = {

mesonbuild/modules/python.py

+13-8
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from ..environment import detect_cpu_family
3232
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
3333
from ..interpreter.type_checking import NoneType
34+
from ..interpreter import primitives as P_OBJ
3435
from ..interpreterbase import (
3536
noPosargs, noKwargs, permittedKwargs, ContainerTypeInfo,
3637
InvalidArguments, typed_pos_args, typed_kwargs, KwargInfo,
@@ -514,7 +515,7 @@ def extension_module_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs
514515
if not isinstance(subdir, str):
515516
raise InvalidArguments('"subdir" argument must be a string.')
516517

517-
kwargs['install_dir'] = os.path.join(self.platlib_install_path, subdir)
518+
kwargs['install_dir'] = self._get_install_dir_impl(False, subdir)
518519

519520
new_deps = []
520521
has_pydep = False
@@ -593,23 +594,27 @@ def dependency_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') ->
593594
def install_sources_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File]]],
594595
kwargs: 'PyInstallKw') -> 'Data':
595596
tag = kwargs['install_tag'] or 'runtime'
597+
install_dir = self._get_install_dir_impl(kwargs['pure'], kwargs['subdir'])
596598
return self.interpreter.install_data_impl(
597599
self.interpreter.source_strings_to_files(args[0]),
598-
self._get_install_dir_impl(kwargs['pure'], kwargs['subdir']),
600+
install_dir,
599601
mesonlib.FileMode(), rename=None, tag=tag, install_data_type='python',
600-
install_dir_name=self._get_install_dir_name_impl(kwargs['pure'], kwargs['subdir']))
602+
install_dir_name=install_dir.optname)
601603

602604
@noPosargs
603605
@typed_kwargs('python_installation.install_dir', _PURE_KW, _SUBDIR_KW)
604606
def get_install_dir_method(self, args: T.List['TYPE_var'], kwargs: 'PyInstallKw') -> str:
605607
return self._get_install_dir_impl(kwargs['pure'], kwargs['subdir'])
606608

607-
def _get_install_dir_impl(self, pure: bool, subdir: str) -> str:
608-
return os.path.join(
609-
self.purelib_install_path if pure else self.platlib_install_path, subdir)
609+
def _get_install_dir_impl(self, pure: bool, subdir: str) -> P_OBJ.OptionString:
610+
if pure:
611+
base = self.purelib_install_path
612+
name = '{py_purelib}'
613+
else:
614+
base = self.platlib_install_path
615+
name = '{py_platlib}'
610616

611-
def _get_install_dir_name_impl(self, pure: bool, subdir: str) -> str:
612-
return os.path.join('{py_purelib}' if pure else '{py_platlib}', subdir)
617+
return P_OBJ.OptionString(os.path.join(base, subdir), os.path.join(name, subdir))
613618

614619
@noPosargs
615620
@noKwargs

unittests/allplatformstests.py

+17-17
Original file line numberDiff line numberDiff line change
@@ -4159,11 +4159,11 @@ def output_name(name, type_):
41594159
expected = {
41604160
'targets': {
41614161
f'{self.builddir}/out1-notag.txt': {
4162-
'destination': '{prefix}/share/out1-notag.txt',
4162+
'destination': '{datadir}/out1-notag.txt',
41634163
'tag': None,
41644164
},
41654165
f'{self.builddir}/out2-notag.txt': {
4166-
'destination': '{prefix}/share/out2-notag.txt',
4166+
'destination': '{datadir}/out2-notag.txt',
41674167
'tag': None,
41684168
},
41694169
f'{self.builddir}/libstatic.a': {
@@ -4211,67 +4211,67 @@ def output_name(name, type_):
42114211
'tag': 'devel',
42124212
},
42134213
f'{self.builddir}/out1-custom.txt': {
4214-
'destination': '{prefix}/share/out1-custom.txt',
4214+
'destination': '{datadir}/out1-custom.txt',
42154215
'tag': 'custom',
42164216
},
42174217
f'{self.builddir}/out2-custom.txt': {
4218-
'destination': '{prefix}/share/out2-custom.txt',
4218+
'destination': '{datadir}/out2-custom.txt',
42194219
'tag': 'custom',
42204220
},
42214221
f'{self.builddir}/out3-custom.txt': {
4222-
'destination': '{prefix}/share/out3-custom.txt',
4222+
'destination': '{datadir}/out3-custom.txt',
42234223
'tag': 'custom',
42244224
},
42254225
f'{self.builddir}/subdir/out1.txt': {
4226-
'destination': '{prefix}/share/out1.txt',
4226+
'destination': '{datadir}/out1.txt',
42274227
'tag': None,
42284228
},
42294229
f'{self.builddir}/subdir/out2.txt': {
4230-
'destination': '{prefix}/share/out2.txt',
4230+
'destination': '{datadir}/out2.txt',
42314231
'tag': None,
42324232
},
42334233
f'{self.builddir}/out-devel.h': {
4234-
'destination': '{prefix}/include/out-devel.h',
4234+
'destination': '{includedir}/out-devel.h',
42354235
'tag': 'devel',
42364236
},
42374237
f'{self.builddir}/out3-notag.txt': {
4238-
'destination': '{prefix}/share/out3-notag.txt',
4238+
'destination': '{datadir}/out3-notag.txt',
42394239
'tag': None,
42404240
},
42414241
},
42424242
'configure': {
42434243
f'{self.builddir}/foo-notag.h': {
4244-
'destination': '{prefix}/share/foo-notag.h',
4244+
'destination': '{datadir}/foo-notag.h',
42454245
'tag': None,
42464246
},
42474247
f'{self.builddir}/foo2-devel.h': {
4248-
'destination': '{prefix}/include/foo2-devel.h',
4248+
'destination': '{includedir}/foo2-devel.h',
42494249
'tag': 'devel',
42504250
},
42514251
f'{self.builddir}/foo-custom.h': {
4252-
'destination': '{prefix}/share/foo-custom.h',
4252+
'destination': '{datadir}/foo-custom.h',
42534253
'tag': 'custom',
42544254
},
42554255
f'{self.builddir}/subdir/foo2.h': {
4256-
'destination': '{prefix}/share/foo2.h',
4256+
'destination': '{datadir}/foo2.h',
42574257
'tag': None,
42584258
},
42594259
},
42604260
'data': {
42614261
f'{testdir}/bar-notag.txt': {
4262-
'destination': '{datadir}/share/bar-notag.txt',
4262+
'destination': '{datadir}/bar-notag.txt',
42634263
'tag': None,
42644264
},
42654265
f'{testdir}/bar-devel.h': {
4266-
'destination': '{datadir}/include/bar-devel.h',
4266+
'destination': '{includedir}/bar-devel.h',
42674267
'tag': 'devel',
42684268
},
42694269
f'{testdir}/bar-custom.txt': {
4270-
'destination': '{datadir}/share/bar-custom.txt',
4270+
'destination': '{datadir}/bar-custom.txt',
42714271
'tag': 'custom',
42724272
},
42734273
f'{testdir}/subdir/bar2-devel.h': {
4274-
'destination': '{datadir}/include/bar2-devel.h',
4274+
'destination': '{includedir}/bar2-devel.h',
42754275
'tag': 'devel',
42764276
},
42774277
},

0 commit comments

Comments
 (0)