rubysl-mkmf 1.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4c4f5efc11b2edf183b785fe82a7ef7771979815
4
- data.tar.gz: 08d9fc19efe61a666083e85ea94ccd2f9e41f49a
3
+ metadata.gz: 9a3cec3459dba8709d26961f5bfd14b1200ea666
4
+ data.tar.gz: 140f79d5b37aeaeff68cdeee470c6212716e5cbd
5
5
  SHA512:
6
- metadata.gz: c8fdb4ecc6cc1c2c111289f08ecd36bd86ca14c4dd260ef32c4b537e7912fdd521ebc596f18082f64c3762291d5b80db5c3285b42049b385788ea48e2f286f13
7
- data.tar.gz: e5f6d761f5ff65e8490ec2add707d220bfb7f9da89e492b59ebc44eed96dfc7058085253cffaca3d98b3a3f48e4b9fd7b1ce90f398f3d9c01eccbbd5885b956c
6
+ metadata.gz: de622c4cb95dcb2e39d2c5af458dc15fc84afd04d6aaf2c79ab3bcc20f3700f04222eb886b77f7c94b4a520a3796333c29f8e44954e6920cef915cfebf87d0ef
7
+ data.tar.gz: e0f5b03b5227f440ddc9a61fb8ff5d74030b699e5b49686d42cd0b78ebf984ffcaa592e5eabb2cd8adbbf9153faf35b938a3ec859fcd7a1774c4fb9c83439b2e
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ env:
3
+ - RUBYLIB=lib
4
+ script: bundle exec mspec spec
5
+ rvm:
6
+ - rbx-nightly-19mode
@@ -1,3 +1,4 @@
1
+ # -*- coding: us-ascii -*-
1
2
  # module to create Makefile for extension modules
2
3
  # invoke like: ruby -r mkmf extconf.rb
3
4
 
@@ -5,1848 +6,2541 @@ require 'rbconfig'
5
6
  require 'fileutils'
6
7
  require 'shellwords'
7
8
 
8
- CONFIG = RbConfig::MAKEFILE_CONFIG
9
- ORIG_LIBPATH = ENV['LIB']
9
+ # :stopdoc:
10
+ class String
11
+ # Wraps a string in escaped quotes if it contains whitespace.
12
+ def quote
13
+ /\s/ =~ self ? "\"#{self}\"" : "#{self}"
14
+ end
10
15
 
11
- CXX_EXT = %w[cc cxx cpp]
12
- if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os']
13
- CXX_EXT.concat(%w[C])
14
- end
15
- SRC_EXT = %w[c m].concat(CXX_EXT)
16
- $static = $config_h = nil
17
- $default_static = $static
18
-
19
- unless defined? $configure_args
20
- $configure_args = {}
21
- args = CONFIG["configure_args"]
22
- if ENV["CONFIGURE_ARGS"]
23
- args << " " << ENV["CONFIGURE_ARGS"]
24
- end
25
- for arg in Shellwords::shellwords(args)
26
- arg, val = arg.split('=', 2)
27
- next unless arg
28
- arg.tr!('_', '-')
29
- if arg.sub!(/^(?!--)/, '--')
30
- val or next
31
- arg.downcase!
32
- end
33
- next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
34
- $configure_args[arg] = val || true
35
- end
36
- for arg in ARGV
37
- arg, val = arg.split('=', 2)
38
- next unless arg
39
- arg.tr!('_', '-')
40
- if arg.sub!(/^(?!--)/, '--')
41
- val or next
42
- arg.downcase!
43
- end
44
- $configure_args[arg] = val || true
16
+ # Escape whitespaces for Makefile.
17
+ def unspace
18
+ gsub(/\s/, '\\\\\\&')
45
19
  end
46
- end
47
20
 
48
- $libdir = CONFIG["libdir"]
49
- $rubylibdir = CONFIG["rubylibdir"]
50
- $archdir = CONFIG["archdir"]
51
- $sitedir = CONFIG["sitedir"]
52
- $sitelibdir = CONFIG["sitelibdir"]
53
- $sitearchdir = CONFIG["sitearchdir"]
54
- $vendordir = CONFIG["vendordir"]
55
- $vendorlibdir = CONFIG["vendorlibdir"]
56
- $vendorarchdir = CONFIG["vendorarchdir"]
57
-
58
- $mswin = /mswin/ =~ RUBY_PLATFORM
59
- $bccwin = /bccwin/ =~ RUBY_PLATFORM
60
- $mingw = /mingw/ =~ RUBY_PLATFORM
61
- $cygwin = /cygwin/ =~ RUBY_PLATFORM
62
- $human = /human/ =~ RUBY_PLATFORM
63
- $netbsd = /netbsd/ =~ RUBY_PLATFORM
64
- $os2 = /os2/ =~ RUBY_PLATFORM
65
- $beos = /beos/ =~ RUBY_PLATFORM
66
- $solaris = /solaris/ =~ RUBY_PLATFORM
67
- $dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
21
+ # Generates a string used as cpp macro name.
22
+ def tr_cpp
23
+ strip.upcase.tr_s("^A-Z0-9_*", "_").tr_s("*", "P")
24
+ end
68
25
 
69
- # :stopdoc:
26
+ def funcall_style
27
+ /\)\z/ =~ self ? dup : "#{self}()"
28
+ end
70
29
 
71
- def config_string(key, config = CONFIG)
72
- s = config[key] and !s.empty? and block_given? ? yield(s) : s
30
+ def sans_arguments
31
+ self[/\A[^()]+/]
32
+ end
73
33
  end
74
34
 
75
- def dir_re(dir)
76
- Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
35
+ class Array
36
+ # Wraps all strings in escaped quotes if they contain whitespace.
37
+ def quote
38
+ map {|s| s.quote}
39
+ end
77
40
  end
41
+ # :startdoc:
78
42
 
