tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: py-tables build failure on Darwin



On 12/7/24 08:46, Jason Bacon wrote:
On 11/26/24 10:48, Jason Bacon wrote:
On 11/26/24 08:38, Jonathan Perkin wrote:
* On 2024-11-26 at 14:23 GMT, Jason Bacon wrote:

Anyone interested in math/py-tables on macOS, please test the following patch:

--- ../../math/py-tables/PLIST.Darwin   1969-12-31 18:00:00.000000000 -0600
+++ ./PLIST.Darwin      2024-11-26 08:21:14.059878353 -0600
@@ -0,0 +1 @@
+${PYSITELIB}/tables/libblosc2.dylib

This is necessary on my Mac M1, but I don't have the means to test on Intel or older macOS versions.

This corroborates with the failures in the latest bulk build:

   https://us-central.manta.mnx.io/pkgsrc/public/reports/Darwin/12.3/ arm64/20241125.1313/meta/report.html

That said I'd recommend seeing if there's a better fix that is less likely to break on updates.  Is there a particular reason only macOS is shipping a shared library for this and not any other platforms?


The 1200+ line setup.py looks like a hack job.  The logic leading to libblosc being copied is here:

         if not rundir:
             loc = {
                 "posix": "the default library paths",
                 "nt": "any of the directories in %%PATH%%",
             }[os.name]

             if package.name == "blosc2":
                 # We will copy this into the tables directory
                 print(
                     "  * Copying blosc2 runtime library to 'tables' dir"
                     " because it was not found in standard locations"
                 )
                 platform_system = platform.system()
                 if platform_system == "Linux":
                     shutil.copy(libdir / "libblosc2.so", ROOT / "tables")
                     copy_libs += ["libblosc2.so"]

                     dll_dir = "/tmp/hdf5/lib"
                     # Copy dlls when producing the wheels in CI
                     if "bdist_wheel" in sys.argv and os.path.exists(dll_dir):                          shared_libs = glob.glob(str(libdir) + "/ libblosc2.so*")
                         for lib in shared_libs:
                             shutil.copy(lib, dll_dir)

                 elif platform_system == "Darwin":
                     shutil.copy(libdir / "libblosc2.dylib", ROOT / "tables")
                     copy_libs += ["libblosc2.dylib"]

So the question is why it's finding libblosc in "standard locations" on Linux, but not on macOS.


I traced the problem to this function in setup.py:

     def find_runtime_path(self, locations=None):
         """
         returns True if the runtime can be found
         returns None otherwise
         """
         # An explicit path can not be provided for runtime libraries.
         # (The argument is accepted for compatibility with previous
         # methods.)

         # dlopen() won't tell us where the file is, just whether
         # success occurred, so this returns True instead of a filename
         for prefix in self._runtime_prefixes:
             for suffix in self._runtime_suffixes:
                 print("find_runtime_path() trying ",
                       f"{prefix}{self.runtime_name}{suffix}")
                 try:
                     ctypes.CDLL(f"{prefix}{self.runtime_name}{suffix}")
                 except OSError:
                     pass
                 else:
                     return True

Called via:

     path = find_path(use_locations)

Relevant output on Darwin:

use_locations =  [PosixPath('/Users/bacon/Pkgsrc/pkg/lib'), PosixPath('/ usr/local/lib64'), PosixPath('/usr/local/lib'), PosixPath('/sw/lib64'), PosixPath('/sw/lib'), PosixPath('/opt/lib64'), PosixPath('/opt/lib'), PosixPath('/opt/local/lib64'), PosixPath('/opt/local/lib'), PosixPath('/ usr/lib64'), PosixPath('/usr/lib'), PosixPath('/lib64'), PosixPath('/lib')]
find_runtime_path() trying  libblosc2.so
find_runtime_path() trying  libblosc2.dylib
path is not set!!  This is a problem.

On NetBSD:

use_locations =  [PosixPath('/usr/lib'), PosixPath('/home/bacon/Pkgsrc/ pkg/lib'), PosixPath('/usr/local/lib64'), PosixPath('/usr/local/lib'), PosixPath('/sw/lib64'), PosixPath('/sw/lib'), PosixPath('/opt/lib64'), PosixPath('/opt/lib'), PosixPath('/opt/local/lib64'), PosixPath('/opt/ local/lib'), PosixPath('/usr/lib64'), PosixPath('/usr/lib'), PosixPath('/lib64'), PosixPath('/lib')]
find_runtime_path() trying  libblosc2.so
path =  True

So, ctypes.CDLL() is finding libblosc.so and libblosc2.so on NetBSD and Linux, but not libblsoc*.dylib on Darwin.  The correct location in this instance is /Users/bacon/Pkgsrc/pkg/lib.  The following is a workaround:

MAKE_ENV+=    DYLD_LIBRARY_PATH=${PREFIX}/lib

LD_LIBRARY_PATH is not set in the NetBSD case.

Now I'm wondering whether this is a py-tables bug, or a pkgsrc shortcoming on Darwin.  Why would ctypes.CDLL() find a .so but not a .dylib when given the same information?

BTW, there are 3 committed packages using this workaround:

# pkg-grep 'DYLD_LIBRARY.*PREFIX'
/home/bacon/Pkgsrc/pkgsrc/wip/py-tables/Makefile:MAKE_ENV+= DYLD_LIBRARY_PATH=${PREFIX}/lib /home/bacon/Pkgsrc/pkgsrc/security/p5-Crypt-OpenSSL-RSA/ Makefile:MAKE_ENV+=    DYLD_LIBRARY_PATH=${PREFIX}/lib # build on macOS /home/bacon/Pkgsrc/pkgsrc/security/p5-Crypt-OpenSSL-Random/ Makefile:MAKE_ENV+= DYLD_LIBRARY_PATH=${PREFIX}/lib # build on macOS /home/bacon/Pkgsrc/pkgsrc/security/p5-Net-SSLeay/Makefile:MAKE_ENV+=       DYLD_LIBRARY_PATH=${PREFIX}/lib # build on Mac OS X

Maybe this should be unnecessary.


Note to posterity:

The "solution" I came up with, that upstream likes, is to provide absolute pathnames to ctypes.CDLL(). find_runtime_path() was already receiving the search path in "locations", but wasn't using it, so I just nested another loop to prefix the library name with each location.

+        for location in locations:
+            for prefix in self._runtime_prefixes:
+                for suffix in self._runtime_suffixes:
+ abs_path = f"{location}/{prefix}{self.runtime_name}{suffix}


This assumes that the runtime environment will be properly configured to find the libraries after install, but so does every other fix we could conceive.

--
Life is a game.  Play hard.  Play fair.  Have fun.


Home | Main Index | Thread Index | Old Index