From a282f9e9a18b8299af71642779242c8a67f3a78a Mon Sep 17 00:00:00 2001 From: Michael Stone Date: Wed, 8 Aug 2018 11:33:17 -0400 Subject: [PATCH] fix ctypes.util.find_library usage Per https://docs.python.org/2/library/ctypes.html the find_library function should be called "without any prefix like lib, suffix like .so, .dylib or version number". - change _LIBRARY_NAME from "libarchive" to "archive" as required - move find_library logic after the *_LIBRARY_PATH logic to preserve current behavior. I suspect that the LD_LIBRARY_PATH logic is not actually necessary, but a side effect of this bug. I'm leaving it alone because I can't test all existing configurations to confirm that. - if find_library returns a result, use it unconditionally. Trying to confirm it is unnecessary (find_library would have returned None otherwise) and impossible without duplicating all of the linker's logic. The result will be something like "libarchive.so.13" (without a path) which will just do the right thing when used with LoadLibrary. - remove note about installing libarchive-dev, that isn't needed --- libarchive/library.py | 15 +++++++-------- libarchive/resources/README.rst | 6 ------ 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/libarchive/library.py b/libarchive/library.py index eaa8812..406ea79 100644 --- a/libarchive/library.py +++ b/libarchive/library.py @@ -6,7 +6,7 @@ _LOGGER = logging.getLogger(__name__) -_LIBRARY_NAME = 'libarchive' +_LIBRARY_NAME = 'archive' _LIBRARY_FILENAME = 'libarchive.so' def find_and_load_library(): @@ -26,13 +26,6 @@ def find_and_load_library(): filepath = os.path.join(path, _LIBRARY_FILENAME) search_filepaths.append(filepath) - # Search for our library using whatever search-path ctypes uses (not the same - # as `LD_LIBRARY_PATH`). - - filepath = ctypes.util.find_library(_LIBRARY_NAME) - if filepath is not None: - search_filepaths.append(filepath) - # Load the first one available. found_filepath = None @@ -40,6 +33,12 @@ def find_and_load_library(): if os.path.exists(filepath) is True: return filepath + # Search for our library using whatever search-path ctypes uses (not the same + # as `LD_LIBRARY_PATH`). + filepath = ctypes.util.find_library(_LIBRARY_NAME) + if filepath is not None: + return filepath + # Fallback on the naively trying to load the filename. _LOGGER.debug("Using default library file-path: [%s]", _LIBRARY_FILENAME) diff --git a/libarchive/resources/README.rst b/libarchive/resources/README.rst index ed6f9ae..1d4c515 100644 --- a/libarchive/resources/README.rst +++ b/libarchive/resources/README.rst @@ -28,12 +28,6 @@ PyPI:: Notes ----- -- The Ubuntu `libarchive` package maintainer only provides a "libarchive.so" symlink in the dev package so you'll have to install the `libarchive-dev` package. - - For example:: - - apt-get install libarchive-dev - - Encryption is not currently supported since it's not supported in the underlying library (*libarchive*). Note `this inquiry `_ and the `wishlist item `_. - OS X has a system version of `libarchive` that is very old. As a result, many users have encountered issues importing an alternate one. Specifically, often they install a different one via Brew but this will not be [sym]linked into the system like other packages. This is a precaution taken by Brew to prevent undefined behavior in the parts of OS X that depend on the factory version. In order to work around this, you should set `LD_LIBRARY_PATH` (or prepend if `LD_LIBRARY_PATH` is already defined) with the path of the location of the library version you want to use. You'll want to set this from your user-profile script (unless your environment can not support this and you need to prepend something like "LD_LIBRARY_PATH=/some/path" to the front of the command-line or set it via `os.environ` above where you import this package). A `tool `_ has been provided that will print the path of the first version of `libarchive` installed via Brew. Just copy-and-paste it. Thanks to @SkyLeach for discussing the issue and treatments.