From 069c83192a299afb87ae3fed0664cfc7a8b705d6 Mon Sep 17 00:00:00 2001
From: Jonathan Helmus <jjhelmus@gmail.com>
Date: Wed, 17 Jul 2019 10:47:03 -0500
Subject: [PATCH] prefer to load libarchive from conda pkg path

Preferentially load libarchive from the platform depend path used in
the libarchive conda packages. The LIBARCHIVE environment variable can
be used to override this check by providing an alternative location.

This also implements some exception handling that should be better than
the str/unicode nonetype message that people see right now.
---
 libarchive/ffi.py | 37 +++++++++++++++++++++++++++++++++++--
 1 file changed, 35 insertions(+), 2 deletions(-)

diff --git a/libarchive/ffi.py b/libarchive/ffi.py
index 698d6ba..b0ec362 100644
--- a/libarchive/ffi.py
+++ b/libarchive/ffi.py
@@ -15,6 +15,7 @@ from ctypes.util import find_library
 import logging
 import mmap
 import os
+import sys
 
 from .exception import ArchiveError
 
@@ -23,8 +24,40 @@ logger = logging.getLogger('libarchive')
 
 page_size = mmap.PAGESIZE
 
-libarchive_path = os.environ.get('LIBARCHIVE') or find_library('archive')
-libarchive = ctypes.cdll.LoadLibrary(libarchive_path)
+# libarchive path order:
+# * path specified by the LIBARCHIVE environment variable
+# * platform dependent location used in conda packages
+# * location determined by find_library
+libarchive_path = os.environ.get('LIBARCHIVE')
+backup_path = os.environ.get('PATH')
+if libarchive_path is None:
+    if sys.platform == 'win32':
+        library_bin = os.path.join(sys.prefix, 'Library', 'bin')
+        test_path = os.path.join(library_bin, 'archive.dll')
+        if backup_path:
+            os.environ['PATH'] = "%s;%s" % (library_bin, backup_path)
+    elif sys.platform == 'darwin':
+        test_path = os.path.join(sys.prefix, 'lib', 'libarchive.dylib')
+    elif sys.platform.startswith('linux'):
+        test_path = os.path.join(sys.prefix, 'lib', 'libarchive.so')
+    else:
+        test_path = find_library('archive')
+    try:
+        ctypes.cdll.LoadLibrary(test_path)
+        libarchive_path = test_path
+    except:
+        libarchive_path = None
+if libarchive_path is None:
+    libarchive_path = find_library('archive')
+if not libarchive_path:
+    raise ImportError("Failed to find libarchive library")
+try:
+    libarchive = ctypes.cdll.LoadLibrary(libarchive_path)
+except:
+    raise ImportError("Failed to load libarchive library from %s - are any dependencies missing?"
+                      "Is your environment activated?")
+if backup_path:
+    os.environ['PATH'] = backup_path
 
 
 # Constants
-- 
2.20.1