79
- INSTALL_DIRS = [
80
- [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
81
- [dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
82
- [dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
83
- [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
84
- [dir_re('archdir'), "$(RUBYARCHDIR)"],
85
- [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
86
- [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
87
- [dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
88
- [dir_re('bindir'), "$(BINDIR)"],
89
- [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
90
- ]
91
-
92
- def install_dirs(target_prefix = nil)
93
- if $extout
94
- dirs = [
95
- ['BINDIR', '$(extout)/bin'],
96
- ['RUBYCOMMONDIR', '$(extout)/common'],
97
- ['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'],
98
- ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'],
99
- ['extout', "#$extout"],
100
- ['extout_prefix', "#$extout_prefix"],
101
- ]
102
- elsif $extmk
103
- dirs = [
104
- ['BINDIR', '$(bindir)'],
105
- ['RUBYCOMMONDIR', '$(rubylibdir)'],
106
- ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'],
107
- ['RUBYARCHDIR', '$(archdir)$(target_prefix)'],
108
- ]
109
- elsif $configure_args.has_key?('--vendor')
110
- dirs = [
111
- ['BINDIR', '$(bindir)'],
112
- ['RUBYCOMMONDIR', '$(vendordir)$(target_prefix)'],
113
- ['RUBYLIBDIR', '$(vendorlibdir)$(target_prefix)'],
114
- ['RUBYARCHDIR', '$(vendorarchdir)$(target_prefix)'],
115
- ]
116
- else
117
- dirs = [
118
- ['BINDIR', '$(bindir)'],
119
- ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
120
- ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'],
121
- ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'],
122
- ]
123
- end
124
- dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
125
- dirs
126
- end
43
+ ##
44
+ # mkmf.rb is used by ruby C extensions to generate a Makefile which will
45
+ # correctly compile and link the C extension to ruby and a third-party
46
+ # library.
47
+ module MakeMakefile
127
48
 
128
- def map_dir(dir, map = nil)
129
- map ||= INSTALL_DIRS
130
- map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}
131
- end
49
+ ##
50
+ # The makefile configuration using the defaults from when ruby was built.
132
51
 
133
- # ---------------------- Changed for Rubinius --------------------------------
134
- if dir = ENV['RBX_CAPI_DIR']
135
- $topdir = "#{dir}/vm/capi/18/include"
136
- else
137
- $topdir = RbConfig::CONFIG["rubyhdrdir"]
138
- end
52
+ CONFIG = RbConfig::MAKEFILE_CONFIG
53
+ ORIG_LIBPATH = ENV['LIB']
139
54
 
140
- $top_srcdir = $topdir
141
- $hdrdir = $topdir
55
+ ##
56
+ # Extensions for files compiled with a C compiler
142
57
 
143
- unless File.exists?($hdrdir + "/ruby.h")
144
- abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
145
- end
146
- # ----------------------------------------------------------------------------
58
+ C_EXT = %w[c m]
147
59
 
148
- OUTFLAG = CONFIG['OUTFLAG']
149
- CPPOUTFILE = CONFIG['CPPOUTFILE']
60
+ ##
61
+ # Extensions for files complied with a C++ compiler
150
62
 
151
- CONFTEST_C = "conftest.c"
63
+ CXX_EXT = %w[cc mm cxx cpp]
64
+ if File::FNM_SYSCASE.zero?
65
+ CXX_EXT.concat(%w[C])
66
+ end
152
67
 
153
- class String
154
- # Wraps a string in escaped quotes if it contains whitespace.
155
- def quote
156
- /\s/ =~ self ? "\"#{self}\"" : "#{self}"
68
+ ##
69
+ # Extensions for source files
70
+
71
+ SRC_EXT = C_EXT + CXX_EXT
72
+
73
+ ##
74
+ # Extensions for header files
75
+
76
+ HDR_EXT = %w[h hpp]
77
+ $static = nil
78
+ $config_h = '$(arch_hdrdir)/ruby/config.h'
79
+ $default_static = $static
80
+
81
+ unless defined? $configure_args
82
+ $configure_args = {}
83
+ args = CONFIG["configure_args"]
84
+ if ENV["CONFIGURE_ARGS"]
85
+ args << " " << ENV["CONFIGURE_ARGS"]
86
+ end
87
+ for arg in Shellwords::shellwords(args)
88
+ arg, val = arg.split('=', 2)
89
+ next unless arg
90
+ arg.tr!('_', '-')
91
+ if arg.sub!(/^(?!--)/, '--')
92
+ val or next
93
+ arg.downcase!
94
+ end
95
+ next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
96
+ $configure_args[arg] = val || true
97
+ end
98
+ for arg in ARGV
99
+ arg, val = arg.split('=', 2)
100
+ next unless arg
101
+ arg.tr!('_', '-')
102
+ if arg.sub!(/^(?!--)/, '--')
103
+ val or next
104
+ arg.downcase!
105
+ end
106
+ $configure_args[arg] = val || true
107
+ end
157
108
  end
158
109
 
159
- # Generates a string used as cpp macro name.
160
- def tr_cpp
161
- strip.upcase.tr_s("^A-Z0-9_", "_")
110
+ $libdir = CONFIG["libdir"]
111
+ $rubylibdir = CONFIG["rubylibdir"]
112
+ $archdir = CONFIG["archdir"]
113
+ $sitedir = CONFIG["sitedir"]
114
+ $sitelibdir = CONFIG["sitelibdir"]
115
+ $sitearchdir = CONFIG["sitearchdir"]
116
+ $vendordir = CONFIG["vendordir"]
117
+ $vendorlibdir = CONFIG["vendorlibdir"]
118
+ $vendorarchdir = CONFIG["vendorarchdir"]
119
+
120
+ $mswin = /mswin/ =~ RUBY_PLATFORM
121
+ $bccwin = /bccwin/ =~ RUBY_PLATFORM
122
+ $mingw = /mingw/ =~ RUBY_PLATFORM
123
+ $cygwin = /cygwin/ =~ RUBY_PLATFORM
124
+ $netbsd = /netbsd/ =~ RUBY_PLATFORM
125
+ $os2 = /os2/ =~ RUBY_PLATFORM
126
+ $beos = /beos/ =~ RUBY_PLATFORM
127
+ $haiku = /haiku/ =~ RUBY_PLATFORM
128
+ $solaris = /solaris/ =~ RUBY_PLATFORM
129
+ $universal = /universal/ =~ RUBY_PLATFORM
130
+ $dest_prefix_pattern = (File::PATH_SEPARATOR == ';' ? /\A([[:alpha:]]:)?/ : /\A/)
131
+
132
+ # :stopdoc:
133
+
134
+ def config_string(key, config = CONFIG)
135
+ s = config[key] and !s.empty? and block_given? ? yield(s) : s
162
136
  end
163
- end
164
- class Array
165
- # Wraps all strings in escaped quotes if they contain whitespace.
166
- def quote
167
- map {|s| s.quote}
137
+ module_function :config_string
138
+
139
+ def dir_re(dir)
140
+ Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
168
141
  end
169
- end
142
+ module_function :dir_re
170
143
 
171
- def rm_f(*files)
172
- FileUtils.rm_f(Dir[files.join("\0")])
173
- end
144
+ def relative_from(path, base)
145
+ dir = File.join(path, "")
146
+ if File.expand_path(dir) == File.expand_path(dir, base)
147
+ path
148
+ else
149
+ File.join(base, path)
150
+ end
151
+ end
174
152
 
175
- # Returns time stamp of the +target+ file if it exists and is newer
176
- # than or equal to all of +times+.
177
- def modified?(target, times)
178
- (t = File.mtime(target)) rescue return nil
179
- Array === times or times = [times]
180
- t if times.all? {|n| n <= t}
181
- end
153
+ INSTALL_DIRS = [
154
+ [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
155
+ [dir_re('sitedir'), "$(RUBYCOMMONDIR)"],
156
+ [dir_re('vendordir'), "$(RUBYCOMMONDIR)"],
157
+ [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
158
+ [dir_re('archdir'), "$(RUBYARCHDIR)"],
159
+ [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
160
+ [dir_re('vendorlibdir'), "$(RUBYLIBDIR)"],
161
+ [dir_re('sitearchdir'), "$(RUBYARCHDIR)"],
162
+ [dir_re('vendorarchdir'), "$(RUBYARCHDIR)"],
163
+ [dir_re('rubyhdrdir'), "$(RUBYHDRDIR)"],
164
+ [dir_re('sitehdrdir'), "$(SITEHDRDIR)"],
165
+ [dir_re('vendorhdrdir'), "$(VENDORHDRDIR)"],
166
+ [dir_re('bindir'), "$(BINDIR)"],
167
+ ]
168
+
169
+ def install_dirs(target_prefix = nil)
170
+ if $extout
171
+ dirs = [
172
+ ['BINDIR', '$(extout)/bin'],
173
+ ['RUBYCOMMONDIR', '$(extout)/common'],
174
+ ['RUBYLIBDIR', '$(RUBYCOMMONDIR)$(target_prefix)'],
175
+ ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'],
176
+ ['HDRDIR', '$(extout)/include/ruby$(target_prefix)'],
177
+ ['ARCHHDRDIR', '$(extout)/include/$(arch)/ruby$(target_prefix)'],
178
+ ['extout', "#$extout"],
179
+ ['extout_prefix', "#$extout_prefix"],
180
+ ]
181
+ elsif $extmk
182
+ dirs = [
183
+ ['BINDIR', '$(bindir)'],
184
+ ['RUBYCOMMONDIR', '$(rubylibdir)'],
185
+ ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'],
186
+ ['RUBYARCHDIR', '$(archdir)$(target_prefix)'],
187
+ ['HDRDIR', '$(rubyhdrdir)/ruby$(target_prefix)'],
188
+ ['ARCHHDRDIR', '$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
189
+ ]
190
+ elsif $configure_args.has_key?('--vendor')
191
+ dirs = [
192
+ ['BINDIR', '$(DESTDIR)$(bindir)'],
193
+ ['RUBYCOMMONDIR', '$(DESTDIR)$(vendordir)$(target_prefix)'],
194
+ ['RUBYLIBDIR', '$(DESTDIR)$(vendorlibdir)$(target_prefix)'],
195
+ ['RUBYARCHDIR', '$(DESTDIR)$(vendorarchdir)$(target_prefix)'],
196
+ ['HDRDIR', '$(DESTDIR)$(rubyhdrdir)/ruby$(target_prefix)'],
197
+ ['ARCHHDRDIR', '$(DESTDIR)$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
198
+ ]
199
+ else
200
+ dirs = [
201
+ ['BINDIR', '$(DESTDIR)$(bindir)'],
202
+ ['RUBYCOMMONDIR', '$(DESTDIR)$(sitedir)$(target_prefix)'],
203
+ ['RUBYLIBDIR', '$(DESTDIR)$(sitelibdir)$(target_prefix)'],
204
+ ['RUBYARCHDIR', '$(DESTDIR)$(sitearchdir)$(target_prefix)'],
205
+ ['HDRDIR', '$(DESTDIR)$(rubyhdrdir)/ruby$(target_prefix)'],
206
+ ['ARCHHDRDIR', '$(DESTDIR)$(rubyhdrdir)/$(arch)/ruby$(target_prefix)'],
207
+ ]
208
+ end
209
+ dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
210
+ dirs
211
+ end
182
212
 
183
- def merge_libs(*libs)
184
- libs.inject([]) do |x, y|
185
- xy = x & y
186
- xn = yn = 0
187
- y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
188
- y.each_with_index do |v, yi|
189
- if xy.include?(v)
190
- xi = [x.index(v), xn].max()
191
- x[xi, 1] = y[yn..yi]
192
- xn, yn = xi + (yi - yn + 1), yi + 1
193
- end
213
+ def map_dir(dir, map = nil)
214
+ map ||= INSTALL_DIRS
215
+ map.inject(dir) {|d, (orig, new)| d.gsub(orig, new)}
216
+ end
217
+
218
+ topdir = File.dirname(File.dirname(__FILE__))
219
+ path = File.expand_path($0)
220
+ until (dir = File.dirname(path)) == path
221
+ if File.identical?(dir, topdir)
222
+ $extmk = true if %r"\A(?:ext|enc|tool|test)\z" =~ File.basename(path)
223
+ break
194
224
  end
195
- x.concat(y[yn..-1] || [])
225
+ path = dir
226
+ end
227
+ $extmk ||= false
228
+ if not $extmk and File.exist?(($hdrdir = RbConfig::CONFIG["rubyhdrdir"]) + "/ruby/ruby.h")
229
+ $topdir = $hdrdir
230
+ $top_srcdir = $hdrdir
231
+ $arch_hdrdir = RbConfig::CONFIG["rubyarchhdrdir"]
232
+ elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir) + "/include") + "/ruby.h")
233
+ $topdir ||= RbConfig::CONFIG["topdir"]
234
+ $arch_hdrdir = "$(extout)/include/$(arch)"
235
+ else
236
+ abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
196
237
  end
197
- end
198
238
 
199
- # This is a custom logging module. It generates an mkmf.log file when you
200
- # run your extconf.rb script. This can be useful for debugging unexpected
201
- # failures.
202
- #
203
- # This module and its associated methods are meant for internal use only.
204
- #
205
- module Logging
206
- @log = nil
207
- @logfile = 'mkmf.log'
208
- @orgerr = $stderr.dup
209
- @orgout = $stdout.dup
210
- @postpone = 0
211
- @quiet = $extmk
212
-
213
- def self::open
214
- @log ||= File::open(@logfile, 'w')
215
- @log.sync = true
216
- $stderr.reopen(@log)
217
- $stdout.reopen(@log)
218
- yield
219
- ensure
220
- $stderr.reopen(@orgerr)
221
- $stdout.reopen(@orgout)
239
+ OUTFLAG = CONFIG['OUTFLAG']
240
+ COUTFLAG = CONFIG['COUTFLAG']
241
+ CPPOUTFILE = CONFIG['CPPOUTFILE']
242
+
243
+ CONFTEST_C = "conftest.c".freeze
244
+
245
+ def rm_f(*files)
246
+ opt = (Hash === files.last ? [files.pop] : [])
247
+ FileUtils.rm_f(Dir[*files.flatten], *opt)
248
+ end
249
+ module_function :rm_f
250
+
251
+ def rm_rf(*files)
252
+ opt = (Hash === files.last ? [files.pop] : [])
253
+ FileUtils.rm_rf(Dir[*files.flatten], *opt)
254
+ end
255
+ module_function :rm_rf
256
+
257
+ # Returns time stamp of the +target+ file if it exists and is newer than or
258
+ # equal to all of +times+.
259
+ def modified?(target, times)
260
+ (t = File.mtime(target)) rescue return nil
261
+ Array === times or times = [times]
262
+ t if times.all? {|n| n <= t}
222
263
  end
223
264
 
224
- def self::message(*s)
225
- @log ||= File::open(@logfile, 'w')
226
- @log.sync = true
227
- @log.printf(*s)
265
+ def split_libs(*strs)
266
+ strs.map {|s| s.split(/\s+(?=-|\z)/)}.flatten
228
267
  end
229
268
 
230
- def self::logfile file
231
- @logfile = file
232
- if @log and not @log.closed?
233
- @log.flush
234
- @log.close
235
- @log = nil
269
+ def merge_libs(*libs)
270
+ libs.inject([]) do |x, y|
271
+ y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
272
+ y.each_with_index do |v, yi|
273
+ if xi = x.rindex(v)
274
+ x[(xi+1)..-1] = merge_libs(y[(yi+1)..-1], x[(xi+1)..-1])
275
+ x[xi, 0] = y[0...yi]
276
+ break
277
+ end
278
+ end and x.concat(y)
279
+ x
236
280
  end
237
281
  end
238
-
239
- def self::postpone
240
- tmplog = "mkmftmp#{@postpone += 1}.log"
241
- open do
242
- log, *save = @log, @logfile, @orgout, @orgerr
243
- @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
244
- begin
245
- log.print(open {yield})
282
+
283
+ # This is a custom logging module. It generates an mkmf.log file when you
284
+ # run your extconf.rb script. This can be useful for debugging unexpected
285
+ # failures.
286
+ #
287
+ # This module and its associated methods are meant for internal use only.
288
+ #
289
+ module Logging
290
+ @log = nil
291
+ @logfile = 'mkmf.log'
292
+ @orgerr = $stderr.dup
293
+ @orgout = $stdout.dup
294
+ @postpone = 0
295
+ @quiet = $extmk
296
+
297
+ def self::log_open
298
+ @log ||= File::open(@logfile, 'wb')
299
+ @log.sync = true
300
+ end
301
+
302
+ def self::open
303
+ log_open
304
+ $stderr.reopen(@log)
305
+ $stdout.reopen(@log)
306
+ yield
307
+ ensure
308
+ $stderr.reopen(@orgerr)
309
+ $stdout.reopen(@orgout)
310
+ end
311
+
312
+ def self::message(*s)
313
+ log_open
314
+ @log.printf(*s)
315
+ end
316
+
317
+ def self::logfile file
318
+ @logfile = file
319
+ log_close
320
+ end
321
+
322
+ def self::log_close
323
+ if @log and not @log.closed?
324
+ @log.flush
246
325
  @log.close
247
- File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
248
- ensure
249
- @log, @logfile, @orgout, @orgerr = log, *save
250
- @postpone -= 1
251
- rm_f tmplog
326
+ @log = nil
252
327
  end
253
328
  end
254
- end
255
329
 
256
- class << self
257
- attr_accessor :quiet
258
- end
259
- end
330
+ def self::postpone
331
+ tmplog = "mkmftmp#{@postpone += 1}.log"
332
+ open do
333
+ log, *save = @log, @logfile, @orgout, @orgerr
334
+ @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
335
+ begin
336
+ log.print(open {yield @log})
337
+ ensure
338
+ @log.close if @log and not @log.closed?
339
+ File::open(tmplog) {|t| FileUtils.copy_stream(t, log)} if File.exist?(tmplog)
340
+ @log, @logfile, @orgout, @orgerr = log, *save
341
+ @postpone -= 1
342
+ MakeMakefile.rm_f tmplog
343
+ end
344
+ end
345
+ end
260
346
 
261
- def xsystem command
262
- varpat = /\$\((\w+)\)|\$\{(\w+)\}/
263
- if varpat =~ command
264
- vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
265
- command = command.dup
266
- nil while command.gsub!(varpat) {vars[$1||$2]}
347
+ class << self
348
+ attr_accessor :quiet
349
+ end
267
350
  end
268
- Logging::open do
269
- puts command.quote
270
- system(command)
351
+
352
+ def xsystem command, opts = nil
353
+ varpat = /\$\((\w+)\)|\$\{(\w+)\}/
354
+ if varpat =~ command
355
+ vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
356
+ command = command.dup
357
+ nil while command.gsub!(varpat) {vars[$1||$2]}
358
+ end
359
+ Logging::open do
360
+ puts command.quote
361
+ if opts and opts[:werror]
362
+ result = nil
363
+ Logging.postpone do |log|
364
+ result = (system(command) and File.zero?(log.path))
365
+ ""
366
+ end
367
+ result
368
+ else
369
+ system(command)
370
+ end
371
+ end
271
372
  end
272
- end
273
373
 
274
- def xpopen command, *mode, &block
275
- Logging::open do
276
- case mode[0]
277
- when nil, /^r/
278
- puts "#{command} |"
279
- else
280
- puts "| #{command}"
374
+ def xpopen command, *mode, &block
375
+ Logging::open do
376
+ case mode[0]
377
+ when nil, /^r/
378
+ puts "#{command} |"
379
+ else
380
+ puts "| #{command}"
381
+ end
382
+ IO.popen(command, *mode, &block)
281
383
  end
282
- IO.popen(command, *mode, &block)
283
384
  end
284
- end
285
385
 
286
- def log_src(src)
287
- src = src.split(/^/)
288
- fmt = "%#{src.size.to_s.size}d: %s"
289
- Logging::message <<"EOM"
290
- checked program was:
386
+ def log_src(src, heading="checked program was")
387
+ src = src.split(/^/)
388
+ fmt = "%#{src.size.to_s.size}d: %s"
389
+ Logging::message <<"EOM"
390
+ #{heading}:
291
391
  /* begin */
292
392
  EOM
293
- src.each_with_index {|line, no| Logging::message fmt, no+1, line}
294
- Logging::message <<"EOM"
393
+ src.each_with_index {|line, no| Logging::message fmt, no+1, line}
394
+ Logging::message <<"EOM"
295
395
  /* end */
296
396
 
297
397
  EOM
298
- end
398
+ end
299
399
 
300
- def create_tmpsrc(src)
301
- src = yield(src) if block_given?
302
- src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n")
303
- open(CONFTEST_C, "wb") do |cfile|
304
- cfile.print src
400
+ def create_tmpsrc(src)
401
+ src = "#{COMMON_HEADERS}\n#{src}"
402
+ src = yield(src) if block_given?
403
+ src.gsub!(/[ \t]+$/, '')
404
+ src.gsub!(/\A\n+|^\n+$/, '')
405
+ src.sub!(/[^\n]\z/, "\\&\n")
406
+ count = 0
407
+ begin
408
+ open(CONFTEST_C, "wb") do |cfile|
409
+ cfile.print src
410
+ end
411
+ rescue Errno::EACCES
412
+ if (count += 1) < 5
413
+ sleep 0.2
414
+ retry
415
+ end
416
+ end
417
+ src
305
418
  end
306
- src
307
- end
308
419
 
309
- def try_do(src, command, &b)
310
- src = create_tmpsrc(src, &b)
311
- xsystem(command)
312
- ensure
313
- log_src(src)
314
- end
420
+ def have_devel?
421
+ unless defined? $have_devel
422
+ $have_devel = true
423
+ $have_devel = try_link(MAIN_DOES_NOTHING)
424
+ end
425
+ $have_devel
426
+ end
315
427
 
316
- def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
317
- conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
318
- 'src' => CONFTEST_C,
319
- 'INCFLAGS' => $INCFLAGS,
320
- 'CPPFLAGS' => $CPPFLAGS,
321
- 'CFLAGS' => "#$CFLAGS",
322
- 'ARCH_FLAG' => "#$ARCH_FLAG",
323
- 'LDFLAGS' => "#$LDFLAGS #{ldflags}",
324
- 'LIBPATH' => libpathflag(libpath),
325
- 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
326
- 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS")
327
- RbConfig::expand(TRY_LINK.dup, conf)
328
- end
428
+ def try_do(src, command, *opts, &b)
429
+ unless have_devel?
430
+ raise <<MSG
431
+ The compiler failed to generate an executable file.
432
+ You have to install development tools first.
433
+ MSG
434
+ end
435
+ begin
436
+ src = create_tmpsrc(src, &b)
437
+ xsystem(command, *opts)
438
+ ensure
439
+ log_src(src)
440
+ MakeMakefile.rm_rf 'conftest.dSYM'
441
+ end
442
+ end
329
443
 
330
- def cc_command(opt="")
331
- conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
332
- RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
333
- conf)
334
- end
444
+ def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
445
+ librubyarg = $extmk ? $LIBRUBYARG_STATIC : "$(LIBRUBYARG)"
446
+ conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote,
447
+ 'src' => "#{CONFTEST_C}",
448
+ 'arch_hdrdir' => $arch_hdrdir.quote,
449
+ 'top_srcdir' => $top_srcdir.quote,
450
+ 'INCFLAGS' => "#$INCFLAGS",
451
+ 'CPPFLAGS' => "#$CPPFLAGS",
452
+ 'CFLAGS' => "#$CFLAGS",
453
+ 'ARCH_FLAG' => "#$ARCH_FLAG",
454
+ 'LDFLAGS' => "#$LDFLAGS #{ldflags}",
455
+ 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
456
+ 'LIBS' => "#{librubyarg} #{opt} #$LIBS")
457
+ conf['LIBPATH'] = libpathflag(libpath.map {|s| RbConfig::expand(s.dup, conf)})
458
+ RbConfig::expand(TRY_LINK.dup, conf)
459
+ end
460
+
461
+ def cc_command(opt="")
462
+ conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
463
+ 'arch_hdrdir' => $arch_hdrdir.quote,
464
+ 'top_srcdir' => $top_srcdir.quote)
465
+ RbConfig::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
466
+ conf)
467
+ end
468
+
469
+ def cpp_command(outfile, opt="")
470
+ conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
471
+ 'arch_hdrdir' => $arch_hdrdir.quote,
472
+ 'top_srcdir' => $top_srcdir.quote)
473
+ if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
474
+ conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
475
+ end
476
+ RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
477
+ conf)
478
+ end
335
479
 
336
- def cpp_command(outfile, opt="")
337
- conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
338
- RbConfig::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
339
- conf)
340
- end
480
+ def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
481
+ libpath.map{|x|
482
+ case x
483
+ when "$(topdir)", /\A\./
484
+ LIBPATHFLAG
485
+ else
486
+ LIBPATHFLAG+RPATHFLAG
487
+ end % x.quote
488
+ }.join
489
+ end
341
490
 
342
- def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
343
- libpath.map{|x|
344
- case x
345
- when "$(topdir)", /\A\./
346
- LIBPATHFLAG
491
+ def with_werror(opt, opts = nil)
492
+ if opts
493
+ if opts[:werror] and config_string("WERRORFLAG") {|flag| opt = opt ? "#{opt} #{flag}" : flag}
494
+ (opts = opts.dup).delete(:werror)
495
+ end
496
+ yield(opt, opts)
347
497
  else
348
- LIBPATHFLAG+RPATHFLAG
349
- end % x.quote
350
- }.join
351
- end
498
+ yield(opt)
499
+ end
500
+ end
352
501
 
353
- def try_link0(src, opt="", &b)
354
- try_do(src, link_command("", opt), &b)
355
- end
502
+ def try_link0(src, opt="", *opts, &b) # :nodoc:
503
+ cmd = link_command("", opt)
504
+ if $universal
505
+ require 'tmpdir'
506
+ Dir.mktmpdir("mkmf_", oldtmpdir = ENV["TMPDIR"]) do |tmpdir|
507
+ begin
508
+ ENV["TMPDIR"] = tmpdir
509
+ try_do(src, cmd, *opts, &b)
510
+ ensure
511
+ ENV["TMPDIR"] = oldtmpdir
512
+ end
513
+ end
514
+ else
515
+ try_do(src, cmd, *opts, &b)
516
+ end and File.executable?("conftest#{$EXEEXT}")
517
+ end
518
+
519
+ # Returns whether or not the +src+ can be compiled as a C source and linked
520
+ # with its depending libraries successfully. +opt+ is passed to the linker
521
+ # as options. Note that +$CFLAGS+ and +$LDFLAGS+ are also passed to the
522
+ # linker.
523
+ #
524
+ # If a block given, it is called with the source before compilation. You can
525
+ # modify the source in the block.
526
+ #
527
+ # [+src+] a String which contains a C source
528
+ # [+opt+] a String which contains linker options
529
+ def try_link(src, opt="", *opts, &b)
530
+ try_link0(src, opt, *opts, &b)
531
+ ensure
532
+ MakeMakefile.rm_f "conftest*", "c0x32*"
533
+ end
534
+
535
+ # Returns whether or not the +src+ can be compiled as a C source. +opt+ is
536
+ # passed to the C compiler as options. Note that +$CFLAGS+ is also passed to
537
+ # the compiler.
538
+ #
539
+ # If a block given, it is called with the source before compilation. You can
540
+ # modify the source in the block.
541
+ #
542
+ # [+src+] a String which contains a C source
543
+ # [+opt+] a String which contains compiler options
544
+ def try_compile(src, opt="", *opts, &b)
545
+ with_werror(opt, *opts) {|_opt, *_opts| try_do(src, cc_command(_opt), *_opts, &b)} and
546
+ File.file?("conftest.#{$OBJEXT}")
547
+ ensure
548
+ MakeMakefile.rm_f "conftest*"
549
+ end
550
+
551
+ # Returns whether or not the +src+ can be preprocessed with the C
552
+ # preprocessor. +opt+ is passed to the preprocessor as options. Note that
553
+ # +$CFLAGS+ is also passed to the preprocessor.
554
+ #
555
+ # If a block given, it is called with the source before preprocessing. You
556
+ # can modify the source in the block.
557
+ #
558
+ # [+src+] a String which contains a C source
559
+ # [+opt+] a String which contains preprocessor options
560
+ def try_cpp(src, opt="", *opts, &b)
561
+ try_do(src, cpp_command(CPPOUTFILE, opt), *opts, &b) and
562
+ File.file?("conftest.i")
563
+ ensure
564
+ MakeMakefile.rm_f "conftest*"
565
+ end
356
566
 
357
- def try_link(src, opt="", &b)
358
- try_link0(src, opt, &b)
359
- ensure
360
- rm_f "conftest*", "c0x32*"
361
- end
567
+ alias_method :try_header, (config_string('try_header') || :try_cpp)
362
568
 
363
- def try_compile(src, opt="", &b)
364
- try_do(src, cc_command(opt), &b)
365
- ensure
366
- rm_f "conftest*"
367
- end
569
+ def cpp_include(header)
570
+ if header
571
+ header = [header] unless header.kind_of? Array
572
+ header.map {|h| String === h ? "#include <#{h}>\n" : h}.join
573
+ else
574
+ ""
575
+ end
576
+ end
368
577
 
369
- def try_cpp(src, opt="", &b)
370
- try_do(src, cpp_command(CPPOUTFILE, opt), &b)
371
- ensure
372
- rm_f "conftest*"
373
- end
578
+ def with_cppflags(flags)
579
+ cppflags = $CPPFLAGS
580
+ $CPPFLAGS = flags
581
+ ret = yield
582
+ ensure
583
+ $CPPFLAGS = cppflags unless ret
584
+ end
374
585
 
375
- def cpp_include(header)
376
- if header
377
- header = [header] unless header.kind_of? Array
378
- header.map {|h| "#include <#{h}>\n"}.join
379
- else
380
- ""
586
+ def try_cppflags(flags)
587
+ with_cppflags(flags) do
588
+ try_header("int main() {return 0;}")
589
+ end
381
590
  end
382
- end
383
591
 
384
- def with_cppflags(flags)
385
- cppflags = $CPPFLAGS
386
- $CPPFLAGS = flags
387
- ret = yield
388
- ensure
389
- $CPPFLAGS = cppflags unless ret
390
- end
592
+ def with_cflags(flags)
593
+ cflags = $CFLAGS
594
+ $CFLAGS = flags
595
+ ret = yield
596
+ ensure
597
+ $CFLAGS = cflags unless ret
598
+ end
391
599
 
392
- def with_cflags(flags)
393
- cflags = $CFLAGS
394
- $CFLAGS = flags
395
- ret = yield
396
- ensure
397
- $CFLAGS = cflags unless ret
398
- end
600
+ def try_cflags(flags)
601
+ with_cflags(flags) do
602
+ try_compile("int main() {return 0;}")
603
+ end
604
+ end
399
605
 
400
- def with_ldflags(flags)
401
- ldflags = $LDFLAGS
402
- $LDFLAGS = flags
403
- ret = yield
404
- ensure
405
- $LDFLAGS = ldflags unless ret
406
- end
606
+ def with_ldflags(flags)
607
+ ldflags = $LDFLAGS
608
+ $LDFLAGS = flags
609
+ ret = yield
610
+ ensure
611
+ $LDFLAGS = ldflags unless ret
612
+ end
407
613
 
408
- def try_static_assert(expr, headers = nil, opt = "", &b)
409
- headers = cpp_include(headers)
410
- try_compile(<<SRC, opt, &b)
411
- #{COMMON_HEADERS}
614
+ def try_ldflags(flags)
615
+ with_ldflags(flags) do
616
+ try_link("int main() {return 0;}")
617
+ end
618
+ end
619
+
620
+ def try_static_assert(expr, headers = nil, opt = "", &b)
621
+ headers = cpp_include(headers)
622
+ try_compile(<<SRC, opt, &b)
412
623
  #{headers}
413
624
  /*top*/
414
625
  int conftest_const[(#{expr}) ? 1 : -1];
415
626
  SRC
416
- end
627
+ end
417
628
 
418
- def try_constant(const, headers = nil, opt = "", &b)
419
- includes = cpp_include(headers)
420
- if CROSS_COMPILING
421
- if try_static_assert("#{const} > 0", headers, opt)
422
- # positive constant
423
- elsif try_static_assert("#{const} < 0", headers, opt)
424
- neg = true
425
- const = "-(#{const})"
426
- elsif try_static_assert("#{const} == 0", headers, opt)
427
- return 0
428
- else
429
- # not a constant
430
- return nil
431
- end
432
- upper = 1
433
- lower = 0
434
- until try_static_assert("#{const} <= #{upper}", headers, opt)
435
- lower = upper
436
- upper <<= 1
437
- end
438
- return nil unless lower
439
- while upper > lower + 1
440
- mid = (upper + lower) / 2
441
- if try_static_assert("#{const} > #{mid}", headers, opt)
442
- lower = mid
629
+ def try_constant(const, headers = nil, opt = "", &b)
630
+ includes = cpp_include(headers)
631
+ neg = try_static_assert("#{const} < 0", headers, opt)
632
+ if CROSS_COMPILING
633
+ if neg
634
+ const = "-(#{const})"
635
+ elsif try_static_assert("#{const} > 0", headers, opt)
636
+ # positive constant
637
+ elsif try_static_assert("#{const} == 0", headers, opt)
638
+ return 0
443
639
  else
444
- upper = mid
640
+ # not a constant
641
+ return nil
445
642
  end
446
- end
447
- upper = -upper if neg
448
- return upper
449
- else
450
- src = %{#{COMMON_HEADERS}
451
- #{includes}
643
+ upper = 1
644
+ lower = 0
645
+ until try_static_assert("#{const} <= #{upper}", headers, opt)
646
+ lower = upper
647
+ upper <<= 1
648
+ end
649
+ return nil unless lower
650
+ while upper > lower + 1
651
+ mid = (upper + lower) / 2
652
+ if try_static_assert("#{const} > #{mid}", headers, opt)
653
+ lower = mid
654
+ else
655
+ upper = mid
656
+ end
657
+ end
658
+ upper = -upper if neg
659
+ return upper
660
+ else
661
+ src = %{#{includes}
452
662
  #include <stdio.h>
453
663
  /*top*/
454
- int conftest_const = (int)(#{const});
455
- int main() {printf("%d\\n", conftest_const); return 0;}
664
+ typedef#{neg ? '' : ' unsigned'}
665
+ #ifdef PRI_LL_PREFIX
666
+ #define PRI_CONFTEST_PREFIX PRI_LL_PREFIX
667
+ LONG_LONG
668
+ #else
669
+ #define PRI_CONFTEST_PREFIX "l"
670
+ long
671
+ #endif
672
+ conftest_type;
673
+ conftest_type conftest_const = (conftest_type)(#{const});
674
+ int main() {printf("%"PRI_CONFTEST_PREFIX"#{neg ? 'd' : 'u'}\\n", conftest_const); return 0;}
456
675
  }
457
- if try_link0(src, opt, &b)
458
- xpopen("./conftest") do |f|
459
- return Integer(f.gets)
676
+ begin
677
+ if try_link0(src, opt, &b)
678
+ xpopen("./conftest") do |f|
679
+ return Integer(f.gets)
680
+ end
681
+ end
682
+ ensure
683
+ MakeMakefile.rm_f "conftest*"
460
684
  end
461
685
  end
686
+ nil
462
687
  end
463
- nil
464
- end
465
688
 
466
- def try_func(func, libs, headers = nil, &b)
467
- headers = cpp_include(headers)
468
- try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b)
469
- #{COMMON_HEADERS}
689
+ # You should use +have_func+ rather than +try_func+.
690
+ #
691
+ # [+func+] a String which contains a symbol name
692
+ # [+libs+] a String which contains library names.
693
+ # [+headers+] a String or an Array of strings which contains names of header
694
+ # files.
695
+ def try_func(func, libs, headers = nil, opt = "", &b)
696
+ headers = cpp_include(headers)
697
+ case func
698
+ when /^&/
699
+ decltype = proc {|x|"const volatile void *#{x}"}
700
+ when /\)$/
701
+ call = func
702
+ else
703
+ call = "#{func}()"
704
+ decltype = proc {|x| "void ((*#{x})())"}
705
+ end
706
+ if opt and !opt.empty?
707
+ [[:to_str], [:join, " "], [:to_s]].each do |meth, *args|
708
+ if opt.respond_to?(meth)
709
+ break opt = opt.send(meth, *args)
710
+ end
711
+ end
712
+ opt = "#{opt} #{libs}"
713
+ else
714
+ opt = libs
715
+ end
716
+ decltype && try_link(<<"SRC", opt, &b) or
470
717
  #{headers}
471
718
  /*top*/
472
- int main() { return 0; }
473
- int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }
719
+ extern int t(void);
720
+ int t(void) { #{decltype["volatile p"]}; p = (#{decltype[]})#{func}; return 0; }
721
+ #{MAIN_DOES_NOTHING "t"}
474
722
  SRC
723
+ call && try_link(<<"SRC", opt, &b)
475
724
  #{headers}
476
725
  /*top*/
477
- int main() { return 0; }
478
- int t() { #{func}(); return 0; }
726
+ extern int t(void);
727
+ int t(void) { #{call}; return 0; }
728
+ #{MAIN_DOES_NOTHING "t"}
479
729
  SRC
480
- end
730
+ end
481
731
 
482
- def try_var(var, headers = nil, &b)
483
- headers = cpp_include(headers)
484
- try_compile(<<"SRC", &b)
485
- #{COMMON_HEADERS}
732
+ # You should use +have_var+ rather than +try_var+.
733
+ def try_var(var, headers = nil, opt = "", &b)
734
+ headers = cpp_include(headers)
735
+ try_compile(<<"SRC", opt, &b)
486
736
  #{headers}
487
737
  /*top*/
488
- int main() { return 0; }
489
- int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
738
+ extern int t(void);
739
+ int t(void) { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
740
+ #{MAIN_DOES_NOTHING "t"}
490
741
  SRC
491
- end
742
+ end
492
743
 
493
- def egrep_cpp(pat, src, opt = "", &b)
494
- src = create_tmpsrc(src, &b)
495
- xpopen(cpp_command('', opt)) do |f|
496
- if Regexp === pat
497
- puts(" ruby -ne 'print if #{pat.inspect}'")
498
- f.grep(pat) {|l|
499
- puts "#{f.lineno}: #{l}"
500
- return true
501
- }
502
- false
503
- else
504
- puts(" egrep '#{pat}'")
505
- begin
506
- stdin = $stdin.dup
507
- $stdin.reopen(f)
508
- system("egrep", pat)
509
- ensure
510
- $stdin.reopen(stdin)
744
+ # Returns whether or not the +src+ can be preprocessed with the C
745
+ # preprocessor and matches with +pat+.
746
+ #
747
+ # If a block given, it is called with the source before compilation. You can
748
+ # modify the source in the block.
749
+ #
750
+ # [+pat+] a Regexp or a String
751
+ # [+src+] a String which contains a C source
752
+ # [+opt+] a String which contains preprocessor options
753
+ #
754
+ # NOTE: When pat is a Regexp the matching will be checked in process,
755
+ # otherwise egrep(1) will be invoked to check it.
756
+ def egrep_cpp(pat, src, opt = "", &b)
757
+ src = create_tmpsrc(src, &b)
758
+ xpopen(cpp_command('', opt)) do |f|
759
+ if Regexp === pat
760
+ puts(" ruby -ne 'print if #{pat.inspect}'")
761
+ f.grep(pat) {|l|
762
+ puts "#{f.lineno}: #{l}"
763
+ return true
764
+ }
765
+ false
766
+ else
767
+ puts(" egrep '#{pat}'")
768
+ begin
769
+ stdin = $stdin.dup
770
+ $stdin.reopen(f)
771
+ system("egrep", pat)
772
+ ensure
773
+ $stdin.reopen(stdin)
774
+ end
511
775
  end
512
776
  end
777
+ ensure
778
+ MakeMakefile.rm_f "conftest*"
779
+ log_src(src)
513
780
  end
514
- ensure
515
- rm_f "conftest*"
516
- log_src(src)
517
- end
518
781
 
519
- # This is used internally by the have_macro? method.
520
- def macro_defined?(macro, src, opt = "", &b)
521
- src = src.sub(/[^\n]\z/, "\\&\n")
522
- try_compile(src + <<"SRC", opt, &b)
782
+ # This is used internally by the have_macro? method.
783
+ def macro_defined?(macro, src, opt = "", &b)
784
+ src = src.sub(/[^\n]\z/, "\\&\n")
785
+ try_compile(src + <<"SRC", opt, &b)
523
786
  /*top*/
524
787
  #ifndef #{macro}
525
788
  # error
526
- >>>>>> #{macro} undefined <<<<<<
789
+ |:/ === #{macro} undefined === /:|
527
790
  #endif
528
791
  SRC
529
- end
530
-
531
- def try_run(src, opt = "", &b)
532
- if try_link0(src, opt, &b)
533
- xsystem("./conftest")
534
- else
535
- nil
536
792
  end
537
- ensure
538
- rm_f "conftest*"
539
- end
540
793
 
541
- def install_files(mfile, ifiles, map = nil, srcprefix = nil)
542
- ifiles or return
543
- ifiles.empty? and return
544
- srcprefix ||= '$(srcdir)'
545
- RbConfig::expand(srcdir = srcprefix.dup)
546
- dirs = []
547
- path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
548
- ifiles.each do |files, dir, prefix|
549
- dir = map_dir(dir, map)
550
- prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
551
- if /\A\.\// =~ files
552
- # install files which are in current working directory.
553
- files = files[2..-1]
554
- len = nil
794
+ # Returns whether or not:
795
+ # * the +src+ can be compiled as a C source,
796
+ # * the result object can be linked with its depending libraries
797
+ # successfully,
798
+ # * the linked file can be invoked as an executable
799
+ # * and the executable exits successfully
800
+ #
801
+ # +opt+ is passed to the linker as options. Note that +$CFLAGS+ and
802
+ # +$LDFLAGS+ are also passed to the linker.
803
+ #
804
+ # If a block given, it is called with the source before compilation. You can
805
+ # modify the source in the block.
806
+ #
807
+ # [+src+] a String which contains a C source
808
+ # [+opt+] a String which contains linker options
809
+ #
810
+ # Returns true when the executable exits successfully, false when it fails,
811
+ # or nil when preprocessing, compilation or link fails.
812
+ def try_run(src, opt = "", &b)
813
+ if try_link0(src, opt, &b)
814
+ xsystem("./conftest")
555
815
  else
556
- # install files which are under the $(srcdir).
557
- files = File.join(srcdir, files)
558
- len = srcdir.size
559
- end
560
- f = nil
561
- Dir.glob(files) do |f|
562
- f[0..len] = "" if len
563
- case File.basename(f)
564
- when *$NONINSTALLFILES
565
- next
566
- end
567
- d = File.dirname(f)
568
- d.sub!(prefix, "") if prefix
569
- d = (d.empty? || d == ".") ? dir : File.join(dir, d)
570
- f = File.join(srcprefix, f) if len
571
- path[d] << f
816
+ nil
572
817
  end
573
- unless len or f
574
- d = File.dirname(files)
575
- d.sub!(prefix, "") if prefix
576
- d = (d.empty? || d == ".") ? dir : File.join(dir, d)
577
- path[d] << files
818
+ ensure
819
+ MakeMakefile.rm_f "conftest*"
820
+ end
821
+
822
+ def install_files(mfile, ifiles, map = nil, srcprefix = nil)
823
+ ifiles or return
824
+ ifiles.empty? and return
825
+ srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
826
+ RbConfig::expand(srcdir = srcprefix.dup)
827
+ dirs = []
828
+ path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
829
+ ifiles.each do |files, dir, prefix|
830
+ dir = map_dir(dir, map)
831
+ prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
832
+ if /\A\.\// =~ files
833
+ # install files which are in current working directory.
834
+ files = files[2..-1]
835
+ len = nil
836
+ else
837
+ # install files which are under the $(srcdir).
838
+ files = File.join(srcdir, files)
839
+ len = srcdir.size
840
+ end
841
+ f = nil
842
+ Dir.glob(files) do |fx|
843
+ f = fx
844
+ f[0..len] = "" if len
845
+ case File.basename(f)
846
+ when *$NONINSTALLFILES
847
+ next
848
+ end
849
+ d = File.dirname(f)
850
+ d.sub!(prefix, "") if prefix
851
+ d = (d.empty? || d == ".") ? dir : File.join(dir, d)
852
+ f = File.join(srcprefix, f) if len
853
+ path[d] << f
854
+ end
855
+ unless len or f
856
+ d = File.dirname(files)
857
+ d.sub!(prefix, "") if prefix
858
+ d = (d.empty? || d == ".") ? dir : File.join(dir, d)
859
+ path[d] << files
860
+ end
578
861
  end
862
+ dirs
579
863
  end
580
- dirs
581
- end
582
864
 
583
- def install_rb(mfile, dest, srcdir = nil)
584
- install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
585
- end
865
+ def install_rb(mfile, dest, srcdir = nil)
866
+ install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
867
+ end
586
868
 
587
- def append_library(libs, lib) # :no-doc:
588
- format(LIBARG, lib) + " " + libs
589
- end
869
+ def append_library(libs, lib) # :no-doc:
870
+ format(LIBARG, lib) + " " + libs
871
+ end
590
872
 
591
- def message(*s)
592
- unless Logging.quiet and not $VERBOSE
593
- printf(*s)
594
- $stdout.flush
873
+ def message(*s)
874
+ unless Logging.quiet and not $VERBOSE
875
+ printf(*s)
876
+ $stdout.flush
877
+ end
595
878
  end
596
- end
597
879
 
598
- # This emits a string to stdout that allows users to see the results of the
599
- # various have* and find* methods as they are tested.
600
- #
601
- # Internal use only.
602
- #
603
- def checking_for(m, fmt = nil)
604
- f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim
605
- m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
606
- message "%s", m
607
- a = r = nil
608
- Logging::postpone do
609
- r = yield
610
- a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
611
- "#{f}#{m}-------------------- #{a}\n"
612
- end
613
- message(a)
614
- Logging::message "--------------------\n\n"
615
- r
616
- end
880
+ # This emits a string to stdout that allows users to see the results of the
881
+ # various have* and find* methods as they are tested.
882
+ #
883
+ # Internal use only.
884
+ #
885
+ def checking_for(m, fmt = nil)
886
+ f = caller[0][/in `([^<].*)'$/, 1] and f << ": " #` for vim #'
887
+ m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
888
+ message "%s", m
889
+ a = r = nil
890
+ Logging::postpone do
891
+ r = yield
892
+ a = (fmt ? "#{fmt % r}" : r ? "yes" : "no") << "\n"
893
+ "#{f}#{m}-------------------- #{a}\n"
894
+ end
895
+ message(a)
896
+ Logging::message "--------------------\n\n"
897
+ r
898
+ end
617
899
 
618
- def checking_message(target, place = nil, opt = nil)
619
- [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
620
- if noun
621
- [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
622
- if noun.respond_to?(meth)
623
- break noun = noun.send(meth, *args)
900
+ def checking_message(target, place = nil, opt = nil)
901
+ [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
902
+ if noun
903
+ [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
904
+ if noun.respond_to?(meth)
905
+ break noun = noun.send(meth, *args)
906
+ end
624
907
  end
908
+ msg << " #{pre} #{noun}" unless noun.empty?
625
909
  end
626
- msg << " #{pre} #{noun}" unless noun.empty?
910
+ msg
627
911
  end
628
- msg
629
912
  end
630
- end
631
913
 
632
- # :startdoc:
914
+ # :startdoc:
633
915
 
634
- # Returns whether or not +macro+ is defined either in the common header
635
- # files or within any +headers+ you provide.
636
- #
637
- # Any options you pass to +opt+ are passed along to the compiler.
638
- #
639
- def have_macro(macro, headers = nil, opt = "", &b)
640
- checking_for checking_message(macro, headers, opt) do
641
- macro_defined?(macro, cpp_include(headers), opt, &b)
916
+ # Returns whether or not +macro+ is defined either in the common header
917
+ # files or within any +headers+ you provide.
918
+ #
919
+ # Any options you pass to +opt+ are passed along to the compiler.
920
+ #
921
+ def have_macro(macro, headers = nil, opt = "", &b)
922
+ checking_for checking_message(macro, headers, opt) do
923
+ macro_defined?(macro, cpp_include(headers), opt, &b)
924
+ end
642
925
  end
643
- end
644
926
 
645
- # Returns whether or not the given entry point +func+ can be found within
646
- # +lib+. If +func+ is nil, the 'main()' entry point is used by default.
647
- # If found, it adds the library to list of libraries to be used when linking
648
- # your extension.
649
- #
650
- # If +headers+ are provided, it will include those header files as the
651
- # header files it looks in when searching for +func+.
652
- #
653
- # The real name of the library to be linked can be altered by
654
- # '--with-FOOlib' configuration option.
655
- #
656
- def have_library(lib, func = nil, headers = nil, &b)
657
- func = "main" if !func or func.empty?
658
- lib = with_config(lib+'lib', lib)
659
- checking_for checking_message("#{func}()", LIBARG%lib) do
660
- if COMMON_LIBS.include?(lib)
661
- true
662
- else
663
- libs = append_library($libs, lib)
664
- if try_func(func, libs, headers, &b)
665
- $libs = libs
927
+ # Returns whether or not the given entry point +func+ can be found within
928
+ # +lib+. If +func+ is +nil+, the <code>main()</code> entry point is used by
929
+ # default. If found, it adds the library to list of libraries to be used
930
+ # when linking your extension.
931
+ #
932
+ # If +headers+ are provided, it will include those header files as the
933
+ # header files it looks in when searching for +func+.
934
+ #
935
+ # The real name of the library to be linked can be altered by
936
+ # <code>--with-FOOlib</code> configuration option.
937
+ #
938
+ def have_library(lib, func = nil, headers = nil, opt = "", &b)
939
+ func = "main" if !func or func.empty?
940
+ lib = with_config(lib+'lib', lib)
941
+ checking_for checking_message(func.funcall_style, LIBARG%lib, opt) do
942
+ if COMMON_LIBS.include?(lib)
666
943
  true
667
944
  else
668
- false
945
+ libs = append_library($libs, lib)
946
+ if try_func(func, libs, headers, opt, &b)
947
+ $libs = libs
948
+ true
949
+ else
950
+ false
951
+ end
669
952
  end
670
953
  end
671
954
  end
672
- end
673
955
 
674
- # Returns whether or not the entry point +func+ can be found within the library
675
- # +lib+ in one of the +paths+ specified, where +paths+ is an array of strings.
676
- # If +func+ is nil , then the main() function is used as the entry point.
677
- #
678
- # If +lib+ is found, then the path it was found on is added to the list of
679
- # library paths searched and linked against.
680
- #
681
- def find_library(lib, func, *paths, &b)
682
- func = "main" if !func or func.empty?
683
- lib = with_config(lib+'lib', lib)
684
- paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
685
- checking_for "#{func}() in #{LIBARG%lib}" do
686
- libpath = $LIBPATH
687
- libs = append_library($libs, lib)
688
- begin
689
- until r = try_func(func, libs, &b) or paths.empty?
690
- $LIBPATH = libpath | [paths.shift]
956
+ # Returns whether or not the entry point +func+ can be found within the
957
+ # library +lib+ in one of the +paths+ specified, where +paths+ is an array
958
+ # of strings. If +func+ is +nil+ , then the <code>main()</code> function is
959
+ # used as the entry point.
960
+ #
961
+ # If +lib+ is found, then the path it was found on is added to the list of
962
+ # library paths searched and linked against.
963
+ #
964
+ def find_library(lib, func, *paths, &b)
965
+ func = "main" if !func or func.empty?
966
+ lib = with_config(lib+'lib', lib)
967
+ paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
968
+ checking_for checking_message(func.funcall_style, LIBARG%lib) do
969
+ libpath = $LIBPATH
970
+ libs = append_library($libs, lib)
971
+ begin
972
+ until r = try_func(func, libs, &b) or paths.empty?
973
+ $LIBPATH = libpath | [paths.shift]
974
+ end
975
+ if r
976
+ $libs = libs
977
+ libpath = nil
978
+ end
979
+ ensure
980
+ $LIBPATH = libpath if libpath
691
981
  end
692
- if r
693
- $libs = libs
694
- libpath = nil
982
+ r
983
+ end
984
+ end
985
+
986
+ # Returns whether or not the function +func+ can be found in the common
987
+ # header files, or within any +headers+ that you provide. If found, a macro
988
+ # is passed as a preprocessor constant to the compiler using the function
989
+ # name, in uppercase, prepended with +HAVE_+.
990
+ #
991
+ # To check functions in an additional library, you need to check that
992
+ # library first using <code>have_library()</code>. The +func+ shall be
993
+ # either mere function name or function name with arguments.
994
+ #
995
+ # For example, if <code>have_func('foo')</code> returned +true+, then the
996
+ # +HAVE_FOO+ preprocessor macro would be passed to the compiler.
997
+ #
998
+ def have_func(func, headers = nil, opt = "", &b)
999
+ checking_for checking_message(func.funcall_style, headers, opt) do
1000
+ if try_func(func, $libs, headers, opt, &b)
1001
+ $defs << "-DHAVE_#{func.sans_arguments.tr_cpp}"
1002
+ true
1003
+ else
1004
+ false
695
1005
  end
696
- ensure
697
- $LIBPATH = libpath if libpath
698
1006
  end
699
- r
700
1007
  end
701
- end
702
1008
 
703
- # Returns whether or not the function +func+ can be found in the common
704
- # header files, or within any +headers+ that you provide. If found, a
705
- # macro is passed as a preprocessor constant to the compiler using the
706
- # function name, in uppercase, prepended with 'HAVE_'.
707
- #
708
- # For example, if have_func('foo') returned true, then the HAVE_FOO
709
- # preprocessor macro would be passed to the compiler.
710
- #
711
- def have_func(func, headers = nil, &b)
712
- checking_for checking_message("#{func}()", headers) do
713
- if try_func(func, $libs, headers, &b)
714
- $defs.push(format("-DHAVE_%s", func.tr_cpp))
715
- true
716
- else
717
- false
1009
+ # Returns whether or not the variable +var+ can be found in the common
1010
+ # header files, or within any +headers+ that you provide. If found, a macro
1011
+ # is passed as a preprocessor constant to the compiler using the variable
1012
+ # name, in uppercase, prepended with +HAVE_+.
1013
+ #
1014
+ # To check variables in an additional library, you need to check that
1015
+ # library first using <code>have_library()</code>.
1016
+ #
1017
+ # For example, if <code>have_var('foo')</code> returned true, then the
1018
+ # +HAVE_FOO+ preprocessor macro would be passed to the compiler.
1019
+ #
1020
+ def have_var(var, headers = nil, opt = "", &b)
1021
+ checking_for checking_message(var, headers, opt) do
1022
+ if try_var(var, headers, opt, &b)
1023
+ $defs.push(format("-DHAVE_%s", var.tr_cpp))
1024
+ true
1025
+ else
1026
+ false
1027
+ end
718
1028
  end
719
1029
  end
720
- end
721
1030
 
722
- # Returns whether or not the variable +var+ can be found in the common
723
- # header files, or within any +headers+ that you provide. If found, a
724
- # macro is passed as a preprocessor constant to the compiler using the
725
- # variable name, in uppercase, prepended with 'HAVE_'.
726
- #
727
- # For example, if have_var('foo') returned true, then the HAVE_FOO
728
- # preprocessor macro would be passed to the compiler.
729
- #
730
- def have_var(var, headers = nil, &b)
731
- checking_for checking_message(var, headers) do
732
- if try_var(var, headers, &b)
733
- $defs.push(format("-DHAVE_%s", var.tr_cpp))
734
- true
735
- else
736
- false
1031
+ # Returns whether or not the given +header+ file can be found on your system.
1032
+ # If found, a macro is passed as a preprocessor constant to the compiler
1033
+ # using the header file name, in uppercase, prepended with +HAVE_+.
1034
+ #
1035
+ # For example, if <code>have_header('foo.h')</code> returned true, then the
1036
+ # +HAVE_FOO_H+ preprocessor macro would be passed to the compiler.
1037
+ #
1038
+ def have_header(header, preheaders = nil, opt = "", &b)
1039
+ checking_for header do
1040
+ if try_header(cpp_include(preheaders)+cpp_include(header), opt, &b)
1041
+ $defs.push(format("-DHAVE_%s", header.tr_cpp))
1042
+ true
1043
+ else
1044
+ false
1045
+ end
737
1046
  end
738
1047
  end
739
- end
740
1048
 
741
- # Returns whether or not the given +header+ file can be found on your system.
742
- # If found, a macro is passed as a preprocessor constant to the compiler using
743
- # the header file name, in uppercase, prepended with 'HAVE_'.
744
- #
745
- # For example, if have_header('foo.h') returned true, then the HAVE_FOO_H
746
- # preprocessor macro would be passed to the compiler.
747
- #
748
- def have_header(header, &b)
749
- checking_for header do
750
- if try_cpp(cpp_include(header), &b)
751
- $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
752
- true
753
- else
754
- false
1049
+ # Returns whether or not the given +framework+ can be found on your system.
1050
+ # If found, a macro is passed as a preprocessor constant to the compiler
1051
+ # using the framework name, in uppercase, prepended with +HAVE_FRAMEWORK_+.
1052
+ #
1053
+ # For example, if <code>have_framework('Ruby')</code> returned true, then
1054
+ # the +HAVE_FRAMEWORK_RUBY+ preprocessor macro would be passed to the
1055
+ # compiler.
1056
+ #
1057
+ def have_framework(fw, &b)
1058
+ checking_for fw do
1059
+ src = cpp_include("#{fw}/#{fw}.h") << "\n" "int main(void){return 0;}"
1060
+ opt = " -framework #{fw}"
1061
+ if try_link(src, "-ObjC#{opt}", &b)
1062
+ $defs.push(format("-DHAVE_FRAMEWORK_%s", fw.tr_cpp))
1063
+ # TODO: non-worse way than this hack, to get rid of separating
1064
+ # option and its argument.
1065
+ $LDFLAGS << " -ObjC" unless /(\A|\s)-ObjC(\s|\z)/ =~ $LDFLAGS
1066
+ $LDFLAGS << opt
1067
+ true
1068
+ else
1069
+ false
1070
+ end
755
1071
  end
756
1072
  end
757
- end
758
1073
 
759
- # Instructs mkmf to search for the given +header+ in any of the +paths+
760
- # provided, and returns whether or not it was found in those paths.
761
- #
762
- # If the header is found then the path it was found on is added to the list
763
- # of included directories that are sent to the compiler (via the -I switch).
764
- #
765
- def find_header(header, *paths)
766
- message = checking_message(header, paths)
767
- header = cpp_include(header)
768
- checking_for message do
769
- if try_cpp(header)
770
- true
771
- else
772
- found = false
773
- paths.each do |dir|
774
- opt = "-I#{dir}".quote
775
- if try_cpp(header, opt)
776
- $INCFLAGS << " " << opt
777
- found = true
778
- break
1074
+ # Instructs mkmf to search for the given +header+ in any of the +paths+
1075
+ # provided, and returns whether or not it was found in those paths.
1076
+ #
1077
+ # If the header is found then the path it was found on is added to the list
1078
+ # of included directories that are sent to the compiler (via the
1079
+ # <code>-I</code> switch).
1080
+ #
1081
+ def find_header(header, *paths)
1082
+ message = checking_message(header, paths)
1083
+ header = cpp_include(header)
1084
+ checking_for message do
1085
+ if try_header(header)
1086
+ true
1087
+ else
1088
+ found = false
1089
+ paths.each do |dir|
1090
+ opt = "-I#{dir}".quote
1091
+ if try_header(header, opt)
1092
+ $INCFLAGS << " " << opt
1093
+ found = true
1094
+ break
1095
+ end
779
1096
  end
1097
+ found
780
1098
  end
781
- found
782
1099
  end
783
1100
  end
784
- end
785
1101
 
786
- # Returns whether or not the struct of type +type+ contains +member+. If
787
- # it does not, or the struct type can't be found, then false is returned. You
788
- # may optionally specify additional +headers+ in which to look for the struct
789
- # (in addition to the common header files).
790
- #
791
- # If found, a macro is passed as a preprocessor constant to the compiler using
792
- # the member name, in uppercase, prepended with 'HAVE_ST_'.
793
- #
794
- # For example, if have_struct_member('struct foo', 'bar') returned true, then the
795
- # HAVE_ST_BAR preprocessor macro would be passed to the compiler.
796
- #
797
- def have_struct_member(type, member, headers = nil, &b)
798
- checking_for checking_message("#{type}.#{member}", headers) do
799
- if try_compile(<<"SRC", &b)
800
- #{COMMON_HEADERS}
1102
+ # Returns whether or not the struct of type +type+ contains +member+. If
1103
+ # it does not, or the struct type can't be found, then false is returned.
1104
+ # You may optionally specify additional +headers+ in which to look for the
1105
+ # struct (in addition to the common header files).
1106
+ #
1107
+ # If found, a macro is passed as a preprocessor constant to the compiler
1108
+ # using the type name and the member name, in uppercase, prepended with
1109
+ # +HAVE_+.
1110
+ #
1111
+ # For example, if <code>have_struct_member('struct foo', 'bar')</code>
1112
+ # returned true, then the +HAVE_STRUCT_FOO_BAR+ preprocessor macro would be
1113
+ # passed to the compiler.
1114
+ #
1115
+ # +HAVE_ST_BAR+ is also defined for backward compatibility.
1116
+ #
1117
+ def have_struct_member(type, member, headers = nil, opt = "", &b)
1118
+ checking_for checking_message("#{type}.#{member}", headers) do
1119
+ if try_compile(<<"SRC", opt, &b)
801
1120
  #{cpp_include(headers)}
802
1121
  /*top*/
803
- int main() { return 0; }
804
1122
  int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
1123
+ #{MAIN_DOES_NOTHING "s"}
805
1124
  SRC
806
- $defs.push(format("-DHAVE_ST_%s", member.tr_cpp))
807
- true
808
- else
809
- false
1125
+ $defs.push(format("-DHAVE_%s_%s", type.tr_cpp, member.tr_cpp))
1126
+ $defs.push(format("-DHAVE_ST_%s", member.tr_cpp)) # backward compatibility
1127
+ true
1128
+ else
1129
+ false
1130
+ end
810
1131
  end
811
1132
  end
812
- end
813
1133
 
814
- def try_type(type, headers = nil, opt = "", &b)
815
- if try_compile(<<"SRC", opt, &b)
816
- #{COMMON_HEADERS}
1134
+ # Returns whether or not the static type +type+ is defined.
1135
+ #
1136
+ # See also +have_type+
1137
+ #
1138
+ def try_type(type, headers = nil, opt = "", &b)
1139
+ if try_compile(<<"SRC", opt, &b)
817
1140
  #{cpp_include(headers)}
818
1141
  /*top*/
819
1142
  typedef #{type} conftest_type;
820
1143
  int conftestval[sizeof(conftest_type)?1:-1];
821
1144
  SRC
822
- $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
823
- true
824
- else
825
- false
1145
+ $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
1146
+ true
1147
+ else
1148
+ false
1149
+ end
826
1150
  end
827
- end
828
1151
 
829
- # Returns whether or not the static type +type+ is defined. You may
830
- # optionally pass additional +headers+ to check against in addition to the
831
- # common header files.
832
- #
833
- # You may also pass additional flags to +opt+ which are then passed along to
834
- # the compiler.
835
- #
836
- # If found, a macro is passed as a preprocessor constant to the compiler using
837
- # the type name, in uppercase, prepended with 'HAVE_TYPE_'.
838
- #
839
- # For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO
840
- # preprocessor macro would be passed to the compiler.
841
- #
842
- def have_type(type, headers = nil, opt = "", &b)
843
- checking_for checking_message(type, headers, opt) do
844
- try_type(type, headers, opt, &b)
1152
+ # Returns whether or not the static type +type+ is defined. You may
1153
+ # optionally pass additional +headers+ to check against in addition to the
1154
+ # common header files.
1155
+ #
1156
+ # You may also pass additional flags to +opt+ which are then passed along to
1157
+ # the compiler.
1158
+ #
1159
+ # If found, a macro is passed as a preprocessor constant to the compiler
1160
+ # using the type name, in uppercase, prepended with +HAVE_TYPE_+.
1161
+ #
1162
+ # For example, if <code>have_type('foo')</code> returned true, then the
1163
+ # +HAVE_TYPE_FOO+ preprocessor macro would be passed to the compiler.
1164
+ #
1165
+ def have_type(type, headers = nil, opt = "", &b)
1166
+ checking_for checking_message(type, headers, opt) do
1167
+ try_type(type, headers, opt, &b)
1168
+ end
845
1169
  end
846
- end
847
1170
 
848
- # Returns where the static type +type+ is defined.
849
- #
850
- # You may also pass additional flags to +opt+ which are then passed along to
851
- # the compiler.
852
- #
853
- # See also +have_type+.
854
- #
855
- def find_type(type, opt, *headers, &b)
856
- opt ||= ""
857
- fmt = "not found"
858
- def fmt.%(x)
859
- x ? x.respond_to?(:join) ? x.join(",") : x : self
860
- end
861
- checking_for checking_message(type, nil, opt), fmt do
862
- headers.find do |h|
863
- try_type(type, h, opt, &b)
1171
+ # Returns where the static type +type+ is defined.
1172
+ #
1173
+ # You may also pass additional flags to +opt+ which are then passed along to
1174
+ # the compiler.
1175
+ #
1176
+ # See also +have_type+.
1177
+ #
1178
+ def find_type(type, opt, *headers, &b)
1179
+ opt ||= ""
1180
+ fmt = "not found"
1181
+ def fmt.%(x)
1182
+ x ? x.respond_to?(:join) ? x.join(",") : x : self
1183
+ end
1184
+ checking_for checking_message(type, nil, opt), fmt do
1185
+ headers.find do |h|
1186
+ try_type(type, h, opt, &b)
1187
+ end
864
1188
  end
865
1189
  end
866
- end
867
1190
 
868
- def try_const(const, headers = nil, opt = "", &b)
869
- const, type = *const
870
- if try_compile(<<"SRC", opt, &b)
871
- #{COMMON_HEADERS}
1191
+ # Returns whether or not the constant +const+ is defined.
1192
+ #
1193
+ # See also +have_const+
1194
+ #
1195
+ def try_const(const, headers = nil, opt = "", &b)
1196
+ const, type = *const
1197
+ if try_compile(<<"SRC", opt, &b)
872
1198
  #{cpp_include(headers)}
873
1199
  /*top*/
874
1200
  typedef #{type || 'int'} conftest_type;
875
1201
  conftest_type conftestval = #{type ? '' : '(int)'}#{const};
876
1202
  SRC
877
- $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
878
- true
879
- else
880
- false
1203
+ $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
1204
+ true
1205
+ else
1206
+ false
1207
+ end
881
1208
  end
882
- end
883
1209
 
884
- # Returns whether or not the constant +const+ is defined. You may
885
- # optionally pass the +type+ of +const+ as <code>[const, type]</code>,
886
- # like as:
887
- #
888
- # have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
889
- #
890
- # You may also pass additional +headers+ to check against in addition
891
- # to the common header files, and additional flags to +opt+ which are
892
- # then passed along to the compiler.
893
- #
894
- # If found, a macro is passed as a preprocessor constant to the compiler using
895
- # the type name, in uppercase, prepended with 'HAVE_CONST_'.
896
- #
897
- # For example, if have_const('foo') returned true, then the HAVE_CONST_FOO
898
- # preprocessor macro would be passed to the compiler.
899
- #
900
- def have_const(const, headers = nil, opt = "", &b)
901
- checking_for checking_message([*const].compact.join(' '), headers, opt) do
902
- try_const(const, headers, opt, &b)
1210
+ # Returns whether or not the constant +const+ is defined. You may
1211
+ # optionally pass the +type+ of +const+ as <code>[const, type]</code>,
1212
+ # such as:
1213
+ #
1214
+ # have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
1215
+ #
1216
+ # You may also pass additional +headers+ to check against in addition to the
1217
+ # common header files, and additional flags to +opt+ which are then passed
1218
+ # along to the compiler.
1219
+ #
1220
+ # If found, a macro is passed as a preprocessor constant to the compiler
1221
+ # using the type name, in uppercase, prepended with +HAVE_CONST_+.
1222
+ #
1223
+ # For example, if <code>have_const('foo')</code> returned true, then the
1224
+ # +HAVE_CONST_FOO+ preprocessor macro would be passed to the compiler.
1225
+ #
1226
+ def have_const(const, headers = nil, opt = "", &b)
1227
+ checking_for checking_message([*const].compact.join(' '), headers, opt) do
1228
+ try_const(const, headers, opt, &b)
1229
+ end
903
1230
  end
904
- end
905
1231
 
906
- # Returns the size of the given +type+. You may optionally specify additional
907
- # +headers+ to search in for the +type+.
908
- #
909
- # If found, a macro is passed as a preprocessor constant to the compiler using
910
- # the type name, in uppercase, prepended with 'SIZEOF_', followed by the type
911
- # name, followed by '=X' where 'X' is the actual size.
912
- #
913
- # For example, if check_sizeof('mystruct') returned 12, then the
914
- # SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
915
- #
916
- def check_sizeof(type, headers = nil, &b)
917
- expr = "sizeof(#{type})"
918
- fmt = "%d"
919
- def fmt.%(x)
1232
+ # :stopdoc:
1233
+ STRING_OR_FAILED_FORMAT = "%s"
1234
+ def STRING_OR_FAILED_FORMAT.%(x) # :nodoc:
920
1235
  x ? super : "failed"
921
1236
  end
922
- checking_for checking_message("size of #{type}", headers), fmt do
923
- if size = try_constant(expr, headers, &b)
924
- $defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size))
925
- size
1237
+
1238
+ def typedef_expr(type, headers)
1239
+ typename, member = type.split('.', 2)
1240
+ prelude = cpp_include(headers).split(/$/)
1241
+ prelude << "typedef #{typename} rbcv_typedef_;\n"
1242
+ return "rbcv_typedef_", member, prelude
1243
+ end
1244
+
1245
+ def try_signedness(type, member, headers = nil, opts = nil)
1246
+ raise ArgumentError, "don't know how to tell signedness of members" if member
1247
+ if try_static_assert("(#{type})-1 < 0", headers, opts)
1248
+ return -1
1249
+ elsif try_static_assert("(#{type})-1 > 0", headers, opts)
1250
+ return +1
1251
+ end
1252
+ end
1253
+
1254
+ # :startdoc:
1255
+
1256
+ # Returns the size of the given +type+. You may optionally specify
1257
+ # additional +headers+ to search in for the +type+.
1258
+ #
1259
+ # If found, a macro is passed as a preprocessor constant to the compiler
1260
+ # using the type name, in uppercase, prepended with +SIZEOF_+, followed by
1261
+ # the type name, followed by <code>=X</code> where "X" is the actual size.
1262
+ #
1263
+ # For example, if <code>check_sizeof('mystruct')</code> returned 12, then
1264
+ # the <code>SIZEOF_MYSTRUCT=12</code> preprocessor macro would be passed to
1265
+ # the compiler.
1266
+ #
1267
+ def check_sizeof(type, headers = nil, opts = "", &b)
1268
+ typedef, member, prelude = typedef_expr(type, headers)
1269
+ prelude << "static #{typedef} *rbcv_ptr_;\n"
1270
+ prelude = [prelude]
1271
+ expr = "sizeof((*rbcv_ptr_)#{"." << member if member})"
1272
+ fmt = STRING_OR_FAILED_FORMAT
1273
+ checking_for checking_message("size of #{type}", headers), fmt do
1274
+ if size = try_constant(expr, prelude, opts, &b)
1275
+ $defs.push(format("-DSIZEOF_%s=%s", type.tr_cpp, size))
1276
+ size
1277
+ end
1278
+ end
1279
+ end
1280
+
1281
+ # Returns the signedness of the given +type+. You may optionally specify
1282
+ # additional +headers+ to search in for the +type+.
1283
+ #
1284
+ # If the +type+ is found and is a numeric type, a macro is passed as a
1285
+ # preprocessor constant to the compiler using the +type+ name, in uppercase,
1286
+ # prepended with +SIGNEDNESS_OF_+, followed by the +type+ name, followed by
1287
+ # <code>=X</code> where "X" is positive integer if the +type+ is unsigned
1288
+ # and a negative integer if the +type+ is signed.
1289
+ #
1290
+ # For example, if +size_t+ is defined as unsigned, then
1291
+ # <code>check_signedness('size_t')</code> would return +1 and the
1292
+ # <code>SIGNEDNESS_OF_SIZE_T=+1</code> preprocessor macro would be passed to
1293
+ # the compiler. The <code>SIGNEDNESS_OF_INT=-1</code> macro would be set
1294
+ # for <code>check_signedness('int')</code>
1295
+ #
1296
+ def check_signedness(type, headers = nil, opts = nil, &b)
1297
+ typedef, member, prelude = typedef_expr(type, headers)
1298
+ signed = nil
1299
+ checking_for("signedness of #{type}", STRING_OR_FAILED_FORMAT) do
1300
+ signed = try_signedness(typedef, member, [prelude], opts, &b) or next nil
1301
+ $defs.push("-DSIGNEDNESS_OF_%s=%+d" % [type.tr_cpp, signed])
1302
+ signed < 0 ? "signed" : "unsigned"
1303
+ end
1304
+ signed
1305
+ end
1306
+
1307
+ # Returns the convertible integer type of the given +type+. You may
1308
+ # optionally specify additional +headers+ to search in for the +type+.
1309
+ # _convertible_ means actually the same type, or typedef'd from the same
1310
+ # type.
1311
+ #
1312
+ # If the +type+ is a integer type and the _convertible_ type is found,
1313
+ # the following macros are passed as preprocessor constants to the compiler
1314
+ # using the +type+ name, in uppercase.
1315
+ #
1316
+ # * +TYPEOF_+, followed by the +type+ name, followed by <code>=X</code>
1317
+ # where "X" is the found _convertible_ type name.
1318
+ # * +TYP2NUM+ and +NUM2TYP+,
1319
+ # where +TYP+ is the +type+ name in uppercase with replacing an +_t+
1320
+ # suffix with "T", followed by <code>=X</code> where "X" is the macro name
1321
+ # to convert +type+ to an Integer object, and vice versa.
1322
+ #
1323
+ # For example, if +foobar_t+ is defined as unsigned long, then
1324
+ # <code>convertible_int("foobar_t")</code> would return "unsigned long", and
1325
+ # define these macros:
1326
+ #
1327
+ # #define TYPEOF_FOOBAR_T unsigned long
1328
+ # #define FOOBART2NUM ULONG2NUM
1329
+ # #define NUM2FOOBART NUM2ULONG
1330
+ #
1331
+ def convertible_int(type, headers = nil, opts = nil, &b)
1332
+ type, macname = *type
1333
+ checking_for("convertible type of #{type}", STRING_OR_FAILED_FORMAT) do
1334
+ if UNIVERSAL_INTS.include?(type)
1335
+ type
1336
+ else
1337
+ typedef, member, prelude = typedef_expr(type, headers, &b)
1338
+ if member
1339
+ prelude << "static rbcv_typedef_ rbcv_var;"
1340
+ compat = UNIVERSAL_INTS.find {|t|
1341
+ try_static_assert("sizeof(rbcv_var.#{member}) == sizeof(#{t})", [prelude], opts, &b)
1342
+ }
1343
+ else
1344
+ next unless signed = try_signedness(typedef, member, [prelude])
1345
+ u = "unsigned " if signed > 0
1346
+ prelude << "extern rbcv_typedef_ foo();"
1347
+ compat = UNIVERSAL_INTS.find {|t|
1348
+ try_compile([prelude, "extern #{u}#{t} foo();"].join("\n"), opts, :werror=>true, &b)
1349
+ }
1350
+ end
1351
+ if compat
1352
+ macname ||= type.sub(/_(?=t\z)/, '').tr_cpp
1353
+ conv = (compat == "long long" ? "LL" : compat.upcase)
1354
+ compat = "#{u}#{compat}"
1355
+ typename = type.tr_cpp
1356
+ $defs.push(format("-DSIZEOF_%s=SIZEOF_%s", typename, compat.tr_cpp))
1357
+ $defs.push(format("-DTYPEOF_%s=%s", typename, compat.quote))
1358
+ $defs.push(format("-DPRI_%s_PREFIX=PRI_%s_PREFIX", macname, conv))
1359
+ conv = (u ? "U" : "") + conv
1360
+ $defs.push(format("-D%s2NUM=%s2NUM", macname, conv))
1361
+ $defs.push(format("-DNUM2%s=NUM2%s", macname, conv))
1362
+ compat
1363
+ end
1364
+ end
1365
+ end
1366
+ end
1367
+ # :stopdoc:
1368
+
1369
+ # Used internally by the what_type? method to determine if +type+ is a scalar
1370
+ # pointer.
1371
+ def scalar_ptr_type?(type, member = nil, headers = nil, &b)
1372
+ try_compile(<<"SRC", &b) # pointer
1373
+ #{cpp_include(headers)}
1374
+ /*top*/
1375
+ volatile #{type} conftestval;
1376
+ extern int t(void);
1377
+ int t(void) {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
1378
+ #{MAIN_DOES_NOTHING "t"}
1379
+ SRC
1380
+ end
1381
+
1382
+ # Used internally by the what_type? method to determine if +type+ is a scalar
1383
+ # pointer.
1384
+ def scalar_type?(type, member = nil, headers = nil, &b)
1385
+ try_compile(<<"SRC", &b) # pointer
1386
+ #{cpp_include(headers)}
1387
+ /*top*/
1388
+ volatile #{type} conftestval;
1389
+ extern int t(void);
1390
+ int t(void) {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
1391
+ #{MAIN_DOES_NOTHING "t"}
1392
+ SRC
1393
+ end
1394
+
1395
+ # Used internally by the what_type? method to check if the _typeof_ GCC
1396
+ # extension is available.
1397
+ def have_typeof?
1398
+ return $typeof if defined?($typeof)
1399
+ $typeof = %w[__typeof__ typeof].find do |t|
1400
+ try_compile(<<SRC)
1401
+ int rbcv_foo;
1402
+ #{t}(rbcv_foo) rbcv_bar;
1403
+ SRC
1404
+ end
1405
+ end
1406
+
1407
+ def what_type?(type, member = nil, headers = nil, &b)
1408
+ m = "#{type}"
1409
+ var = val = "*rbcv_var_"
1410
+ func = "rbcv_func_(void)"
1411
+ if member
1412
+ m << "." << member
1413
+ else
1414
+ type, member = type.split('.', 2)
1415
+ end
1416
+ if member
1417
+ val = "(#{var}).#{member}"
1418
+ end
1419
+ prelude = [cpp_include(headers).split(/^/)]
1420
+ prelude << ["typedef #{type} rbcv_typedef_;\n",
1421
+ "extern rbcv_typedef_ *#{func};\n",
1422
+ "static rbcv_typedef_ #{var};\n",
1423
+ ]
1424
+ type = "rbcv_typedef_"
1425
+ fmt = member && !(typeof = have_typeof?) ? "seems %s" : "%s"
1426
+ if typeof
1427
+ var = "*rbcv_member_"
1428
+ func = "rbcv_mem_func_(void)"
1429
+ member = nil
1430
+ type = "rbcv_mem_typedef_"
1431
+ prelude[-1] << "typedef #{typeof}(#{val}) #{type};\n"
1432
+ prelude[-1] << "extern #{type} *#{func};\n"
1433
+ prelude[-1] << "static #{type} #{var};\n"
1434
+ val = var
1435
+ end
1436
+ def fmt.%(x)
1437
+ x ? super : "unknown"
1438
+ end
1439
+ checking_for checking_message(m, headers), fmt do
1440
+ if scalar_ptr_type?(type, member, prelude, &b)
1441
+ if try_static_assert("sizeof(*#{var}) == 1", prelude)
1442
+ return "string"
1443
+ end
1444
+ ptr = "*"
1445
+ elsif scalar_type?(type, member, prelude, &b)
1446
+ unless member and !typeof or try_static_assert("(#{type})-1 < 0", prelude)
1447
+ unsigned = "unsigned"
1448
+ end
1449
+ ptr = ""
1450
+ else
1451
+ next
1452
+ end
1453
+ type = UNIVERSAL_INTS.find do |t|
1454
+ pre = prelude
1455
+ unless member
1456
+ pre += [["static #{unsigned} #{t} #{ptr}#{var};\n",
1457
+ "extern #{unsigned} #{t} #{ptr}*#{func};\n"]]
1458
+ end
1459
+ try_static_assert("sizeof(#{ptr}#{val}) == sizeof(#{unsigned} #{t})", pre)
1460
+ end
1461
+ type or next
1462
+ [unsigned, type, ptr].join(" ").strip
926
1463
  end
927
1464
  end
928
- end
929
-
930
- # :stopdoc:
931
1465
 
932
- # Used internally by the what_type? method to determine if +type+ is a scalar
933
- # pointer.
934
- def scalar_ptr_type?(type, member = nil, headers = nil, &b)
935
- try_compile(<<"SRC", &b) # pointer
936
- #{COMMON_HEADERS}
937
- #{cpp_include(headers)}
938
- /*top*/
939
- volatile #{type} conftestval;
940
- int main() { return 0; }
941
- int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
942
- SRC
943
- end
944
-
945
- # Used internally by the what_type? method to determine if +type+ is a scalar
946
- # pointer.
947
- def scalar_type?(type, member = nil, headers = nil, &b)
948
- try_compile(<<"SRC", &b) # pointer
949
- #{COMMON_HEADERS}
950
- #{cpp_include(headers)}
951
- /*top*/
952
- volatile #{type} conftestval;
953
- int main() { return 0; }
954
- int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
955
- SRC
956
- end
1466
+ # This method is used internally by the find_executable method.
1467
+ #
1468
+ # Internal use only.
1469
+ #
1470
+ def find_executable0(bin, path = nil)
1471
+ executable_file = proc do |name|
1472
+ begin
1473
+ stat = File.stat(name)
1474
+ rescue SystemCallError
1475
+ else
1476
+ next name if stat.file? and stat.executable?
1477
+ end
1478
+ end
957
1479
 
958
- def what_type?(type, member = nil, headers = nil, &b)
959
- m = "#{type}"
960
- name = type
961
- if member
962
- m << "." << member
963
- name = "(((#{type} *)0)->#{member})"
964
- end
965
- fmt = "seems %s"
966
- def fmt.%(x)
967
- x ? super : "unknown"
968
- end
969
- checking_for checking_message(m, headers), fmt do
970
- if scalar_ptr_type?(type, member, headers, &b)
971
- if try_static_assert("sizeof(*#{name}) == 1", headers)
972
- "string"
1480
+ exts = config_string('EXECUTABLE_EXTS') {|s| s.split} || config_string('EXEEXT') {|s| [s]}
1481
+ if File.expand_path(bin) == bin
1482
+ return bin if executable_file.call(bin)
1483
+ if exts
1484
+ exts.each {|ext| executable_file.call(file = bin + ext) and return file}
973
1485
  end
974
- elsif scalar_type?(type, member, headers, &b)
975
- if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
976
- "long long"
977
- elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
978
- "long"
979
- elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
980
- "int"
981
- elsif try_static_assert("sizeof(#{name}) > 1", headers)
982
- "short"
983
- else
984
- "char"
1486
+ return nil
1487
+ end
1488
+ if path ||= ENV['PATH']
1489
+ path = path.split(File::PATH_SEPARATOR)
1490
+ else
1491
+ path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
1492
+ end
1493
+ file = nil
1494
+ path.each do |dir|
1495
+ return file if executable_file.call(file = File.join(dir, bin))
1496
+ if exts
1497
+ exts.each {|ext| executable_file.call(ext = file + ext) and return ext}
985
1498
  end
986
1499
  end
1500
+ nil
987
1501
  end
988
- end
989
1502
 
990
- # This method is used internally by the find_executable method.
991
- #
992
- # Internal use only.
993
- #
994
- def find_executable0(bin, path = nil)
995
- ext = config_string('EXEEXT')
996
- if File.expand_path(bin) == bin
997
- return bin if File.executable?(bin)
998
- ext and File.executable?(file = bin + ext) and return file
999
- return nil
1000
- end
1001
- if path ||= ENV['PATH']
1002
- path = path.split(File::PATH_SEPARATOR)
1003
- else
1004
- path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
1005
- end
1006
- file = nil
1007
- path.each do |dir|
1008
- return file if File.executable?(file = File.join(dir, bin))
1009
- return file if ext and File.executable?(file << ext)
1503
+ # :startdoc:
1504
+
1505
+ # Searches for the executable +bin+ on +path+. The default path is your
1506
+ # +PATH+ environment variable. If that isn't defined, it will resort to
1507
+ # searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
1508
+ #
1509
+ # If found, it will return the full path, including the executable name, of
1510
+ # where it was found.
1511
+ #
1512
+ # Note that this method does not actually affect the generated Makefile.
1513
+ #
1514
+ def find_executable(bin, path = nil)
1515
+ checking_for checking_message(bin, path) do
1516
+ find_executable0(bin, path)
1517
+ end
1010
1518
  end
1011
- nil
1012
- end
1013
1519
 
1014
- # :startdoc:
1520
+ # :stopdoc:
1015
1521
 
1016
- # Searches for the executable +bin+ on +path+. The default path is your
1017
- # PATH environment variable. If that isn't defined, it will resort to
1018
- # searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
1019
- #
1020
- # If found, it will return the full path, including the executable name,
1021
- # of where it was found.
1022
- #
1023
- # Note that this method does not actually affect the generated Makefile.
1024
- #
1025
- def find_executable(bin, path = nil)
1026
- checking_for checking_message(bin, path) do
1027
- find_executable0(bin, path)
1522
+ def arg_config(config, default=nil, &block)
1523
+ $arg_config << [config, default]
1524
+ defaults = []
1525
+ if default
1526
+ defaults << default
1527
+ elsif !block
1528
+ defaults << nil
1529
+ end
1530
+ $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
1531
+ end
1532
+
1533
+ # :startdoc:
1534
+
1535
+ # Tests for the presence of a <tt>--with-</tt>_config_ or
1536
+ # <tt>--without-</tt>_config_ option. Returns +true+ if the with option is
1537
+ # given, +false+ if the without option is given, and the default value
1538
+ # otherwise.
1539
+ #
1540
+ # This can be useful for adding custom definitions, such as debug
1541
+ # information.
1542
+ #
1543
+ # Example:
1544
+ #
1545
+ # if with_config("debug")
1546
+ # $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1547
+ # end
1548
+ #
1549
+ def with_config(config, default=nil)
1550
+ config = config.sub(/^--with[-_]/, '')
1551
+ val = arg_config("--with-"+config) do
1552
+ if arg_config("--without-"+config)
1553
+ false
1554
+ elsif block_given?
1555
+ yield(config, default)
1556
+ else
1557
+ break default
1558
+ end
1559
+ end
1560
+ case val
1561
+ when "yes"
1562
+ true
1563
+ when "no"
1564
+ false
1565
+ else
1566
+ val
1567
+ end
1028
1568
  end
1029
- end
1030
-
1031
- # :stopdoc:
1032
-
1033
- def arg_config(config, *defaults, &block)
1034
- $arg_config << [config, *defaults]
1035
- defaults << nil if !block and defaults.empty?
1036
- $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
1037
- end
1038
-
1039
- # :startdoc:
1040
1569
 
1041
- # Tests for the presence of a --with-<tt>config</tt> or --without-<tt>config</tt>
1042
- # option. Returns true if the with option is given, false if the without
1043
- # option is given, and the default value otherwise.
1044
- #
1045
- # This can be useful for adding custom definitions, such as debug information.
1046
- #
1047
- # Example:
1048
- #
1049
- # if with_config("debug")
1050
- # $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1051
- # end
1052
- #
1053
- def with_config(config, *defaults)
1054
- config = config.sub(/^--with[-_]/, '')
1055
- val = arg_config("--with-"+config) do
1056
- if arg_config("--without-"+config)
1570
+ # Tests for the presence of an <tt>--enable-</tt>_config_ or
1571
+ # <tt>--disable-</tt>_config_ option. Returns +true+ if the enable option is
1572
+ # given, +false+ if the disable option is given, and the default value
1573
+ # otherwise.
1574
+ #
1575
+ # This can be useful for adding custom definitions, such as debug
1576
+ # information.
1577
+ #
1578
+ # Example:
1579
+ #
1580
+ # if enable_config("debug")
1581
+ # $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1582
+ # end
1583
+ #
1584
+ def enable_config(config, default=nil)
1585
+ if arg_config("--enable-"+config)
1586
+ true
1587
+ elsif arg_config("--disable-"+config)
1057
1588
  false
1058
1589
  elsif block_given?
1059
- yield(config, *defaults)
1590
+ yield(config, default)
1060
1591
  else
1061
- break *defaults
1592
+ return default
1062
1593
  end
1063
1594
  end
1064
- case val
1065
- when "yes"
1066
- true
1067
- when "no"
1068
- false
1069
- else
1070
- val
1071
- end
1072
- end
1073
1595
 
1074
- # Tests for the presence of an --enable-<tt>config</tt> or
1075
- # --disable-<tt>config</tt> option. Returns true if the enable option is given,
1076
- # false if the disable option is given, and the default value otherwise.
1077
- #
1078
- # This can be useful for adding custom definitions, such as debug information.
1079
- #
1080
- # Example:
1081
- #
1082
- # if enable_config("debug")
1083
- # $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1084
- # end
1085
- #
1086
- def enable_config(config, *defaults)
1087
- if arg_config("--enable-"+config)
1088
- true
1089
- elsif arg_config("--disable-"+config)
1090
- false
1091
- elsif block_given?
1092
- yield(config, *defaults)
1093
- else
1094
- return *defaults
1095
- end
1096
- end
1596
+ # Generates a header file consisting of the various macro definitions
1597
+ # generated by other methods such as have_func and have_header. These are
1598
+ # then wrapped in a custom <code>#ifndef</code> based on the +header+ file
1599
+ # name, which defaults to "extconf.h".
1600
+ #
1601
+ # For example:
1602
+ #
1603
+ # # extconf.rb
1604
+ # require 'mkmf'
1605
+ # have_func('realpath')
1606
+ # have_header('sys/utime.h')
1607
+ # create_header
1608
+ # create_makefile('foo')
1609
+ #
1610
+ # The above script would generate the following extconf.h file:
1611
+ #
1612
+ # #ifndef EXTCONF_H
1613
+ # #define EXTCONF_H
1614
+ # #define HAVE_REALPATH 1
1615
+ # #define HAVE_SYS_UTIME_H 1
1616
+ # #endif
1617
+ #
1618
+ # Given that the create_header method generates a file based on definitions
1619
+ # set earlier in your extconf.rb file, you will probably want to make this
1620
+ # one of the last methods you call in your script.
1621
+ #
1622
+ def create_header(header = "extconf.h")
1623
+ message "creating %s\n", header
1624
+ sym = header.tr_cpp
1625
+ hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
1626
+ for line in $defs
1627
+ case line
1628
+ when /^-D([^=]+)(?:=(.*))?/
1629
+ hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0].gsub(/(?=\t+)/, "\\\n") : 1}\n"
1630
+ when /^-U(.*)/
1631
+ hdr << "#undef #$1\n"
1632
+ end
1633
+ end
1634
+ hdr << "#endif\n"
1635
+ hdr = hdr.join("")
1636
+ log_src(hdr, "#{header} is")
1637
+ unless (IO.read(header) == hdr rescue false)
1638
+ open(header, "wb") do |hfile|
1639
+ hfile.write(hdr)
1640
+ end
1641
+ end
1642
+ $extconf_h = header
1643
+ end
1644
+
1645
+ # Sets a +target+ name that the user can then use to configure various
1646
+ # "with" options with on the command line by using that name. For example,
1647
+ # if the target is set to "foo", then the user could use the
1648
+ # <code>--with-foo-dir</code> command line option.
1649
+ #
1650
+ # You may pass along additional "include" or "lib" defaults via the
1651
+ # +idefault+ and +ldefault+ parameters, respectively.
1652
+ #
1653
+ # Note that dir_config only adds to the list of places to search for
1654
+ # libraries and include files. It does not link the libraries into your
1655
+ # application.
1656
+ #
1657
+ def dir_config(target, idefault=nil, ldefault=nil)
1658
+ if dir = with_config(target + "-dir", (idefault unless ldefault))
1659
+ defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
1660
+ idefault = ldefault = nil
1661
+ end
1097
1662
 
1098
- # Generates a header file consisting of the various macro definitions generated
1099
- # by other methods such as have_func and have_header. These are then wrapped in
1100
- # a custom #ifndef based on the +header+ file name, which defaults to
1101
- # 'extconf.h'.
1102
- #
1103
- # For example:
1104
- #
1105
- # # extconf.rb
1106
- # require 'mkmf'
1107
- # have_func('realpath')
1108
- # have_header('sys/utime.h')
1109
- # create_header
1110
- # create_makefile('foo')
1111
- #
1112
- # The above script would generate the following extconf.h file:
1113
- #
1114
- # #ifndef EXTCONF_H
1115
- # #define EXTCONF_H
1116
- # #define HAVE_REALPATH 1
1117
- # #define HAVE_SYS_UTIME_H 1
1118
- # #endif
1119
- #
1120
- # Given that the create_header method generates a file based on definitions
1121
- # set earlier in your extconf.rb file, you will probably want to make this
1122
- # one of the last methods you call in your script.
1123
- #
1124
- def create_header(header = "extconf.h")
1125
- message "creating %s\n", header
1126
- sym = header.tr("a-z./\055", "A-Z___")
1127
- hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
1128
- for line in $defs
1129
- case line
1130
- when /^-D([^=]+)(?:=(.*))?/
1131
- hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
1132
- when /^-U(.*)/
1133
- hdr << "#undef #$1\n"
1134
- end
1135
- end
1136
- hdr << "#endif\n"
1137
- hdr = hdr.join
1138
- unless (IO.read(header) == hdr rescue false)
1139
- open(header, "w") do |hfile|
1140
- hfile.write(hdr)
1141
- end
1142
- end
1143
- $extconf_h = header
1144
- end
1663
+ idir = with_config(target + "-include", idefault)
1664
+ $arg_config.last[1] ||= "${#{target}-dir}/include"
1665
+ ldir = with_config(target + "-lib", ldefault)
1666
+ $arg_config.last[1] ||= "${#{target}-dir}/#{@libdir_basename}"
1145
1667
 
1146
- # Sets a +target+ name that the user can then use to configure various 'with'
1147
- # options with on the command line by using that name. For example, if the
1148
- # target is set to "foo", then the user could use the --with-foo-dir command
1149
- # line option.
1150
- #
1151
- # You may pass along additional 'include' or 'lib' defaults via the +idefault+
1152
- # and +ldefault+ parameters, respectively.
1153
- #
1154
- # Note that dir_config only adds to the list of places to search for libraries
1155
- # and include files. It does not link the libraries into your application.
1156
- #
1157
- def dir_config(target, idefault=nil, ldefault=nil)
1158
- if dir = with_config(target + "-dir", (idefault unless ldefault))
1159
- defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
1160
- idefault = ldefault = nil
1161
- end
1162
-
1163
- idir = with_config(target + "-include", idefault)
1164
- $arg_config.last[1] ||= "${#{target}-dir}/include"
1165
- ldir = with_config(target + "-lib", ldefault)
1166
- $arg_config.last[1] ||= "${#{target}-dir}/lib"
1167
-
1168
- idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
1169
- if defaults
1170
- idirs.concat(defaults.collect {|dir| dir + "/include"})
1171
- idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
1172
- end
1173
- unless idirs.empty?
1174
- idirs.collect! {|dir| "-I" + dir}
1175
- idirs -= Shellwords.shellwords($CPPFLAGS)
1668
+ idirs = idir ? Array === idir ? idir.dup : idir.split(File::PATH_SEPARATOR) : []
1669
+ if defaults
1670
+ idirs.concat(defaults.collect {|d| d + "/include"})
1671
+ idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
1672
+ end
1176
1673
  unless idirs.empty?
1177
- $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
1674
+ idirs.collect! {|d| "-I" + d}
1675
+ idirs -= Shellwords.shellwords($CPPFLAGS)
1676
+ unless idirs.empty?
1677
+ $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
1678
+ end
1178
1679
  end
1179
- end
1180
1680
 
1181
- ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
1182
- if defaults
1183
- ldirs.concat(defaults.collect {|dir| dir + "/lib"})
1184
- ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
1681
+ ldirs = ldir ? Array === ldir ? ldir.dup : ldir.split(File::PATH_SEPARATOR) : []
1682
+ if defaults
1683
+ ldirs.concat(defaults.collect {|d| "#{d}/#{@libdir_basename}"})
1684
+ ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
1685
+ end
1686
+ $LIBPATH = ldirs | $LIBPATH
1687
+
1688
+ [idir, ldir]
1689
+ end
1690
+
1691
+ # :stopdoc:
1692
+
1693
+ # Handles meta information about installed libraries. Uses your platform's
1694
+ # pkg-config program if it has one.
1695
+ #
1696
+ # The actual command name can be overridden by
1697
+ # <code>--with-pkg-config</code> command line option.
1698
+ def pkg_config(pkg)
1699
+ if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
1700
+ # iff package specific config command is given
1701
+ get = proc {|opt| `#{pkgconfig} --#{opt}`.strip}
1702
+ elsif ($PKGCONFIG ||=
1703
+ (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
1704
+ find_executable0(pkgconfig) && pkgconfig) and
1705
+ system("#{$PKGCONFIG} --exists #{pkg}")
1706
+ # default to pkg-config command
1707
+ get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.strip}
1708
+ elsif find_executable0(pkgconfig = "#{pkg}-config")
1709
+ # default to package specific config command, as a last resort.
1710
+ get = proc {|opt| `#{pkgconfig} --#{opt}`.strip}
1711
+ end
1712
+ orig_ldflags = $LDFLAGS
1713
+ if get and try_ldflags(ldflags = get['libs'])
1714
+ cflags = get['cflags']
1715
+ libs = get['libs-only-l']
1716
+ ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
1717
+ $CFLAGS += " " << cflags
1718
+ $LDFLAGS = [orig_ldflags, ldflags].join(' ')
1719
+ $libs += " " << libs
1720
+ Logging::message "package configuration for %s\n", pkg
1721
+ Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
1722
+ cflags, ldflags, libs
1723
+ [cflags, ldflags, libs]
1724
+ else
1725
+ Logging::message "package configuration for %s is not found\n", pkg
1726
+ nil
1727
+ end
1185
1728
  end
1186
- $LIBPATH = ldirs | $LIBPATH
1187
-
1188
- [idir, ldir]
1189
- end
1190
-
1191
- # :stopdoc:
1192
1729
 
1193
- # Handles meta information about installed libraries. Uses your platform's
1194
- # pkg-config program if it has one.
1195
- def pkg_config(pkg)
1196
- if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
1197
- # iff package specific config command is given
1198
- get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1199
- elsif ($PKGCONFIG ||=
1200
- (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
1201
- find_executable0(pkgconfig) && pkgconfig) and
1202
- system("#{$PKGCONFIG} --exists #{pkg}")
1203
- # default to pkg-config command
1204
- get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}
1205
- elsif find_executable0(pkgconfig = "#{pkg}-config")
1206
- # default to package specific config command, as a last resort.
1207
- get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1208
- end
1209
- if get
1210
- cflags = get['cflags']
1211
- ldflags = get['libs']
1212
- libs = get['libs-only-l']
1213
- ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
1214
- $CFLAGS += " " << cflags
1215
- $LDFLAGS += " " << ldflags
1216
- $libs += " " << libs
1217
- Logging::message "package configuration for %s\n", pkg
1218
- Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
1219
- cflags, ldflags, libs
1220
- [cflags, ldflags, libs]
1221
- else
1222
- Logging::message "package configuration for %s is not found\n", pkg
1223
- nil
1730
+ def with_destdir(dir)
1731
+ return dir unless $extmk
1732
+ dir = dir.sub($dest_prefix_pattern, '')
1733
+ /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
1224
1734
  end
1225
- end
1226
-
1227
- def with_destdir(dir)
1228
- dir = dir.sub($dest_prefix_pattern, '')
1229
- /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
1230
- end
1231
1735
 
1232
- # Converts forward slashes to backslashes. Aimed at MS Windows.
1233
- #
1234
- # Internal use only.
1235
- #
1236
- def winsep(s)
1237
- s.tr('/', '\\')
1238
- end
1239
-
1240
- # Converts native path to format acceptable in Makefile
1241
- #
1242
- # Internal use only.
1243
- #
1244
- if !CROSS_COMPILING
1245
- case CONFIG['build_os']
1246
- when 'mingw32'
1247
- def mkintpath(path)
1248
- # mingw uses make from msys and it needs special care
1249
- # converts from C:\some\path to /C/some/path
1250
- path = path.dup
1251
- path.tr!('\\', '/')
1252
- path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
1253
- path
1254
- end
1255
- end
1256
- end
1257
- unless defined?(mkintpath)
1258
- def mkintpath(path)
1259
- path
1736
+ # Converts forward slashes to backslashes. Aimed at MS Windows.
1737
+ #
1738
+ # Internal use only.
1739
+ #
1740
+ def winsep(s)
1741
+ s.tr('/', '\\')
1260
1742
  end
1261
- end
1262
1743
 
1263
- def configuration(srcdir)
1264
- mk = []
1265
- vpath = %w[$(srcdir) $(topdir) $(hdrdir)]
1744
+ # Converts native path to format acceptable in Makefile
1745
+ #
1746
+ # Internal use only.
1747
+ #
1266
1748
  if !CROSS_COMPILING
1267
1749
  case CONFIG['build_os']
1750
+ when 'mingw32'
1751
+ def mkintpath(path)
1752
+ # mingw uses make from msys and it needs special care
1753
+ # converts from C:\some\path to /C/some/path
1754
+ path = path.dup
1755
+ path.tr!('\\', '/')
1756
+ path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
1757
+ path
1758
+ end
1268
1759
  when 'cygwin'
1269
1760
  if CONFIG['target_os'] != 'cygwin'
1270
- vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')}
1761
+ def mkintpath(path)
1762
+ IO.popen(["cygpath", "-u", path], &:read).chomp
1763
+ end
1271
1764
  end
1272
- when 'msdosdjgpp'
1273
- CONFIG['PATH_SEPARATOR'] = ';'
1274
1765
  end
1275
1766
  end
1276
- mk << %{
1767
+ unless method_defined?(:mkintpath)
1768
+ def mkintpath(path)
1769
+ path
1770
+ end
1771
+ end
1772
+
1773
+ def configuration(srcdir)
1774
+ mk = []
1775
+ vpath = $VPATH.dup
1776
+ CONFIG["hdrdir"] ||= $hdrdir
1777
+ mk << %{
1277
1778
  SHELL = /bin/sh
1278
1779
 
1780
+ # V=0 quiet, V=1 verbose. other values don't work.
1781
+ V = 0
1782
+ Q1 = $(V:1=)
1783
+ Q = $(Q1:0=@)
1784
+ ECHO1 = $(V:1=@#{CONFIG['NULLCMD']})
1785
+ ECHO = $(ECHO1:0=@echo)
1786
+
1279
1787
  #### Start of system configuration section. ####
1280
- #{
1281
- if $extmk
1282
- "top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/")
1283
- end
1284
- }
1285
- srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2])}.quote}
1286
- topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote}
1287
- hdrdir = #{$extmk ? mkintpath(CONFIG["hdrdir"]).quote : '$(topdir)'}
1788
+ #{"top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/") if $extmk}
1789
+ srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2]).unspace}}
1790
+ topdir = #{mkintpath(topdir = $extmk ? CONFIG["topdir"] : $topdir).unspace}
1791
+ hdrdir = #{(hdrdir = CONFIG["hdrdir"]) == topdir ? "$(topdir)" : mkintpath(hdrdir).unspace}
1792
+ arch_hdrdir = #{$arch_hdrdir.quote}
1793
+ PATH_SEPARATOR = #{CONFIG['PATH_SEPARATOR']}
1288
1794
  VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
1289
1795
  }
1290
- if $extmk
1291
- mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n"
1292
- end
1293
- if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1]
1294
- mk << "\nDESTDIR = #{destdir}\n"
1295
- end
1296
- CONFIG.each do |key, var|
1297
- next unless /prefix$/ =~ key
1298
- mk << "#{key} = #{with_destdir(var)}\n"
1299
- end
1300
- CONFIG.each do |key, var|
1301
- next if /^abs_/ =~ key
1302
- next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1
1303
- mk << "#{key} = #{with_destdir(var)}\n"
1304
- end
1305
- if !$extmk and !$configure_args.has_key?('--ruby') and
1306
- sep = config_string('BUILD_FILE_SEPARATOR')
1307
- sep = ":/=#{sep}"
1308
- else
1309
- sep = ""
1310
- end
1311
- extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" "
1312
- mk << %{
1796
+ if $extmk
1797
+ mk << "RUBYLIB =\n""RUBYOPT = -\n"
1798
+ end
1799
+ prefix = mkintpath(CONFIG["prefix"])
1800
+ if destdir = prefix[$dest_prefix_pattern, 1]
1801
+ mk << "\nDESTDIR = #{destdir}\n"
1802
+ end
1803
+ mk << "prefix = #{with_destdir(prefix).unspace}\n"
1804
+ CONFIG.each do |key, var|
1805
+ mk << "#{key} = #{with_destdir(mkintpath(var)).unspace}\n" if /.prefix$/ =~ key
1806
+ end
1807
+ CONFIG.each do |key, var|
1808
+ next if /^abs_/ =~ key
1809
+ next if /^(?:src|top|hdr)dir$/ =~ key
1810
+ next unless /dir$/ =~ key
1811
+ mk << "#{key} = #{with_destdir(var)}\n"
1812
+ end
1813
+ if !$extmk and !$configure_args.has_key?('--ruby') and
1814
+ sep = config_string('BUILD_FILE_SEPARATOR')
1815
+ sep = ":/=#{sep}"
1816
+ else
1817
+ sep = ""
1818
+ end
1819
+ possible_command = (proc {|s| s if /top_srcdir/ !~ s} unless $extmk)
1820
+ extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ") << " "
1821
+ headers = %w[$(hdrdir)/ruby.h $(hdrdir)/ruby/defines.h]
1822
+ if RULE_SUBST
1823
+ headers.each {|h| h.sub!(/.*/, &RULE_SUBST.method(:%))}
1824
+ end
1825
+ headers << $config_h
1826
+ headers << '$(RUBY_EXTCONF_H)' if $extconf_h
1827
+ mk << %{
1828
+
1313
1829
  CC = #{CONFIG['CC']}
1830
+ CXX = #{CONFIG['CXX']}
1314
1831
  LIBRUBY = #{CONFIG['LIBRUBY']}
1315
1832
  LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
1316
1833
  LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
1317
1834
  LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
1835
+ empty =
1836
+ OUTFLAG = #{OUTFLAG}$(empty)
1837
+ COUTFLAG = #{COUTFLAG}$(empty)
1318
1838
 
1319
1839
  RUBY_EXTCONF_H = #{$extconf_h}
1320
- CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG
1840
+ cflags = #{CONFIG['cflags']}
1841
+ optflags = #{CONFIG['optflags']}
1842
+ debugflags = #{CONFIG['debugflags']}
1843
+ warnflags = #{$warnflags}
1844
+ CCDLFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']}
1845
+ CFLAGS = $(CCDLFLAGS) #$CFLAGS $(ARCH_FLAG)
1321
1846
  INCFLAGS = -I. #$INCFLAGS
1322
1847
  DEFS = #{CONFIG['DEFS']}
1323
1848
  CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
1324
- CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
1849
+ CXXFLAGS = $(CCDLFLAGS) #{CONFIG['CXXFLAGS']} $(ARCH_FLAG)
1325
1850
  ldflags = #{$LDFLAGS}
1326
- dldflags = #{$DLDFLAGS}
1327
- archflag = #{$ARCH_FLAG}
1328
- DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
1851
+ dldflags = #{$DLDFLAGS} #{CONFIG['EXTDLDFLAGS']}
1852
+ ARCH_FLAG = #{$ARCH_FLAG}
1853
+ DLDFLAGS = $(ldflags) $(dldflags) $(ARCH_FLAG)
1329
1854
  LDSHARED = #{CONFIG['LDSHARED']}
1855
+ LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'}
1330
1856
  AR = #{CONFIG['AR']}
1331
1857
  EXEEXT = #{CONFIG['EXEEXT']}
1332
1858
 
1333
- RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
1334
- RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
1859
+ }
1860
+ CONFIG.each do |key, val|
1861
+ mk << "#{key} = #{val}\n" if /^RUBY.*NAME/ =~ key
1862
+ end
1863
+ mk << %{
1335
1864
  arch = #{CONFIG['arch']}
1336
1865
  sitearch = #{CONFIG['sitearch']}
1337
1866
  ruby_version = #{RbConfig::CONFIG['ruby_version']}
1338
- ruby = #{$ruby}
1867
+ ruby = #{$ruby.sub(%r[\A#{Regexp.quote(RbConfig::CONFIG['bindir'])}(?=/|\z)]) {'$(bindir)'}}
1339
1868
  RUBY = $(ruby#{sep})
1340
- RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}
1341
- MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}
1342
- INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}
1869
+ ruby_headers = #{headers.join(' ')}
1870
+
1871
+ RM = #{config_string('RM', &possible_command) || '$(RUBY) -run -e rm -- -f'}
1872
+ RM_RF = #{'$(RUBY) -run -e rm -- -rf'}
1873
+ RMDIRS = #{config_string('RMDIRS', &possible_command) || '$(RUBY) -run -e rmdir -- -p'}
1874
+ MAKEDIRS = #{config_string('MAKEDIRS', &possible_command) || '@$(RUBY) -run -e mkdir -- -p'}
1875
+ INSTALL = #{config_string('INSTALL', &possible_command) || '@$(RUBY) -run -e install -- -vp'}
1343
1876
  INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
1344
1877
  INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
1345
- COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
1878
+ COPY = #{config_string('CP', &possible_command) || '@$(RUBY) -run -e cp -- -v'}
1879
+ TOUCH = exit >
1346
1880
 
1347
1881
  #### End of system configuration section. ####
1348
1882
 
1349
- preload = #{$preload ? $preload.join(' ') : ''}
1883
+ preload = #{defined?($preload) && $preload ? $preload.join(' ') : ''}
1350
1884
  }
