mirror of
https://github.com/mesonbuild/meson.git
synced 2026-06-30 19:57:45 +00:00
depfixer: add RPATH handling for AIX's XCOFF object files.
Ensures install_rpath used in shared library and shared modules targets is set at install time on AIX.
This commit is contained in:
committed by
Paolo Bonzini
parent
40023e00ea
commit
271e1e50d9
@@ -144,6 +144,7 @@ class TargetInstallData:
|
||||
# TODO: install_mode should just always be a FileMode object
|
||||
install_mode: T.Optional['FileMode']
|
||||
subproject: str
|
||||
system: str
|
||||
optional: bool = False
|
||||
tag: T.Optional[str] = None
|
||||
can_strip: bool = False
|
||||
@@ -1749,7 +1750,8 @@ class Backend:
|
||||
first_outdir_name,
|
||||
should_strip, mappings, t.rpath_dirs_to_remove,
|
||||
t.install_rpath, install_mode, t.subproject,
|
||||
tag=tag, can_strip=can_strip)
|
||||
tag=tag, can_strip=can_strip,
|
||||
system=self.environment.machines[t.for_machine].system)
|
||||
d.targets.append(i)
|
||||
|
||||
for alias, to, tag in t.get_aliases():
|
||||
@@ -1774,7 +1776,8 @@ class Backend:
|
||||
implib_install_dir, first_outdir_name,
|
||||
False, {}, set(), '', install_mode,
|
||||
t.subproject, optional=isinstance(t, build.SharedModule),
|
||||
tag='devel')
|
||||
tag='devel',
|
||||
system=self.environment.machines[t.for_machine].system)
|
||||
d.targets.append(i)
|
||||
|
||||
if not should_strip and t.get_debug_filename():
|
||||
@@ -1783,7 +1786,8 @@ class Backend:
|
||||
first_outdir_name,
|
||||
False, {}, set(), '',
|
||||
install_mode, t.subproject,
|
||||
optional=True, tag='devel')
|
||||
optional=True, tag='devel',
|
||||
system=self.environment.machines[t.for_machine].system)
|
||||
d.targets.append(i)
|
||||
# Install secondary outputs. Only used for Vala right now.
|
||||
if num_outdirs > 1:
|
||||
@@ -1794,7 +1798,8 @@ class Backend:
|
||||
f = os.path.join(self.get_target_dir(t), output)
|
||||
i = TargetInstallData(f, outdir, outdir_name, False, {}, set(), None,
|
||||
install_mode, t.subproject,
|
||||
tag=tag)
|
||||
tag=tag,
|
||||
system=self.environment.machines[t.for_machine].system)
|
||||
d.targets.append(i)
|
||||
elif isinstance(t, build.CustomTarget):
|
||||
# If only one install_dir is specified, assume that all
|
||||
@@ -1815,7 +1820,8 @@ class Backend:
|
||||
i = TargetInstallData(f, first_outdir, first_outdir_name,
|
||||
False, {}, set(), None, install_mode,
|
||||
t.subproject, optional=not t.build_by_default,
|
||||
tag=tag)
|
||||
tag=tag,
|
||||
system=self.environment.machines[t.for_machine].system)
|
||||
d.targets.append(i)
|
||||
else:
|
||||
for output, outdir, outdir_name, tag in zip(t.get_outputs(), outdirs, install_dir_names, t.install_tag):
|
||||
@@ -1827,7 +1833,8 @@ class Backend:
|
||||
i = TargetInstallData(f, outdir, outdir_name,
|
||||
False, {}, set(), None, install_mode,
|
||||
t.subproject, optional=not t.build_by_default,
|
||||
tag=tag)
|
||||
tag=tag,
|
||||
system=self.environment.machines[t.for_machine].system)
|
||||
d.targets.append(i)
|
||||
|
||||
def generate_custom_install_script(self, d: InstallData) -> None:
|
||||
|
||||
@@ -1698,14 +1698,24 @@ class AIXDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
|
||||
def build_rpath_args(self, build_dir: str, from_dir: str, target: BuildTarget,
|
||||
extra_paths: T.Optional[T.List[str]] = None
|
||||
) -> T.Tuple[T.List[str], T.Set[bytes]]:
|
||||
# Extract rpath information from target
|
||||
rpath_paths = target.determine_rpath_dirs()
|
||||
install_rpath = target.install_rpath
|
||||
build_rpath = target.build_rpath
|
||||
|
||||
all_paths: mesonlib.OrderedSet[str] = mesonlib.OrderedSet()
|
||||
rpath_dirs_to_remove: T.Set[bytes] = set()
|
||||
# install_rpath first, followed by other paths, and the system path last
|
||||
if target.install_rpath != '':
|
||||
all_paths.add(target.install_rpath)
|
||||
if target.build_rpath != '':
|
||||
all_paths.add(target.build_rpath)
|
||||
for p in target.determine_rpath_dirs():
|
||||
all_paths.add(os.path.join(build_dir, p))
|
||||
if install_rpath != '':
|
||||
all_paths.add(install_rpath)
|
||||
if build_rpath != '':
|
||||
all_paths.add(build_rpath)
|
||||
for p in build_rpath.split(':'):
|
||||
rpath_dirs_to_remove.add(p.encode('utf8'))
|
||||
for p in rpath_paths:
|
||||
path = os.path.join(build_dir, p)
|
||||
all_paths.add(path)
|
||||
rpath_dirs_to_remove.add(path.encode('utf8'))
|
||||
# We should consider allowing the $LIBPATH environment variable
|
||||
# to override sys_path.
|
||||
sys_path = self.environment.get_compiler_system_lib_dirs(self.for_machine)
|
||||
@@ -1720,7 +1730,7 @@ class AIXDynamicLinker(PosixDynamicLinkerMixin, DynamicLinker):
|
||||
all_paths.add(p)
|
||||
if extra_paths:
|
||||
all_paths.update(extra_paths)
|
||||
return (self._apply_prefix('-blibpath:' + ':'.join(all_paths)), set())
|
||||
return (self._apply_prefix('-blibpath:' + ':'.join(all_paths)), rpath_dirs_to_remove)
|
||||
|
||||
def thread_flags(self) -> T.List[str]:
|
||||
return ['-pthread']
|
||||
|
||||
@@ -786,7 +786,7 @@ class Installer:
|
||||
self.did_install_something = True
|
||||
try:
|
||||
self.fix_rpath(outname, t.rpath_dirs_to_remove, install_rpath, final_path,
|
||||
install_name_mappings, verbose=False)
|
||||
install_name_mappings, t.system, verbose=False)
|
||||
except SystemExit as e:
|
||||
if isinstance(e.code, int) and e.code == 0:
|
||||
pass
|
||||
|
||||
@@ -25,6 +25,277 @@ DT_MIPS_RLD_MAP_REL = 1879048245
|
||||
# Global cache for tools
|
||||
INSTALL_NAME_TOOL = False
|
||||
|
||||
# -------------------AIX-------------------------
|
||||
# Reference documents:
|
||||
# https://www.ibm.com/docs/en/aix/7.1?topic=formats-xcoff-object-file-format
|
||||
# https://www.ibm.com/docs/en/aix/7.2?topic=formats-ar-file-format-big
|
||||
|
||||
# Size of magic number
|
||||
XCOFF_MAGIC_SIZE = 2
|
||||
|
||||
|
||||
def align(value: int, align_bytes: int) -> int:
|
||||
# Function used by AIX to align value to align_bytes
|
||||
align_bytes = 1 << align_bytes
|
||||
return ((value + align_bytes - 1) // align_bytes) * align_bytes
|
||||
|
||||
|
||||
class XcoffFixedLengthHeader:
|
||||
# AIX archive fixed length header (struct fl_hdr)
|
||||
FL_HDR_SIZE = 128
|
||||
FL_HDR_FORMAT = '8s 20s 20s 20s 20s 20s 20s'
|
||||
|
||||
def __init__(self, file: T.BinaryIO) -> None:
|
||||
header_data = file.read(self.FL_HDR_SIZE)
|
||||
fl_magic, fl_memoff, fl_gstoff, fl_gst64off, fl_fstmoff, fl_lstmoff, fl_freeoff = struct.unpack(
|
||||
self.FL_HDR_FORMAT, header_data
|
||||
)
|
||||
self.fl_magic = fl_magic
|
||||
self.fl_fstmoff = int(fl_fstmoff)
|
||||
|
||||
|
||||
class XcoffArchiveHeader:
|
||||
# AIX archive header (struct ar_hdr)
|
||||
AR_HDR_SIZE = 114
|
||||
AR_HDR_FORMAT = '20s 20s 20s 12s 12s 12s 12s 4s 2s'
|
||||
|
||||
def __init__(self, file: T.BinaryIO) -> None:
|
||||
header_data = file.read(self.AR_HDR_SIZE)
|
||||
ar_size, ar_nxtmem, ar_prvmem, ar_date, ar_uid, ar_gid, ar_mode, ar_namlen, _ar_name = struct.unpack(
|
||||
self.AR_HDR_FORMAT, header_data
|
||||
)
|
||||
ar_namlen_int = int(ar_namlen.strip())
|
||||
# The Magic number always starts at the even byte boundary
|
||||
self.ar_namlen = ar_namlen_int if ar_namlen_int % 2 == 0 else ar_namlen_int + 1
|
||||
# Seek past the archive member name
|
||||
file.seek(self.ar_namlen, os.SEEK_CUR)
|
||||
|
||||
|
||||
class XcoffCompositeFileHeader:
|
||||
# XCOFF composite file header
|
||||
CFH_HDR_SIZE = 24
|
||||
CFH_HDR_SIZE_32 = 20
|
||||
CFH_HDR_FORMAT = '2s 2s 4s 8s 2s 2s 4s'
|
||||
CFH_HDR_FORMAT_32 = '2s 2s 4s 4s 4s 2s 2s'
|
||||
|
||||
def __init__(self, file: T.BinaryIO, magic: int) -> None:
|
||||
if magic == 0x01DF:
|
||||
cfh_header_data = file.read(self.CFH_HDR_SIZE_32)
|
||||
f_magic, f_nscns, f_timdat, f_symptr, f_nsyms, f_opthdr, f_flags = struct.unpack(
|
||||
self.CFH_HDR_FORMAT_32, cfh_header_data
|
||||
)
|
||||
else:
|
||||
cfh_header_data = file.read(self.CFH_HDR_SIZE)
|
||||
f_magic, f_nscns, f_timdat, f_symptr, f_opthdr, f_flags, f_nsyms = struct.unpack(
|
||||
self.CFH_HDR_FORMAT, cfh_header_data
|
||||
)
|
||||
self.f_flags = int.from_bytes(f_flags, byteorder='big')
|
||||
self.f_opthdr = int.from_bytes(f_opthdr, byteorder='big')
|
||||
|
||||
|
||||
class XcoffAuxiliaryHeader:
|
||||
# XCOFF auxiliary header
|
||||
AUX_HDR_SIZE = 120
|
||||
AUX_HDR_SIZE_32 = 72
|
||||
AUX_HDR_FORMAT = '2s 2s 4s 8s 8s 8s 2s 2s 2s 2s 2s 2s 2s 2s 2s 1s 1s 1s 1s 1s 1s 8s 8s 8s 8s 8s 8s 2s 2s 2s 10s'
|
||||
AUX_HDR_FORMAT_32 = '2s 2s 4s 4s 4s 4s 4s 4s 4s 2s 2s 2s 2s 2s 2s 2s 2s 2s 1s 1s 4s 4s 4s 1s 1s 1s 1s 2s 2s'
|
||||
|
||||
def __init__(self, file: T.BinaryIO, magic: int, opthdr_size: int) -> None:
|
||||
if magic == 0x01DF:
|
||||
if opthdr_size < self.AUX_HDR_SIZE_32:
|
||||
sys.exit(f'Error: Auxiliary header size {opthdr_size} is too small for 32-bit XCOFF')
|
||||
aux_header_data = file.read(self.AUX_HDR_SIZE_32)
|
||||
if len(aux_header_data) < self.AUX_HDR_SIZE_32:
|
||||
sys.exit(f'Error: Could not read auxiliary header, got {len(aux_header_data)} bytes, expected {self.AUX_HDR_SIZE_32}')
|
||||
(o_mflags, o_vstamp, o_tsize, o_dsize, o_bsize, o_entry, o_text_start, o_data_start, o_toc,
|
||||
o_snentry, o_sntext, o_sndata, o_sntoc, o_snloader, o_snbss, o_algntext, o_algndata, o_modtype,
|
||||
o_cpuflag, o_cputype, o_maxstack, o_maxdata, o_debugger, o_textpsize, o_datapsize, o_stackpsize,
|
||||
o_flags, o_sntdata, o_sntbss) = struct.unpack(self.AUX_HDR_FORMAT_32, aux_header_data)
|
||||
else:
|
||||
if opthdr_size < self.AUX_HDR_SIZE:
|
||||
sys.exit(f'Error: Auxiliary header size {opthdr_size} is too small for 64-bit XCOFF')
|
||||
aux_header_data = file.read(self.AUX_HDR_SIZE)
|
||||
if len(aux_header_data) < self.AUX_HDR_SIZE:
|
||||
sys.exit(f'Error: Could not read auxiliary header, got {len(aux_header_data)} bytes, expected {self.AUX_HDR_SIZE}')
|
||||
(o_mflags, o_vstamp, o_debugger, o_text_start, o_data_start, o_toc, o_snentry, o_sntext, o_sndata,
|
||||
o_sntoc, o_snloader, o_snbss, o_algntext, o_algndata, o_modtype, o_cpuflag, o_cputype, o_textpsize,
|
||||
o_datapsize, o_stackpsize, o_flags, o_tsize, o_dsize, o_bsize, o_entry, o_maxstack, o_maxdata,
|
||||
o_sntdata, o_sntbss, o_x64flags, dummy) = struct.unpack(self.AUX_HDR_FORMAT, aux_header_data)
|
||||
|
||||
self.o_algntext = int.from_bytes(o_algntext, byteorder='big')
|
||||
self.o_algndata = int.from_bytes(o_algndata, byteorder='big')
|
||||
self.o_snloader = int.from_bytes(o_snloader, byteorder='big')
|
||||
|
||||
|
||||
class XcoffSectionHeader:
|
||||
# XCOFF section header
|
||||
SCN_HDR_SIZE = 72
|
||||
SCN_HDR_SIZE_32 = 40
|
||||
SCN_HDR_FORMAT = '8s 8s 8s 8s 8s 8s 8s 4s 4s 4s 4s'
|
||||
SCN_HDR_FORMAT_32 = '8s 4s 4s 4s 4s 4s 4s 2s 2s 2s 2s'
|
||||
|
||||
def __init__(self, file: T.BinaryIO, magic: int) -> None:
|
||||
if magic == 0x01DF:
|
||||
scn_header_data = file.read(self.SCN_HDR_SIZE_32)
|
||||
if len(scn_header_data) < self.SCN_HDR_SIZE_32:
|
||||
raise EOFError('End of archive member reached')
|
||||
(s_name, s_paddr, s_vaddr, s_size, s_scnptr, s_relptr, s_lnnoptr, s_nreloc, s_nlnno, s_flags,
|
||||
dummy) = struct.unpack(self.SCN_HDR_FORMAT_32, scn_header_data)
|
||||
else:
|
||||
scn_header_data = file.read(self.SCN_HDR_SIZE)
|
||||
if len(scn_header_data) < self.SCN_HDR_SIZE:
|
||||
raise EOFError('End of archive member reached')
|
||||
(s_name, s_paddr, s_vaddr, s_size, s_scnptr, s_relptr, s_lnnoptr, s_nreloc, s_nlnno, s_flags,
|
||||
dummy) = struct.unpack(self.SCN_HDR_FORMAT, scn_header_data)
|
||||
self.s_scnptr = int.from_bytes(s_scnptr, byteorder='big')
|
||||
|
||||
|
||||
class XcoffLoaderHeader:
|
||||
# XCOFF loader header
|
||||
LDR_HDR_SIZE = 56
|
||||
LDR_HDR_SIZE_32 = 32
|
||||
LDR_HDR_FORMAT = '4s 4s 4s 4s 4s 4s 8s 8s 8s 8s'
|
||||
LDR_HDR_FORMAT_32 = '4s 4s 4s 4s 4s 4s 4s 4s'
|
||||
|
||||
def __init__(self, file: T.BinaryIO, magic: int) -> None:
|
||||
if magic == 0x01DF:
|
||||
ldr_header_data = file.read(self.LDR_HDR_SIZE_32)
|
||||
(l_version, l_nsyms, l_nreloc, l_istlen, l_nimpid, l_impoff, l_stlen,
|
||||
l_stoff) = struct.unpack(self.LDR_HDR_FORMAT_32, ldr_header_data)
|
||||
else:
|
||||
ldr_header_data = file.read(self.LDR_HDR_SIZE)
|
||||
(l_version, l_nsyms, l_nreloc, l_istlen, l_nimpid, l_stlen, l_impoff, l_stoff, l_symoff,
|
||||
l_rldoff) = struct.unpack(self.LDR_HDR_FORMAT, ldr_header_data)
|
||||
self.l_impoff = int.from_bytes(l_impoff, byteorder='big')
|
||||
self.l_istlen = int.from_bytes(l_istlen, byteorder='big')
|
||||
|
||||
|
||||
def traverse_xcoff(file: T.BinaryIO, rpath_dirs_to_remove: T.Set[bytes], new_rpath: T.Optional[bytes], verbose: bool = True) -> None:
|
||||
"""Traverse XCOFF file or archive and modify Libpath entries.
|
||||
|
||||
Handles both standalone XCOFF shared objects (.so) and XCOFF archives (.a).
|
||||
Archives are detected by magic number and processed member by member.
|
||||
"""
|
||||
def dummy_print(*args: object) -> None:
|
||||
pass
|
||||
log_msg: T.Callable[..., None]
|
||||
log_msg = print if verbose else dummy_print # type: ignore[assignment]
|
||||
|
||||
# Detect if this is an archive by checking for magic number
|
||||
magic_check = file.read(8)
|
||||
file.seek(0)
|
||||
|
||||
# Read archive headers if this is an archive
|
||||
ar_header: T.Optional[XcoffArchiveHeader] = None
|
||||
if magic_check == b'<bigaf>\n':
|
||||
fl_header = XcoffFixedLengthHeader(file)
|
||||
file.seek(fl_header.fl_fstmoff)
|
||||
ar_header = XcoffArchiveHeader(file)
|
||||
|
||||
composite_header_pos = file.tell()
|
||||
# Read XCOFF magic number
|
||||
magic_data = file.read(XCOFF_MAGIC_SIZE)
|
||||
if len(magic_data) != XCOFF_MAGIC_SIZE:
|
||||
sys.exit(0)
|
||||
magic_number = struct.unpack('>H', magic_data)[0] # Big-endian 16-bit integer
|
||||
if magic_number == 0x01DF:
|
||||
log_msg(' Changing Libpath for a 32-bit Shared Object')
|
||||
elif magic_number == 0x01F7:
|
||||
log_msg(' Changing Libpath for a 64-bit Shared Object')
|
||||
else:
|
||||
log_msg(' Not a shared object')
|
||||
sys.exit(0)
|
||||
# Reposition to start of XCOFF headers
|
||||
file.seek(composite_header_pos)
|
||||
cfh_header = XcoffCompositeFileHeader(file, magic_number)
|
||||
if not cfh_header.f_flags & 0x2000:
|
||||
log_msg('Did not change rpath since not a shared library/archive')
|
||||
return
|
||||
# Read auxiliary header
|
||||
aux_header = XcoffAuxiliaryHeader(file, magic_number, cfh_header.f_opthdr)
|
||||
|
||||
# Calculate the bytes_to_align
|
||||
bytes_to_align = max(aux_header.o_algntext, aux_header.o_algndata)
|
||||
|
||||
# Seek to section header and read it
|
||||
if magic_number == 0x01DF:
|
||||
file.seek((aux_header.o_snloader - 1) * XcoffSectionHeader.SCN_HDR_SIZE_32, os.SEEK_CUR)
|
||||
else:
|
||||
file.seek((aux_header.o_snloader - 1) * XcoffSectionHeader.SCN_HDR_SIZE, os.SEEK_CUR)
|
||||
try:
|
||||
scn_header = XcoffSectionHeader(file, magic_number)
|
||||
except EOFError:
|
||||
return # End of archive member, nothing to fix
|
||||
|
||||
header_len = 0
|
||||
if ar_header:
|
||||
header_len = XcoffFixedLengthHeader.FL_HDR_SIZE + XcoffArchiveHeader.AR_HDR_SIZE + ar_header.ar_namlen
|
||||
scnptrFromArchiveStart = scn_header.s_scnptr + align(header_len, bytes_to_align)
|
||||
else:
|
||||
scnptrFromArchiveStart = scn_header.s_scnptr
|
||||
|
||||
file.seek(scnptrFromArchiveStart)
|
||||
|
||||
# Read loader header
|
||||
ldr_header = XcoffLoaderHeader(file, magic_number)
|
||||
|
||||
if ar_header:
|
||||
scnptrFromArchiveStartPlusOff = scn_header.s_scnptr + ldr_header.l_impoff + align(header_len, bytes_to_align)
|
||||
else:
|
||||
scnptrFromArchiveStartPlusOff = scn_header.s_scnptr + ldr_header.l_impoff
|
||||
file.seek(scnptrFromArchiveStartPlusOff)
|
||||
|
||||
# Read and update libpath
|
||||
libpath = file.read(ldr_header.l_istlen)
|
||||
build_libpath = libpath.split(b'\x00')[0]
|
||||
# Build the new rpath by merging new_rpath with existing paths (excluding removed ones)
|
||||
new_rpaths: OrderedSet[bytes] = OrderedSet()
|
||||
if new_rpath:
|
||||
new_rpaths.update(new_rpath.split(b':'))
|
||||
|
||||
new_rpaths.update(
|
||||
path
|
||||
for path in build_libpath.split(b':')
|
||||
if path and path not in rpath_dirs_to_remove
|
||||
)
|
||||
|
||||
install_rpath = b':'.join(new_rpaths)
|
||||
|
||||
# If the length of the build_rpath length is < install_rpath length then we do not have space to write
|
||||
# the same hence exit. Otherwise, we can and the length has to be the same as build_rpath.
|
||||
# If the install_rpath length is less than build_rpath length then pad the difference
|
||||
if len(install_rpath) > len(build_libpath):
|
||||
sys.exit('Error: install_rpath is bigger than build_rpath')
|
||||
# Pad with colon bytes to match build_libpath length
|
||||
install_rpath = install_rpath + (b':' * (len(build_libpath) - len(install_rpath)))
|
||||
file.seek(scnptrFromArchiveStartPlusOff)
|
||||
file.write(install_rpath)
|
||||
log_msg(f'Successfully changed libpath from {build_libpath!r} to {install_rpath!r}')
|
||||
|
||||
|
||||
def fix_aix(fname: str, rpath_dirs_to_remove: T.Set[bytes], new_rpath: T.Optional[bytes], verbose: bool = True) -> None:
|
||||
"""Writes Libpath to an xcoff shared object.
|
||||
|
||||
In AIX, shared modules are .so files and shared libraries are in .a archives.
|
||||
Follows the same calling convention as fix_elf:
|
||||
- Errors: sys.exit('error message')
|
||||
- Wrong file type: sys.exit(0)
|
||||
- Success: return normally
|
||||
"""
|
||||
if new_rpath is None:
|
||||
return
|
||||
|
||||
try:
|
||||
with open(fname, 'r+b') as file:
|
||||
traverse_xcoff(file, rpath_dirs_to_remove, new_rpath, verbose)
|
||||
except FileNotFoundError:
|
||||
sys.exit(f'Error: File not found: {fname}')
|
||||
except Exception as e:
|
||||
sys.exit(f'Unexpected error processing {fname}: {e}')
|
||||
|
||||
|
||||
# ----------------ELF------------------
|
||||
|
||||
class DataSizes:
|
||||
def __init__(self, ptrsize: int, is_le: bool) -> None:
|
||||
if is_le:
|
||||
@@ -379,7 +650,7 @@ class Elf(DataSizes):
|
||||
new_rpath = b':'.join(new_rpaths)
|
||||
|
||||
if len(old_rpath) < len(new_rpath):
|
||||
msg = "New rpath must not be longer than the old one.\n Old: {}\n New: {}".format(old_rpath.decode('utf-8'), new_rpath.decode('utf-8'))
|
||||
msg = 'New rpath must not be longer than the old one.\n Old: {}\n New: {}'.format(old_rpath.decode('utf-8'), new_rpath.decode('utf-8'))
|
||||
sys.exit(msg)
|
||||
# The linker does read-only string deduplication. If there is a
|
||||
# string that shares a suffix with the rpath, they might get
|
||||
@@ -534,20 +805,27 @@ def fix_jar(fname: str) -> None:
|
||||
# than the beginning, but the spec doesn't forbid that.
|
||||
subprocess.check_call(['jar', 'ufM', fname, 'META-INF/MANIFEST.MF'])
|
||||
|
||||
def fix_rpath(fname: str, rpath_dirs_to_remove: T.Set[bytes], new_rpath: T.Union[str, bytes], final_path: str, install_name_mappings: T.Dict[str, str], verbose: bool = True) -> None:
|
||||
def fix_rpath(fname: str, rpath_dirs_to_remove: T.Set[bytes], new_rpath: T.Union[str, bytes], final_path: str, install_name_mappings: T.Dict[str, str], system: str, verbose: bool = True) -> None:
|
||||
global INSTALL_NAME_TOOL # pylint: disable=global-statement
|
||||
# Static libraries, import libraries, debug information, headers, etc
|
||||
# never have rpaths
|
||||
# DLLs and EXE currently do not need runtime path fixing
|
||||
if fname.endswith(('.a', '.lib', '.pdb', '.h', '.hpp', '.dll', '.exe')):
|
||||
|
||||
if fname.endswith(('.lib', '.pdb', '.h', '.hpp', '.dll', '.exe')):
|
||||
return
|
||||
# Shared libraries are .a files on AIX
|
||||
if fname.endswith('.a') and system != 'aix':
|
||||
return
|
||||
if isinstance(new_rpath, str):
|
||||
new_rpath = new_rpath.encode('utf8')
|
||||
try:
|
||||
if fname.endswith('.jar'):
|
||||
fix_jar(fname)
|
||||
return
|
||||
if isinstance(new_rpath, str):
|
||||
new_rpath = new_rpath.encode('utf8')
|
||||
fix_elf(fname, rpath_dirs_to_remove, new_rpath, verbose)
|
||||
if system == 'aix':
|
||||
fix_aix(fname, rpath_dirs_to_remove, new_rpath, verbose)
|
||||
else:
|
||||
fix_elf(fname, rpath_dirs_to_remove, new_rpath, verbose)
|
||||
return
|
||||
except SystemExit as e:
|
||||
if isinstance(e.code, int) and e.code == 0:
|
||||
|
||||
Reference in New Issue
Block a user