delocate


Namedelocate JSON
Version 0.12.0 PyPI version JSON
download
home_pageNone
SummaryMove macOS dynamic libraries into package
upload_time2024-08-29 20:11:24
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseCopyright (c) 2014-2024, Matthew Brett and the Delocate contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            .. image:: https://img.shields.io/pypi/v/delocate
    :target: https://pypi.org/project/delocate/
.. image:: https://codecov.io/gh/matthew-brett/delocate/branch/master/graph/badge.svg?token=wvAWRBK5Di
    :target: https://codecov.io/gh/matthew-brett/delocate

########
Delocate
########

macOS utilities to:

* find dynamic libraries imported from python extensions
* copy needed dynamic libraries to directory within package
* update macOS ``install_names`` and ``rpath`` to cause code to load from copies
  of libraries

Provides scripts:

* ``delocate-listdeps`` -- show libraries a tree depends on
* ``delocate-path`` -- copy libraries a tree depends on into the tree and relink
* ``delocate-wheel`` -- rewrite wheel having copied and relinked library
  dependencies into the wheel tree.
* ``delocate-merge`` -- combine two wheels with different architectures into one
  wheel with dual architecture binaries.

`Auditwheel <https://github.com/pypa/auditwheel>`_ is a similar tool for Linux.
Auditwheel started life as a partial fork of Delocate.

***********
The problem
***********

Let's say you have built a wheel somewhere, but it's linking to dynamic
libraries elsewhere on the machine, so you can't distribute it, because others
may not have these same libraries.  Here we analyze the dependencies for
a Scipy wheel::

    $ delocate-listdeps scipy-0.14.0b1-cp34-cp34m-macosx_10_6_intel.whl
    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgcc_s.1.dylib
    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib
    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libquadmath.0.dylib

By default, this does not include libraries in ``/usr/lib`` and ``/System``.
See those too with::

    $ delocate-listdeps --all scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl
    /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate
    /usr/lib/libSystem.B.dylib
    /usr/lib/libstdc++.6.dylib
    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgcc_s.1.dylib
    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib
    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libquadmath.0.dylib

The output tells me that Scipy has picked up dynamic libraries from my
Homebrew installation of ``gfortran`` (as well as the system libs).

You can get a listing of the files depending on each of the libraries,
using the ``--depending`` flag::

    $ delocate-listdeps --depending scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl
    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgcc_s.1.dylib:
        scipy/interpolate/dfitpack.so
        scipy/special/specfun.so
        scipy/interpolate/_fitpack.so
        ...

**********
A solution
**********

We can fix like this::

    $ delocate-wheel -w fixed_wheels -v scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl
    Fixing: scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl
    Copied to package .dylibs directory:
        /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgcc_s.1.dylib
        /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib
        /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libquadmath.0.dylib

The ``-w`` flag tells `delocate-wheel` to output to a new wheel directory
instead of overwriting the old wheel.  ``-v`` (verbose) tells you what
`delocate-wheel` is doing.  In this case it has made a new directory in the
wheel zipfile, named ``scipy/.dylibs``. It has copied all the library
dependencies that are outside the macOS system trees into this directory, and
patched the python ``.so`` extensions in the wheel to use these copies instead
of looking in ``/usr/local/Cellar/gfortran/4.8.2/gfortran/lib``.

Check the links again to confirm::

    $ delocate-listdeps --all fixed_wheels/scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl
    /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate
    /usr/lib/libSystem.B.dylib
    /usr/lib/libstdc++.6.0.9.dylib
    @loader_path/../../../../.dylibs/libgcc_s.1.dylib
    @loader_path/../../../../.dylibs/libgfortran.3.dylib
    @loader_path/../../../../.dylibs/libquadmath.0.dylib
    @loader_path/../../../.dylibs/libgcc_s.1.dylib
    @loader_path/../../../.dylibs/libgfortran.3.dylib
    @loader_path/../../../.dylibs/libquadmath.0.dylib
    @loader_path/../../.dylibs/libgcc_s.1.dylib
    @loader_path/../../.dylibs/libgfortran.3.dylib
    @loader_path/../../.dylibs/libquadmath.0.dylib
    @loader_path/../.dylibs/libgcc_s.1.dylib
    @loader_path/../.dylibs/libgfortran.3.dylib
    @loader_path/../.dylibs/libquadmath.0.dylib
    @loader_path/libgcc_s.1.dylib
    @loader_path/libquadmath.0.dylib

So - system dylibs the same, but the others moved into the wheel tree.

This makes the wheel more likely to work on another machine which does not have
the same version of Gfortran installed - in this example.

Checking required architectures
===============================

Current Python.org Python and the macOS system Python (``/usr/bin/python``)
are both dual architecture binaries.  For example::

    $ lipo -info /usr/bin/python
    Architectures in the fat file: /usr/bin/python are: x86_64 arm64e

**Note**: you can compile ARM binaries for basic ARM (``arm64``), or to use
some extended ARM capabilities (``arm64e``) - see `this SO post
<https://stackoverflow.com/questions/52624308/xcode-arm64-vs-arm64e>`_.  Both
types of binaries work on Mac M1 and M2 machines, so we will use ``arm64`` to
refer to either ``arm64`` or ``arm64e``.

The Big Sur macOS Python above has both ``x86_64`` and ``arm64`` (M1) versions
fused into one file.  Earlier versions of macOS had dual architectures that
were 32-bit (``i386``) and 64-bit (``x86_64``).

For full compatibility with system and Python.org Python, wheels built for
Python.org Python or system Python should have the corresponding architectures
— e.g. ``x86_64`` and ``arm64`` versions of the Python extensions and their
libraries.  It is easy to link Python extensions against single architecture
libraries by mistake, and therefore get single architecture extensions and /
or libraries. In fact my Scipy wheel is one such example, because I
inadvertently linked against the Homebrew libraries, which were ``x86_64``
only. To check this you can use the ``--require-archs`` flag::

    $ delocate-wheel --require-archs=intel scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl
    Traceback (most recent call last):
    File "/Users/mb312/.virtualenvs/delocate/bin/delocate-wheel", line 77, in <module>
        main()
    File "/Users/mb312/.virtualenvs/delocate/bin/delocate-wheel", line 69, in main
        check_verbose=opts.verbose)
    File "/Users/mb312/.virtualenvs/delocate/lib/python2.7/site-packages/delocate/delocating.py", line 477, in delocate_wheel
        "Some missing architectures in wheel")
    delocate.delocating.DelocationError: Some missing architectures in wheel

Notice that this command was using an earlier version of Delocate that
supported Python 2; we now support Python 3 only.

The ``intel`` argument to ``--require-archs`` above requires dual 32- and 64-
bit architecture extensions and libraries. You can see which extensions are at
fault by adding the ``-v`` (verbose) flag::

    $ delocate-wheel -w fixed_wheels --require-archs=intel -v scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl
    Fixing: scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl
    Required arch i386 missing from /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib
    Required arch i386 missing from /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libquadmath.0.dylib
    Required arch i386 missing from scipy/fftpack/_fftpack.so
    Required arch i386 missing from scipy/fftpack/convolve.so
    Required arch i386 missing from scipy/integrate/_dop.so
    ...

I need to rebuild this wheel to link with dual-architecture libraries.

Making dual-architecture binaries
=================================

Modern Mac wheels can be either ``arm64`` (M1/M2 ARM), ``x86_64`` (64-bit
Intel) or both (``universal2``).

Building an entire Python wheel as dual-architecture can be difficult, perhaps
because you need to link different libraries in the two cases, or you need
different compiler flags, or because you build for ``arm64`` on one continuous
integration platform (such as - at time of writing - Cirrus CI), and ``x86_64``
on another.

One solution to this problem is to do an entire ``arm64`` wheel build, and then
an entire ``x86_64`` wheel build, and *fuse* the two wheels into a universal
wheel.

That is what the ``delocate-merge`` command does.

Let's say you have built an ARM and Intel wheel, called, respectively:

* ``scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl``
* ``scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl``

Then you could create a new fused (``universal2``) wheel in the ``tmp``
subdirectory with::

    delocate-merge scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl -w tmp

The output wheel in that case would be:

* ``tmp/scipy-1.9.3-cp311-cp311-macosx_12_0_universal2.whl``

In the new wheel, you will find, using ``lipo -archs`` - that all binaries with
the same name in each wheel are now universal (``x86_64`` and ``arm64``).

    `:warning:` **Note:** In previous versions (``<0.12.0``) making dual architecture binaries was
    performed with the ``delocate-fuse`` command. This commannd would overwrite the
    first wheel passed in by default. This led to the user needing to rename the
    wheel to correctly describe what platforms it supported. For this and other
    reasons, wheels created with this were often incorrect. From version ``0.12.0``
    and on, the ``delocate-fuse`` command has been removed and replaced with
    ``delocate-merge``. The ``delocate-merge`` command will create a new wheel with an
    automatically generated name based on the wheels that were merged together.
    There is no need to perform any further changes to the merged wheel's name. If
    the old behavior is needed (not recommended), pin the version to
    ``delocate==0.11.0``.

