jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
5.5KB

  1. #!/usr/bin/env python
  2. # encoding: utf-8
  3. # daniel.svensson at purplescout.se 2008
  4. # Thomas Nagy 2010 (ita)
  5. """
  6. Support for Ruby extensions. A C/C++ compiler is required::
  7. def options(opt):
  8. opt.load('compiler_c ruby')
  9. def configure(conf):
  10. conf.load('compiler_c ruby')
  11. conf.check_ruby_version((1,8,0))
  12. conf.check_ruby_ext_devel()
  13. conf.check_ruby_module('libxml')
  14. def build(bld):
  15. bld(
  16. features = 'c cshlib rubyext',
  17. source = 'rb_mytest.c',
  18. target = 'mytest_ext',
  19. install_path = '${ARCHDIR_RUBY}')
  20. bld.install_files('${LIBDIR_RUBY}', 'Mytest.rb')
  21. """
  22. import os
  23. from waflib import Task, Options, Utils
  24. from waflib.TaskGen import before_method, feature, after_method, Task, extension
  25. from waflib.Configure import conf
  26. @feature('rubyext')
  27. @before_method('apply_incpaths', 'apply_lib_vars', 'apply_bundle', 'apply_link')
  28. def init_rubyext(self):
  29. """
  30. Add required variables for ruby extensions
  31. """
  32. self.install_path = '${ARCHDIR_RUBY}'
  33. self.uselib = self.to_list(getattr(self, 'uselib', ''))
  34. if not 'RUBY' in self.uselib:
  35. self.uselib.append('RUBY')
  36. if not 'RUBYEXT' in self.uselib:
  37. self.uselib.append('RUBYEXT')
  38. @feature('rubyext')
  39. @before_method('apply_link', 'propagate_uselib')
  40. def apply_ruby_so_name(self):
  41. """
  42. Strip the *lib* prefix from ruby extensions
  43. """
  44. self.env['cshlib_PATTERN'] = self.env['cxxshlib_PATTERN'] = self.env['rubyext_PATTERN']
  45. @conf
  46. def check_ruby_version(self, minver=()):
  47. """
  48. Checks if ruby is installed.
  49. If installed the variable RUBY will be set in environment.
  50. The ruby binary can be overridden by ``--with-ruby-binary`` command-line option.
  51. """
  52. if Options.options.rubybinary:
  53. self.env.RUBY = Options.options.rubybinary
  54. else:
  55. self.find_program('ruby', var='RUBY')
  56. ruby = self.env.RUBY
  57. try:
  58. version = self.cmd_and_log(ruby + ['-e', 'puts defined?(VERSION) ? VERSION : RUBY_VERSION']).strip()
  59. except Exception:
  60. self.fatal('could not determine ruby version')
  61. self.env.RUBY_VERSION = version
  62. try:
  63. ver = tuple(map(int, version.split(".")))
  64. except Exception:
  65. self.fatal('unsupported ruby version %r' % version)
  66. cver = ''
  67. if minver:
  68. if ver < minver:
  69. self.fatal('ruby is too old %r' % ver)
  70. cver = '.'.join([str(x) for x in minver])
  71. else:
  72. cver = ver
  73. self.msg('Checking for ruby version %s' % str(minver or ''), cver)
  74. @conf
  75. def check_ruby_ext_devel(self):
  76. """
  77. Check if a ruby extension can be created
  78. """
  79. if not self.env.RUBY:
  80. self.fatal('ruby detection is required first')
  81. if not self.env.CC_NAME and not self.env.CXX_NAME:
  82. self.fatal('load a c/c++ compiler first')
  83. version = tuple(map(int, self.env.RUBY_VERSION.split(".")))
  84. def read_out(cmd):
  85. return Utils.to_list(self.cmd_and_log(self.env.RUBY + ['-rrbconfig', '-e', cmd]))
  86. def read_config(key):
  87. return read_out('puts RbConfig::CONFIG[%r]' % key)
  88. ruby = self.env['RUBY']
  89. archdir = read_config('archdir')
  90. cpppath = archdir
  91. if version >= (1, 9, 0):
  92. ruby_hdrdir = read_config('rubyhdrdir')
  93. cpppath += ruby_hdrdir
  94. cpppath += [os.path.join(ruby_hdrdir[0], read_config('arch')[0])]
  95. self.check(header_name='ruby.h', includes=cpppath, errmsg='could not find ruby header file')
  96. self.env.LIBPATH_RUBYEXT = read_config('libdir')
  97. self.env.LIBPATH_RUBYEXT += archdir
  98. self.env.INCLUDES_RUBYEXT = cpppath
  99. self.env.CFLAGS_RUBYEXT = read_config('CCDLFLAGS')
  100. self.env.rubyext_PATTERN = '%s.' + read_config('DLEXT')[0]
  101. # ok this is really stupid, but the command and flags are combined.
  102. # so we try to find the first argument...
  103. flags = read_config('LDSHARED')
  104. while flags and flags[0][0] != '-':
  105. flags = flags[1:]
  106. # we also want to strip out the deprecated ppc flags
  107. if len(flags) > 1 and flags[1] == "ppc":
  108. flags = flags[2:]
  109. self.env.LINKFLAGS_RUBYEXT = flags
  110. self.env.LINKFLAGS_RUBYEXT += read_config('LIBS')
  111. self.env.LINKFLAGS_RUBYEXT += read_config('LIBRUBYARG_SHARED')
  112. if Options.options.rubyarchdir:
  113. self.env.ARCHDIR_RUBY = Options.options.rubyarchdir
  114. else:
  115. self.env.ARCHDIR_RUBY = read_config('sitearchdir')[0]
  116. if Options.options.rubylibdir:
  117. self.env.LIBDIR_RUBY = Options.options.rubylibdir
  118. else:
  119. self.env.LIBDIR_RUBY = read_config('sitelibdir')[0]
  120. @conf
  121. def check_ruby_module(self, module_name):
  122. """
  123. Check if the selected ruby interpreter can require the given ruby module::
  124. def configure(conf):
  125. conf.check_ruby_module('libxml')
  126. :param module_name: module
  127. :type module_name: string
  128. """
  129. self.start_msg('Ruby module %s' % module_name)
  130. try:
  131. self.cmd_and_log(self.env.RUBY + ['-e', 'require \'%s\';puts 1' % module_name])
  132. except Exception:
  133. self.end_msg(False)
  134. self.fatal('Could not find the ruby module %r' % module_name)
  135. self.end_msg(True)
  136. @extension('.rb')
  137. def process(self, node):
  138. tsk = self.create_task('run_ruby', node)
  139. class run_ruby(Task.Task):
  140. """
  141. Task to run ruby files detected by file extension .rb::
  142. def options(opt):
  143. opt.load('ruby')
  144. def configure(ctx):
  145. ctx.check_ruby_version()
  146. def build(bld):
  147. bld.env['RBFLAGS'] = '-e puts "hello world"'
  148. bld(source='a_ruby_file.rb')
  149. """
  150. run_str = '${RUBY} ${RBFLAGS} -I ${SRC[0].parent.abspath()} ${SRC}'
  151. def options(opt):
  152. """
  153. Add the ``--with-ruby-archdir``, ``--with-ruby-libdir`` and ``--with-ruby-binary`` options
  154. """
  155. opt.add_option('--with-ruby-archdir', type='string', dest='rubyarchdir', help='Specify directory where to install arch specific files')
  156. opt.add_option('--with-ruby-libdir', type='string', dest='rubylibdir', help='Specify alternate ruby library path')
  157. opt.add_option('--with-ruby-binary', type='string', dest='rubybinary', help='Specify alternate ruby binary')