softlink_libs.py 2.3 KB

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