Package wafadmin :: Package Tools :: Module libtool
[hide private]
[frames] | no frames]

Source Code for Module wafadmin.Tools.libtool

  1  #!/usr/bin/env python 
  2  # encoding: utf-8 
  3  # Matthias Jahn, 2008, jahn matthias ath freenet punto de 
  4  # Thomas Nagy, 2008 (ita) 
  5   
  6  import sys, re, os, optparse 
  7   
  8  import TaskGen, Task, Utils, preproc 
  9  from Logs import error, debug, warn 
 10  from TaskGen import taskgen, after, before, feature 
 11   
 12  REVISION="0.1.3" 
 13   
 14  """ 
 15  if you want to use the code here, you must use something like this: 
 16  obj = obj.create(...) 
 17  obj.features.append("libtool") 
 18  obj.vnum = "1.2.3" # optional, but versioned libraries are common 
 19  """ 
20 21 # fake libtool files 22 fakelibtool_vardeps = ['CXX', 'PREFIX'] 23 -def fakelibtool_build(task):
24 # Writes a .la file, used by libtool 25 env = task.env 26 dest = open(task.outputs[0].abspath(env), 'w') 27 sname = task.inputs[0].name 28 fu = dest.write 29 fu("# Generated by ltmain.sh - GNU libtool 1.5.18 - (pwn3d by BKsys II code name WAF)\n") 30 if env['vnum']: 31 nums = env['vnum'].split('.') 32 libname = task.inputs[0].name 33 name3 = libname+'.'+env['vnum'] 34 name2 = libname+'.'+nums[0] 35 name1 = libname 36 fu("dlname='%s'\n" % name2) 37 strn = " ".join([name3, name2, name1]) 38 fu("library_names='%s'\n" % (strn) ) 39 else: 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) 45 fu("current=0\n") 46 fu("age=0\nrevision=0\ninstalled=yes\nshouldnotlink=no\n") 47 fu("dlopen=''\ndlpreopen=''\n") 48 fu("libdir='%s/lib'\n" % env['PREFIX']) 49 dest.close() 50 return 0
51
52 -def read_la_file(path):
53 sp = re.compile(r'^([^=]+)=\'(.*)\'$') 54 dc={} 55 file = open(path, "r") 56 for line in file.readlines(): 57 try: 58 #print sp.split(line.strip()) 59 _, left, right, _ = sp.split(line.strip()) 60 dc[left]=right 61 except ValueError: 62 pass 63 file.close() 64 return dc
65 79
80 @taskgen 81 @feature("libtool") 82 @before('apply_core') 83 -def apply_libtool(self):
84 self.env['vnum']=self.vnum 85 86 paths=[] 87 libs=[] 88 libtool_files=[] 89 libtool_vars=[] 90 91 for l in self.env['LINKFLAGS']: 92 if l[:2]=='-L': 93 paths.append(l[2:]) 94 elif l[:2]=='-l': 95 libs.append(l[2:]) 96 97 for l in libs: 98 for p in paths: 99 dict = read_la_file(p+'/lib'+l+'.la') 100 linkflags2 = dict.get('dependency_libs', '') 101 for v in linkflags2.split(): 102 if v.endswith('.la'): 103 libtool_files.append(v) 104 libtool_vars.append(v) 105 continue 106 self.env.append_unique('LINKFLAGS', v) 107 break 108 109 self.env['libtoolvars']=libtool_vars 110 111 while libtool_files: 112 file = libtool_files.pop() 113 dict = read_la_file(file) 114 for v in dict['dependency_libs'].split(): 115 if v[-3:] == '.la': 116 libtool_files.append(v) 117 continue 118 self.env.append_unique('LINKFLAGS', v)
119 120 Task.task_type_from_func('fakelibtool', vars=fakelibtool_vardeps, func=fakelibtool_build, color='BLUE', after="cc_link cxx_link ar_link_static")
121 122 -class libtool_la_file:
123 - def __init__ (self, la_filename):
124 self.__la_filename = la_filename 125 #remove path and .la suffix 126 self.linkname = str(os.path.split(la_filename)[-1])[:-3] 127 if self.linkname.startswith("lib"): 128 self.linkname = self.linkname[3:] 129 # The name that we can dlopen(3). 130 self.dlname = None 131 # Names of this library 132 self.library_names = None 133 # The name of the static archive. 134 self.old_library = None 135 # Libraries that this one depends upon. 136 self.dependency_libs = None 137 # Version information for libIlmImf. 138 self.current = None 139 self.age = None 140 self.revision = None 141 # Is this an already installed library? 142 self.installed = None 143 # Should we warn about portability when linking against -modules? 144 self.shouldnotlink = None 145 # Files to dlopen/dlpreopen 146 self.dlopen = None 147 self.dlpreopen = None 148 # Directory that this library needs to be installed in: 149 self.libdir = '/usr/lib' 150 if not self.__parse(): 151 raise "file %s not found!!" %(la_filename)
152
153 - def __parse(self):
154 "Retrieve the variables from a file" 155 if not os.path.isfile(self.__la_filename): return 0 156 la_file=open(self.__la_filename, 'r') 157 for line in la_file: 158 ln = line.strip() 159 if not ln: continue 160 if ln[0]=='#': continue 161 (key, value) = str(ln).split('=', 1) 162 key = key.strip() 163 value = value.strip() 164 if value == "no": value = False 165 elif value == "yes": value = True 166 else: 167 try: value = int(value) 168 except ValueError: value = value.strip("'") 169 setattr(self, key, value) 170 la_file.close() 171 return 1
172
173 - def get_libs(self):
174 """return linkflags for this lib""" 175 libs = [] 176 if self.dependency_libs: 177 libs = str(self.dependency_libs).strip().split() 178 if libs == None: 179 libs = [] 180 # add la lib and libdir 181 libs.insert(0, "-l%s" % self.linkname.strip()) 182 libs.insert(0, "-L%s" % self.libdir.strip()) 183 return libs
184
185 - def __str__(self):
186 return '''\ 187 dlname = "%(dlname)s" 188 library_names = "%(library_names)s" 189 old_library = "%(old_library)s" 190 dependency_libs = "%(dependency_libs)s" 191 version = %(current)s.%(age)s.%(revision)s 192 installed = "%(installed)s" 193 shouldnotlink = "%(shouldnotlink)s" 194 dlopen = "%(dlopen)s" 195 dlpreopen = "%(dlpreopen)s" 196 libdir = "%(libdir)s"''' % self.__dict__
197
198 -class libtool_config:
199 - def __init__ (self, la_filename):
200 self.__libtool_la_file = libtool_la_file(la_filename) 201 tmp = self.__libtool_la_file 202 self.__version = [int(tmp.current), int(tmp.age), int(tmp.revision)] 203 self.__sub_la_files = [] 204 self.__sub_la_files.append(la_filename) 205 self.__libs = None
206
207 - def __cmp__(self, other):
208 """make it compareable with X.Y.Z versions (Y and Z are optional)""" 209 if not other: 210 return 1 211 othervers = [int(s) for s in str(other).split(".")] 212 selfvers = self.__version 213 return cmp(selfvers, othervers)
214
215 - def __str__(self):
216 return "\n".join([ 217 str(self.__libtool_la_file), 218 ' '.join(self.__libtool_la_file.get_libs()), 219 '* New getlibs:', 220 ' '.join(self.get_libs()) 221 ])
222
223 - def __get_la_libs(self, la_filename):
224 return libtool_la_file(la_filename).get_libs()
225
226 - def get_libs(self):
227 """return the complete uniqe linkflags that do not 228 contain .la files anymore""" 229 libs_list = list(self.__libtool_la_file.get_libs()) 230 libs_map = {} 231 while len(libs_list) > 0: 232 entry = libs_list.pop(0) 233 if entry: 234 if str(entry).endswith(".la"): 235 ## prevents duplicate .la checks 236 if entry not in self.__sub_la_files: 237 self.__sub_la_files.append(entry) 238 libs_list.extend(self.__get_la_libs(entry)) 239 else: 240 libs_map[entry]=1 241 self.__libs = libs_map.keys() 242 return self.__libs
243
244 - def get_libs_only_L(self):
245 if not self.__libs: self.get_libs() 246 libs = self.__libs 247 libs = filter(lambda s: str(s).startswith('-L'), libs) 248 return libs
249
250 - def get_libs_only_l(self):
251 if not self.__libs: self.get_libs() 252 libs = self.__libs 253 libs = filter(lambda s: str(s).startswith('-l'), libs) 254 return libs
255
256 - def get_libs_only_other(self):
257 if not self.__libs: self.get_libs() 258 libs = self.__libs 259 libs = filter(lambda s: not (str(s).startswith('-L') or str(s).startswith('-l')), libs) 260 return libs
261
262 -def useCmdLine():
263 """parse cmdline args and control build""" 264 usage = '''Usage: %prog [options] PathToFile.la 265 example: %prog --atleast-version=2.0.0 /usr/lib/libIlmImf.la 266 nor: %prog --libs /usr/lib/libamarok.la''' 267 parser = optparse.OptionParser(usage) 268 a = parser.add_option 269 a("--version", dest = "versionNumber", 270 action = "store_true", default = False, 271 help = "output version of libtool-config" 272 ) 273 a("--debug", dest = "debug", 274 action = "store_true", default = False, 275 help = "enable debug" 276 ) 277 a("--libs", dest = "libs", 278 action = "store_true", default = False, 279 help = "output all linker flags" 280 ) 281 a("--libs-only-l", dest = "libs_only_l", 282 action = "store_true", default = False, 283 help = "output -l flags" 284 ) 285 a("--libs-only-L", dest = "libs_only_L", 286 action = "store_true", default = False, 287 help = "output -L flags" 288 ) 289 a("--libs-only-other", dest = "libs_only_other", 290 action = "store_true", default = False, 291 help = "output other libs (e.g. -pthread)" 292 ) 293 a("--atleast-version", dest = "atleast_version", 294 default=None, 295 help = "return 0 if the module is at least version ATLEAST_VERSION" 296 ) 297 a("--exact-version", dest = "exact_version", 298 default=None, 299 help = "return 0 if the module is exactly version EXACT_VERSION" 300 ) 301 a("--max-version", dest = "max_version", 302 default=None, 303 help = "return 0 if the module is at no newer than version MAX_VERSION" 304 ) 305 306 (options, args) = parser.parse_args() 307 if len(args) != 1 and not options.versionNumber: 308 parser.error("incorrect number of arguments") 309 if options.versionNumber: 310 print "libtool-config version %s" % REVISION 311 return 0 312 ltf = libtool_config(args[0]) 313 if options.debug: 314 print(ltf) 315 if options.atleast_version: 316 if ltf >= options.atleast_version: return 0 317 sys.exit(1) 318 if options.exact_version: 319 if ltf == options.exact_version: return 0 320 sys.exit(1) 321 if options.max_version: 322 if ltf <= options.max_version: return 0 323 sys.exit(1) 324 325 def p(x): 326 print " ".join(x)
327 if options.libs: p(ltf.get_libs()) 328 elif options.libs_only_l: p(ltf.get_libs_only_l()) 329 elif options.libs_only_L: p(ltf.get_libs_only_L()) 330 elif options.libs_only_other: p(ltf.get_libs_only_other()) 331 return 0 332 333 if __name__ == '__main__': 334 useCmdLine() 335