1351
- if $nmake == ?b
1352
- mk.each do |x|
1353
- x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
1354
- "!ifndef " + $1 + "\n" +
1355
- $& +
1356
- "!endif\n"
1885
+ if $nmake == ?b
1886
+ mk.each do |x|
1887
+ x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
1888
+ "!ifndef " + $1 + "\n" +
1889
+ $& +
1890
+ "!endif\n"
1891
+ end
1357
1892
  end
1358
1893
  end
1894
+ mk
1359
1895
  end
1360
- mk
1361
- end
1362
1896
 
1363
- def dummy_makefile(srcdir)
1364
- configuration(srcdir) << <<RULES << CLEANINGS
1897
+ def timestamp_file(name)
1898
+ name = name.gsub(/(\$[({]|[})])|(\/+)|[^-.\w]+/) {$1 ? "" : $2 ? ".-." : "_"}
1899
+ "./.#{name}.time"
1900
+ end
1901
+ # :startdoc:
1902
+
1903
+ # creates a stub Makefile.
1904
+ #
1905
+ def dummy_makefile(srcdir)
1906
+ configuration(srcdir) << <<RULES << CLEANINGS
1365
1907
  CLEANFILES = #{$cleanfiles.join(' ')}
1366
1908
  DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1367
1909
 
