3
# Matthias Jahn, 2008, jahn matthias ath freenet punto de
4
# Thomas Nagy, 2008 (ita)
6
import sys, re, os, optparse
8
import TaskGen, Task, Utils, preproc
9
from Logs import error, debug, warn
10
from TaskGen import taskgen, after, before, feature
15
if you want to use the code here, you must use something like this:
17
obj.features.append("libtool")
18
obj.vnum = "1.2.3" # optional, but versioned libraries are common
22
fakelibtool_vardeps = ['CXX', 'PREFIX']
23
def fakelibtool_build(task):
24
# Writes a .la file, used by libtool
26
dest = open(task.outputs[0].abspath(env), 'w')
27
sname = task.inputs[0].name
29
fu("# Generated by ltmain.sh - GNU libtool 1.5.18 - (pwn3d by BKsys II code name WAF)\n")
31
nums = env['vnum'].split('.')
32
libname = task.inputs[0].name
33
name3 = libname+'.'+env['vnum']
34
name2 = libname+'.'+nums[0]
36
fu("dlname='%s'\n" % name2)
37
strn = " ".join([name3, name2, name1])
38
fu("library_names='%s'\n" % (strn) )
40
fu("dlname='%s'\n" % sname)
41
fu("library_names='%s %s %s'\n" % (sname, sname, sname) )
42
fu("old_library=''\n")
43
vars = ' '.join(env['libtoolvars']+env['LINKFLAGS'])
44
fu("dependency_libs='%s'\n" % vars)
46
fu("age=0\nrevision=0\ninstalled=yes\nshouldnotlink=no\n")
47
fu("dlopen=''\ndlpreopen=''\n")
48
fu("libdir='%s/lib'\n" % env['PREFIX'])
52
def read_la_file(path):
53
sp = re.compile(r'^([^=]+)=\'(.*)\'$')
55
file = open(path, "r")
56
for line in file.readlines():
58
#print sp.split(line.strip())
59
_, left, right, _ = sp.split(line.strip())
68
def apply_link_libtool(self):
69
if self.type != 'program':
70
linktask = self.link_task
71
self.latask = self.create_task('fakelibtool', linktask.outputs, linktask.outputs[0].change_ext('.la'))
73
if self.bld.is_install:
74
self.bld.install_files('${PREFIX}/lib', linktask.outputs[0], self.env)
78
def apply_libtool(self):
79
self.env['vnum']=self.vnum
86
for l in self.env['LINKFLAGS']:
94
dict = read_la_file(p+'/lib'+l+'.la')
95
linkflags2 = dict.get('dependency_libs', '')
96
for v in linkflags2.split():
98
libtool_files.append(v)
99
libtool_vars.append(v)
101
self.env.append_unique('LINKFLAGS', v)
104
self.env['libtoolvars']=libtool_vars
107
file = libtool_files.pop()
108
dict = read_la_file(file)
109
for v in dict['dependency_libs'].split():
111
libtool_files.append(v)
113
self.env.append_unique('LINKFLAGS', v)
115
Task.task_type_from_func('fakelibtool', vars=fakelibtool_vardeps, func=fakelibtool_build, color='BLUE', after="cc_link cxx_link static_link")
117
class libtool_la_file:
118
def __init__ (self, la_filename):
119
self.__la_filename = la_filename
120
#remove path and .la suffix
121
self.linkname = str(os.path.split(la_filename)[-1])[:-3]
122
if self.linkname.startswith("lib"):
123
self.linkname = self.linkname[3:]
124
# The name that we can dlopen(3).
126
# Names of this library
127
self.library_names = None
128
# The name of the static archive.
129
self.old_library = None
130
# Libraries that this one depends upon.
131
self.dependency_libs = None
132
# Version information for libIlmImf.
136
# Is this an already installed library?
137
self.installed = None
138
# Should we warn about portability when linking against -modules?
139
self.shouldnotlink = None
140
# Files to dlopen/dlpreopen
142
self.dlpreopen = None
143
# Directory that this library needs to be installed in:
144
self.libdir = '/usr/lib'
145
if not self.__parse():
146
raise ValueError("file %s not found!!" %(la_filename))
149
"Retrieve the variables from a file"
150
if not os.path.isfile(self.__la_filename): return 0
151
la_file=open(self.__la_filename, 'r')
155
if ln[0]=='#': continue
156
(key, value) = str(ln).split('=', 1)
158
value = value.strip()
159
if value == "no": value = False
160
elif value == "yes": value = True
162
try: value = int(value)
163
except ValueError: value = value.strip("'")
164
setattr(self, key, value)
169
"""return linkflags for this lib"""
171
if self.dependency_libs:
172
libs = str(self.dependency_libs).strip().split()
175
# add la lib and libdir
176
libs.insert(0, "-l%s" % self.linkname.strip())
177
libs.insert(0, "-L%s" % self.libdir.strip())
182
dlname = "%(dlname)s"
183
library_names = "%(library_names)s"
184
old_library = "%(old_library)s"
185
dependency_libs = "%(dependency_libs)s"
186
version = %(current)s.%(age)s.%(revision)s
187
installed = "%(installed)s"
188
shouldnotlink = "%(shouldnotlink)s"
189
dlopen = "%(dlopen)s"
190
dlpreopen = "%(dlpreopen)s"
191
libdir = "%(libdir)s"''' % self.__dict__
193
class libtool_config:
194
def __init__ (self, la_filename):
195
self.__libtool_la_file = libtool_la_file(la_filename)
196
tmp = self.__libtool_la_file
197
self.__version = [int(tmp.current), int(tmp.age), int(tmp.revision)]
198
self.__sub_la_files = []
199
self.__sub_la_files.append(la_filename)
202
def __cmp__(self, other):
203
"""make it compareable with X.Y.Z versions (Y and Z are optional)"""
206
othervers = [int(s) for s in str(other).split(".")]
207
selfvers = self.__version
208
return cmp(selfvers, othervers)
212
str(self.__libtool_la_file),
213
' '.join(self.__libtool_la_file.get_libs()),
215
' '.join(self.get_libs())
218
def __get_la_libs(self, la_filename):
219
return libtool_la_file(la_filename).get_libs()
222
"""return the complete uniqe linkflags that do not
223
contain .la files anymore"""
224
libs_list = list(self.__libtool_la_file.get_libs())
226
while len(libs_list) > 0:
227
entry = libs_list.pop(0)
229
if str(entry).endswith(".la"):
230
## prevents duplicate .la checks
231
if entry not in self.__sub_la_files:
232
self.__sub_la_files.append(entry)
233
libs_list.extend(self.__get_la_libs(entry))
236
self.__libs = libs_map.keys()
239
def get_libs_only_L(self):
240
if not self.__libs: self.get_libs()
242
libs = [s for s in libs if str(s).startswith('-L')]
245
def get_libs_only_l(self):
246
if not self.__libs: self.get_libs()
248
libs = [s for s in libs if str(s).startswith('-l')]
251
def get_libs_only_other(self):
252
if not self.__libs: self.get_libs()
254
libs = [s for s in libs if not(str(s).startswith('-L')or str(s).startswith('-l'))]
258
"""parse cmdline args and control build"""
259
usage = '''Usage: %prog [options] PathToFile.la
260
example: %prog --atleast-version=2.0.0 /usr/lib/libIlmImf.la
261
nor: %prog --libs /usr/lib/libamarok.la'''
262
parser = optparse.OptionParser(usage)
263
a = parser.add_option
264
a("--version", dest = "versionNumber",
265
action = "store_true", default = False,
266
help = "output version of libtool-config"
268
a("--debug", dest = "debug",
269
action = "store_true", default = False,
270
help = "enable debug"
272
a("--libs", dest = "libs",
273
action = "store_true", default = False,
274
help = "output all linker flags"
276
a("--libs-only-l", dest = "libs_only_l",
277
action = "store_true", default = False,
278
help = "output -l flags"
280
a("--libs-only-L", dest = "libs_only_L",
281
action = "store_true", default = False,
282
help = "output -L flags"
284
a("--libs-only-other", dest = "libs_only_other",
285
action = "store_true", default = False,
286
help = "output other libs (e.g. -pthread)"
288
a("--atleast-version", dest = "atleast_version",
290
help = "return 0 if the module is at least version ATLEAST_VERSION"
292
a("--exact-version", dest = "exact_version",
294
help = "return 0 if the module is exactly version EXACT_VERSION"
296
a("--max-version", dest = "max_version",
298
help = "return 0 if the module is at no newer than version MAX_VERSION"
301
(options, args) = parser.parse_args()
302
if len(args) != 1 and not options.versionNumber:
303
parser.error("incorrect number of arguments")
304
if options.versionNumber:
305
print("libtool-config version %s" % REVISION)
307
ltf = libtool_config(args[0])
310
if options.atleast_version:
311
if ltf >= options.atleast_version: return 0
313
if options.exact_version:
314
if ltf == options.exact_version: return 0
316
if options.max_version:
317
if ltf <= options.max_version: return 0
322
if options.libs: p(ltf.get_libs())
323
elif options.libs_only_l: p(ltf.get_libs_only_l())
324
elif options.libs_only_L: p(ltf.get_libs_only_L())
325
elif options.libs_only_other: p(ltf.get_libs_only_other())
328
if __name__ == '__main__':