def mk_relative_osx(path): assert sys.platform == 'darwin' and is_obj(path) macho.install_name_change(path, osx_ch_link) if path.endswith('.dylib'): # note that not every MachO binaries is a "dynamically linked shared # library" which have an identification name, a .so C extensions # extensions is a "bundle". One can verify this using the "file" # command. names = macho.otool(path) if names: args = ['install_name_tool', '-id', basename(names[0]), path] print(' '.join(args)) p = Popen(args, stderr=PIPE) stdout, stderr = p.communicate() stderr = stderr.decode('utf-8') if "Mach-O dynamic shared library stub file" in stderr: print("Skipping Mach-O dynamic shared library stub file %s" % path) return else: print(stderr, file=sys.stderr) if p.returncode: raise RuntimeError("install_name_tool failed with exit status %d" % p.returncode) for name in macho.otool(path): assert not name.startswith(build_prefix), path
def mk_relative_osx(path): assert sys.platform == 'darwin' and is_obj(path) s = macho.install_name_change(path, osx_ch_link) if macho.is_dylib(path): names = macho.otool(path) if names: args = ['install_name_tool', '-id', basename(names[0]), path] print(' '.join(args)) p = Popen(args, stderr=PIPE) stdout, stderr = p.communicate() stderr = stderr.decode('utf-8') if "Mach-O dynamic shared library stub file" in stderr: print("Skipping Mach-O dynamic shared library stub file %s" % path) return else: print(stderr, file=sys.stderr) if p.returncode: raise RuntimeError("install_name_tool failed with exit status %d" % p.returncode) if s: # Skip for stub files, which have to use binary_has_prefix_files to be # made relocatable. assert_relative_osx(path)
def mk_relative_osx(path, build_prefix=None): ''' if build_prefix is None, then this is a standard conda build. The path and all dependencies are in the build_prefix. if package is built in develop mode, build_prefix is specified. Object specified by 'path' needs to relink runtime dependences to libs found in build_prefix/lib/. Also, in develop mode, 'path' is not in 'build_prefix' ''' if build_prefix is None: assert path.startswith(config.build_prefix + '/') else: config.short_build_prefix = build_prefix assert sys.platform == 'darwin' and is_obj(path) s = macho.install_name_change(path, osx_ch_link) names = macho.otool(path) if names: # Add an rpath to every executable to increase the chances of it # being found. rpath = join('@loader_path', relpath(join(config.build_prefix, 'lib'), dirname(path)), '').replace('/./', '/') macho.add_rpath(path, rpath, verbose=True) # 10.7 install_name_tool -delete_rpath causes broken dylibs, I will revisit this ASAP. # .. and remove config.build_prefix/lib which was added in-place of # DYLD_FALLBACK_LIBRARY_PATH since El Capitan's SIP. #macho.delete_rpath(path, config.build_prefix + '/lib', verbose = True) if s: # Skip for stub files, which have to use binary_has_prefix_files to be # made relocatable. assert_relative_osx(path)
def mk_relative_osx(path): assert sys.platform == 'darwin' and is_obj(path) s = macho.install_name_change(path, osx_ch_link) names = macho.otool(path) if names: # Strictly speaking, not all object files have install names (e.g., # bundles and executables do not). In that case, the first name here # will not be the install name (i.e., the id), but it isn't a problem, # because in that case it will be a no-op (with the exception of stub # files, which give an error, which is handled below). args = [ 'install_name_tool', '-id', join('@rpath', relpath(dirname(path), join(config.build_prefix, 'lib')), basename(names[0])), path, ] print(' '.join(args)) p = Popen(args, stderr=PIPE) stdout, stderr = p.communicate() stderr = stderr.decode('utf-8') if "Mach-O dynamic shared library stub file" in stderr: print("Skipping Mach-O dynamic shared library stub file %s" % path) return else: print(stderr, file=sys.stderr) if p.returncode: raise RuntimeError("install_name_tool failed with exit status %d" % p.returncode) # Add an rpath to every executable to increase the chances of it # being found. args = [ 'install_name_tool', '-add_rpath', join('@loader_path', relpath(join(config.build_prefix, 'lib'), dirname(path)), '').replace('/./', '/'), path, ] print(' '.join(args)) p = Popen(args, stderr=PIPE) stdout, stderr = p.communicate() stderr = stderr.decode('utf-8') if "Mach-O dynamic shared library stub file" in stderr: print("Skipping Mach-O dynamic shared library stub file %s\n" % path) return elif "would duplicate path, file already has LC_RPATH for:" in stderr: print("Skipping -add_rpath, file already has LC_RPATH set") return else: print(stderr, file=sys.stderr) if p.returncode: raise RuntimeError("install_name_tool failed with exit status %d" % p.returncode) if s: # Skip for stub files, which have to use binary_has_prefix_files to be # made relocatable. assert_relative_osx(path)
def mk_relative_osx(path, build_prefix=None): ''' if build_prefix is None, then this is a standard conda build. The path and all dependencies are in the build_prefix. if package is built in develop mode, build_prefix is specified. Object specified by 'path' needs to relink runtime dependences to libs found in build_prefix/lib/. Also, in develop mode, 'path' is not in 'build_prefix' ''' if build_prefix is None: assert path.startswith(config.build_prefix + '/') else: config.short_build_prefix = build_prefix assert sys.platform == 'darwin' and is_obj(path) s = macho.install_name_change(path, osx_ch_link) names = macho.otool(path) if names: # Add an rpath to every executable to increase the chances of it # being found. rpath = join('@loader_path', relpath(join(config.build_prefix, 'lib'), dirname(path)), '').replace('/./', '/') macho.add_rpath(path, rpath, verbose = True) # .. and remove config.build_prefix/lib which was added in-place of # DYLD_FALLBACK_LIBRARY_PATH since El Capitan's SIP. macho.delete_rpath(path, config.build_prefix + '/lib', verbose = True) if s: # Skip for stub files, which have to use binary_has_prefix_files to be # made relocatable. assert_relative_osx(path)
def mk_relative_osx(path): assert sys.platform == 'darwin' and is_obj(path) macho.install_name_change(path, osx_ch_link) if path.endswith('.dylib'): # note that not every MachO binaries is a "dynamically linked shared # library" which have an identification name, a .so C extensions # extensions is a "bundle". One can verify this using the "file" # command. names = macho.otool(path) if names: args = ['install_name_tool', '-id', basename(names[0]), path] print(' '.join(args)) check_call(args) for name in macho.otool(path): assert not name.startswith(build_prefix), path
def get_linkages(obj_files, prefix): res = {} for f in obj_files: path = join(prefix, f) if sys.platform.startswith('linux'): res[f] = ldd(path) elif sys.platform.startswith('darwin'): links = otool(path) res[f] = [(basename(l['name']), l['name']) for l in links] return res
def get_linkages(obj_files, prefix): res = {} for f in obj_files: path = join(prefix, f) if sys.platform.startswith('linux'): res[f] = ldd(path) elif sys.platform.startswith('darwin'): links = otool(path) res[f] = [(basename(l), l) for l in links] return res
def assert_relative_osx(path): for name in macho.otool(path): assert not name.startswith(config.build_prefix), path
def mk_relative_osx(path, build_prefix=None): ''' if build_prefix is None, then this is a standard conda build. The path and all dependencies are in the build_prefix. if package is built in develop mode, build_prefix is specified. Object specified by 'path' needs to relink runtime dependences to libs found in build_prefix/lib/. Also, in develop mode, 'path' is not in 'build_prefix' ''' if build_prefix is None: assert path.startswith(config.build_prefix + '/') else: config.short_build_prefix = build_prefix assert sys.platform == 'darwin' and is_obj(path) s = macho.install_name_change(path, osx_ch_link) names = macho.otool(path) if names: # Strictly speaking, not all object files have install names (e.g., # bundles and executables do not). In that case, the first name here # will not be the install name (i.e., the id), but it isn't a problem, # because in that case it will be a no-op (with the exception of stub # files, which give an error, which is handled below). args = [ 'install_name_tool', '-id', join('@rpath', relpath(dirname(path), join(config.build_prefix, 'lib')), basename(names[0])), path, ] print(' '.join(args)) return_code = 0 try: stdout, stderr = utils.execute(args) except subprocess.CalledProcessError as exc: stdout, stderr = exc.output return_code = exc.return_code if "Mach-O dynamic shared library stub file" in stderr: print("Skipping Mach-O dynamic shared library stub file %s" % path) return else: print(stderr, file=sys.stderr) if return_code: raise RuntimeError("install_name_tool failed with exit " "status %d" % return_code) # Add an rpath to every executable to increase the chances of it # being found. args = [ 'install_name_tool', '-add_rpath', join('@loader_path', relpath(join(config.build_prefix, 'lib'), dirname(path)), '').replace('/./', '/'), path, ] print(' '.join(args)) return_code = 0 try: stdout, strerr = utils.execute(args) except subprocess.CalledProcessError as exc: stdout, stderr = exc.output return_code = exc.return_code if "Mach-O dynamic shared library stub file" in stderr: print("Skipping Mach-O dynamic shared library stub file %s\n" % path) return elif "would duplicate path, file already has LC_RPATH for:" in stderr: print("Skipping -add_rpath, file already has LC_RPATH set") return else: print(stderr, file=sys.stderr) if return_code: raise RuntimeError("install_name_tool failed with exit " "status %d" % return_code) if s: # Skip for stub files, which have to use binary_has_prefix_files to be # made relocatable. assert_relative_osx(path)