1368
1910
  all install static install-so install-rb: Makefile
1911
+ .PHONY: all install static install-so install-rb
1912
+ .PHONY: clean clean-so clean-static clean-rb
1369
1913
 
1370
1914
  RULES
1371
- end
1372
- # :startdoc:
1373
-
1374
- # Generates the Makefile for your extension, passing along any options and
1375
- # preprocessor constants that you may have generated through other methods.
1376
- #
1377
- # The +target+ name should correspond the name of the global function name
1378
- # defined within your C extension, minus the 'Init_'. For example, if your
1379
- # C extension is defined as 'Init_foo', then your target would simply be 'foo'.
1380
- #
1381
- # If any '/' characters are present in the target name, only the last name
1382
- # is interpreted as the target name, and the rest are considered toplevel
1383
- # directory names, and the generated Makefile will be altered accordingly to
1384
- # follow that directory structure.
1385
- #
1386
- # For example, if you pass 'test/foo' as a target name, your extension will
1387
- # be installed under the 'test' directory. This means that in order to
1388
- # load the file within a Ruby program later, that directory structure will
1389
- # have to be followed, e.g. "require 'test/foo'".
1390
- #
1391
- # The +srcprefix+ should be used when your source files are not in the same
1392
- # directory as your build script. This will not only eliminate the need for
1393
- # you to manually copy the source files into the same directory as your build
1394
- # script, but it also sets the proper +target_prefix+ in the generated
1395
- # Makefile.
1396
- #
1397
- # Setting the +target_prefix+ will, in turn, install the generated binary in
1398
- # a directory under your RbConfig::CONFIG['sitearchdir'] that mimics your local
1399
- # filesystem when you run 'make install'.
1400
- #
1401
- # For example, given the following file tree:
1402
- #
1403
- # ext/
1404
- # extconf.rb
1405
- # test/
1406
- # foo.c
1407
- #
1408
- # And given the following code:
1409
- #
1410
- # create_makefile('test/foo', 'test')
1411
- #
1412
- # That will set the +target_prefix+ in the generated Makefile to 'test'. That,
1413
- # in turn, will create the following file tree when installed via the
1414
- # 'make install' command:
1415
- #
1416
- # /path/to/ruby/sitearchdir/test/foo.so
1417
- #
1418
- # It is recommended that you use this approach to generate your makefiles,
1419
- # instead of copying files around manually, because some third party
1420
- # libraries may depend on the +target_prefix+ being set properly.
1421
- #
1422
- # The +srcprefix+ argument can be used to override the default source
1423
- # directory, i.e. the current directory . It is included as part of the VPATH
1424
- # and added to the list of INCFLAGS.
1425
- #
1426
- def create_makefile(target, srcprefix = nil)
1427
- $target = target
1428
- libpath = $DEFLIBPATH|$LIBPATH
1429
- message "creating Makefile\n"
1430
- rm_f "conftest*"
1431
- if CONFIG["DLEXT"] == $OBJEXT
1432
- for lib in libs = $libs.split
1433
- lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
1434
- end
1435
- $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
1436
- end
1437
-
1438
- if target.include?('/')
1439
- target_prefix, target = File.split(target)
1440
- target_prefix[0,0] = '/'
1441
- else
1442
- target_prefix = ""
1443
1915
  end
