def set_rpath_library(filename, toplevel, searchpath): logger.debug('set_rpath_library %s %s' % (filename, toplevel)) assert not any(map(P.isabs, searchpath)), 'set_rpath: searchpaths must be relative to distdir (was given %s)' % (searchpath,) def linux(): rel_to_top = P.relpath(toplevel, P.dirname(filename)) rpath = [P.join('$ORIGIN', rel_to_top, path) for path in searchpath] if run('chrpath', '-r', ':'.join(rpath), filename, raise_on_failure = False) is None: logger.warn('Failed to set_rpath on %s' % filename) def osx(): info = otool(filename) # soname is None for an executable if info.soname is not None: info.libs[info.soname] = info.sopath logger.debug('Soname: %s' % info.soname) for soname, sopath in info.libs.iteritems(): logger.debug(' Processing soname: %s' % soname) # OSX rpath points to one specific file, not anything that matches the # library SONAME. We've already done a whitelist check earlier, so # ignore it if we can't find the lib we want if info.sopath == sopath: run('install_name_tool', '-id', filename, filename) continue for rpath in searchpath: if P.exists(P.join(toplevel, rpath, soname)): new_path = P.join('@loader_path', P.relpath(P.join(toplevel,rpath,soname),P.dirname(filename))) # new_path = P.join('@loader_path', '..', rpath, soname) # If the entry is the "self" one, it has to be changed differently run('install_name_tool', '-change', sopath, new_path, filename) break locals()[get_platform().os]()
def required_libs(filename): ''' Returns a dict where the keys are required SONAMEs and the values are proposed full paths. ''' def linux(): soname = set(readelf(filename).needed) return dict((k,v) for k,v in ldd(filename).iteritems() if k in soname) def osx(): return otool(filename).libs return locals()[get_platform().os]()
def tarball_name(): arch = get_platform() if opt.version is not None: return '%s-%s-%s-%s' % (opt.name, opt.version, arch.machine, arch.prettyos) else: git = run('git', 'describe', '--always', '--dirty', output=False, raise_on_failure=False) if git is None: git = '' if len(git): git = '%s-' % git.strip() return '%s-%s-%s-%s%s' % (opt.name, arch.machine, arch.prettyos, git, time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime()))
def tarball_name(): arch = get_platform() if opt.version is not None: return "%s-%s-%s-%s%s" % (opt.name, opt.version, arch.machine, arch.dist_name, arch.dist_version) else: git = run("git", "describe", "--always", "--dirty", output=False, raise_on_failure=False) if git is None: git = "" if len(git): git = "%s" % git.strip() return "%s-%s-%s%s-%s%s" % ( opt.name, arch.machine, arch.dist_name, arch.dist_version, time.strftime("%Y-%m-%d_%H-%M-%S", time.localtime()), git, )
def set_rpath(filename, toplevel, searchpath): assert not any(map(P.isabs, searchpath)), 'set_rpath: searchpaths must be relative to distdir (was given %s)' % (searchpath,) def linux(): rel_to_top = P.relpath(toplevel, P.dirname(filename)) rpath = [P.join('$ORIGIN', rel_to_top, path) for path in searchpath] if run('chrpath', '-r', ':'.join(rpath), filename, raise_on_failure = False) is None: logger.warn('Failed to set_rpath on %s' % filename) def osx(): info = otool(filename) # soname is None for an executable if info.soname is not None: info.libs[info.soname] = info.sopath for soname, sopath in info.libs.iteritems(): # /tmp/build/install/lib/libvwCore.5.dylib # base = libvwCore.5.dylib # looks for @executable_path/../lib/libvwCore.5.dylib # /opt/local/libexec/qt4-mac/lib/QtXml.framework/Versions/4/QtXml # base = QtXml.framework/Versions/4/QtXml # looks for @executable_path/../lib/QtXml.framework/Versions/4/QtXml # OSX rpath points to one specific file, not anything that matches the # library SONAME. We've already done a whitelist check earlier, so # ignore it if we can't find the lib we want # XXX: This code carries an implicit assumption that all # executables are one level below the root (because # @executable_path is always the exe path, not the path of the # current binary like $ORIGIN in linux) for rpath in searchpath: if P.exists(P.join(toplevel, rpath, soname)): new_path = P.join('@executable_path', '..', rpath, soname) # If the entry is the "self" one, it has to be changed differently if info.sopath == sopath: run('install_name_tool', '-id', new_path, filename) break else: run('install_name_tool', '-change', sopath, new_path, filename) break locals()[get_platform().os]()
def strip(filename): flags = None def linux(): typ = run('file', filename, output=True) if typ.find('current ar archive') != -1: return ['-g'] elif typ.find('SB executable') != -1 or typ.find('SB shared object') != -1: save_elf_debug(filename) return ['--strip-unneeded', '-R', '.comment'] elif typ.find('SB relocatable') != -1: return ['--strip-unneeded'] return None def osx(): return ['-S'] flags = locals()[get_platform().os]() flags.append(filename) run('strip', *flags)
def strip(filename): '''Discard all symbols from this object file with OS specific flags''' flags = None def linux(): typ = run('file', filename, output=True) if typ.find('current ar archive') != -1: return ['-g'] elif typ.find('SB executable') != -1 or typ.find('SB shared object') != -1: save_elf_debug(filename) return ['--strip-unneeded', '-R', '.comment'] elif typ.find('SB relocatable') != -1: return ['--strip-unneeded'] return None def osx(): return ['-S'] # Get flags from one of the two functions above then run the strip command. flags = locals()[get_platform().os]() flags.append(filename) run('strip', *flags)
if "PATH" not in os.environ: os.environ["PATH"] = "" os.environ["PATH"] = P.join(installdir, "bin") + os.pathsep + os.environ["PATH"] logging.basicConfig(level=opt.loglevel) mgr = DistManager(tarball_name()) try: INSTALLDIR = Prefix(installdir) # ISISROOT = P.join(INSTALLDIR) SEARCHPATH = [INSTALLDIR.lib()] # Bug fix for osg3. Must set LD_LIBRARY_PATH for ldd to later # work correctly on Ubuntu 13.10. if get_platform().os == "linux": if "LD_LIBRARY_PATH" not in os.environ: os.environ["LD_LIBRARY_PATH"] = "" os.environ["LD_LIBRARY_PATH"] = INSTALLDIR.lib() + os.pathsep + os.environ["LD_LIBRARY_PATH"] # if opt.isisroot is not None: # ISISROOT = opt.isisroot if opt.include == "all": mgr.add_directory(INSTALLDIR, hardlink=True) mgr.make_tarball() sys.exit(0) else: print("Adding requested files") sys.stdout.flush() with file(opt.include, "r") as f:
# Ensure that opt.isis3_deps_dir and opt.build_root/install/bin # are is in the path, as there we keep # cmake, chrpath, etc. if "PATH" not in os.environ: os.environ["PATH"] = "" os.environ["PATH"] = P.join(opt.isis3_deps_dir, 'bin') + os.pathsep + \ P.join(opt.build_root, 'install/bin') + os.pathsep + \ os.environ["PATH"] if "LD_LIBRARY_PATH" not in os.environ: os.environ["LD_LIBRARY_PATH"] = "" os.environ["LD_LIBRARY_PATH"] = P.join(opt.build_root, 'install/lib') + \ os.pathsep + os.environ["LD_LIBRARY_PATH"] MIN_CC_VERSION = 5.0 arch = get_platform() # Populate the compiler, unless explicitely specified if opt.cc == "": if arch.os == 'linux': opt.cc = 'gcc' elif arch.os == 'osx': opt.cc = 'clang' if opt.cxx == "": if arch.os == 'linux': opt.cxx = 'g++' elif arch.os == 'osx': opt.cxx = 'clang++' # From the path to the compiler infer the path to the libs
def outer(f): @wraps(f) def inner(*args, **kw): return f(*args, **kw) if get_platform().os != os: inner.__doc__ = '%s is only supported on %s' % (inner.__name__, os) return inner
PATH = os.environ['PATH'], FAST = str(int(opt.fast)) ) if opt.ld_library_path is not None: build_env['LD_LIBRARY_PATH'] = opt.ld_library_path # Bugfix, add compiler's libraries to LD_LIBRARY_PATH. comp_path = which(build_env['CC']) libdir1 = P.join(P.dirname(P.dirname(comp_path)), "lib") libdir2 = P.join(P.dirname(P.dirname(comp_path)), "lib64") if 'LD_LIBRARY_PATH' not in build_env: build_env['LD_LIBRARY_PATH'] = "" build_env['LD_LIBRARY_PATH'] += ":" + libdir1 + ":" + libdir2 arch = get_platform() # Check compiler version for compilers we hate output = run(build_env['CC'],'--version') if 'gcc' in build_env['CC']: output = output.lower() if "llvm" in output or "clang" in output: die('Your compiler is an LLVM-GCC hybrid. It is our experience that these tools can not compile Vision Workbench and Stereo Pipeline correctly. Please change your compiler choice.') if arch.os == 'linux': ver1 = get_prog_version(build_env['CC']) ver2 = get_prog_version(build_env['CXX']) if ver1 < MIN_CC_VERSION or ver2 < MIN_CC_VERSION: die('Expecting gcc and g++ version >= ' + str(MIN_CC_VERSION)) if arch.os == 'linux':
def set_rpath(filename, toplevel, searchpath, relative_name=True): '''For each input file, set the rpath to contain all the input search paths to be relative to the top level.''' assert not any(map(P.isabs, searchpath)), 'set_rpath: searchpaths must be relative to distdir (was given %s)' % (searchpath,) def linux(): rel_to_top = P.relpath(toplevel, P.dirname(filename)) rpath = [P.join('$ORIGIN', rel_to_top, path) for path in searchpath] if run('chrpath', '-r', ':'.join(rpath), filename, raise_on_failure = False) is None: logger.warn('Failed to set_rpath on %s' % filename) def osx(): info = otool(filename) # soname is None for an executable if info.soname is not None: info.libs[info.soname] = info.sopath # If we are not using relative paths .. always fix the install name. if not relative_name: run('install_name_tool', '-id', filename, filename) logger.debug("Trying to Bake %s" % filename) logger.debug("Info sopath %s" % info.sopath) logger.debug("Toplevel var %s" % toplevel) logger.debug("Possible search path %s" % searchpath) for soname, sopath in info.libs.iteritems(): logger.debug("Soname %s Sopath %s" % (soname, sopath)) # /tmp/build/install/lib/libvwCore.5.dylib # base = libvwCore.5.dylib # looks for @executable_path/../lib/libvwCore.5.dylib # /opt/local/libexec/qt4-mac/lib/QtXml.framework/Versions/4/QtXml # base = QtXml.framework/Versions/4/QtXml # looks for @executable_path/../lib/QtXml.framework/Versions/4/QtXml # OSX rpath points to one specific file, not anything that matches the # library SONAME. We've already done a whitelist check earlier, so # ignore it if we can't find the lib we want # XXX: This code carries an implicit assumption that all # executables are one level below the root (because # @executable_path is always the exe path, not the path of the # current binary like $ORIGIN in linux) for rpath in searchpath: if P.exists(P.join(toplevel, rpath, soname)): new_path = P.join('@rpath', soname) # If the entry is the "self" one, it has to be # changed differently if info.sopath == sopath: if relative_name: run('install_name_tool', '-id', new_path, filename) break else: run('install_name_tool', '-change', sopath, new_path, filename) break if len(info.libs): for rpath in searchpath: if run('install_name_tool','-add_rpath',P.join('@executable_path','..',rpath), filename, raise_on_failure = False) is None: logger.warn('Failed to add rpath on %s' % filename) if run('install_name_tool','-add_rpath',P.join('@loader_path','..',rpath), filename, raise_on_failure = False) is None: logger.warn('Failed to add rpath on %s' % filename) # We'd like to wipe the hard-coded RPATH pointing to the # original install directory. The user won't have it, and it # causes problems on the build machine, as libraries are # loaded from both the new and original locations which # results in a subtle crash. If the same rpath shows up twice, # wiping it causes problems, so then we don't do it. if len(info.old_rpaths) == 1: for old_rpath in info.old_rpaths: run('install_name_tool', '-delete_rpath', old_rpath, filename) # Call one of the two functions above depending on the OS locals()[get_platform().os]()
def set_rpath(filename, toplevel, searchpath, relative_name=True): assert not any( map(P.isabs, searchpath) ), 'set_rpath: searchpaths must be relative to distdir (was given %s)' % ( searchpath, ) def linux(): rel_to_top = P.relpath(toplevel, P.dirname(filename)) rpath = [P.join('$ORIGIN', rel_to_top, path) for path in searchpath] if run( 'chrpath', '-r', ':'.join(rpath), filename, raise_on_failure=False) is None: logger.warn('Failed to set_rpath on %s' % filename) def osx(): info = otool(filename) # soname is None for an executable if info.soname is not None: info.libs[info.soname] = info.sopath # If we are not using relative paths .. always fix the install name. if not relative_name: run('install_name_tool', '-id', filename, filename) logger.debug("Trying to Bake %s" % filename) logger.debug("Info sopath %s" % info.sopath) logger.debug("Toplevel var %s" % toplevel) logger.debug("Possible search path %s" % searchpath) for soname, sopath in info.libs.iteritems(): logger.debug("Soname %s Sopath %s" % (soname, sopath)) # /tmp/build/install/lib/libvwCore.5.dylib # base = libvwCore.5.dylib # looks for @executable_path/../lib/libvwCore.5.dylib # /opt/local/libexec/qt4-mac/lib/QtXml.framework/Versions/4/QtXml # base = QtXml.framework/Versions/4/QtXml # looks for @executable_path/../lib/QtXml.framework/Versions/4/QtXml # OSX rpath points to one specific file, not anything that matches the # library SONAME. We've already done a whitelist check earlier, so # ignore it if we can't find the lib we want # XXX: This code carries an implicit assumption that all # executables are one level below the root (because # @executable_path is always the exe path, not the path of the # current binary like $ORIGIN in linux) for rpath in searchpath: if P.exists(P.join(toplevel, rpath, soname)): new_path = P.join('@rpath', soname) # If the entry is the "self" one, it has to be # changed differently if info.sopath == sopath: if relative_name: run('install_name_tool', '-id', new_path, filename) break else: run('install_name_tool', '-change', sopath, new_path, filename) break if len(info.libs): for rpath in searchpath: if run('install_name_tool', '-add_rpath', P.join('@executable_path', '..', rpath), filename, raise_on_failure=False) is None: logger.warn('Failed to add rpath on %s' % filename) if run('install_name_tool', '-add_rpath', P.join('@loader_path', '..', rpath), filename, raise_on_failure=False) is None: logger.warn('Failed to add rpath on %s' % filename) locals()[get_platform().os]()
libX11.so.6 libXext.so.6 libXi.so.6 libXmu.so.6 libXrandr.so.2 libXt.so.6 libc.so.6 libdl.so.2 libglut.so.3 libm.so.6 libpthread.so.0 librt.so.1 '''.split() # prefixes of libs that we always ship (on linux, anyway) if get_platform().os == 'linux': LIB_SHIP_PREFIX = ''' libstdc++. libgcc_s. '''.split() else: LIB_SHIP_PREFIX = '' LIB_SYSTEM_LIST.extend(['libgcc_s.1.dylib', 'libstdc++.6.dylib']) def tarball_name(): arch = get_platform() if opt.version is not None: return '%s-%s-%s-%s' % (opt.name, opt.version, arch.machine, arch.prettyos) else: git = run('git', 'describe', '--always', '--dirty', output=False, raise_on_failure=False) if git is None: git = '' if len(git): git = '%s-' % git.strip() return '%s-%s-%s-%s%s' % (opt.name, arch.machine, arch.prettyos, git, time.strftime('%Y-%m-%d_%H-%M-%S', time.localtime()))
def set_rpath(filename, toplevel, searchpath, relative_name=True): '''For each input file, set the rpath to contain all the input search paths to be relative to the top level.''' assert not any( map(P.isabs, searchpath) ), 'set_rpath: searchpaths must be relative to distdir (was given %s)' % ( searchpath, ) def linux(): rel_to_top = P.relpath(toplevel, P.dirname(filename)) rpath = [P.join('$ORIGIN', rel_to_top, path) for path in searchpath] if run( 'chrpath', '-r', ':'.join(rpath), filename, raise_on_failure=False) is None: logger.warn('Failed to set_rpath on %s' % filename) def osx(): info = otool(filename) # soname is None for an executable if info.soname is not None: info.libs[info.soname] = info.sopath # If we are not using relative paths .. always fix the install name. if not relative_name: run('install_name_tool', '-id', filename, filename) logger.debug("Trying to Bake %s" % filename) logger.debug("Info sopath %s" % info.sopath) logger.debug("Toplevel var %s" % toplevel) logger.debug("Possible search path %s" % searchpath) for soname, sopath in info.libs.iteritems(): logger.debug("Soname %s Sopath %s" % (soname, sopath)) # /tmp/build/install/lib/libvwCore.5.dylib # base = libvwCore.5.dylib # looks for @executable_path/../lib/libvwCore.5.dylib # /opt/local/libexec/qt4-mac/lib/QtXml.framework/Versions/4/QtXml # base = QtXml.framework/Versions/4/QtXml # looks for @executable_path/../lib/QtXml.framework/Versions/4/QtXml # OSX rpath points to one specific file, not anything that matches the # library SONAME. We've already done a whitelist check earlier, so # ignore it if we can't find the lib we want # XXX: This code carries an implicit assumption that all # executables are one level below the root (because # @executable_path is always the exe path, not the path of the # current binary like $ORIGIN in linux) for rpath in searchpath: if P.exists(P.join(toplevel, rpath, soname)): new_path = P.join('@rpath', soname) # If the entry is the "self" one, it has to be # changed differently if info.sopath == sopath: if relative_name: run('install_name_tool', '-id', new_path, filename) break else: run('install_name_tool', '-change', sopath, new_path, filename) break if len(info.libs): for rpath in searchpath: if run('install_name_tool', '-add_rpath', P.join('@executable_path', '..', rpath), filename, raise_on_failure=False) is None: logger.warn('Failed to add rpath on %s' % filename) if run('install_name_tool', '-add_rpath', P.join('@loader_path', '..', rpath), filename, raise_on_failure=False) is None: logger.warn('Failed to add rpath on %s' % filename) # We'd like to wipe the hard-coded RPATH pointing to the # original install directory. The user won't have it, and it # causes problems on the build machine, as libraries are # loaded from both the new and original locations which # results in a subtle crash. If the same rpath shows up twice, # wiping it causes problems, so then we don't do it. if len(info.old_rpaths) == 1: for old_rpath in info.old_rpaths: run('install_name_tool', '-delete_rpath', old_rpath, filename) # Call one of the two functions above depending on the OS locals()[get_platform().os]()
logging.basicConfig(level=opt.loglevel) wrapper_file = 'libexec-helper.sh' if (opt.vw_build): wrapper_file = 'libexec-helper_vw.sh' mgr = DistManager(tarball_name(), wrapper_file) try: INSTALLDIR = Prefix(installdir) ISISROOT = P.join(INSTALLDIR) SEARCHPATH = [INSTALLDIR.lib(), INSTALLDIR.lib()+'64'] print('Search path = ' + str(SEARCHPATH)) # Bug fix for osg3. Must set LD_LIBRARY_PATH for ldd to later # work correctly on Ubuntu 13.10. if get_platform().os == 'linux': if "LD_LIBRARY_PATH" not in os.environ: os.environ["LD_LIBRARY_PATH"] = "" os.environ["LD_LIBRARY_PATH"] = INSTALLDIR.lib() + \ os.pathsep + os.environ["LD_LIBRARY_PATH"] if opt.isisroot is not None: ISISROOT = opt.isisroot if opt.include == 'all': mgr.add_directory(INSTALLDIR, hardlink=True) mgr.make_tarball() sys.exit(0) print('Adding requested files')