Troubleshooting
===============

DelocationError: "library does not exist"
-----------------------------------------

When running ``delocate-wheel`` or its sister command ``delocate-path``, you
may get errors like this::

    delocate.delocating.DelocationError: library "<long temporary path>/wheel/libme.dylib" does not exist

This happens when one of your libraries gives a library dependency with a
relative path.  For example, let's say that some file in my wheel has this for
the output of ``otool -L myext.so``::

    myext.so:
        libme.dylib (compatibility version 10.0.0, current version 10.0.0)
        /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 60.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

The first line means that ``myext.so`` expects to find ``libme.dylib`` at
exactly the path ``./libme.dylib`` - the current working directory from which
you ran the executable.  The output *should* be something like::

    myext.so:
        /path/to/libme.dylib (compatibility version 10.0.0, current version 10.0.0)
        /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 60.0.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

To set the path to the library, the linker is using the `install name id`_ of
the linked library.  In this bad case, then ``otool -L libme.dylib`` will give
something like::

    libme.dylib (compatibility version 10.0.0, current version 10.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)

where the first line is the `install name id`_ that the linker picked up when
linking ``myext.so`` to ``libme.dylib``.  Your job is to fix the build process
so that ``libme.dylib`` has install name id ``/path/to/libme.dylib``.
This is not a problem specific to Delocate; you will need to do this to
make sure that ``myext.so`` can load ``libme.dylib`` without ``libme.dylib``
being in the current working directory.  For ``CMAKE`` builds you may want to
check out CMAKE_INSTALL_NAME_DIR_.

****
Code
****

See https://github.com/matthew-brett/delocate

Released under the BSD two-clause license - see the file ``LICENSE`` in the
source distribution.

`GitHub Actions <https://github.com/matthew-brett/delocate/actions>`_
kindly tests the code automatically.

The latest released version is at https://pypi.python.org/pypi/delocate

*******
Support
*******

Please put up issues on the `Delocate issue tracker
<https://github.com/matthew-brett/delocate/issues>`_.

.. _install name id:
   http://matthew-brett.github.io/docosx/mac_runtime_link.html#the-install-name