1444
1916
 
1445
- srcprefix ||= '$(srcdir)'
1446
- RbConfig::expand(srcdir = srcprefix.dup)
1447
-
1448
- if not $objs
1449
- $objs = []
1450
- srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
1451
- for f in srcs
1452
- obj = File.basename(f, ".*") << ".o"
1453
- $objs.push(obj) unless $objs.index(obj)
1917
+ def each_compile_rules # :nodoc:
1918
+ vpath_splat = /\$\(\*VPATH\*\)/
1919
+ COMPILE_RULES.each do |rule|
1920
+ if vpath_splat =~ rule
1921
+ $VPATH.each do |path|
1922
+ yield rule.sub(vpath_splat) {path}
1923
+ end
1924
+ else
1925
+ yield rule
1926
+ end
1454
1927
  end
1455
- elsif !(srcs = $srcs)
1456
- srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
1457
1928
  end
1458
- $srcs = srcs
1459
- for i in $objs
1460
- i.sub!(/\.o\z/, ".#{$OBJEXT}")
1461
- end
1462
- $objs = $objs.join(" ")
1463
1929
 
1464
- target = nil if $objs == ""
1930
+ # Processes the data contents of the "depend" file. Each line of this file
1931
+ # is expected to be a file name.
1932
+ #
1933
+ # Returns the output of findings, in Makefile format.
1934
+ #
1935
+ def depend_rules(depend)
1936
+ suffixes = []
1937
+ depout = []
1938
+ cont = implicit = nil
1939
+ impconv = proc do
1940
+ each_compile_rules {|rule| depout << (rule % implicit[0]) << implicit[1]}
1941
+ implicit = nil
1942
+ end
1943
+ ruleconv = proc do |line|
1944
+ if implicit
1945
+ if /\A\t/ =~ line
1946
+ implicit[1] << line
1947
+ next
1948
+ else
1949
+ impconv[]
1950
+ end
1951
+ end
1952
+ if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
1953
+ suffixes << m[1] << m[2]
1954
+ implicit = [[m[1], m[2]], [m.post_match]]
1955
+ next
1956
+ elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
1957
+ line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
1958
+ end
1959
+ depout << line
1960
+ end
1961
+ depend.each_line do |line|
1962
+ line.gsub!(/\.o\b/, ".#{$OBJEXT}")
1963
+ line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h)
1964
+ line.gsub!(%r"\$\(hdrdir\)/(?!ruby(?![^:;/\s]))(?=[-\w]+\.h)", '\&ruby/')
1965
+ if $nmake && /\A\s*\$\(RM|COPY\)/ =~ line
1966
+ line.gsub!(%r"[-\w\./]{2,}"){$&.tr("/", "\\")}
1967
+ line.gsub!(/(\$\((?!RM|COPY)[^:)]+)(?=\))/, '\1:/=\\')
1968
+ end
1969
+ if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
1970
+ (cont ||= []) << line
1971
+ next
1972
+ elsif cont
1973
+ line = (cont << line).join
1974
+ cont = nil
1975
+ end
1976
+ ruleconv.call(line)
1977
+ end
1978
+ if cont
1979
+ ruleconv.call(cont.join)
1980
+ elsif implicit
1981
+ impconv.call
1982
+ end
1983
+ unless suffixes.empty?
1984
+ depout.unshift(".SUFFIXES: ." + suffixes.uniq.join(" .") + "\n\n")
1985
+ end
1986
+ depout.unshift("$(OBJS): $(RUBY_EXTCONF_H)\n\n") if $extconf_h
1987
+ depout.flatten!
1988
+ depout
1989
+ end
1990
+
1991
+ # Generates the Makefile for your extension, passing along any options and
1992
+ # preprocessor constants that you may have generated through other methods.
1993
+ #
1994
+ # The +target+ name should correspond the name of the global function name
1995
+ # defined within your C extension, minus the +Init_+. For example, if your
1996
+ # C extension is defined as +Init_foo+, then your target would simply be
1997
+ # "foo".
1998
+ #
1999
+ # If any "/" characters are present in the target name, only the last name
2000
+ # is interpreted as the target name, and the rest are considered toplevel
2001
+ # directory names, and the generated Makefile will be altered accordingly to
2002
+ # follow that directory structure.
2003
+ #
2004
+ # For example, if you pass "test/foo" as a target name, your extension will
2005
+ # be installed under the "test" directory. This means that in order to
2006
+ # load the file within a Ruby program later, that directory structure will
2007
+ # have to be followed, e.g. <code>require 'test/foo'</code>.
2008
+ #
2009
+ # The +srcprefix+ should be used when your source files are not in the same
2010
+ # directory as your build script. This will not only eliminate the need for
2011
+ # you to manually copy the source files into the same directory as your
2012
+ # build script, but it also sets the proper +target_prefix+ in the generated
2013
+ # Makefile.
2014
+ #
2015
+ # Setting the +target_prefix+ will, in turn, install the generated binary in
2016
+ # a directory under your <code>RbConfig::CONFIG['sitearchdir']</code> that
2017
+ # mimics your local filesystem when you run <code>make install</code>.
2018
+ #
2019
+ # For example, given the following file tree:
2020
+ #
2021
+ # ext/
2022
+ # extconf.rb
2023
+ # test/
2024
+ # foo.c
2025
+ #
2026
+ # And given the following code:
2027
+ #
2028
+ # create_makefile('test/foo', 'test')
2029
+ #
2030
+ # That will set the +target_prefix+ in the generated Makefile to "test".
2031
+ # That, in turn, will create the following file tree when installed via the
2032
+ # <code>make install</code> command:
2033
+ #
2034
+ # /path/to/ruby/sitearchdir/test/foo.so
2035
+ #
2036
+ # It is recommended that you use this approach to generate your makefiles,
2037
+ # instead of copying files around manually, because some third party
2038
+ # libraries may depend on the +target_prefix+ being set properly.
2039
+ #
2040
+ # The +srcprefix+ argument can be used to override the default source
2041
+ # directory, i.e. the current directory. It is included as part of the
2042
+ # +VPATH+ and added to the list of +INCFLAGS+.
2043
+ #
2044
+ def create_makefile(target, srcprefix = nil)
2045
+ $target = target
2046
+ libpath = $DEFLIBPATH|$LIBPATH
2047
+ message "creating Makefile\n"
2048
+ MakeMakefile.rm_f "conftest*"
2049
+ if CONFIG["DLEXT"] == $OBJEXT
2050
+ for lib in libs = $libs.split
2051
+ lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
2052
+ end
2053
+ $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
2054
+ end
2055
+
2056
+ if target.include?('/')
2057
+ target_prefix, target = File.split(target)
2058
+ target_prefix[0,0] = '/'
2059
+ else
2060
+ target_prefix = ""
2061
+ end
1465
2062
 
