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__':