.. _CMAKE_INSTALL_NAME_DIR:
   http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_NAME_DIR.html

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "delocate",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": "Matthew Brett <matthew.brett@gmail.com>",
    "keywords": null,
    "author": null,
    "author_email": "Matthew Brett <matthew.brett@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/d3/c1/9ce172375070c59f3a40973fa4daf98d80a874cddc9ddaed494656dd9259/delocate-0.12.0.tar.gz",
    "platform": null,
    "description": ".. image:: https://img.shields.io/pypi/v/delocate\n    :target: https://pypi.org/project/delocate/\n.. image:: https://codecov.io/gh/matthew-brett/delocate/branch/master/graph/badge.svg?token=wvAWRBK5Di\n    :target: https://codecov.io/gh/matthew-brett/delocate\n\n########\nDelocate\n########\n\nmacOS utilities to:\n\n* find dynamic libraries imported from python extensions\n* copy needed dynamic libraries to directory within package\n* update macOS ``install_names`` and ``rpath`` to cause code to load from copies\n  of libraries\n\nProvides scripts:\n\n* ``delocate-listdeps`` -- show libraries a tree depends on\n* ``delocate-path`` -- copy libraries a tree depends on into the tree and relink\n* ``delocate-wheel`` -- rewrite wheel having copied and relinked library\n  dependencies into the wheel tree.\n* ``delocate-merge`` -- combine two wheels with different architectures into one\n  wheel with dual architecture binaries.\n\n`Auditwheel <https://github.com/pypa/auditwheel>`_ is a similar tool for Linux.\nAuditwheel started life as a partial fork of Delocate.\n\n***********\nThe problem\n***********\n\nLet's say you have built a wheel somewhere, but it's linking to dynamic\nlibraries elsewhere on the machine, so you can't distribute it, because others\nmay not have these same libraries.  Here we analyze the dependencies for\na Scipy wheel::\n\n    $ delocate-listdeps scipy-0.14.0b1-cp34-cp34m-macosx_10_6_intel.whl\n    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgcc_s.1.dylib\n    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib\n    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libquadmath.0.dylib\n\nBy default, this does not include libraries in ``/usr/lib`` and ``/System``.\nSee those too with::\n\n    $ delocate-listdeps --all scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl\n    /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate\n    /usr/lib/libSystem.B.dylib\n    /usr/lib/libstdc++.6.dylib\n    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgcc_s.1.dylib\n    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib\n    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libquadmath.0.dylib\n\nThe output tells me that Scipy has picked up dynamic libraries from my\nHomebrew installation of ``gfortran`` (as well as the system libs).\n\nYou can get a listing of the files depending on each of the libraries,\nusing the ``--depending`` flag::\n\n    $ delocate-listdeps --depending scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl\n    /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgcc_s.1.dylib:\n        scipy/interpolate/dfitpack.so\n        scipy/special/specfun.so\n        scipy/interpolate/_fitpack.so\n        ...\n\n**********\nA solution\n**********\n\nWe can fix like this::\n\n    $ delocate-wheel -w fixed_wheels -v scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl\n    Fixing: scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl\n    Copied to package .dylibs directory:\n        /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgcc_s.1.dylib\n        /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib\n        /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libquadmath.0.dylib\n\nThe ``-w`` flag tells `delocate-wheel` to output to a new wheel directory\ninstead of overwriting the old wheel.  ``-v`` (verbose) tells you what\n`delocate-wheel` is doing.  In this case it has made a new directory in the\nwheel zipfile, named ``scipy/.dylibs``. It has copied all the library\ndependencies that are outside the macOS system trees into this directory, and\npatched the python ``.so`` extensions in the wheel to use these copies instead\nof looking in ``/usr/local/Cellar/gfortran/4.8.2/gfortran/lib``.\n\nCheck the links again to confirm::\n\n    $ delocate-listdeps --all fixed_wheels/scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl\n    /System/Library/Frameworks/Accelerate.framework/Versions/A/Accelerate\n    /usr/lib/libSystem.B.dylib\n    /usr/lib/libstdc++.6.0.9.dylib\n    @loader_path/../../../../.dylibs/libgcc_s.1.dylib\n    @loader_path/../../../../.dylibs/libgfortran.3.dylib\n    @loader_path/../../../../.dylibs/libquadmath.0.dylib\n    @loader_path/../../../.dylibs/libgcc_s.1.dylib\n    @loader_path/../../../.dylibs/libgfortran.3.dylib\n    @loader_path/../../../.dylibs/libquadmath.0.dylib\n    @loader_path/../../.dylibs/libgcc_s.1.dylib\n    @loader_path/../../.dylibs/libgfortran.3.dylib\n    @loader_path/../../.dylibs/libquadmath.0.dylib\n    @loader_path/../.dylibs/libgcc_s.1.dylib\n    @loader_path/../.dylibs/libgfortran.3.dylib\n    @loader_path/../.dylibs/libquadmath.0.dylib\n    @loader_path/libgcc_s.1.dylib\n    @loader_path/libquadmath.0.dylib\n\nSo - system dylibs the same, but the others moved into the wheel tree.\n\nThis makes the wheel more likely to work on another machine which does not have\nthe same version of Gfortran installed - in this example.\n\nChecking required architectures\n===============================\n\nCurrent Python.org Python and the macOS system Python (``/usr/bin/python``)\nare both dual architecture binaries.  For example::\n\n    $ lipo -info /usr/bin/python\n    Architectures in the fat file: /usr/bin/python are: x86_64 arm64e\n\n**Note**: you can compile ARM binaries for basic ARM (``arm64``), or to use\nsome extended ARM capabilities (``arm64e``) - see `this SO post\n<https://stackoverflow.com/questions/52624308/xcode-arm64-vs-arm64e>`_.  Both\ntypes of binaries work on Mac M1 and M2 machines, so we will use ``arm64`` to\nrefer to either ``arm64`` or ``arm64e``.\n\nThe Big Sur macOS Python above has both ``x86_64`` and ``arm64`` (M1) versions\nfused into one file.  Earlier versions of macOS had dual architectures that\nwere 32-bit (``i386``) and 64-bit (``x86_64``).\n\nFor full compatibility with system and Python.org Python, wheels built for\nPython.org Python or system Python should have the corresponding architectures\n\u2014 e.g. ``x86_64`` and ``arm64`` versions of the Python extensions and their\nlibraries.  It is easy to link Python extensions against single architecture\nlibraries by mistake, and therefore get single architecture extensions and /\nor libraries. In fact my Scipy wheel is one such example, because I\ninadvertently linked against the Homebrew libraries, which were ``x86_64``\nonly. To check this you can use the ``--require-archs`` flag::\n\n    $ delocate-wheel --require-archs=intel scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl\n    Traceback (most recent call last):\n    File \"/Users/mb312/.virtualenvs/delocate/bin/delocate-wheel\", line 77, in <module>\n        main()\n    File \"/Users/mb312/.virtualenvs/delocate/bin/delocate-wheel\", line 69, in main\n        check_verbose=opts.verbose)\n    File \"/Users/mb312/.virtualenvs/delocate/lib/python2.7/site-packages/delocate/delocating.py\", line 477, in delocate_wheel\n        \"Some missing architectures in wheel\")\n    delocate.delocating.DelocationError: Some missing architectures in wheel\n\nNotice that this command was using an earlier version of Delocate that\nsupported Python 2; we now support Python 3 only.\n\nThe ``intel`` argument to ``--require-archs`` above requires dual 32- and 64-\nbit architecture extensions and libraries. You can see which extensions are at\nfault by adding the ``-v`` (verbose) flag::\n\n    $ delocate-wheel -w fixed_wheels --require-archs=intel -v scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl\n    Fixing: scipy-0.14.0-cp34-cp34m-macosx_10_6_intel.whl\n    Required arch i386 missing from /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libgfortran.3.dylib\n    Required arch i386 missing from /usr/local/Cellar/gfortran/4.8.2/gfortran/lib/libquadmath.0.dylib\n    Required arch i386 missing from scipy/fftpack/_fftpack.so\n    Required arch i386 missing from scipy/fftpack/convolve.so\n    Required arch i386 missing from scipy/integrate/_dop.so\n    ...\n\nI need to rebuild this wheel to link with dual-architecture libraries.\n\nMaking dual-architecture binaries\n=================================\n\nModern Mac wheels can be either ``arm64`` (M1/M2 ARM), ``x86_64`` (64-bit\nIntel) or both (``universal2``).\n\nBuilding an entire Python wheel as dual-architecture can be difficult, perhaps\nbecause you need to link different libraries in the two cases, or you need\ndifferent compiler flags, or because you build for ``arm64`` on one continuous\nintegration platform (such as - at time of writing - Cirrus CI), and ``x86_64``\non another.\n\nOne solution to this problem is to do an entire ``arm64`` wheel build, and then\nan entire ``x86_64`` wheel build, and *fuse* the two wheels into a universal\nwheel.\n\nThat is what the ``delocate-merge`` command does.\n\nLet's say you have built an ARM and Intel wheel, called, respectively:\n\n* ``scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl``\n* ``scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl``\n\nThen you could create a new fused (``universal2``) wheel in the ``tmp``\nsubdirectory with::\n\n    delocate-merge scipy-1.9.3-cp311-cp311-macosx_12_0_arm64.whl scipy-1.9.3-cp311-cp311-macosx_10_9_x86_64.whl -w tmp\n\nThe output wheel in that case would be:\n\n* ``tmp/scipy-1.9.3-cp311-cp311-macosx_12_0_universal2.whl``\n\nIn the new wheel, you will find, using ``lipo -archs`` - that all binaries with\nthe same name in each wheel are now universal (``x86_64`` and ``arm64``).\n\n    `:warning:` **Note:** In previous versions (``<0.12.0``) making dual architecture binaries was\n    performed with the ``delocate-fuse`` command. This commannd would overwrite the\n    first wheel passed in by default. This led to the user needing to rename the\n    wheel to correctly describe what platforms it supported. For this and other\n    reasons, wheels created with this were often incorrect. From version ``0.12.0``\n    and on, the ``delocate-fuse`` command has been removed and replaced with\n    ``delocate-merge``. The ``delocate-merge`` command will create a new wheel with an\n    automatically generated name based on the wheels that were merged together.\n    There is no need to perform any further changes to the merged wheel's name. If\n    the old behavior is needed (not recommended), pin the version to\n    ``delocate==0.11.0``.\n\nTroubleshooting\n===============\n\nDelocationError: \"library does not exist\"\n-----------------------------------------\n\nWhen running ``delocate-wheel`` or its sister command ``delocate-path``, you\nmay get errors like this::\n\n    delocate.delocating.DelocationError: library \"<long temporary path>/wheel/libme.dylib\" does not exist\n\nThis happens when one of your libraries gives a library dependency with a\nrelative path.  For example, let's say that some file in my wheel has this for\nthe output of ``otool -L myext.so``::\n\n    myext.so:\n        libme.dylib (compatibility version 10.0.0, current version 10.0.0)\n        /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 60.0.0)\n        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)\n\nThe first line means that ``myext.so`` expects to find ``libme.dylib`` at\nexactly the path ``./libme.dylib`` - the current working directory from which\nyou ran the executable.  The output *should* be something like::\n\n    myext.so:\n        /path/to/libme.dylib (compatibility version 10.0.0, current version 10.0.0)\n        /usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 60.0.0)\n        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)\n\nTo set the path to the library, the linker is using the `install name id`_ of\nthe linked library.  In this bad case, then ``otool -L libme.dylib`` will give\nsomething like::\n\n    libme.dylib (compatibility version 10.0.0, current version 10.0.0)\n    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)\n\nwhere the first line is the `install name id`_ that the linker picked up when\nlinking ``myext.so`` to ``libme.dylib``.  Your job is to fix the build process\nso that ``libme.dylib`` has install name id ``/path/to/libme.dylib``.\nThis is not a problem specific to Delocate; you will need to do this to\nmake sure that ``myext.so`` can load ``libme.dylib`` without ``libme.dylib``\nbeing in the current working directory.  For ``CMAKE`` builds you may want to\ncheck out CMAKE_INSTALL_NAME_DIR_.\n\n****\nCode\n****\n\nSee https://github.com/matthew-brett/delocate\n\nReleased under the BSD two-clause license - see the file ``LICENSE`` in the\nsource distribution.\n\n`GitHub Actions <https://github.com/matthew-brett/delocate/actions>`_\nkindly tests the code automatically.\n\nThe latest released version is at https://pypi.python.org/pypi/delocate\n\n*******\nSupport\n*******\n\nPlease put up issues on the `Delocate issue tracker\n<https://github.com/matthew-brett/delocate/issues>`_.\n\n.. _install name id:\n   http://matthew-brett.github.io/docosx/mac_runtime_link.html#the-install-name\n.. _CMAKE_INSTALL_NAME_DIR:\n   http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_INSTALL_NAME_DIR.html\n",
    "bugtrack_url": null,
    "license": "Copyright (c) 2014-2024, Matthew Brett and the Delocate contributors. All rights reserved.  Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ",
    "summary": "Move macOS dynamic libraries into package",
    "version": "0.12.0",
    "project_urls": {
        "Homepage": "http://github.com/matthew-brett/delocate"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bf4aaa78a0333ce108aa722a6b8f449dfae55b12ed180e98721a90e571896dbd",
                "md5": "6a220a2ae85dd7c205b7aec7c5b84169",
                "sha256": "0da599c7561dcca2835149eaa4733e85408d71f249c6c4c43c3cb16cedb43a09"
            },
            "downloads": -1,
            "filename": "delocate-0.12.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6a220a2ae85dd7c205b7aec7c5b84169",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 236096,
            "upload_time": "2024-08-29T20:11:23",
            "upload_time_iso_8601": "2024-08-29T20:11:23.257432Z",
            "url": "https://files.pythonhosted.org/packages/bf/4a/aa78a0333ce108aa722a6b8f449dfae55b12ed180e98721a90e571896dbd/delocate-0.12.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d3c19ce172375070c59f3a40973fa4daf98d80a874cddc9ddaed494656dd9259",
                "md5": "d035fbbbfe47c8f192e773ee686da8fe",
                "sha256": "e051660836a87b61c99b9b180344be363c31e1f2d9fdc94caebc854b6611335c"
            },
            "downloads": -1,
            "filename": "delocate-0.12.0.tar.gz",
            "has_sig": false,
            "md5_digest": "d035fbbbfe47c8f192e773ee686da8fe",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 238813,
            "upload_time": "2024-08-29T20:11:24",
            "upload_time_iso_8601": "2024-08-29T20:11:24.490801Z",
            "url": "https://files.pythonhosted.org/packages/d3/c1/9ce172375070c59f3a40973fa4daf98d80a874cddc9ddaed494656dd9259/delocate-0.12.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-29 20:11:24",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "matthew-brett",
    "github_project": "delocate",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "delocate"
}
        
Elapsed time: 0.55059s