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