1466
- if target and EXPORT_PREFIX
1467
- if File.exist?(File.join(srcdir, target + '.def'))
1468
- deffile = "$(srcdir)/$(TARGET).def"
1469
- unless EXPORT_PREFIX.empty?
1470
- makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
2063
+ srcprefix ||= "$(srcdir)/#{srcprefix}".chomp('/')
2064
+ RbConfig.expand(srcdir = srcprefix.dup)
2065
+
2066
+ ext = ".#{$OBJEXT}"
2067
+ orig_srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
2068
+ if not $objs
2069
+ srcs = $srcs || orig_srcs
2070
+ objs = srcs.inject(Hash.new {[]}) {|h, f| h[File.basename(f, ".*") << ext] <<= f; h}
2071
+ $objs = objs.keys
2072
+ unless objs.delete_if {|b, f| f.size == 1}.empty?
2073
+ dups = objs.sort.map {|b, f|
2074
+ "#{b[/.*\./]}{#{f.collect {|n| n[/([^.]+)\z/]}.join(',')}}"
2075
+ }
2076
+ abort "source files duplication - #{dups.join(", ")}"
1471
2077
  end
1472
2078
  else
1473
- makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
2079
+ $objs.collect! {|o| File.basename(o, ".*") << ext} unless $OBJEXT == "o"
2080
+ srcs = $srcs || $objs.collect {|o| o.chomp(ext) << ".c"}
1474
2081
  end
