cfg_altoptions.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. # Tool to extend c_config.check_cfg()
  4. __author__ = __maintainer__ = "Jérôme Carretero <cJ-waf@zougloub.eu>"
  5. __copyright__ = "Jérôme Carretero, 2014"
  6. """
  7. This tool allows to work around the absence of ``*-config`` programs
  8. on systems, by keeping the same clean configuration syntax but inferring
  9. values or permitting their modification via the options interface.
  10. Note that pkg-config can also support setting ``PKG_CONFIG_PATH``,
  11. so you can put custom files in a folder containing new .pc files.
  12. This tool could also be implemented by taking advantage of this fact.
  13. Usage::
  14. def options(opt):
  15. opt.load('c_config_alt')
  16. opt.add_package_option('package')
  17. def configure(cfg):
  18. conf.load('c_config_alt')
  19. conf.check_cfg(...)
  20. Known issues:
  21. - Behavior with different build contexts...
  22. """
  23. import os
  24. import functools
  25. from waflib import Configure, Options, Errors
  26. def name_to_dest(x):
  27. return x.lower().replace('-', '_')
  28. def options(opt):
  29. def x(opt, param):
  30. dest = name_to_dest(param)
  31. gr = opt.get_option_group("configure options")
  32. gr.add_option('--%s-root' % dest,
  33. help="path containing include and lib subfolders for %s" \
  34. % param,
  35. )
  36. opt.add_package_option = functools.partial(x, opt)
  37. check_cfg_old = getattr(Configure.ConfigurationContext, 'check_cfg')
  38. @Configure.conf
  39. def check_cfg(conf, *k, **kw):
  40. if k:
  41. lst = k[0].split()
  42. kw['package'] = lst[0]
  43. kw['args'] = ' '.join(lst[1:])
  44. if not 'package' in kw:
  45. return check_cfg_old(conf, **kw)
  46. package = kw['package']
  47. package_lo = name_to_dest(package)
  48. package_hi = package.upper().replace('-', '_') # TODO FIXME
  49. package_hi = kw.get('uselib_store', package_hi)
  50. def check_folder(path, name):
  51. try:
  52. assert os.path.isdir(path)
  53. except AssertionError:
  54. raise Errors.ConfigurationError(
  55. "%s_%s (%s) is not a folder!" \
  56. % (package_lo, name, path))
  57. return path
  58. root = getattr(Options.options, '%s_root' % package_lo, None)
  59. if root is None:
  60. return check_cfg_old(conf, **kw)
  61. else:
  62. def add_manual_var(k, v):
  63. conf.start_msg('Adding for %s a manual var' % (package))
  64. conf.env["%s_%s" % (k, package_hi)] = v
  65. conf.end_msg("%s = %s" % (k, v))
  66. check_folder(root, 'root')
  67. pkg_inc = check_folder(os.path.join(root, "include"), 'inc')
  68. add_manual_var('INCLUDES', [pkg_inc])
  69. pkg_lib = check_folder(os.path.join(root, "lib"), 'libpath')
  70. add_manual_var('LIBPATH', [pkg_lib])
  71. add_manual_var('LIB', [package])
  72. for x in kw.get('manual_deps', []):
  73. for k, v in sorted(conf.env.get_merged_dict().items()):
  74. if k.endswith('_%s' % x):
  75. k = k.replace('_%s' % x, '')
  76. conf.start_msg('Adding for %s a manual dep' \
  77. %(package))
  78. conf.env["%s_%s" % (k, package_hi)] += v
  79. conf.end_msg('%s += %s' % (k, v))
  80. return True