aboutsummaryrefslogtreecommitdiffstats
path: root/utils.py
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2017-11-27 17:01:22 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2017-11-27 17:01:22 +0100
commit1c9e0d95263480a5ae5d645cabb41f835d1dbb70 (patch)
tree25f46dc18d8f8430d46ad365452ce0d8a7c9d9d0 /utils.py
parentad14f64972d182fca3e180c08750ca020a91b84e (diff)
parent2490c34325bb1b39922582090a4cb69c01726999 (diff)
Merge remote-tracking branch 'origin/5.6' into 5.9
Diffstat (limited to 'utils.py')
-rw-r--r--utils.py108
1 files changed, 72 insertions, 36 deletions
diff --git a/utils.py b/utils.py
index 75ff2d851..e0cbc276a 100644
--- a/utils.py
+++ b/utils.py
@@ -262,7 +262,7 @@ def init_msvc_env(platform_arch, build_type):
log.info("Done initializing MSVC env")
-def copyfile(src, dst, force=True, vars=None):
+def copyfile(src, dst, force=True, vars=None, force_copy_symlink=False):
if vars is not None:
src = src.format(**vars)
dst = dst.format(**vars)
@@ -271,7 +271,7 @@ def copyfile(src, dst, force=True, vars=None):
log.info("**Skiping copy file %s to %s. Source does not exists." % (src, dst))
return
- if not os.path.islink(src):
+ if not os.path.islink(src) or force_copy_symlink:
log.info("Copying file %s to %s." % (src, dst))
shutil.copy2(src, dst)
else:
@@ -315,8 +315,8 @@ def makefile(dst, content=None, vars=None):
f.close()
-def copydir(src, dst, filter=None, ignore=None, force=True,
- recursive=True, vars=None):
+def copydir(src, dst, filter=None, ignore=None, force=True, recursive=True, vars=None,
+ dir_filter_function=None, force_copy_symlinks=False):
if vars is not None:
src = src.format(**vars)
@@ -345,15 +345,19 @@ def copydir(src, dst, filter=None, ignore=None, force=True,
dstname = os.path.join(dst, name)
try:
if os.path.isdir(srcname):
+ if dir_filter_function and not dir_filter_function(name, src, srcname):
+ continue
if recursive:
- results.extend(copydir(srcname, dstname, filter, ignore, force, recursive, vars))
+ results.extend(
+ copydir(srcname, dstname, filter, ignore, force, recursive,
+ vars, dir_filter_function, force_copy_symlinks))
else:
if (filter is not None and not filter_match(name, filter)) or \
(ignore is not None and filter_match(name, ignore)):
continue
if not os.path.exists(dst):
os.makedirs(dst)
- results.append(copyfile(srcname, dstname, True, vars))
+ results.append(copyfile(srcname, dstname, True, vars, force_copy_symlinks))
# catch the Error from the recursive copytree so that we can
# continue with other files
except shutil.Error as err:
@@ -589,7 +593,7 @@ def osx_get_install_names(libpath):
OSX_RPATH_RE = re.compile(r"path (.+) \(offset \d+\)")
def osx_get_rpaths(libpath):
- """ Get rpaths from library `libpath` using ``otool``
+ """ Get rpath load commands from library `libpath` using ``otool``
Parameters
----------
@@ -623,43 +627,75 @@ def osx_get_rpaths(libpath):
return rpaths
-def osx_localize_libpaths(libpath, local_libs, enc_path=None):
- """ Set rpaths and install names to load local dynamic libs at run time
+def osx_fix_rpaths_for_library(library_path, qt_lib_dir):
+ """ Adds required rpath load commands to given library.
- Use ``install_name_tool`` to set relative install names in `libpath` (as
- named in `local_libs` to be relative to `enc_path`. The default for
- `enc_path` is the directory containing `libpath`.
+ This is a necessary post-installation step, to allow loading PySide modules without setting
+ DYLD_LIBRARY_PATH or DYLD_FRAMEWORK_PATH.
+ The CMake rpath commands which are added at build time are used only for testing (make check),
+ and they are stripped once the equivalent of make install is executed (except for shiboken,
+ which currently uses CMAKE_INSTALL_RPATH_USE_LINK_PATH, which might be necessary to remove in
+ the future).
Parameters
----------
- libpath : str
- path to library for which to set install names and rpaths
- local_libs : sequence of str
- library (install) names that should be considered relative paths
- enc_path : str, optional
- path that does or will contain the `libpath` library, and to which the
- `local_libs` are relative. Defaults to current directory containing
- `libpath`.
+ library_path : str
+ path to library for which to set rpaths.
+ qt_lib_dir : str
+ rpath to installed Qt lib directory.
"""
- if enc_path is None:
- enc_path = os.path.abspath(os.path.dirname(libpath))
- install_names = osx_get_install_names(libpath)
- need_rpath = False
+
+ install_names = osx_get_install_names(library_path)
+ existing_rpath_commands = osx_get_rpaths(library_path)
+
+ needs_loader_path = False
for install_name in install_names:
+ # Absolute path, skip it.
if install_name[0] == '/':
- # absolute path, nothing to do
continue
- # we possibly need to add an rpath command.
- # note that a @rpath may be there already, but no rpath command.
- # this happens when Qt is not linked (with qt5 this is the default)
- need_rpath = True
- if install_name[0] != '@':
- # we need to change a relative path to @rpath
- back_tick('install_name_tool -change {ina} @rpath/{ina} {lipa}'.format(
- ina=install_name, lipa=libpath ))
- if need_rpath and enc_path not in osx_get_rpaths(libpath):
- back_tick('install_name_tool -add_rpath {epa} {lipa}'.format(
- epa=enc_path, lipa=libpath ))
+
+ # If there are dynamic library install names that contain @rpath tokens, we will
+ # provide an rpath load command with the value of "@loader_path". This will allow loading
+ # dependent libraries from within the same directory as 'library_path'.
+ if install_name[0] == '@':
+ needs_loader_path = True
+ break
+
+ if needs_loader_path and "@loader_path" not in existing_rpath_commands:
+ back_tick('install_name_tool -add_rpath {rpath} {library_path}'.format(
+ rpath="@loader_path", library_path=library_path))
+
+ # If the library depends on a Qt library, add an rpath load comment pointing to the Qt lib
+ # directory.
+ osx_add_qt_rpath(library_path, qt_lib_dir, existing_rpath_commands, install_names)
+
+def osx_add_qt_rpath(library_path, qt_lib_dir,
+ existing_rpath_commands = [], library_dependencies = []):
+ """ Adds an rpath load command to the Qt lib directory if necessary
+
+ Checks if library pointed to by 'library_path' has Qt dependencies, and adds an rpath load
+ command that points to the Qt lib directory (qt_lib_dir).
+ """
+ if not existing_rpath_commands:
+ existing_rpath_commands = osx_get_rpaths(library_path)
+
+ # Return early if qt rpath is already present.
+ if qt_lib_dir in existing_rpath_commands:
+ return
+
+ # Check if any library dependencies are Qt libraries (hacky).
+ if not library_dependencies:
+ library_dependencies = osx_get_install_names(library_path)
+
+ needs_qt_rpath = False
+ for library in library_dependencies:
+ if 'Qt' in library:
+ needs_qt_rpath = True
+ break
+
+ if needs_qt_rpath:
+ back_tick('install_name_tool -add_rpath {rpath} {library_path}'.format(
+ rpath=qt_lib_dir, library_path=library_path))
# Find an executable specified by a glob pattern ('foo*') in the OS path
def findGlobInPath(pattern):