def _versioned_implib_symlinks(env, libnode, version, prefix, suffix, **kw): """Generate link names that should be created for a versioned shared library. Returns a list in the form [ (link, linktarget), ... ] """ Verbose = False if Verbose: print("_versioned_implib_symlinks: libnode=%r" % libnode.get_path()) print("_versioned_implib_symlinks: version=%r" % version) try: libtype = kw['libtype'] except KeyError: libtype = 'ShLib' linkdir = os.path.dirname(libnode.get_path()) if Verbose: print("_versioned_implib_symlinks: linkdir=%r" % linkdir) name = ImpLibNameGenerator(env, libnode, implib_libtype=libtype, generator_libtype=libtype + 'ImpLib') if Verbose: print("_versioned_implib_symlinks: name=%r" % name) major = version.split('.')[0] link0 = env.fs.File(os.path.join(linkdir, name)) symlinks = [(link0, libnode)] if Verbose: print("_versioned_implib_symlinks: return symlinks=%r" % StringizeLibSymlinks(symlinks)) return symlinks
def installShlibLinks(dest, source, env): """If we are installing a versioned shared library create the required links.""" Verbose = False symlinks = listShlibLinksToInstall(dest, source, env) if Verbose: print('installShlibLinks: symlinks={!r}'.format(StringizeLibSymlinks(symlinks))) if symlinks: CreateLibSymlinks(env, symlinks) return
def shlib_symlink_emitter(target, source, env, **kw): verbose = False if 'variable_prefix' in kw: var_prefix = kw['variable_prefix'] else: var_prefix = 'SHLIB' do_symlinks = env.subst('$%sNOVERSIONSYMLINKS' % var_prefix) if do_symlinks in ['1', 'True', 'true', True]: return target, source shlibversion = env.subst('$%sVERSION' % var_prefix) if shlibversion: if verbose: print("shlib_symlink_emitter: %sVERSION=%s" % (var_prefix, shlibversion)) libnode = target[0] shlib_soname_symlink = env.subst('$%s_SONAME_SYMLINK' % var_prefix, target=target, source=source) shlib_noversion_symlink = env.subst('$%s_NOVERSION_SYMLINK' % var_prefix, target=target, source=source) if verbose: print("shlib_soname_symlink :%s" % shlib_soname_symlink) print("shlib_noversion_symlink :%s" % shlib_noversion_symlink) print("libnode :%s" % libnode) symlinks = [(env.File(shlib_soname_symlink), libnode), (env.File(shlib_noversion_symlink), libnode)] if verbose: print("_lib_emitter: symlinks={!r}".format(', '.join([ "%r->%r" % (k, v) for k, v in StringizeLibSymlinks(symlinks) ]))) if symlinks: # This does the actual symlinking EmitLibSymlinks(env, symlinks, target[0]) # This saves the information so if the versioned shared library is installed # it can faithfully reproduce the correct symlinks target[0].attributes.shliblinks = symlinks return target, source
def _versioned_lib_symlinks(env, libnode, version, prefix, suffix, name_func, soname_func): """Generate link names that should be created for a versioned shared library. Returns a dictionary in the form { linkname : linktarget } """ Verbose = False if Verbose: print("_versioned_lib_symlinks: libnode={!r}".format( libnode.get_path())) print("_versioned_lib_symlinks: version={!r}".format(version)) if sys.platform.startswith('openbsd'): # OpenBSD uses x.y shared library versioning numbering convention # and doesn't use symlinks to backwards-compatible libraries if Verbose: print("_versioned_lib_symlinks: return symlinks={!r}".format(None)) return None linkdir = libnode.get_dir() if Verbose: print("_versioned_lib_symlinks: linkdir={!r}".format( linkdir.get_path())) name = name_func(env, libnode, version, prefix, suffix) if Verbose: print("_versioned_lib_symlinks: name={!r}".format(name)) soname = soname_func(env, libnode, version, prefix, suffix) if Verbose: print("_versioned_lib_symlinks: soname={!r}".format(soname)) link0 = env.fs.File(soname, linkdir) link1 = env.fs.File(name, linkdir) # We create direct symlinks, not daisy-chained. if link0 == libnode: # This enables SHLIBVERSION without periods (e.g. SHLIBVERSION=1) symlinks = [(link1, libnode)] else: # This handles usual SHLIBVERSION, i.e. '1.2', '1.2.3', etc. symlinks = [(link0, libnode), (link1, libnode)] if Verbose: print("_versioned_lib_symlinks: return symlinks={!r}".format( StringizeLibSymlinks(symlinks))) return symlinks
def LibSymlinksStrFun(target, source, env, *args): cmd = None for tgt in target: symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None) if symlinks: if cmd is None: cmd = "" if cmd: cmd += "\n" cmd += "Create symlinks for: %r\n\t" % tgt.get_path() try: linkstr = '\n\t'.join([ "%r->%r" % (k, v) for k, v in StringizeLibSymlinks(symlinks) ]) except (KeyError, ValueError): pass else: cmd += "%s" % linkstr return cmd
def cyglink_shlib_symlink_emitter(target, source, env, **kw): """ On cygwin, we only create a symlink from the non-versioned implib to the versioned implib. We don't version the shared library itself. :param target: :param source: :param env: :param kw: :return: """ verbose = True if 'variable_prefix' in kw: var_prefix = kw['variable_prefix'] else: var_prefix = 'SHLIB' no_import_lib = env.get('no_import_lib', False) if no_import_lib in ['1', 'True', 'true', True]: if verbose: print("cyglink_shlib_symlink_emitter: no_import_lib=%s" % no_import_lib) return target, source no_symlinks = env.subst('$%sNOVERSIONSYMLINKS' % var_prefix) if no_symlinks in ['1', 'True', 'true', True]: return target, source shlibversion = env.subst('$%sVERSION' % var_prefix) if shlibversion: if verbose: print("cyglink_shlib_symlink_emitter: %sVERSION=%s" % (var_prefix, shlibversion)) # The implib (added by the cyglink_lib_emitter) imp_lib_node = target[1] shlib_noversion_symlink = env.subst('$%s_NOVERSION_SYMLINK' % var_prefix, target=target[0], source=source) if verbose: print( "cyglink_shlib_symlink_emitter: shlib_noversion_symlink :%s" % shlib_noversion_symlink) print( "cyglink_shlib_symlink_emitter: imp_lib_node :%s" % imp_lib_node) symlinks = [(env.File(shlib_noversion_symlink), imp_lib_node)] if verbose: print("cyglink_shlib_symlink_emitter: symlinks={!r}".format( ', '.join([ "%r->%r" % (k, v) for k, v in StringizeLibSymlinks(symlinks) ]))) if symlinks: # This does the actual symlinking EmitLibSymlinks(env, symlinks, target[0]) # This saves the information so if the versioned shared library is installed # it can faithfully reproduce the correct symlinks target[0].attributes.shliblinks = symlinks return target, source
def _lib_emitter(target, source, env, **kw): Verbose = False if Verbose: print("_lib_emitter: target[0]=%r" % target[0].get_path()) try: vp = kw['varprefix'] except KeyError: vp = 'SHLIB' try: libtype = kw['libtype'] except KeyError: libtype = 'ShLib' dll = env.FindIxes(target, '%sPREFIX' % vp, '%sSUFFIX' % vp) no_import_lib = env.get('no_import_lib', 0) if Verbose: print("_lib_emitter: dll=%r" % dll.get_path()) if not dll or len(target) > 1: raise SCons.Errors.UserError( "A shared library should have exactly one target with the suffix: %s" % env.subst("$%sSUFFIX" % vp)) # Remove any "lib" after the prefix pre = env.subst('$%sPREFIX' % vp) if dll.name[len(pre):len(pre) + 3] == 'lib': dll.name = pre + dll.name[len(pre) + 3:] if Verbose: print("_lib_emitter: dll.name=%r" % dll.name) orig_target = target target = [env.fs.File(dll)] target[0].attributes.shared = 1 if Verbose: print("_lib_emitter: after target=[env.fs.File(dll)]: target[0]=%r" % target[0].get_path()) # Append an import lib target if not no_import_lib: # Create list of target libraries as strings target_strings = env.ReplaceIxes(orig_target[0], '%sPREFIX' % vp, '%sSUFFIX' % vp, 'IMPLIBPREFIX', 'IMPLIBSUFFIX') if Verbose: print("_lib_emitter: target_strings=%r" % target_strings) implib_target = env.fs.File(target_strings) if Verbose: print("_lib_emitter: implib_target=%r" % implib_target.get_path()) implib_target.attributes.shared = 1 target.append(implib_target) symlinks = ImpLibSymlinkGenerator(env, implib_target, implib_libtype=libtype, generator_libtype=libtype + 'ImpLib') if Verbose: print("_lib_emitter: implib symlinks=%r" % StringizeLibSymlinks(symlinks)) if symlinks: EmitLibSymlinks(env, symlinks, implib_target, clean_targets=target[0]) implib_target.attributes.shliblinks = symlinks return (target, source)