mirror of
https://github.com/kennethreitz-archive/pyinstaller.git
synced 2026-06-05 23:50:17 +00:00
Fix ctypes support on Linux.
find_library() is not the correct function to resolve the full path, at least not on Linux. git-svn-id: http://svn.pyinstaller.org/trunk@632 8dd32b29-ccff-0310-8a9a-9233e24343b1
This commit is contained in:
+23
-10
@@ -1,22 +1,35 @@
|
||||
# -*- mode: python -*-
|
||||
|
||||
import sys
|
||||
if not sys.platform.startswith("darwin"):
|
||||
raise RuntimeError("please port test15 under linux2 and win32")
|
||||
|
||||
import os
|
||||
|
||||
CTYPES_DIR = "ctypes"
|
||||
TEST_LIB = os.path.join(CTYPES_DIR, "testctypes")
|
||||
if sys.platform == "linux2":
|
||||
TEST_LIB += ".so"
|
||||
elif sys.platform == "darwin2":
|
||||
TEST_LIB += ".dylib"
|
||||
elif sys.platform == "win32":
|
||||
TEST_LIB += ".dll"
|
||||
else:
|
||||
raise NotImplentedError
|
||||
|
||||
# If the required dylib does not reside in the current directory, the Analysis
|
||||
# class machinery, based on ctypes.util.find_library, will not find it. This was
|
||||
# done on purpose for this test, to show how to give Analysis class a clue.
|
||||
os.environ["DYLD_LIBRARY_PATH"] = "ctypes/"
|
||||
os.environ["DYLD_LIBRARY_PATH"] = CTYPES_DIR
|
||||
os.environ["LD_LIBRARY_PATH"] = CTYPES_DIR
|
||||
|
||||
# Check for presence of testctypes shared library, build it if not present
|
||||
if not os.path.exists("ctypes/testctypes.dylib"):
|
||||
os.chdir("ctypes")
|
||||
os.system("gcc -Wall -dynamiclib testctypes.c -o testctypes.dylib -headerpad_max_install_names")
|
||||
id_dylib = os.path.abspath("testctypes.dylib")
|
||||
os.system("install_name_tool -id %s testctypes.dylib" % (id_dylib,))
|
||||
if not os.path.exists(TEST_LIB):
|
||||
os.chdir(CTYPES_DIR)
|
||||
if sys.platform == "darwin2":
|
||||
os.system("gcc -Wall -dynamiclib testctypes.c -o testctypes.dylib -headerpad_max_install_names")
|
||||
id_dylib = os.path.abspath("testctypes.dylib")
|
||||
os.system("install_name_tool -id %s testctypes.dylib" % (id_dylib,))
|
||||
elif sys.platform == "linux2":
|
||||
os.system("gcc -fPIC -shared testctypes.c -o testctypes.so")
|
||||
else:
|
||||
raise NotImplementedError
|
||||
os.chdir("..")
|
||||
|
||||
__testname__ = 'test15'
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from ctypes import *
|
||||
|
||||
def dummy(arg):
|
||||
tct = CDLL("testctypes.dylib")
|
||||
if sys.platform == "linux2":
|
||||
tct = CDLL("testctypes.so")
|
||||
elif sys.platform == "darwin":
|
||||
tct = CDLL("testctypes.dylib")
|
||||
elif sys.platform == "win32":
|
||||
tct = CDLL("testctypes.dll")
|
||||
else:
|
||||
raise NotImplementedError
|
||||
return tct.dummy(arg)
|
||||
|
||||
@@ -539,11 +539,35 @@ class ImportTracker:
|
||||
|
||||
cbinaries = list(mod.binaries)
|
||||
mod.binaries = []
|
||||
# Executes find_library prepending ImportTracker's local paths to
|
||||
# library search paths, then replaces original values.
|
||||
|
||||
# Try to locate the shared library on disk. This is done by
|
||||
# executing ctypes.utile.find_library prepending ImportTracker's
|
||||
# local paths to library search paths, then replaces original values.
|
||||
old = _savePaths()
|
||||
for cbin in cbinaries:
|
||||
cpath = find_library(os.path.splitext(cbin)[0])
|
||||
if sys.platform == "linux2":
|
||||
# CAVEAT: find_library() is not the correct function. Ctype's
|
||||
# documentation says that it is meant to resolve only the filename
|
||||
# (as a *compiler* does) not the full path. Anyway, it works well
|
||||
# enough on Windows and Mac. On Linux, we need to implement
|
||||
# more code to find out the full path.
|
||||
if cpath is None:
|
||||
cpath = cbin
|
||||
# "man ld.so" says that we should first search LD_LIBRARY_PATH
|
||||
# and then the ldcache
|
||||
for d in os.environ["LD_LIBRARY_PATH"].split(":"):
|
||||
if os.path.isfile(d + "/" + cpath):
|
||||
cpath = d + "/" + cpath
|
||||
break
|
||||
else:
|
||||
for L in os.popen("ldconfig -p").read().splitlines():
|
||||
if cpath in L:
|
||||
cpath = L.split("=>", 1)[1].strip()
|
||||
assert os.path.isfile(cpath)
|
||||
break
|
||||
else:
|
||||
cpath = None
|
||||
if cpath is None:
|
||||
print "W: library %s required via ctypes not found" % (cbin,)
|
||||
else:
|
||||
|
||||
Reference in New Issue
Block a user