mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2026-01-07 04:20:07 +01:00
Set install names using @loader_path in the extension modules and the wx libs so they can be loaded from the same folder and they can be included in the wx package dir.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxPython/Phoenix/trunk@71226 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -53,4 +53,5 @@
|
||||
/wx/*.pi
|
||||
/wx/*.so
|
||||
/wx/*.pyd
|
||||
/wx/*.dylib
|
||||
/wx/locale
|
||||
|
||||
54
build.py
54
build.py
@@ -20,7 +20,8 @@ import urllib2
|
||||
|
||||
from distutils.dep_util import newer, newer_group
|
||||
from buildtools.config import Config, msg, opj, posixjoin, loadETG, etg2sip, findCmd, \
|
||||
phoenixDir, wxDir, copyIfNewer
|
||||
phoenixDir, wxDir, copyIfNewer, copyFile, \
|
||||
macFixDependencyInstallName, macSetLoaderNames
|
||||
|
||||
import buildtools.version as version
|
||||
|
||||
@@ -360,21 +361,6 @@ def delFiles(fileList, verbose=True):
|
||||
os.remove(afile)
|
||||
|
||||
|
||||
def macFixDependencyInstallName(destdir, prefix, extension, buildDir):
|
||||
print("**** macFixDependencyInstallName(%s, %s, %s, %s)" % (destdir, prefix, extension, buildDir))
|
||||
pwd = os.getcwd()
|
||||
os.chdir(destdir+prefix+'/lib')
|
||||
dylibs = glob.glob('*.dylib')
|
||||
for lib in dylibs:
|
||||
#cmd = 'install_name_tool -change %s/lib/%s %s/lib/%s %s' % \
|
||||
# (destdir+prefix,lib, prefix,lib, extension)
|
||||
cmd = 'install_name_tool -change %s/lib/%s %s/lib/%s %s' % \
|
||||
(buildDir,lib, prefix,lib, extension)
|
||||
print(cmd)
|
||||
os.system(cmd)
|
||||
os.chdir(pwd)
|
||||
|
||||
|
||||
|
||||
def getSipCmd():
|
||||
# Returns the sip command to use, checking for an explicit version and
|
||||
@@ -863,15 +849,27 @@ def copyWxDlls(options):
|
||||
dlls += glob.glob(os.path.join(msw.dllDir, "wx*%sud_*.pdb" % ver))
|
||||
|
||||
for dll in dlls:
|
||||
shutil.copyfile(dll, posixjoin(phoenixDir(), cfg.PKGDIR, os.path.basename(dll)))
|
||||
copyIfNewer(dll, posixjoin(phoenixDir(), cfg.PKGDIR, os.path.basename(dll)), verbose=True)
|
||||
|
||||
elif isDarwin:
|
||||
# Copy the wxWidgets dylibs
|
||||
cfg = Config()
|
||||
wxlibdir = os.path.join(getBuildDir(options), "lib")
|
||||
dlls = glob.glob(wxlibdir + '/*.dylib')
|
||||
for dll in dlls:
|
||||
copyIfNewer(dll, posixjoin(phoenixDir(), cfg.PKGDIR, os.path.basename(dll)), verbose=True)
|
||||
|
||||
# Now use install_name_tool to change the extension modules to look
|
||||
# in the same folder for the wx libs, instead of the build dir. Also
|
||||
# change the wx libs the same way.
|
||||
macSetLoaderNames(glob.glob(opj(phoenixDir(), cfg.PKGDIR, '*.so')) +
|
||||
glob.glob(opj(phoenixDir(), cfg.PKGDIR, '*.dylib')))
|
||||
|
||||
|
||||
|
||||
def setup_py(options, args):
|
||||
cmdTimer = CommandTimer('setup_py')
|
||||
|
||||
copyWxDlls(options)
|
||||
|
||||
BUILD_DIR = getBuildDir(options)
|
||||
DESTDIR = options.installdir
|
||||
PREFIX = options.prefix
|
||||
@@ -922,6 +920,8 @@ def setup_py(options, args):
|
||||
(build_mode, " ".join(build_options), options.extra_setup)
|
||||
runcmd(command)
|
||||
|
||||
copyWxDlls(options)
|
||||
|
||||
# Do an install?
|
||||
if options.install:
|
||||
# only add the --prefix flag if we have an explicit request to do
|
||||
@@ -937,6 +937,8 @@ def setup_py(options, args):
|
||||
(WXPY_PREFIX, " ".join(build_options), options.extra_setup)
|
||||
runcmd(command)
|
||||
|
||||
# NOTE: Can probably get rid of this if we keep the code that is
|
||||
# setting @loader_path in the install names...
|
||||
if isDarwin and DESTDIR:
|
||||
# Now that we are finished with the build fix the ids and
|
||||
# names in the wx .dylibs
|
||||
@@ -962,8 +964,6 @@ def waf_py(options, args):
|
||||
cmdTimer = CommandTimer('waf_py')
|
||||
waf = getWafCmd()
|
||||
|
||||
copyWxDlls(options)
|
||||
|
||||
BUILD_DIR = getBuildDir(options)
|
||||
DESTDIR = options.installdir
|
||||
PREFIX = options.prefix
|
||||
@@ -990,6 +990,13 @@ def waf_py(options, args):
|
||||
cmd = '%s %s %s configure build %s' % (PYTHON, waf, ' '.join(build_options), options.extra_waf)
|
||||
runcmd(cmd)
|
||||
|
||||
copyWxDlls(options)
|
||||
|
||||
# Do an install?
|
||||
if options.install:
|
||||
pass # TODO...
|
||||
|
||||
|
||||
print("\n------------ BUILD FINISHED ------------")
|
||||
print("To run the wxPython demo:")
|
||||
print(" - Set your PYTHONPATH variable to %s." % phoenixDir())
|
||||
@@ -1037,7 +1044,7 @@ def clean_py(options, args):
|
||||
deleteIfExists(build_base)
|
||||
deleteIfExists('build_waf') # make this smarter later, or just use 'build' for waf too
|
||||
files = list()
|
||||
for wc in ['*.py', '*.pyc', '*.so', '*.pyd', '*.pdb', '*.pi']:
|
||||
for wc in ['*.py', '*.pyc', '*.so', '*.dylib', '*.pyd', '*.pdb', '*.pi']:
|
||||
files += glob.glob(opj(cfg.PKGDIR, wc))
|
||||
if isWindows:
|
||||
msw = getMSWSettings(options)
|
||||
@@ -1212,9 +1219,9 @@ def bdist(options, args):
|
||||
from ftplib import FTP
|
||||
ftp = FTP(parser.get("FTP", "host"))
|
||||
ftp.login(parser.get("FTP", "user"), parser.get("FTP", "pass"))
|
||||
f = open(tarfilename, 'rb')
|
||||
ftp_dir = parser.get("FTP", "dir")
|
||||
old_files = ftp.nlst(ftp_dir)
|
||||
old_files.sort()
|
||||
|
||||
to_delete = []
|
||||
for afile in old_files:
|
||||
@@ -1226,6 +1233,7 @@ def bdist(options, args):
|
||||
ftp.delete("%s/%s" % (ftp_dir, to_delete[i]))
|
||||
ftp_path = '%s/%s' % (ftp_dir, os.path.basename(tarfilename))
|
||||
print("Uploading package (this may take some time)...")
|
||||
f = open(tarfilename, 'rb')
|
||||
ftp.storbinary('STOR %s' % ftp_path, f)
|
||||
|
||||
ftp.close()
|
||||
|
||||
@@ -524,7 +524,7 @@ def Config(*args, **kw):
|
||||
|
||||
def msg(text):
|
||||
if not runSilently:
|
||||
print text
|
||||
print(text)
|
||||
|
||||
|
||||
def opj(*args):
|
||||
@@ -616,11 +616,28 @@ def wxDir():
|
||||
return WXWIN
|
||||
|
||||
|
||||
def copyIfNewer(src, dest):
|
||||
def copyFile(src, dest, verbose=False):
|
||||
"""
|
||||
Copy file from src to dest, preserving permission bits, etc. If src is a
|
||||
symlink then dest will be a symlink as well instead of just copying the
|
||||
linked file's contents to a new file.
|
||||
"""
|
||||
if verbose:
|
||||
msg('copying %s --> %s' % (src, dest))
|
||||
if os.path.islink(src):
|
||||
if os.path.exists(dest):
|
||||
os.unlink(dest)
|
||||
linkto = os.readlink(src)
|
||||
os.symlink(linkto, dest)
|
||||
else:
|
||||
shutil.copy2(src, dest)
|
||||
|
||||
|
||||
def copyIfNewer(src, dest, verbose=False):
|
||||
if os.path.isdir(dest):
|
||||
dest = os.path.join(dest, os.path.basename(src))
|
||||
if newer(src, dest):
|
||||
shutil.copy(src, dest)
|
||||
copyFile(src, dest, verbose)
|
||||
|
||||
|
||||
def writeIfChanged(filename, text):
|
||||
@@ -641,3 +658,38 @@ def writeIfChanged(filename, text):
|
||||
f = codecs.open(filename, 'w', 'utf-8')
|
||||
f.write(text.encode('utf-8'))
|
||||
f.close()
|
||||
|
||||
|
||||
# TODO: we might be able to get rid of this when the install code is updated...
|
||||
def macFixDependencyInstallName(destdir, prefix, extension, buildDir):
|
||||
print("**** macFixDependencyInstallName(%s, %s, %s, %s)" % (destdir, prefix, extension, buildDir))
|
||||
pwd = os.getcwd()
|
||||
os.chdir(destdir+prefix+'/lib')
|
||||
dylibs = glob.glob('*.dylib')
|
||||
for lib in dylibs:
|
||||
#cmd = 'install_name_tool -change %s/lib/%s %s/lib/%s %s' % \
|
||||
# (destdir+prefix,lib, prefix,lib, extension)
|
||||
cmd = 'install_name_tool -change %s/lib/%s %s/lib/%s %s' % \
|
||||
(buildDir,lib, prefix,lib, extension)
|
||||
print(cmd)
|
||||
os.system(cmd)
|
||||
os.chdir(pwd)
|
||||
|
||||
|
||||
def macSetLoaderNames(filenames):
|
||||
"""
|
||||
Scan the list of dynamically loaded files for each file in filenames,
|
||||
replacing the path for the wxWidgets libraries with "@loader_path"
|
||||
"""
|
||||
for filename in filenames:
|
||||
if not os.path.isfile(filename):
|
||||
continue
|
||||
for line in os.popen('otool -L %s' % filename, 'r').readlines(): # -arch all ??
|
||||
if line.startswith('\t') and 'libwx_' in line:
|
||||
line = line.strip()
|
||||
endPos = line.rfind(' (')
|
||||
curName = line[:endPos]
|
||||
newName = '@loader_path/' + os.path.basename(curName)
|
||||
cmd = 'install_name_tool -change %s %s %s' % (curName, newName, filename)
|
||||
os.system(cmd)
|
||||
|
||||
|
||||
@@ -44,15 +44,18 @@ nothing extra should be needed because the system will automatically
|
||||
look for the DLLs in the same folder that the extension modules are
|
||||
located in.
|
||||
|
||||
For Unix-like systems like Linux or OSX the locations that are
|
||||
searched for the dynamic libraries can be controlled by setting
|
||||
environment variables, DYLD_LIBRARY_PATH for OSX or LD_LIBRARY_PATH
|
||||
for the others. Basically you just need to set that variable to the
|
||||
path of the wx package, for example if you're on a Mac and currently
|
||||
in the folder where this README is located, then you can do something
|
||||
like this::
|
||||
For Mac OSX there should also not be anything extra needed to help Phoenix
|
||||
find the wxWidgets dynamic libraries because the install names have been
|
||||
modified to use @loader_path so they can find the libraries in the same
|
||||
folder as the extension modules.
|
||||
|
||||
export DYLD_LIBRARY_PATH=`pwd`/wx
|
||||
For Unix-like systems like Linux the locations that are searched for the
|
||||
dynamic libraries can be controlled by setting the LD_LIBRARY_PATH
|
||||
environment variable. Basically you just need to set that variable to the
|
||||
path of the wx package, for example if you're in the folder where this README
|
||||
is located, then you can do something like this::
|
||||
|
||||
export LD_LIBRARY_PATH=`pwd`/wx
|
||||
|
||||
The phoenix_environ.sh shell script included with this build can help
|
||||
you do that, just be sure to use the "source" command so the variables
|
||||
@@ -60,6 +63,4 @@ in the current shell's environment will be modified.
|
||||
|
||||
It is also possible to embed the path that the dynamic library should
|
||||
be loaded from directly into the extension module. For now at least
|
||||
this is left as an exercise for the reader. For OSX look at the man
|
||||
pages for the otool and install_name_tool commands. For the other
|
||||
unix-like platforms look at chrpath.
|
||||
this is left as an exercise for the reader. Look for the chrpath tool.
|
||||
@@ -1,4 +1,3 @@
|
||||
DIR=$(cd $(dirname "$BASH_SOURCE") && pwd)
|
||||
export PYTHONPATH=$DIR
|
||||
export DYLD_LIBRARY_PATH=$DIR/wx
|
||||
export LD_LIBRARY_PATH=$DIR/wx
|
||||
|
||||
Reference in New Issue
Block a user