1475
- if makedef
1476
- $distcleanfiles << '$(DEFFILE)'
1477
- origdef = deffile
1478
- deffile = "$(TARGET)-$(arch).def"
2082
+ $srcs = srcs
2083
+
2084
+ hdrs = Dir[File.join(srcdir, "*.{#{HDR_EXT.join(%q{,})}}")]
2085
+
2086
+ target = nil if $objs.empty?
2087
+
2088
+ if target and EXPORT_PREFIX
2089
+ if File.exist?(File.join(srcdir, target + '.def'))
2090
+ deffile = "$(srcdir)/$(TARGET).def"
2091
+ unless EXPORT_PREFIX.empty?
2092
+ makedef = %{-pe "$_.sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
2093
+ end
2094
+ else
2095
+ makedef = %{-e "puts 'EXPORTS', '$(TARGET_ENTRY)'"}
2096
+ end
2097
+ if makedef
2098
+ $cleanfiles << '$(DEFFILE)'
2099
+ origdef = deffile
2100
+ deffile = "$(TARGET)-$(arch).def"
2101
+ end
1479
2102
  end
1480
- end
1481
- origdef ||= ''
2103
+ origdef ||= ''
1482
2104
 
1483
- libpath = libpathflag(libpath)
2105
+ if $extout and $INSTALLFILES
2106
+ $cleanfiles.concat($INSTALLFILES.collect {|files, dir|File.join(dir, files.sub(/\A\.\//, ''))})
2107
+ $distcleandirs.concat($INSTALLFILES.collect {|files, dir| dir})
2108
+ end
2109
+
2110
+ if $extmk and not $extconf_h
2111
+ create_header
2112
+ end
2113
+
2114
+ libpath = libpathflag(libpath)
1484
2115
 
1485
- dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
1486
- staticlib = target ? "$(TARGET).#$LIBEXT" : ""
1487
- mfile = open("Makefile", "wb")
1488
- mfile.print configuration(srcprefix)
1489
- mfile.print "
2116
+ dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
2117
+ staticlib = target ? "$(TARGET).#$LIBEXT" : ""
2118
+ mfile = open("Makefile", "wb")
2119
+ conf = configuration(srcprefix)
2120
+ conf = yield(conf) if block_given?
2121
+ mfile.puts(conf)
2122
+ mfile.print "
1490
2123
  libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
1491
2124
  LIBPATH = #{libpath}
1492
2125
  DEFFILE = #{deffile}
1493
2126
 
1494
2127
  CLEANFILES = #{$cleanfiles.join(' ')}
1495
2128
  DISTCLEANFILES = #{$distcleanfiles.join(' ')}
2129
+ DISTCLEANDIRS = #{$distcleandirs.join(' ')}
1496
2130
 
1497
- extout = #{$extout}
2131
+ extout = #{$extout && $extout.quote}
1498
2132
  extout_prefix = #{$extout_prefix}
1499
2133
  target_prefix = #{target_prefix}
1500
2134
  LOCAL_LIBS = #{$LOCAL_LIBS}
1501
2135
  LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
1502
- SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
1503
- OBJS = #{$objs}
2136
+ ORIG_SRCS = #{orig_srcs.collect(&File.method(:basename)).join(' ')}
2137
+ SRCS = $(ORIG_SRCS) #{(srcs - orig_srcs).collect(&File.method(:basename)).join(' ')}
2138
+ OBJS = #{$objs.join(" ")}
2139
+ HDRS = #{hdrs.map{|h| '$(srcdir)/' + File.basename(h)}.join(' ')}
1504
2140
  TARGET = #{target}
2141
+ TARGET_NAME = #{target && target[/\A\w+/]}
2142
+ TARGET_ENTRY = #{EXPORT_PREFIX || ''}Init_$(TARGET_NAME)
1505
2143
  DLLIB = #{dllib}
1506
2144
  EXTSTATIC = #{$static || ""}
1507
2145
  STATIC_LIB = #{staticlib unless $static.nil?}
1508
2146
  #{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
1509
- "
1510
- install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
1511
- n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'
1512
- mfile.print "
2147
+ " #"
2148
+ # TODO: fixme
2149
+ install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
2150
+ n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET)'
2151
+ mfile.print "
1513
2152
  TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
1514
- CLEANLIBS = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map
1515
- CLEANOBJS = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak
2153
+ CLEANLIBS = #{n}.#{CONFIG['DLEXT']} #{config_string('cleanlibs') {|t| t.gsub(/\$\*/) {n}}}
2154
+ CLEANOBJS = *.#{$OBJEXT} #{config_string('cleanobjs') {|t| t.gsub(/\$\*/, "$(TARGET)#{deffile ? '-$(arch)': ''}")} if target} *.bak
1516
2155
 
1517
- all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
1518
- static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
2156
+ all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
2157
+ static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
2158
+ .PHONY: all install static install-so install-rb
2159
+ .PHONY: clean clean-so clean-static clean-rb
1519
2160
  "
1520
- mfile.print CLEANINGS
1521
- dirs = []
1522
- mfile.print "install: install-so install-rb\n\n"
1523
- sodir = (dir = "$(RUBYARCHDIR)").dup
1524
- mfile.print("install-so: ")
1525
- if target
1526
- f = "$(DLLIB)"
1527
- dest = "#{dir}/#{f}"
1528
- mfile.puts dir, "install-so: #{dest}"
1529
- unless $extout
1530
- mfile.print "#{dest}: #{f}\n"
1531
- if (sep = config_string('BUILD_FILE_SEPARATOR'))
1532
- f.gsub!("/", sep)
1533
- dir.gsub!("/", sep)
1534
- sep = ":/="+sep
1535
- f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1536
- f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1537
- dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1538
- dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1539
- end
1540
- mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
1541
- if defined?($installed_list)
1542
- mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
2161
+ mfile.print CLEANINGS
2162
+ fsep = config_string('BUILD_FILE_SEPARATOR') {|s| s unless s == "/"}
2163
+ if fsep
2164
+ sep = ":/=#{fsep}"
2165
+ fseprepl = proc {|s|
2166
+ s = s.gsub("/", fsep)
2167
+ s = s.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
2168
+ s = s.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
2169
+ }
2170
+ rsep = ":#{fsep}=/"
2171
+ else
2172
+ fseprepl = proc {|s| s}
2173
+ sep = ""
2174
+ rsep = ""
2175
+ end
2176
+ dirs = []
2177
+ mfile.print "install: install-so install-rb\n\n"
2178
+ sodir = (dir = "$(RUBYARCHDIR)").dup
2179
+ mfile.print("install-so: ")
2180
+ if target
2181
+ f = "$(DLLIB)"
2182
+ dest = "#{dir}/#{f}"
2183
+ if $extout
2184
+ mfile.puts dest
2185
+ mfile.print "clean-so::\n"
2186
+ mfile.print "\t-$(Q)$(RM) #{fseprepl[dest]}\n"
2187
+ mfile.print "\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n"
2188
+ else
2189
+ mfile.print "#{f} #{timestamp_file(dir)}\n"
2190
+ mfile.print "\t$(INSTALL_PROG) #{fseprepl[f]} #{dir}\n"
2191
+ if defined?($installed_list)
2192
+ mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
2193
+ end
1543
2194
  end
2195
+ mfile.print "clean-static::\n"
2196
+ mfile.print "\t-$(Q)$(RM) $(STATIC_LIB)\n"
2197
+ else
2198
+ mfile.puts "Makefile"
1544
2199
  end
1545
- else
1546
- mfile.puts "Makefile"
1547
- end
1548
- mfile.print("install-rb: pre-install-rb install-rb-default\n")
1549
- mfile.print("install-rb-default: pre-install-rb-default\n")
1550
- mfile.print("pre-install-rb: Makefile\n")
1551
- mfile.print("pre-install-rb-default: Makefile\n")
1552
- for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
1553
- files = install_files(mfile, i, nil, srcprefix) or next
1554
- for dir, *files in files
1555
- unless dirs.include?(dir)
1556
- dirs << dir
1557
- mfile.print "pre-install-rb#{sfx}: #{dir}\n"
2200
+ mfile.print("install-rb: pre-install-rb install-rb-default\n")
2201
+ mfile.print("install-rb-default: pre-install-rb-default\n")
2202
+ mfile.print("pre-install-rb: Makefile\n")
2203
+ mfile.print("pre-install-rb-default: Makefile\n")
2204
+ for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
2205
+ files = install_files(mfile, i, nil, srcprefix) or next
2206
+ for dir, *files in files
2207
+ unless dirs.include?(dir)
2208
+ dirs << dir
2209
+ mfile.print "pre-install-rb#{sfx}: #{timestamp_file(dir)}\n"
2210
+ end
2211
+ for f in files
2212
+ dest = "#{dir}/#{File.basename(f)}"
2213
+ mfile.print("install-rb#{sfx}: #{dest}\n")
2214
+ mfile.print("#{dest}: #{f} #{timestamp_file(dir)}\n")
2215
+ mfile.print("\t$(Q) $(#{$extout ? 'COPY' : 'INSTALL_DATA'}) #{f} $(@D#{sep})\n")
2216
+ if defined?($installed_list) and !$extout
2217
+ mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
2218
+ end
2219
+ if $extout
2220
+ mfile.print("clean-rb#{sfx}::\n")
2221
+ mfile.print("\t-$(Q)$(RM) #{fseprepl[dest]}\n")
2222
+ end
2223
+ end
1558
2224
  end
1559
- files.each do |f|
1560
- dest = "#{dir}/#{File.basename(f)}"
1561
- mfile.print("install-rb#{sfx}: #{dest}\n")
1562
- mfile.print("#{dest}: #{f} #{dir}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
1563
- sep = config_string('BUILD_FILE_SEPARATOR')
1564
- if sep
1565
- f = f.gsub("/", sep)
1566
- sep = ":/="+sep
1567
- f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
1568
- f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
1569
- else
1570
- sep = ""
1571
- end
1572
- mfile.print("#{f} $(@D#{sep})\n")
1573
- if defined?($installed_list) and !$extout
1574
- mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
1575
- end
2225
+ mfile.print "pre-install-rb#{sfx}:\n"
2226
+ mfile.print("\t$(ECHO) installing#{sfx.sub(/^-/, " ")} #{target} libraries\n")
2227
+ if $extout
2228
+ dirs.uniq!
2229
+ unless dirs.empty?
2230
+ mfile.print("clean-rb#{sfx}::\n")
2231
+ for dir in dirs.sort_by {|d| -d.count('/')}
2232
+ mfile.print("\t-$(Q)$(RMDIRS) #{fseprepl[dir]}#{$ignore_error}\n")
2233
+ end
2234
+ end
1576
2235
  end
1577
2236
  end
1578
- end
1579
- dirs.unshift(sodir) if target and !dirs.include?(sodir)
1580
- dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}
2237
+ dirs.unshift(sodir) if target and !dirs.include?(sodir)
2238
+ dirs.each do |d|
2239
+ t = timestamp_file(d)
2240
+ mfile.print "#{t}:\n\t$(Q) $(MAKEDIRS) #{d}\n\t$(Q) $(TOUCH) $@\n"
2241
+ end
1581
2242
 
1582
- mfile.print <<-SITEINSTALL
2243
+ mfile.print <<-SITEINSTALL
1583
2244
 
1584
2245
  site-install: site-install-so site-install-rb
1585
2246
  site-install-so: install-so
1586
2247
  site-install-rb: install-rb
1587
2248
 
1588
- SITEINSTALL
2249
+ SITEINSTALL
1589
2250
 
1590
- return unless target
2251
+ return unless target
1591
2252
 
1592
- mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
1593
- mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
1594
- mfile.print "\n"
2253
+ mfile.puts SRC_EXT.collect {|e| ".path.#{e} = $(VPATH)"} if $nmake == ?b
2254
+ mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
2255
+ mfile.print "\n"
1595
2256
 
1596
- CXX_EXT.each do |ext|
1597
- COMPILE_RULES.each do |rule|
1598
- mfile.printf(rule, ext, $OBJEXT)
1599
- mfile.printf("\n\t%s\n\n", COMPILE_CXX)
2257
+ compile_command = "\n\t$(ECHO) compiling $(<#{rsep})\n\t$(Q) %s\n\n"
2258
+ CXX_EXT.each do |e|
2259
+ each_compile_rules do |rule|
2260
+ mfile.printf(rule, e, $OBJEXT)
2261
+ mfile.printf(compile_command, COMPILE_CXX)
2262
+ end
1600
2263
  end
1601
- end
1602
- %w[c].each do |ext|
1603
- COMPILE_RULES.each do |rule|
1604
- mfile.printf(rule, ext, $OBJEXT)
1605
- mfile.printf("\n\t%s\n\n", COMPILE_C)
2264
+ C_EXT.each do |e|
2265
+ each_compile_rules do |rule|
2266
+ mfile.printf(rule, e, $OBJEXT)
2267
+ mfile.printf(compile_command, COMPILE_C)
2268
+ end
1606
2269
  end
1607
- end
1608
2270
 
1609
- mfile.print "$(RUBYARCHDIR)/" if $extout
1610
- mfile.print "$(DLLIB): "
1611
- mfile.print "$(DEFFILE) " if makedef
1612
- mfile.print "$(OBJS) Makefile\n"
1613
- mfile.print "\t@-$(RM) $@\n"
1614
- mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
1615
- link_so = LINK_SO.gsub(/^/, "\t")
1616
- mfile.print link_so, "\n\n"
1617
- unless $static.nil?
1618
- mfile.print "$(STATIC_LIB): $(OBJS)\n\t"
1619
- mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
1620
- config_string('RANLIB') do |ranlib|
1621
- mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
2271
+ mfile.print "$(RUBYARCHDIR)/" if $extout
2272
+ mfile.print "$(DLLIB): "
2273
+ mfile.print "$(DEFFILE) " if makedef
2274
+ mfile.print "$(OBJS) Makefile"
2275
+ mfile.print " #{timestamp_file('$(RUBYARCHDIR)')}" if $extout
2276
+ mfile.print "\n"
2277
+ mfile.print "\t$(ECHO) linking shared-object #{target_prefix.sub(/\A\/(.*)/, '\1/')}$(DLLIB)\n"
2278
+ mfile.print "\t-$(Q)$(RM) $(@#{sep})\n"
2279
+ link_so = LINK_SO.gsub(/^/, "\t$(Q) ")
2280
+ if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===))
2281
+ link_so = link_so.sub(/\bLDSHARED\b/, '\&XX')
1622
2282
  end
1623
- end
1624
- mfile.print "\n\n"
1625
- if makedef
1626
- mfile.print "$(DEFFILE): #{origdef}\n"
1627
- mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
1628
- end
1629
-
1630
- depend = File.join(srcdir, "depend")
1631
- if File.exist?(depend)
1632
- suffixes = []
1633
- depout = []
1634
- open(depend, "r") do |dfile|
1635
- mfile.printf "###\n"
1636
- cont = implicit = nil
1637
- impconv = proc do
1638
- COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
1639
- implicit = nil
1640
- end
1641
- ruleconv = proc do |line|
1642
- if implicit
1643
- if /\A\t/ =~ line
1644
- implicit[1] << line
1645
- next
1646
- else
1647
- impconv[]
1648
- end
1649
- end
1650
- if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
1651
- suffixes << m[1] << m[2]
1652
- implicit = [[m[1], m[2]], [m.post_match]]
1653
- next
1654
- elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
1655
- line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
1656
- end
1657
- depout << line
1658
- end
1659
- while line = dfile.gets()
1660
- line.gsub!(/\.o\b/, ".#{$OBJEXT}")
1661
- line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $config_h
1662
- if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
1663
- (cont ||= []) << line
1664
- next
1665
- elsif cont
1666
- line = (cont << line).join
1667
- cont = nil
1668
- end
1669
- ruleconv.call(line)
1670
- end
1671
- if cont
1672
- ruleconv.call(cont.join)
1673
- elsif implicit
1674
- impconv.call
2283
+ mfile.print link_so, "\n\n"
2284
+ unless $static.nil?
2285
+ mfile.print "$(STATIC_LIB): $(OBJS)\n\t-$(Q)$(RM) $(@#{sep})\n\t"
2286
+ mfile.print "$(ECHO) linking static-library $(@#{rsep})\n\t$(Q) "
2287
+ mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
2288
+ config_string('RANLIB') do |ranlib|
2289
+ mfile.print "\n\t-$(Q)#{ranlib} $(DLLIB) 2> /dev/null || true"
1675
2290
  end
1676
2291
  end
1677
- unless suffixes.empty?
1678
- mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
2292
+ mfile.print "\n\n"
2293
+ if makedef
2294
+ mfile.print "$(DEFFILE): #{origdef}\n"
2295
+ mfile.print "\t$(ECHO) generating $(@#{rsep})\n"
2296
+ mfile.print "\t$(Q) $(RUBY) #{makedef} #{origdef} > $@\n\n"
1679
2297
  end
1680
- mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h
1681
- mfile.print depout
1682
- else
1683
- headers = %w[ruby.h defines.h]
1684
- if RULE_SUBST
1685
- headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}
2298
+
2299
+ depend = File.join(srcdir, "depend")
2300
+ if File.exist?(depend)
2301
+ mfile.print("###\n", *depend_rules(File.read(depend)))
2302
+ else
2303
+ mfile.print "$(OBJS): $(HDRS) $(ruby_headers)\n"
1686
2304
  end
1687
- headers << $config_h if $config_h
1688
- headers << "$(RUBY_EXTCONF_H)" if $extconf_h
1689
- mfile.print "$(OBJS): ", headers.join(' '), "\n"
1690
- end
1691
2305
 
1692
- $makefile_created = true
1693
- ensure
1694
- mfile.close if mfile
1695
- end
2306
+ $makefile_created = true
2307
+ ensure
2308
+ mfile.close if mfile
2309
+ end
2310
+
2311
+ # :stopdoc:
2312
+
2313
+ def init_mkmf(config = CONFIG, rbconfig = RbConfig::CONFIG)
2314
+ $makefile_created = false
2315
+ $arg_config = []
2316
+ $enable_shared = config['ENABLE_SHARED'] == 'yes'
2317
+ $defs = []
2318
+ $extconf_h = nil
2319
+ if $warnflags = CONFIG['warnflags'] and CONFIG['GCC'] == 'yes'
2320
+ # turn warnings into errors only for bundled extensions.
2321
+ config['warnflags'] = $warnflags.gsub(/(\A|\s)-Werror[-=]/, '\1-W')
2322
+ RbConfig.expand(rbconfig['warnflags'] = config['warnflags'].dup)
2323
+ config.each do |key, val|
2324
+ RbConfig.expand(rbconfig[key] = val.dup) if /warnflags/ =~ val
2325
+ end
2326
+ $warnflags = config['warnflags'] unless $extmk
2327
+ end
2328
+ $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
2329
+ $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
2330
+ $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
2331
+ $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
2332
+ $INCFLAGS = "-I$(arch_hdrdir)"
2333
+ $INCFLAGS << " -I$(hdrdir)/ruby/backward" unless $extmk
2334
+ $INCFLAGS << " -I$(hdrdir) -I$(srcdir)"
2335
+ $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
2336
+ $LIBEXT = config['LIBEXT'].dup
2337
+ $OBJEXT = config["OBJEXT"].dup
2338
+ $EXEEXT = config["EXEEXT"].dup
2339
+ $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
2340
+ $LIBRUBYARG = ""
2341
+ $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
2342
+ $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
2343
+ $DEFLIBPATH = [$extmk ? "$(topdir)" : "$(libdir)"]
2344
+ $DEFLIBPATH.unshift(".")
2345
+ $LIBPATH = []
2346
+ $INSTALLFILES = []
2347
+ $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
2348
+ $VPATH = %w[$(srcdir) $(arch_hdrdir)/ruby $(hdrdir)/ruby]
2349
+
2350
+ $objs = nil
2351
+ $srcs = nil
2352
+ $libs = ""
2353
+ if $enable_shared or RbConfig.expand(config["LIBRUBY"].dup) != RbConfig.expand(config["LIBRUBY_A"].dup)
2354
+ $LIBRUBYARG = config['LIBRUBYARG']
2355
+ end
1696
2356
 
1697
- # :stopdoc:
2357
+ $LOCAL_LIBS = ""
1698
2358
 
1699
- def init_mkmf(config = CONFIG)
1700
- $makefile_created = false
1701
- $arg_config = []
1702
- $enable_shared = config['ENABLE_SHARED'] == 'yes'
1703
- $defs = []
1704
- $extconf_h = nil
1705
- $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
1706
- $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
1707
- $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
1708
- $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
1709
- $INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)"
1710
- $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
1711
- $LIBEXT = config['LIBEXT'].dup
1712
- $OBJEXT = config["OBJEXT"].dup
1713
- $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
1714
- $LIBRUBYARG = ""
1715
- $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
1716
- $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
1717
- $DEFLIBPATH = [$extmk ? "$(topdir)" : "$(libdir)"]
1718
- $DEFLIBPATH.unshift(".")
1719
-
1720
- # ---------------------- Changed for Rubinius --------------------------------
1721
- # Make sure that we include the lib paths here that we may find libraries so
1722
- # that built in extensions will also find them if they have been configured
1723
- # at build time for Rubinius.
1724
- Rubinius::BUILD_CONFIG[:include_dirs].each do |inc|
1725
- $INCFLAGS << " -I#{inc.quote}"
1726
- end
1727
- Rubinius::BUILD_CONFIG[:lib_dirs].each do |lib|
1728
- $DEFLIBPATH << lib
1729
- end
1730
- # ----------------------------------------------------------------------------
1731
-
1732
- $LIBPATH = []
1733
- $INSTALLFILES = []
1734
- $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
1735
-
1736
- $objs = nil
1737
- $srcs = nil
1738
- $libs = ""
1739
- if $enable_shared or RbConfig.expand(config["LIBRUBY"].dup) != RbConfig.expand(config["LIBRUBY_A"].dup)
1740
- $LIBRUBYARG = config['LIBRUBYARG']
1741
- end
1742
-
1743
- $LOCAL_LIBS = ""
1744
-
1745
- $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
1746
- $cleanfiles << "mkmf.log"
1747
- $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
1748
-
1749
- $extout ||= nil
1750
- $extout_prefix ||= nil
1751
-
1752
- $arg_config.clear
1753
- dir_config("opt")
1754
- end
2359
+ $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
2360
+ $cleanfiles << "mkmf.log"
2361
+ $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
2362
+ $distcleandirs = config_string('DISTCLEANDIRS') {|s| Shellwords.shellwords(s)} || []
2363
+
2364
+ $extout ||= nil
2365
+ $extout_prefix ||= nil
2366
+
2367
+ @libdir_basename = config["libdir"] && config["libdir"][/\A\$\(exec_prefix\)\/(.*)/, 1] or "lib"
1755
2368
 
