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