From 5af440655f932410ac04e0a8b0ed00c2585a6727 Mon Sep 17 00:00:00 2001 From: Will Ayd Date: Tue, 9 Jan 2024 17:16:35 -0500 Subject: [PATCH] custom delocate for version 10.4 --- pyproject.toml | 2 +- scripts/custom_delocate_wheel.py | 187 +++++++++++++++++++------------ 2 files changed, 115 insertions(+), 74 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index dbfac6aa..a1582d3a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,5 +83,5 @@ auditwheel repair -w {dest_dir} {wheel} --exclude libtableauhyperapi.so [tool.cibuildwheel.macos] repair-wheel-command = """ -delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v --exclude tableau {wheel} +./scripts/custom_delocate_wheel.py --require-archs {delocate_archs} -w {dest_dir} -v {wheel} """ diff --git a/scripts/custom_delocate_wheel.py b/scripts/custom_delocate_wheel.py index 9fdec93b..13c9d94a 100755 --- a/scripts/custom_delocate_wheel.py +++ b/scripts/custom_delocate_wheel.py @@ -4,8 +4,12 @@ # this script is a customization of delocate to prevent that library from complaining # about the missing libtableauhyperapi library # See https://github.com/matthew-brett/delocate/issues/77 -# File is adopted from matthe-brett delocate library which is licensed under -# the BSD 2-clause license. A copy of the License is as follows: +# File is adopted from matthe-brett delocate library version 10.4 +# Newer library versions will have an --exclude command line argument +# See https://github.com/matthew-brett/delocate/pull/106 +# Until then we need this module vendored to add a copy_filt_func +# delocate is licensed under the BSD 2-clause license. +# A copy of the License is as follows: # Copyright (c) 2014-2023, Matthew Brett and the Delocate contributors. # All rights reserved. @@ -36,105 +40,142 @@ Overwrites the wheel in-place by default """ -# vim: ft=python -from __future__ import annotations +from __future__ import absolute_import, division, print_function +import logging import os -from argparse import ArgumentParser +import sys +from optparse import Option, OptionParser from os.path import basename, exists, expanduser from os.path import join as pjoin from typing import List, Optional, Text -from delocate import delocate_wheel -from delocate.cmd.common import ( - common_parser, - delocate_parser, - delocate_values, - glob_paths, - verbosity_config, -) -from delocate.delocating import filter_system_libs - -parser = ArgumentParser(description=__doc__, parents=[common_parser, delocate_parser]) -parser.add_argument( - "wheels", - nargs="+", - metavar="WHEEL", - type=str, - help="The wheel files to be delocated", -) -parser.add_argument( - "-L", - "--lib-sdir", - action="store", - type=str, - default=".dylibs", - help="Subdirectory in packages to store copied libraries", -) -parser.add_argument( - "-w", - "--wheel-dir", - action="store", - type=str, - help="Directory to store delocated wheels (default is to overwrite input)", -) -parser.add_argument( - "-k", - "--check-archs", - action="store_true", - help="Check architectures of depended libraries", -) -parser.add_argument( - "--require-archs", - metavar="ARCHITECTURES", - action="store", - type=str, - help="Architectures that all wheel libraries should have" - " (from 'intel', 'i386', 'x86_64', 'i386,x86_64', 'universal2'," - " 'x86_64,arm64')", -) +from delocate import __version__, delocate_wheel def main() -> None: - args = parser.parse_args() - verbosity_config(args) - wheels = list(glob_paths(args.wheels)) + parser = OptionParser( + usage="%s WHEEL_FILENAME\n\n" % sys.argv[0] + __doc__, + version="%prog " + __version__, + ) + parser.add_options( + [ + Option( + "-L", + "--lib-sdir", + action="store", + type="string", + default=".dylibs", + help="Subdirectory in packages to store copied libraries", + ), + Option( + "-w", + "--wheel-dir", + action="store", + type="string", + help=( + "Directory to store delocated wheels (default is to " + "overwrite input)" + ), + ), + Option( + "-v", + "--verbose", + action="count", + help=( + "Show a more verbose report of progress and failure." + " Additional flags show even more info, up to -vv." + ), + default=0, + ), + Option( + "-k", + "--check-archs", + action="store_true", + help="Check architectures of depended libraries", + ), + Option( + "-d", + "--dylibs-only", + action="store_true", + help="Only analyze files with known dynamic library extensions", + ), + Option( + "--require-archs", + action="store", + type="string", + help=( + "Architectures that all wheel libraries should " + "have (from 'intel', 'i386', 'x86_64', 'i386,x86_64'" + "'universal2', 'x86_64,arm64')" + ), + ), + Option( + "--executable-path", + action="store", + type="string", + default=os.path.dirname(sys.executable), + help=("The path used to resolve @executable_path in dependencies"), + ), + Option( + "--ignore-missing-dependencies", + action="store_true", + help=( + "Skip dependencies which couldn't be found and delocate " + "as much as possible" + ), + ), + ] + ) + (opts, wheels) = parser.parse_args() + if len(wheels) < 1: + parser.print_help() + sys.exit(1) + logging.basicConfig( + level={0: logging.WARNING, 1: logging.INFO, 2: logging.DEBUG}.get( + opts.verbose, logging.DEBUG + ) + ) multi = len(wheels) > 1 - if args.wheel_dir: - wheel_dir = expanduser(args.wheel_dir) + if opts.wheel_dir: + wheel_dir = expanduser(opts.wheel_dir) if not exists(wheel_dir): os.makedirs(wheel_dir) else: wheel_dir = None require_archs: Optional[List[Text]] = None - if args.require_archs is None: - require_archs = [] if args.check_archs else None - elif "," in args.require_archs: - require_archs = [s.strip() for s in args.require_archs.split(",")] + if opts.require_archs is None: + require_archs = [] if opts.check_archs else None + elif "," in opts.require_archs: + require_archs = [s.strip() for s in opts.require_archs.split(",")] else: - require_archs = args.require_archs - + require_archs = opts.require_archs + lib_filt_func = "dylibs-only" if opts.dylibs_only else None for wheel in wheels: - if multi or args.verbose: + if multi or opts.verbose: print("Fixing: " + wheel) if wheel_dir: out_wheel = pjoin(wheel_dir, basename(wheel)) else: out_wheel = wheel - delocate_kwargs = {k: v for k, v in delocate_values(args).items()} - delocate_kwargs["copy_filter_exclude"] = ( - lambda name: False if "tableau" in name else filter_system_libs(name) - ) + def copy_filter_func(name): + if "tableau" in name: + return False + return True + copied = delocate_wheel( wheel, out_wheel, - lib_sdir=args.lib_sdir, + lib_filt_func=lib_filt_func, + copy_filt_func=copy_filter_func, + lib_sdir=opts.lib_sdir, require_archs=require_archs, - **delocate_kwargs, + executable_path=opts.executable_path, + ignore_missing=opts.ignore_missing_dependencies, ) - if args.verbose and len(copied): - print("Copied to package {0} directory:".format(args.lib_sdir)) + if opts.verbose and len(copied): + print("Copied to package {0} directory:".format(opts.lib_sdir)) copy_lines = [" " + name for name in sorted(copied)] print("\n".join(copy_lines))