-
-
Notifications
You must be signed in to change notification settings - Fork 274
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
When the ABI doesn't match the package version... #610
Comments
Interesting problem. Gfortran has this problem, too. If conda build needs some new functionality, we can do that. |
The simplest version in my mind would be to have the ABI version (just int for major version? Or full version string?) as additional metadata in the package and automatically add it to run_exports, if defined. I'm not quite sure how to define such a field or how the conda solver could take it into account. libtool has a unique three-field versioning system:
These numbers have some unusual if logical definitions, but the semver way to write a given libtool version would generally be This all assumes that conda package managers know that they have to record the ABI version in meta.yaml and actually do it (I wouldn't have for libsodium until the above zeromq issue, and I'll probably forget to update). What would be double-awesome if is conda-build could automatically detect the ABI version (e.g. by the package stating that it installs "libsodium.dylib" and conda-build looks at the installed files and sees that So if I had to only add to my meta.yaml: build:
abi_library: "libsodium"
# or ${PREFIX}/lib/libsodium${SHLIB_EXT} if meta.yaml should specify the full path and conda-build produced an appropriate abi-pinning metadata and run_exports, that would be awesome. Here's a sketch of the abi-detection-by-symlink: import os
import re
import sys
macos_abi_pat = re.compile("lib[^\.]+\.([\d\.]+)\.dylib$", re.IGNORECASE)
linux_abi_pat = re.compile("lib[^\.]+\.so\.([\d\.]+)$", re.IGNORECASE)
abi_pat = macos_abi_pat if sys.platform == 'darwin' else linux_abi_pat
SHLIB_EXT = '.dylib' if sys.platform == 'darwin' else '.so'
def detect_abi_version(libname):
"""Return the ABI version of a library
given 'libzmq' return '5' as its ABI version
because $PREFIX/lib/libzmq.dylib is a symlink to libzmq.5.dylib
or $PREFIX/lib/libzmq.so is a symlink to libzmq.so.5
"""
lib = os.path.join(sys.prefix, 'lib', libname + SHLIB_EXT)
if not os.path.exists(lib):
raise OSError("%s does not exist" % lib)
if not os.path.islink(lib):
print("%s is not a symlink, no ABI info found" % lib)
# libfoo.dylib is not a symlink, no ABI version to find
return
target = os.readlink(lib)
target_libname = os.path.basename(target)
match = abi_pat.match(target_libname)
if not match:
print("No ABI found in %s" % target_libname)
return
return match.group(1) |
This can get a bit tricky. For instance, see this comment about OpenBLAS. That said, it would be nice to have some automated detection like what you have described here. |
Rather than symlinks, one could check the actual SONAME. Something like this: https://gist.github.com/lebedov/5111696 |
I drafted a CFEP to propose putting the ABI major version in the build string. I'd appreciate thoughts on the proposal or any further ideas on this topic. |
While investigating conda-forge/zeromq-feedstock#36 I learned that the libsodium package version (e.g. 1.0.16) doesn't reflect the ABI version (24 in 1.-.15-16, 23 in 13, 18 in 1.0.8, etc.). In the meantime, I'm pinning run_exports with max_pin=x.x.x since I can't know the next patch version won't bump the ABI version, even though it probably won't.
So the question has been raised: how to pin abi compatibility in run_exports, when the version number of the package isn't enough.
A few options have been proposed on gitter:
The text was updated successfully, but these errors were encountered: