From: Rosen Penev Date: Thu, 30 Jul 2026 01:41:24 +0000 (-0700) Subject: tools/meson: update to 1.11.2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc636dac867fcd8c68dee0ad69fc15954e075715;p=thirdparty%2Fopenwrt.git tools/meson: update to 1.11.2 Remove upstreamed patch and refresh others. Signed-off-by: Rosen Penev Link: https://github.com/openwrt/openwrt/pull/24560 Signed-off-by: Jonas Jelonek --- diff --git a/tools/meson/Makefile b/tools/meson/Makefile index 6593f41f538..32053efa0b7 100644 --- a/tools/meson/Makefile +++ b/tools/meson/Makefile @@ -1,11 +1,11 @@ include $(TOPDIR)/rules.mk PKG_NAME:=meson -PKG_VERSION:=1.6.1 +PKG_VERSION:=1.11.2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/mesonbuild/meson/releases/download/$(PKG_VERSION) -PKG_HASH:=1eca49eb6c26d58bbee67fd3337d8ef557c0804e30a6d16bfdf269db997464de +PKG_HASH:=698feae069cef3ecd4d7aaf281d7df359bdfcf555a9a1564383d3b913fa8a736 PKG_MAINTAINER:=Andre Heider PKG_LICENSE:=Apache-2.0 diff --git a/tools/meson/patches/100-depfixer-zero-out-rpath-entry-string-on-removing-ent.patch b/tools/meson/patches/100-depfixer-zero-out-rpath-entry-string-on-removing-ent.patch deleted file mode 100644 index 4ab9590a0cf..00000000000 --- a/tools/meson/patches/100-depfixer-zero-out-rpath-entry-string-on-removing-ent.patch +++ /dev/null @@ -1,161 +0,0 @@ -From 8586a5eff0c117c627fe3f71003dd30e3785796a Mon Sep 17 00:00:00 2001 -From: Christian Marangi -Date: Sat, 11 Oct 2025 01:48:51 +0200 -Subject: [PATCH] depfixer: zero-out rpath entry string on removing entry - -While investigating a reproducible problem with a binary compiled with -Meson, it was notice that the RPATH entry was never removed. - -By comparing the binary from 2 different build system it was observed -that altough the RPATH entry was removed (verified by the readelf -d -command) the actual path was still present causing 2 different binary. - -Going deeper in the Meson build process, it was discovered that -remove_rpath_entry only deletes the entry in the '.dynamic' section but -never actually 'clean' (or better say zero-out) the path from the -.dynstr section producing binary dependendt of the build system. - -To address this, introduce a new helper to to zero-out the entry from -the .dynstr section permitting to produce REAL reproducible binary. - -Additional logic was needed to handle GCC linker optimization for dynstr -table where the rpath string might be reused for other dym function -string. The setion that is actually removed is filled with 'X' following -patchelf behaviour. - -Signed-off-by: Christian Marangi ---- - mesonbuild/scripts/depfixer.py | 79 ++++++++++++++++++++++++++++++++++ - 1 file changed, 79 insertions(+) - ---- a/mesonbuild/scripts/depfixer.py -+++ b/mesonbuild/scripts/depfixer.py -@@ -31,8 +31,12 @@ class DataSizes: - p = '<' - else: - p = '>' -+ self.Char = p + 'c' -+ self.CharSize = 1 - self.Half = p + 'h' - self.HalfSize = 2 -+ self.Section = p + 'h' -+ self.SectionSize = 2 - self.Word = p + 'I' - self.WordSize = 4 - self.Sword = p + 'i' -@@ -71,6 +75,24 @@ class DynamicEntry(DataSizes): - ofile.write(struct.pack(self.Sword, self.d_tag)) - ofile.write(struct.pack(self.Word, self.val)) - -+class DynsymEntry(DataSizes): -+ def __init__(self, ifile: T.BinaryIO, ptrsize: int, is_le: bool) -> None: -+ super().__init__(ptrsize, is_le) -+ is_64 = ptrsize == 64 -+ self.st_name = struct.unpack(self.Word, ifile.read(self.WordSize))[0] -+ if is_64: -+ self.st_info = struct.unpack(self.Char, ifile.read(self.CharSize))[0] -+ self.st_other = struct.unpack(self.Char, ifile.read(self.CharSize))[0] -+ self.st_shndx = struct.unpack(self.Section, ifile.read(self.SectionSize))[0] -+ self.st_value = struct.unpack(self.Addr, ifile.read(self.AddrSize))[0] -+ self.st_size = struct.unpack(self.XWord, ifile.read(self.XWordSize))[0] -+ else: -+ self.st_value = struct.unpack(self.Addr, ifile.read(self.AddrSize))[0] -+ self.st_size = struct.unpack(self.Word, ifile.read(self.WordSize))[0] -+ self.st_info = struct.unpack(self.Char, ifile.read(self.CharSize))[0] -+ self.st_other = struct.unpack(self.Char, ifile.read(self.CharSize))[0] -+ self.st_shndx = struct.unpack(self.Section, ifile.read(self.SectionSize))[0] -+ - class SectionHeader(DataSizes): - def __init__(self, ifile: T.BinaryIO, ptrsize: int, is_le: bool) -> None: - super().__init__(ptrsize, is_le) -@@ -115,6 +137,8 @@ class Elf(DataSizes): - self.verbose = verbose - self.sections: T.List[SectionHeader] = [] - self.dynamic: T.List[DynamicEntry] = [] -+ self.dynsym: T.List[DynsymEntry] = [] -+ self.dynsym_strings: T.List[str] = [] - self.open_bf(bfile) - try: - (self.ptrsize, self.is_le) = self.detect_elf_type() -@@ -122,6 +146,8 @@ class Elf(DataSizes): - self.parse_header() - self.parse_sections() - self.parse_dynamic() -+ self.parse_dynsym() -+ self.parse_dynsym_strings() - except (struct.error, RuntimeError): - self.close_bf() - raise -@@ -232,6 +258,23 @@ class Elf(DataSizes): - if e.d_tag == 0: - break - -+ def parse_dynsym(self) -> None: -+ sec = self.find_section(b'.dynsym') -+ if sec is None: -+ return -+ self.bf.seek(sec.sh_offset) -+ for i in range(sec.sh_size // sec.sh_entsize): -+ e = DynsymEntry(self.bf, self.ptrsize, self.is_le) -+ self.dynsym.append(e) -+ -+ def parse_dynsym_strings(self) -> None: -+ sec = self.find_section(b'.dynstr') -+ if sec is None: -+ return -+ for i in self.dynsym: -+ self.bf.seek(sec.sh_offset + i.st_name) -+ self.dynsym_strings.append(self.read_str().decode()) -+ - @generate_list - def get_section_names(self) -> T.Generator[str, None, None]: - section_names = self.sections[self.e_shstrndx] -@@ -353,12 +396,48 @@ class Elf(DataSizes): - self.bf.write(new_rpath) - self.bf.write(b'\0') - -+ def clean_rpath_entry_string(self, entrynum: int) -> None: -+ # Get the rpath string -+ offset = self.get_entry_offset(entrynum) -+ self.bf.seek(offset) -+ rpath_string = self.read_str().decode() -+ reused_str = '' -+ -+ # Inspect the dyn strings and check if our rpath string -+ # ends with one of them. -+ # This is to handle a subtle optimization of the linker -+ # where one of the dyn function name offset in the dynstr -+ # table might be set at the an offset of the rpath string. -+ # Example: -+ # -+ # rpath offset = 1314 string = /usr/lib/foo -+ # dym function offset = 1322 string = foo -+ # -+ # In the following case, the dym function string offset is -+ # placed at the offset +10 of the rpath. -+ # To correctly clear the rpath entry AND keep normal -+ # functionality of this optimization (and the binary), -+ # parse the maximum string we can remove from the rpath entry. -+ # -+ # Since strings MUST be null terminated, we can always check -+ # if the rpath string ends with the dyn function string and -+ # calculate what we can actually remove accordingly. -+ for dynsym_string in self.dynsym_strings: -+ if rpath_string.endswith(dynsym_string): -+ if len(dynsym_string) > len(reused_str): -+ reused_str = dynsym_string -+ -+ # Seek back to start of string -+ self.bf.seek(offset) -+ self.bf.write(b'X' * (len(rpath_string) - len(reused_str))) -+ - def remove_rpath_entry(self, entrynum: int) -> None: - sec = self.find_section(b'.dynamic') - if sec is None: - return None - for (i, entry) in enumerate(self.dynamic): - if entry.d_tag == entrynum: -+ self.clean_rpath_entry_string(entrynum) - rpentry = self.dynamic[i] - rpentry.d_tag = 0 - self.dynamic = self.dynamic[:i] + self.dynamic[i + 1:] + [rpentry] diff --git a/tools/meson/patches/101-01-interpreter-move-can_run_host_binaries-to-environmen.patch b/tools/meson/patches/101-01-interpreter-move-can_run_host_binaries-to-environmen.patch index ad30ef9a1f2..153f82b09ad 100644 --- a/tools/meson/patches/101-01-interpreter-move-can_run_host_binaries-to-environmen.patch +++ b/tools/meson/patches/101-01-interpreter-move-can_run_host_binaries-to-environmen.patch @@ -15,10 +15,10 @@ Signed-off-by: Christian Marangi --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py -@@ -999,3 +999,10 @@ class Environment: - - def has_exe_wrapper(self) -> bool: - return self.exe_wrapper and self.exe_wrapper.found() +@@ -632,3 +632,10 @@ class Environment: + machines = self.machines.miss_defaulting() + machines.build = detect_machine_info(compilers) + self.machines = machines.default_missing() + + def can_run_host_binaries(self) -> bool: + return not ( @@ -28,9 +28,9 @@ Signed-off-by: Christian Marangi + ) --- a/mesonbuild/interpreter/mesonmain.py +++ b/mesonbuild/interpreter/mesonmain.py -@@ -277,20 +277,13 @@ class MesonMain(MesonInterpreterObject): - @noKwargs +@@ -258,21 +258,14 @@ class MesonMain(MesonInterpreterObject): @FeatureDeprecated('meson.has_exe_wrapper', '0.55.0', 'use meson.can_run_host_binaries instead.') + @InterpreterObject.method('has_exe_wrapper') def has_exe_wrapper_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool: - return self._can_run_host_binaries_impl() + return self.build.environment.can_run_host_binaries() @@ -38,6 +38,7 @@ Signed-off-by: Christian Marangi @noPosargs @noKwargs @FeatureNew('meson.can_run_host_binaries', '0.55.0') + @InterpreterObject.method('can_run_host_binaries') def can_run_host_binaries_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> bool: - return self._can_run_host_binaries_impl() - diff --git a/tools/meson/patches/101-02-linkers-don-t-include-absolue-RPATH-on-cross-compili.patch b/tools/meson/patches/101-02-linkers-don-t-include-absolue-RPATH-on-cross-compili.patch index 692116ac54c..fedfe08d1bf 100644 --- a/tools/meson/patches/101-02-linkers-don-t-include-absolue-RPATH-on-cross-compili.patch +++ b/tools/meson/patches/101-02-linkers-don-t-include-absolue-RPATH-on-cross-compili.patch @@ -32,9 +32,9 @@ Signed-off-by: Christian Marangi --- a/mesonbuild/linkers/linkers.py +++ b/mesonbuild/linkers/linkers.py -@@ -523,11 +523,11 @@ class MetrowerksStaticLinkerARM(Metrower - class MetrowerksStaticLinkerEmbeddedPowerPC(MetrowerksStaticLinker): - id = 'mwldeppc' +@@ -588,11 +588,11 @@ class EmxomfArLinker(ArLinker): + def get_std_link_args(self, env: 'Environment', is_thin: bool) -> T.List[str]: + return ['cr'] -def prepare_rpaths(raw_rpaths: T.Tuple[str, ...], build_dir: str, from_dir: str) -> T.List[str]: +def prepare_rpaths(env: Environment, raw_rpaths: T.Tuple[str, ...], build_dir: str, from_dir: str) -> T.List[str]: @@ -46,7 +46,7 @@ Signed-off-by: Christian Marangi ordered_rpaths = order_rpaths(internal_format_rpaths) return ordered_rpaths -@@ -544,11 +544,16 @@ def order_rpaths(rpath_list: T.List[str] +@@ -609,11 +609,16 @@ def order_rpaths(rpath_list: T.List[str] return sorted(rpath_list, key=os.path.isabs) @@ -54,7 +54,7 @@ Signed-off-by: Christian Marangi +def evaluate_rpath(env: Environment, p: str, build_dir: str, from_dir: str) -> str: if p == from_dir: return '' # relpath errors out in this case - elif os.path.isabs(p): + elif path_has_root(p): - return p # These can be outside of build dir. + if env.can_run_host_binaries(): + return p # These can be outside of build dir. @@ -65,103 +65,103 @@ Signed-off-by: Christian Marangi else: return os.path.relpath(os.path.join(build_dir, p), os.path.join(build_dir, from_dir)) -@@ -673,7 +678,7 @@ class GnuLikeDynamicLinkerMixin(DynamicL +@@ -752,7 +757,7 @@ class GnuLikeDynamicLinkerMixin(DynamicL return ([], set()) args: T.List[str] = [] origin_placeholder = '$ORIGIN' - processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) -+ processed_rpaths = prepare_rpaths(env, rpath_paths, build_dir, from_dir) ++ processed_rpaths = prepare_rpaths(self.environment, rpath_paths, build_dir, from_dir) # Need to deduplicate rpaths, as macOS's install_name_tool # is *very* allergic to duplicate -delete_rpath arguments # when calling depfixer on installation. -@@ -683,9 +688,13 @@ class GnuLikeDynamicLinkerMixin(DynamicL +@@ -762,9 +767,13 @@ class GnuLikeDynamicLinkerMixin(DynamicL rpath_dirs_to_remove.add(p.encode('utf8')) # Build_rpath is used as-is (it is usually absolute). - if build_rpath != '': -- all_paths.add(build_rpath) -- for p in build_rpath.split(':'): + if target.build_rpath != '': +- all_paths.add(target.build_rpath) +- for p in target.build_rpath.split(':'): - rpath_dirs_to_remove.add(p.encode('utf8')) -+ paths = build_rpath.split(':') ++ paths = target.build_rpath.split(':') + for p in paths: + # Only include relative paths if we can't run binaries on host system. + # (cross-compilation and no exe_wrapper) -+ if env.can_run_host_binaries() or not os.path.isabs(p): ++ if self.environment.can_run_host_binaries() or not os.path.isabs(p): + all_paths.add(p) + rpath_dirs_to_remove.add(p.encode('utf8')) + if extra_paths: + all_paths.update(extra_paths) - # TODO: should this actually be "for (dragonfly|open)bsd"? - if mesonlib.is_dragonflybsd() or mesonlib.is_openbsd(): -@@ -828,10 +837,15 @@ class AppleDynamicLinker(PosixDynamicLin +@@ -937,10 +946,15 @@ class AppleDynamicLinker(PosixDynamicLin # @loader_path is the equivalent of $ORIGIN on macOS # https://stackoverflow.com/q/26280738 origin_placeholder = '@loader_path' - processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) -+ processed_rpaths = prepare_rpaths(env, rpath_paths, build_dir, from_dir) ++ processed_rpaths = prepare_rpaths(self.environment, rpath_paths, build_dir, from_dir) all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths]) - if build_rpath != '': -- all_paths.update(build_rpath.split(':')) -+ paths = build_rpath.split(':') + if target.build_rpath != '': +- all_paths.update(target.build_rpath.split(':')) ++ paths = target.build_rpath.split(':') + for p in paths: + # Only include relative paths if we can't run binaries on host system. + # (cross-compilation and no exe_wrapper) -+ if env.can_run_host_binaries() or not os.path.isabs(p): ++ if self.environment.can_run_host_binaries() or not os.path.isabs(p): + all_paths.add(p) + if extra_paths: + all_paths.update(extra_paths) for rp in all_paths: - rpath_dirs_to_remove.add(rp.encode('utf8')) - args.extend(self._apply_prefix('-rpath,' + rp)) -@@ -1200,10 +1214,15 @@ class NAGDynamicLinker(PosixDynamicLinke +@@ -1356,10 +1370,15 @@ class NAGDynamicLinker(PosixDynamicLinke return ([], set()) args: T.List[str] = [] origin_placeholder = '$ORIGIN' - processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) -+ processed_rpaths = prepare_rpaths(env, rpath_paths, build_dir, from_dir) ++ processed_rpaths = prepare_rpaths(self.environment, rpath_paths, build_dir, from_dir) all_paths = mesonlib.OrderedSet([os.path.join(origin_placeholder, p) for p in processed_rpaths]) - if build_rpath != '': -- all_paths.add(build_rpath) -+ paths = build_rpath.split(':') + if target.build_rpath != '': +- all_paths.add(target.build_rpath) ++ paths = target.build_rpath.split(':') + for p in paths: + # Only include relative paths if we can't run binaries on host system. + # (cross-compilation and no exe_wrapper) -+ if env.can_run_host_binaries() or not os.path.isabs(p): ++ if self.environment.can_run_host_binaries() or not os.path.isabs(p): + all_paths.add(p) + if extra_paths: + all_paths.update(extra_paths) for rp in all_paths: - args.extend(self._apply_prefix('-Wl,-Wl,,-rpath,,' + rp)) - -@@ -1454,15 +1473,19 @@ class SolarisDynamicLinker(PosixDynamicL - install_rpath: str) -> T.Tuple[T.List[str], T.Set[bytes]]: - if not rpath_paths and not install_rpath and not build_rpath: +@@ -1627,15 +1646,19 @@ class SolarisDynamicLinker(PosixDynamicL + rpath_paths = target.determine_rpath_dirs() + if not rpath_paths and not target.install_rpath and not target.build_rpath and not extra_paths: return ([], set()) - processed_rpaths = prepare_rpaths(rpath_paths, build_dir, from_dir) -+ processed_rpaths = prepare_rpaths(env, rpath_paths, build_dir, from_dir) ++ processed_rpaths = prepare_rpaths(self.environment, rpath_paths, build_dir, from_dir) all_paths = mesonlib.OrderedSet([os.path.join('$ORIGIN', p) for p in processed_rpaths]) rpath_dirs_to_remove: T.Set[bytes] = set() for p in all_paths: rpath_dirs_to_remove.add(p.encode('utf8')) - if build_rpath != '': -- all_paths.add(build_rpath) -- for p in build_rpath.split(':'): + if target.build_rpath != '': +- all_paths.add(target.build_rpath) +- for p in target.build_rpath.split(':'): - rpath_dirs_to_remove.add(p.encode('utf8')) -+ paths = build_rpath.split(':') ++ paths = target.build_rpath.split(':') + for p in paths: + # Only include relative paths if we can't run binaries on host system. + # (cross-compilation and no exe_wrapper) -+ if env.can_run_host_binaries() or not os.path.isabs(p): ++ if self.environment.can_run_host_binaries() or not os.path.isabs(p): + all_paths.add(p) + rpath_dirs_to_remove.add(p.encode('utf8')) + if extra_paths: + all_paths.update(extra_paths) - # In order to avoid relinking for RPATH removal, the binary needs to contain just - # enough space in the ELF header to hold the final installation RPATH. -@@ -1525,7 +1548,12 @@ class AIXDynamicLinker(PosixDynamicLinke - if install_rpath != '': - all_paths.add(install_rpath) - if build_rpath != '': -- all_paths.add(build_rpath) -+ paths = build_rpath.split(':') +@@ -1703,7 +1726,12 @@ class AIXDynamicLinker(PosixDynamicLinke + if target.install_rpath != '': + all_paths.add(target.install_rpath) + if target.build_rpath != '': +- all_paths.add(target.build_rpath) ++ paths = target.build_rpath.split(':') + for p in paths: + # Only include relative paths if we can't run binaries on host system. + # (cross-compilation and no exe_wrapper) -+ if env.can_run_host_binaries() or not os.path.isabs(p): ++ if self.environment.can_run_host_binaries() or not os.path.isabs(p): + all_paths.add(p) - for p in rpath_paths: + for p in target.determine_rpath_dirs(): all_paths.add(os.path.join(build_dir, p)) # We should consider allowing the $LIBPATH environment variable