1#! /usr/bin/env python 2# per rosengren 2011 3 4from waflib.TaskGen import feature, after_method 5from waflib.Task import Task, always_run 6from os.path import basename, isabs 7from os import tmpfile, linesep 8 9def options(opt): 10 grp = opt.add_option_group('Softlink Libraries Options') 11 grp.add_option('--exclude', default='/usr/lib,/lib', help='No symbolic links are created for libs within [%default]') 12 13def configure(cnf): 14 cnf.find_program('ldd') 15 if not cnf.env.SOFTLINK_EXCLUDE: 16 cnf.env.SOFTLINK_EXCLUDE = cnf.options.exclude.split(',') 17 18@feature('softlink_libs') 19@after_method('process_rule') 20def add_finder(self): 21 tgt = self.path.find_or_declare(self.target) 22 self.create_task('sll_finder', tgt=tgt) 23 self.create_task('sll_installer', tgt=tgt) 24 always_run(sll_installer) 25 26class sll_finder(Task): 27 ext_out = 'softlink_libs' 28 def run(self): 29 bld = self.generator.bld 30 linked=[] 31 target_paths = [] 32 for g in bld.groups: 33 for tgen in g: 34 # FIXME it might be better to check if there is a link_task (getattr?) 35 target_paths += [tgen.path.get_bld().bldpath()] 36 linked += [t.outputs[0].bldpath() 37 for t in getattr(tgen, 'tasks', []) 38 if t.__class__.__name__ in 39 ['cprogram', 'cshlib', 'cxxprogram', 'cxxshlib']] 40 lib_list = [] 41 if len(linked): 42 cmd = [self.env.LDD] + linked 43 # FIXME add DYLD_LIBRARY_PATH+PATH for osx+win32 44 ldd_env = {'LD_LIBRARY_PATH': ':'.join(target_paths + self.env.LIBPATH)} 45 # FIXME the with syntax will not work in python 2 46 with tmpfile() as result: 47 self.exec_command(cmd, env=ldd_env, stdout=result) 48 result.seek(0) 49 for line in result.readlines(): 50 words = line.split() 51 if len(words) < 3 or words[1] != '=>': 52 continue 53 lib = words[2] 54 if lib == 'not': 55 continue 56 if any([lib.startswith(p) for p in 57 [bld.bldnode.abspath(), '('] + 58 self.env.SOFTLINK_EXCLUDE]): 59 continue 60 if not isabs(lib): 61 continue 62 lib_list.append(lib) 63 lib_list = sorted(set(lib_list)) 64 self.outputs[0].write(linesep.join(lib_list + self.env.DYNAMIC_LIBS)) 65 return 0 66 67class sll_installer(Task): 68 ext_in = 'softlink_libs' 69 def run(self): 70 tgt = self.outputs[0] 71 self.generator.bld.install_files('${LIBDIR}', tgt, postpone=False) 72 lib_list=tgt.read().split() 73 for lib in lib_list: 74 self.generator.bld.symlink_as('${LIBDIR}/'+basename(lib), lib, postpone=False) 75 return 0 76 77