| 1 | # functions to support bundled libraries
|
|---|
| 2 |
|
|---|
| 3 | from Configure import conf
|
|---|
| 4 | import sys, Logs
|
|---|
| 5 | from samba_utils import *
|
|---|
| 6 |
|
|---|
| 7 | def PRIVATE_NAME(bld, name, private_extension, private_library):
|
|---|
| 8 | '''possibly rename a library to include a bundled extension'''
|
|---|
| 9 |
|
|---|
| 10 | # we now use the same private name for libraries as the public name.
|
|---|
| 11 | # see http://git.samba.org/?p=tridge/junkcode.git;a=tree;f=shlib for a
|
|---|
| 12 | # demonstration that this is the right thing to do
|
|---|
| 13 | # also see http://lists.samba.org/archive/samba-technical/2011-January/075816.html
|
|---|
| 14 | return name
|
|---|
| 15 |
|
|---|
| 16 |
|
|---|
| 17 | def target_in_list(target, lst, default):
|
|---|
| 18 | for l in lst:
|
|---|
| 19 | if target == l:
|
|---|
| 20 | return True
|
|---|
| 21 | if '!' + target == l:
|
|---|
| 22 | return False
|
|---|
| 23 | if l == 'ALL':
|
|---|
| 24 | return True
|
|---|
| 25 | if l == 'NONE':
|
|---|
| 26 | return False
|
|---|
| 27 | return default
|
|---|
| 28 |
|
|---|
| 29 |
|
|---|
| 30 | def BUILTIN_LIBRARY(bld, name):
|
|---|
| 31 | '''return True if a library should be builtin
|
|---|
| 32 | instead of being built as a shared lib'''
|
|---|
| 33 | if bld.env.DISABLE_SHARED:
|
|---|
| 34 | return True
|
|---|
| 35 | return target_in_list(name, bld.env.BUILTIN_LIBRARIES, False)
|
|---|
| 36 | Build.BuildContext.BUILTIN_LIBRARY = BUILTIN_LIBRARY
|
|---|
| 37 |
|
|---|
| 38 |
|
|---|
| 39 | def BUILTIN_DEFAULT(opt, builtins):
|
|---|
| 40 | '''set a comma separated default list of builtin libraries for this package'''
|
|---|
| 41 | if 'BUILTIN_LIBRARIES_DEFAULT' in Options.options:
|
|---|
| 42 | return
|
|---|
| 43 | Options.options['BUILTIN_LIBRARIES_DEFAULT'] = builtins
|
|---|
| 44 | Options.Handler.BUILTIN_DEFAULT = BUILTIN_DEFAULT
|
|---|
| 45 |
|
|---|
| 46 |
|
|---|
| 47 | def PRIVATE_EXTENSION_DEFAULT(opt, extension, noextension=''):
|
|---|
| 48 | '''set a default private library extension'''
|
|---|
| 49 | if 'PRIVATE_EXTENSION_DEFAULT' in Options.options:
|
|---|
| 50 | return
|
|---|
| 51 | Options.options['PRIVATE_EXTENSION_DEFAULT'] = extension
|
|---|
| 52 | Options.options['PRIVATE_EXTENSION_EXCEPTION'] = noextension
|
|---|
| 53 | Options.Handler.PRIVATE_EXTENSION_DEFAULT = PRIVATE_EXTENSION_DEFAULT
|
|---|
| 54 |
|
|---|
| 55 |
|
|---|
| 56 | def minimum_library_version(conf, libname, default):
|
|---|
| 57 | '''allow override of mininum system library version'''
|
|---|
| 58 |
|
|---|
| 59 | minlist = Options.options.MINIMUM_LIBRARY_VERSION
|
|---|
| 60 | if not minlist:
|
|---|
| 61 | return default
|
|---|
| 62 |
|
|---|
| 63 | for m in minlist.split(','):
|
|---|
| 64 | a = m.split(':')
|
|---|
| 65 | if len(a) != 2:
|
|---|
| 66 | Logs.error("Bad syntax for --minimum-library-version of %s" % m)
|
|---|
| 67 | sys.exit(1)
|
|---|
| 68 | if a[0] == libname:
|
|---|
| 69 | return a[1]
|
|---|
| 70 | return default
|
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 | @conf
|
|---|
| 74 | def LIB_MAY_BE_BUNDLED(conf, libname):
|
|---|
| 75 | return ('NONE' not in conf.env.BUNDLED_LIBS and
|
|---|
| 76 | '!%s' % libname not in conf.env.BUNDLED_LIBS)
|
|---|
| 77 |
|
|---|
| 78 |
|
|---|
| 79 | @conf
|
|---|
| 80 | def LIB_MUST_BE_BUNDLED(conf, libname):
|
|---|
| 81 | return ('ALL' in conf.env.BUNDLED_LIBS or
|
|---|
| 82 | libname in conf.env.BUNDLED_LIBS)
|
|---|
| 83 |
|
|---|
| 84 |
|
|---|
| 85 | @runonce
|
|---|
| 86 | @conf
|
|---|
| 87 | def CHECK_BUNDLED_SYSTEM(conf, libname, minversion='0.0.0',
|
|---|
| 88 | checkfunctions=None, headers=None,
|
|---|
| 89 | onlyif=None, implied_deps=None,
|
|---|
| 90 | require_headers=True):
|
|---|
| 91 | '''check if a library is available as a system library.
|
|---|
| 92 | this first tries via pkg-config, then if that fails
|
|---|
| 93 | tries by testing for a specified function in the specified lib
|
|---|
| 94 | '''
|
|---|
| 95 | if conf.LIB_MUST_BE_BUNDLED(libname):
|
|---|
| 96 | return False
|
|---|
| 97 | found = 'FOUND_SYSTEMLIB_%s' % libname
|
|---|
| 98 | if found in conf.env:
|
|---|
| 99 | return conf.env[found]
|
|---|
| 100 |
|
|---|
| 101 | def check_functions_headers():
|
|---|
| 102 | '''helper function for CHECK_BUNDLED_SYSTEM'''
|
|---|
| 103 | if checkfunctions is None:
|
|---|
| 104 | return True
|
|---|
| 105 | if require_headers and headers and not conf.CHECK_HEADERS(headers, lib=libname):
|
|---|
| 106 | return False
|
|---|
| 107 | return conf.CHECK_FUNCS_IN(checkfunctions, libname, headers=headers,
|
|---|
| 108 | empty_decl=False, set_target=False)
|
|---|
| 109 |
|
|---|
| 110 | # see if the library should only use a system version if another dependent
|
|---|
| 111 | # system version is found. That prevents possible use of mixed library
|
|---|
| 112 | # versions
|
|---|
| 113 | if onlyif:
|
|---|
| 114 | for syslib in TO_LIST(onlyif):
|
|---|
| 115 | f = 'FOUND_SYSTEMLIB_%s' % syslib
|
|---|
| 116 | if not f in conf.env:
|
|---|
| 117 | if not conf.LIB_MAY_BE_BUNDLED(libname):
|
|---|
| 118 | Logs.error('ERROR: Use of system library %s depends on missing system library %s' % (libname, syslib))
|
|---|
| 119 | sys.exit(1)
|
|---|
| 120 | conf.env[found] = False
|
|---|
| 121 | return False
|
|---|
| 122 |
|
|---|
| 123 | minversion = minimum_library_version(conf, libname, minversion)
|
|---|
| 124 |
|
|---|
| 125 | msg = 'Checking for system %s' % libname
|
|---|
| 126 | if minversion != '0.0.0':
|
|---|
| 127 | msg += ' >= %s' % minversion
|
|---|
| 128 |
|
|---|
| 129 | # try pkgconfig first
|
|---|
| 130 | if (conf.check_cfg(package=libname,
|
|---|
| 131 | args='"%s >= %s" --cflags --libs' % (libname, minversion),
|
|---|
| 132 | msg=msg) and
|
|---|
| 133 | check_functions_headers()):
|
|---|
| 134 | conf.SET_TARGET_TYPE(libname, 'SYSLIB')
|
|---|
| 135 | conf.env[found] = True
|
|---|
| 136 | if implied_deps:
|
|---|
| 137 | conf.SET_SYSLIB_DEPS(libname, implied_deps)
|
|---|
| 138 | return True
|
|---|
| 139 | if checkfunctions is not None:
|
|---|
| 140 | if check_functions_headers():
|
|---|
| 141 | conf.env[found] = True
|
|---|
| 142 | if implied_deps:
|
|---|
| 143 | conf.SET_SYSLIB_DEPS(libname, implied_deps)
|
|---|
| 144 | conf.SET_TARGET_TYPE(libname, 'SYSLIB')
|
|---|
| 145 | return True
|
|---|
| 146 | conf.env[found] = False
|
|---|
| 147 | if not conf.LIB_MAY_BE_BUNDLED(libname):
|
|---|
| 148 | Logs.error('ERROR: System library %s of version %s not found, and bundling disabled' % (libname, minversion))
|
|---|
| 149 | sys.exit(1)
|
|---|
| 150 | return False
|
|---|
| 151 |
|
|---|
| 152 |
|
|---|
| 153 | @runonce
|
|---|
| 154 | @conf
|
|---|
| 155 | def CHECK_BUNDLED_SYSTEM_PYTHON(conf, libname, modulename, minversion='0.0.0'):
|
|---|
| 156 | '''check if a python module is available on the system and
|
|---|
| 157 | has the specified minimum version.
|
|---|
| 158 | '''
|
|---|
| 159 | if conf.LIB_MUST_BE_BUNDLED(libname):
|
|---|
| 160 | return False
|
|---|
| 161 |
|
|---|
| 162 | # see if the library should only use a system version if another dependent
|
|---|
| 163 | # system version is found. That prevents possible use of mixed library
|
|---|
| 164 | # versions
|
|---|
| 165 | minversion = minimum_library_version(conf, libname, minversion)
|
|---|
| 166 |
|
|---|
| 167 | try:
|
|---|
| 168 | m = __import__(modulename)
|
|---|
| 169 | except ImportError:
|
|---|
| 170 | found = False
|
|---|
| 171 | else:
|
|---|
| 172 | try:
|
|---|
| 173 | version = m.__version__
|
|---|
| 174 | except AttributeError:
|
|---|
| 175 | found = False
|
|---|
| 176 | else:
|
|---|
| 177 | found = tuple(version.split(".")) >= tuple(minversion.split("."))
|
|---|
| 178 | if not found and not conf.LIB_MAY_BE_BUNDLED(libname):
|
|---|
| 179 | Logs.error('ERROR: Python module %s of version %s not found, and bundling disabled' % (libname, minversion))
|
|---|
| 180 | sys.exit(1)
|
|---|
| 181 | return found
|
|---|
| 182 |
|
|---|
| 183 |
|
|---|
| 184 | def NONSHARED_BINARY(bld, name):
|
|---|
| 185 | '''return True if a binary should be built without non-system shared libs'''
|
|---|
| 186 | if bld.env.DISABLE_SHARED:
|
|---|
| 187 | return True
|
|---|
| 188 | return target_in_list(name, bld.env.NONSHARED_BINARIES, False)
|
|---|
| 189 | Build.BuildContext.NONSHARED_BINARY = NONSHARED_BINARY
|
|---|
| 190 |
|
|---|
| 191 |
|
|---|