rubysl-mkmf 1.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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)}