1756
- FailedMessage = <<MESSAGE
1757
- Could not create Makefile due to some reason, probably lack of
1758
- necessary libraries and/or headers. Check the mkmf.log file for more
1759
- details. You may need configuration options.
2369
+ $arg_config.clear
2370
+ dir_config("opt")
2371
+ end
2372
+
2373
+ FailedMessage = <<MESSAGE
2374
+ Could not create Makefile due to some reason, probably lack of necessary
2375
+ libraries and/or headers. Check the mkmf.log file for more details. You may
2376
+ need configuration options.
1760
2377
 
1761
2378
  Provided configuration options:
1762
2379
  MESSAGE
1763
2380
 
1764
- # Returns whether or not the Makefile was successfully generated. If not,
1765
- # the script will abort with an error message.
1766
- #
1767
- # Internal use only.
1768
- #
1769
- def mkmf_failed(path)
1770
- unless $makefile_created or File.exist?("Makefile")
1771
- opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"}
1772
- abort "*** #{path} failed ***\n" + FailedMessage + opts.join
2381
+ # Returns whether or not the Makefile was successfully generated. If not,
2382
+ # the script will abort with an error message.
2383
+ #
2384
+ # Internal use only.
2385
+ #
2386
+ def mkmf_failed(path)
2387
+ unless $makefile_created or File.exist?("Makefile")
2388
+ opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"}
2389
+ abort "*** #{path} failed ***\n" + FailedMessage + opts.join
2390
+ end
1773
2391
  end
1774
- end
1775
2392
 
1776
- # :startdoc:
2393
+ def MAIN_DOES_NOTHING(*refs)
2394
+ src = MAIN_DOES_NOTHING
2395
+ unless refs.empty?
2396
+ src = src.sub(/\{/) do
2397
+ $& +
2398
+ "\n if (argc > 1000000) {\n" +
2399
+ refs.map {|n|" printf(\"%p\", &#{n});\n"}.join("") +
2400
+ " }\n"
2401
+ end
2402
+ end
2403
+ src
2404
+ end
1777
2405
 
1778
- init_mkmf
2406
+ extend self
2407
+ init_mkmf
1779
2408
 
1780
- $make = with_config("make-prog", ENV["MAKE"] || "make")
1781
- make, = Shellwords.shellwords($make)
1782
- $nmake = nil
1783
- case
1784
- when $mswin
1785
- $nmake = ?m if /nmake/i =~ make
1786
- when $bccwin
1787
- $nmake = ?b if /Borland/i =~ `#{make} -h`
1788
- end
2409
+ $make = with_config("make-prog", ENV["MAKE"] || "make")
2410
+ make, = Shellwords.shellwords($make)
2411
+ $nmake = nil
2412
+ case
2413
+ when $mswin
2414
+ $nmake = ?m if /nmake/i =~ make
2415
+ when $bccwin
2416
+ $nmake = ?b if /Borland/i =~ `#{make} -h`
2417
+ end
2418
+ $ignore_error = $nmake ? '' : ' 2> /dev/null || true'
1789
2419
 
1790
- RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] =
1791
- $srcdir = arg_config("--srcdir", File.dirname($0))
1792
- $configure_args["--topsrcdir"] ||= $srcdir
1793
- if $curdir = arg_config("--curdir")
1794
- RbConfig.expand(curdir = $curdir.dup)
1795
- else
1796
- curdir = $curdir = "."
1797
- end
1798
- unless File.expand_path(RbConfig::CONFIG["topdir"]) == File.expand_path(curdir)
1799
- CONFIG["topdir"] = $curdir
1800
- RbConfig::CONFIG["topdir"] = curdir
1801
- end
1802
- $configure_args["--topdir"] ||= $curdir
1803
- $ruby = arg_config("--ruby", File.join(RbConfig::CONFIG["bindir"], CONFIG["ruby_install_name"]))
2420
+ RbConfig::CONFIG["srcdir"] = CONFIG["srcdir"] =
2421
+ $srcdir = arg_config("--srcdir", File.dirname($0))
2422
+ $configure_args["--topsrcdir"] ||= $srcdir
2423
+ if $curdir = arg_config("--curdir")
2424
+ RbConfig.expand(curdir = $curdir.dup)
2425
+ else
2426
+ curdir = $curdir = "."
2427
+ end
2428
+ unless File.expand_path(RbConfig::CONFIG["topdir"]) == File.expand_path(curdir)
2429
+ CONFIG["topdir"] = $curdir
2430
+ RbConfig::CONFIG["topdir"] = curdir
2431
+ end
2432
+ $configure_args["--topdir"] ||= $curdir
2433
+ $ruby = arg_config("--ruby", File.join(RbConfig::CONFIG["bindir"], CONFIG["ruby_install_name"]))
1804
2434
 
1805
- split = Shellwords.method(:shellwords).to_proc
2435
+ # :startdoc:
1806
2436
 
1807
- EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
2437
+ split = Shellwords.method(:shellwords).to_proc
1808
2438
 
1809
- hdr = []
1810
- config_string('COMMON_MACROS') do |s|
1811
- Shellwords.shellwords(s).each do |w|
1812
- hdr << "#define " + w.split(/=/, 2).join(" ")
2439
+ EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
2440
+
2441
+ hdr = ['#include "ruby.h"' "\n"]
2442
+ config_string('COMMON_MACROS') do |s|
2443
+ Shellwords.shellwords(s).each do |w|
2444
+ w, v = w.split(/=/, 2)
2445
+ hdr << "#ifndef #{w}"
2446
+ hdr << "#define #{[w, v].compact.join(" ")}"
2447
+ hdr << "#endif /* #{w} */"
2448
+ end
1813
2449
  end
1814
- end
1815
- config_string('COMMON_HEADERS') do |s|
1816
- Shellwords.shellwords(s).each {|s| hdr << "#include <#{s}>"}
1817
- end
1818
- COMMON_HEADERS = hdr.join("\n")
1819
- COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
1820
-
1821
- COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
1822
- RULE_SUBST = config_string('RULE_SUBST')
1823
- COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<'
1824
- COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<'
1825
- TRY_LINK = config_string('TRY_LINK') ||
1826
- "$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \
1827
- "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
1828
- LINK_SO = config_string('LINK_SO') ||
1829
- if CONFIG["DLEXT"] == $OBJEXT
1830
- "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
1831
- else
1832
- "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \
1833
- "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)"
2450
+ config_string('COMMON_HEADERS') do |s|
2451
+ Shellwords.shellwords(s).each {|w| hdr << "#include <#{w}>"}
2452
+ end
2453
+
2454
+ ##
2455
+ # Common headers for ruby C extensions
2456
+
2457
+ COMMON_HEADERS = hdr.join("\n")
2458
+
2459
+ ##
2460
+ # Common libraries for ruby C extensions
2461
+
2462
+ COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
2463
+
2464
+ ##
2465
+ # make compile rules
2466
+
2467
+ COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
2468
+ RULE_SUBST = config_string('RULE_SUBST')
2469
+
2470
+ ##
2471
+ # Command which will compile C files in the generated Makefile
2472
+
2473
+ COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) $(COUTFLAG)$@ -c $<'
2474
+
2475
+ ##
2476
+ # Command which will compile C++ files in the generated Makefile
2477
+
2478
+ COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) $(COUTFLAG)$@ -c $<'
2479
+
2480
+ ##
2481
+ # Command which will compile a program in order to test linking a library
2482
+
2483
+ TRY_LINK = config_string('TRY_LINK') ||
2484
+ "$(CC) #{OUTFLAG}conftest#{$EXEEXT} $(INCFLAGS) $(CPPFLAGS) " \
2485
+ "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
2486
+
2487
+ ##
2488
+ # Command which will link a shared library
2489
+
2490
+ LINK_SO = (config_string('LINK_SO') || "").sub(/^$/) do
2491
+ if CONFIG["DLEXT"] == $OBJEXT
2492
+ "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
2493
+ else
2494
+ "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \
2495
+ "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)"
2496
+ end
1834
2497
  end
1835
- LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"'
1836
- RPATHFLAG = config_string('RPATHFLAG') || ''
1837
- LIBARG = config_string('LIBARG') || '-l%s'
1838
2498
 
1839
- sep = config_string('BUILD_FILE_SEPARATOR') {|sep| ":/=#{sep}" if sep != "/"} || ""
1840
- CLEANINGS = "
1841
- clean:
1842
- @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})
2499
+ ##
2500
+ # Argument which will add a library path to the linker
2501
+
2502
+ LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L%s'
2503
+ RPATHFLAG = config_string('RPATHFLAG') || ''
2504
+
2505
+ ##
2506
+ # Argument which will add a library to the linker
1843
2507
 
1844
- distclean: clean
1845
- @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
1846
- @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
2508
+ LIBARG = config_string('LIBARG') || '-l%s'
1847
2509
 
1848
- realclean: distclean
2510
+ ##
2511
+ # A C main function which does no work
2512
+
2513
+ MAIN_DOES_NOTHING = config_string('MAIN_DOES_NOTHING') || "int main(int argc, char **argv)\n{\n return 0;\n}"
2514
+ UNIVERSAL_INTS = config_string('UNIVERSAL_INTS') {|s| Shellwords.shellwords(s)} ||
2515
+ %w[int short long long\ long]
2516
+
2517
+ sep = config_string('BUILD_FILE_SEPARATOR') {|s| ":/=#{s}" if s != "/"} || ""
2518
+
2519
+ ##
2520
+ # Makefile rules that will clean the extension build directory
2521
+
2522
+ CLEANINGS = "
2523
+ clean-static::
2524
+ clean-rb-default::
2525
+ clean-rb::
2526
+ clean-so::
2527
+ clean: clean-so clean-static clean-rb-default clean-rb
2528
+ \t\t-$(Q)$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep}) .*.time
2529
+
2530
+ distclean-rb-default::
2531
+ distclean-rb::
2532
+ distclean-so::
2533
+ distclean-static::
2534
+ distclean: clean distclean-so distclean-static distclean-rb-default distclean-rb
2535
+ \t\t-$(Q)$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
2536
+ \t\t-$(Q)$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
2537
+ \t\t-$(Q)$(RMDIRS) $(DISTCLEANDIRS#{sep})#{$ignore_error}
2538
+
2539
+ realclean: distclean
1849
2540
  "
2541
+ end
2542
+
2543
+ include MakeMakefile
1850
2544
 
1851
2545
  if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
1852
2546
  END {mkmf_failed($0)}