rubysl-mkmf 1.0.0

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4c4f5efc11b2edf183b785fe82a7ef7771979815
4
+ data.tar.gz: 08d9fc19efe61a666083e85ea94ccd2f9e41f49a
5
+ SHA512:
6
+ metadata.gz: c8fdb4ecc6cc1c2c111289f08ecd36bd86ca14c4dd260ef32c4b537e7912fdd521ebc596f18082f64c3762291d5b80db5c3285b42049b385788ea48e2f286f13
7
+ data.tar.gz: e5f6d761f5ff65e8490ec2add707d220bfb7f9da89e492b59ebc44eed96dfc7058085253cffaca3d98b3a3f48e4b9fd7b1ce90f398f3d9c01eccbbd5885b956c
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in rubysl-mkmf.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,25 @@
1
+ Copyright (c) 2013, Brian Shirai
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without
5
+ modification, are permitted provided that the following conditions are met:
6
+
7
+ 1. Redistributions of source code must retain the above copyright notice, this
8
+ list of conditions and the following disclaimer.
9
+ 2. Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ 3. Neither the name of the library nor the names of its contributors may be
13
+ used to endorse or promote products derived from this software without
14
+ specific prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY DIRECT,
20
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23
+ OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
25
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Rubysl::Mkmf
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rubysl-mkmf'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rubysl-mkmf
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/lib/mkmf.rb ADDED
@@ -0,0 +1 @@
1
+ require "rubysl/mkmf"
@@ -0,0 +1,2 @@
1
+ require "rubysl/mkmf/version"
2
+ require "rubysl/mkmf/mkmf"
@@ -0,0 +1,1853 @@
1
+ # module to create Makefile for extension modules
2
+ # invoke like: ruby -r mkmf extconf.rb
3
+
4
+ require 'rbconfig'
5
+ require 'fileutils'
6
+ require 'shellwords'
7
+
8
+ CONFIG = RbConfig::MAKEFILE_CONFIG
9
+ ORIG_LIBPATH = ENV['LIB']
10
+
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
45
+ end
46
+ end
47
+
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/)
68
+
69
+ # :stopdoc:
70
+
71
+ def config_string(key, config = CONFIG)
72
+ s = config[key] and !s.empty? and block_given? ? yield(s) : s
73
+ end
74
+
75
+ def dir_re(dir)
76
+ Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$(?:\(target_prefix\)|\{target_prefix\}))?')
77
+ end
78
+
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
127
+
128
+ def map_dir(dir, map = nil)
129
+ map ||= INSTALL_DIRS
130
+ map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}
131
+ end
132
+
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
139
+
140
+ $top_srcdir = $topdir
141
+ $hdrdir = $topdir
142
+
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
+ # ----------------------------------------------------------------------------
147
+
148
+ OUTFLAG = CONFIG['OUTFLAG']
149
+ CPPOUTFILE = CONFIG['CPPOUTFILE']
150
+
151
+ CONFTEST_C = "conftest.c"
152
+
153
+ class String
154
+ # Wraps a string in escaped quotes if it contains whitespace.
155
+ def quote
156
+ /\s/ =~ self ? "\"#{self}\"" : "#{self}"
157
+ end
158
+
159
+ # Generates a string used as cpp macro name.
160
+ def tr_cpp
161
+ strip.upcase.tr_s("^A-Z0-9_", "_")
162
+ 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}
168
+ end
169
+ end
170
+
171
+ def rm_f(*files)
172
+ FileUtils.rm_f(Dir[files.join("\0")])
173
+ end
174
+
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
182
+
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
194
+ end
195
+ x.concat(y[yn..-1] || [])
196
+ end
197
+ end
198
+
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)
222
+ end
223
+
224
+ def self::message(*s)
225
+ @log ||= File::open(@logfile, 'w')
226
+ @log.sync = true
227
+ @log.printf(*s)
228
+ end
229
+
230
+ def self::logfile file
231
+ @logfile = file
232
+ if @log and not @log.closed?
233
+ @log.flush
234
+ @log.close
235
+ @log = nil
236
+ end
237
+ 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})
246
+ @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
252
+ end
253
+ end
254
+ end
255
+
256
+ class << self
257
+ attr_accessor :quiet
258
+ end
259
+ end
260
+
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]}
267
+ end
268
+ Logging::open do
269
+ puts command.quote
270
+ system(command)
271
+ end
272
+ end
273
+
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}"
281
+ end
282
+ IO.popen(command, *mode, &block)
283
+ end
284
+ end
285
+
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:
291
+ /* begin */
292
+ EOM
293
+ src.each_with_index {|line, no| Logging::message fmt, no+1, line}
294
+ Logging::message <<"EOM"
295
+ /* end */
296
+
297
+ EOM
298
+ end
299
+
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
305
+ end
306
+ src
307
+ end
308
+
309
+ def try_do(src, command, &b)
310
+ src = create_tmpsrc(src, &b)
311
+ xsystem(command)
312
+ ensure
313
+ log_src(src)
314
+ end
315
+
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
329
+
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
335
+
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
341
+
342
+ def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
343
+ libpath.map{|x|
344
+ case x
345
+ when "$(topdir)", /\A\./
346
+ LIBPATHFLAG
347
+ else
348
+ LIBPATHFLAG+RPATHFLAG
349
+ end % x.quote
350
+ }.join
351
+ end
352
+
353
+ def try_link0(src, opt="", &b)
354
+ try_do(src, link_command("", opt), &b)
355
+ end
356
+
357
+ def try_link(src, opt="", &b)
358
+ try_link0(src, opt, &b)
359
+ ensure
360
+ rm_f "conftest*", "c0x32*"
361
+ end
362
+
363
+ def try_compile(src, opt="", &b)
364
+ try_do(src, cc_command(opt), &b)
365
+ ensure
366
+ rm_f "conftest*"
367
+ end
368
+
369
+ def try_cpp(src, opt="", &b)
370
+ try_do(src, cpp_command(CPPOUTFILE, opt), &b)
371
+ ensure
372
+ rm_f "conftest*"
373
+ end
374
+
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
+ ""
381
+ end
382
+ end
383
+
384
+ def with_cppflags(flags)
385
+ cppflags = $CPPFLAGS
386
+ $CPPFLAGS = flags
387
+ ret = yield
388
+ ensure
389
+ $CPPFLAGS = cppflags unless ret
390
+ end
391
+
392
+ def with_cflags(flags)
393
+ cflags = $CFLAGS
394
+ $CFLAGS = flags
395
+ ret = yield
396
+ ensure
397
+ $CFLAGS = cflags unless ret
398
+ end
399
+
400
+ def with_ldflags(flags)
401
+ ldflags = $LDFLAGS
402
+ $LDFLAGS = flags
403
+ ret = yield
404
+ ensure
405
+ $LDFLAGS = ldflags unless ret
406
+ end
407
+
408
+ def try_static_assert(expr, headers = nil, opt = "", &b)
409
+ headers = cpp_include(headers)
410
+ try_compile(<<SRC, opt, &b)
411
+ #{COMMON_HEADERS}
412
+ #{headers}
413
+ /*top*/
414
+ int conftest_const[(#{expr}) ? 1 : -1];
415
+ SRC
416
+ end
417
+
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
443
+ else
444
+ upper = mid
445
+ end
446
+ end
447
+ upper = -upper if neg
448
+ return upper
449
+ else
450
+ src = %{#{COMMON_HEADERS}
451
+ #{includes}
452
+ #include <stdio.h>
453
+ /*top*/
454
+ int conftest_const = (int)(#{const});
455
+ int main() {printf("%d\\n", conftest_const); return 0;}
456
+ }
457
+ if try_link0(src, opt, &b)
458
+ xpopen("./conftest") do |f|
459
+ return Integer(f.gets)
460
+ end
461
+ end
462
+ end
463
+ nil
464
+ end
465
+
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}
470
+ #{headers}
471
+ /*top*/
472
+ int main() { return 0; }
473
+ int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }
474
+ SRC
475
+ #{headers}
476
+ /*top*/
477
+ int main() { return 0; }
478
+ int t() { #{func}(); return 0; }
479
+ SRC
480
+ end
481
+
482
+ def try_var(var, headers = nil, &b)
483
+ headers = cpp_include(headers)
484
+ try_compile(<<"SRC", &b)
485
+ #{COMMON_HEADERS}
486
+ #{headers}
487
+ /*top*/
488
+ int main() { return 0; }
489
+ int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
490
+ SRC
491
+ end
492
+
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)
511
+ end
512
+ end
513
+ end
514
+ ensure
515
+ rm_f "conftest*"
516
+ log_src(src)
517
+ end
518
+
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)
523
+ /*top*/
524
+ #ifndef #{macro}
525
+ # error
526
+ >>>>>> #{macro} undefined <<<<<<
527
+ #endif
528
+ 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
+ end
537
+ ensure
538
+ rm_f "conftest*"
539
+ end
540
+
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
555
+ 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
572
+ 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
578
+ end
579
+ end
580
+ dirs
581
+ end
582
+
583
+ def install_rb(mfile, dest, srcdir = nil)
584
+ install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
585
+ end
586
+
587
+ def append_library(libs, lib) # :no-doc:
588
+ format(LIBARG, lib) + " " + libs
589
+ end
590
+
591
+ def message(*s)
592
+ unless Logging.quiet and not $VERBOSE
593
+ printf(*s)
594
+ $stdout.flush
595
+ end
596
+ end
597
+
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
617
+
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)
624
+ end
625
+ end
626
+ msg << " #{pre} #{noun}" unless noun.empty?
627
+ end
628
+ msg
629
+ end
630
+ end
631
+
632
+ # :startdoc:
633
+
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)
642
+ end
643
+ end
644
+
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
666
+ true
667
+ else
668
+ false
669
+ end
670
+ end
671
+ end
672
+ end
673
+
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]
691
+ end
692
+ if r
693
+ $libs = libs
694
+ libpath = nil
695
+ end
696
+ ensure
697
+ $LIBPATH = libpath if libpath
698
+ end
699
+ r
700
+ end
701
+ end
702
+
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
718
+ end
719
+ end
720
+ end
721
+
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
737
+ end
738
+ end
739
+ end
740
+
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
755
+ end
756
+ end
757
+ end
758
+
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
779
+ end
780
+ end
781
+ found
782
+ end
783
+ end
784
+ end
785
+
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}
801
+ #{cpp_include(headers)}
802
+ /*top*/
803
+ int main() { return 0; }
804
+ int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
805
+ SRC
806
+ $defs.push(format("-DHAVE_ST_%s", member.tr_cpp))
807
+ true
808
+ else
809
+ false
810
+ end
811
+ end
812
+ end
813
+
814
+ def try_type(type, headers = nil, opt = "", &b)
815
+ if try_compile(<<"SRC", opt, &b)
816
+ #{COMMON_HEADERS}
817
+ #{cpp_include(headers)}
818
+ /*top*/
819
+ typedef #{type} conftest_type;
820
+ int conftestval[sizeof(conftest_type)?1:-1];
821
+ SRC
822
+ $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
823
+ true
824
+ else
825
+ false
826
+ end
827
+ end
828
+
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)
845
+ end
846
+ end
847
+
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)
864
+ end
865
+ end
866
+ end
867
+
868
+ def try_const(const, headers = nil, opt = "", &b)
869
+ const, type = *const
870
+ if try_compile(<<"SRC", opt, &b)
871
+ #{COMMON_HEADERS}
872
+ #{cpp_include(headers)}
873
+ /*top*/
874
+ typedef #{type || 'int'} conftest_type;
875
+ conftest_type conftestval = #{type ? '' : '(int)'}#{const};
876
+ SRC
877
+ $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
878
+ true
879
+ else
880
+ false
881
+ end
882
+ end
883
+
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)
903
+ end
904
+ end
905
+
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)
920
+ x ? super : "failed"
921
+ 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
926
+ end
927
+ end
928
+ end
929
+
930
+ # :stopdoc:
931
+
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
957
+
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"
973
+ 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"
985
+ end
986
+ end
987
+ end
988
+ end
989
+
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)
1010
+ end
1011
+ nil
1012
+ end
1013
+
1014
+ # :startdoc:
1015
+
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)
1028
+ 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
+
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)
1057
+ false
1058
+ elsif block_given?
1059
+ yield(config, *defaults)
1060
+ else
1061
+ break *defaults
1062
+ end
1063
+ end
1064
+ case val
1065
+ when "yes"
1066
+ true
1067
+ when "no"
1068
+ false
1069
+ else
1070
+ val
1071
+ end
1072
+ end
1073
+
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
1097
+
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
1145
+
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)
1176
+ unless idirs.empty?
1177
+ $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
1178
+ end
1179
+ end
1180
+
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)
1185
+ end
1186
+ $LIBPATH = ldirs | $LIBPATH
1187
+
1188
+ [idir, ldir]
1189
+ end
1190
+
1191
+ # :stopdoc:
1192
+
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
1224
+ 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
+
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
1260
+ end
1261
+ end
1262
+
1263
+ def configuration(srcdir)
1264
+ mk = []
1265
+ vpath = %w[$(srcdir) $(topdir) $(hdrdir)]
1266
+ if !CROSS_COMPILING
1267
+ case CONFIG['build_os']
1268
+ when 'cygwin'
1269
+ if CONFIG['target_os'] != 'cygwin'
1270
+ vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')}
1271
+ end
1272
+ when 'msdosdjgpp'
1273
+ CONFIG['PATH_SEPARATOR'] = ';'
1274
+ end
1275
+ end
1276
+ mk << %{
1277
+ SHELL = /bin/sh
1278
+
1279
+ #### 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)'}
1288
+ VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
1289
+ }
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 << %{
1313
+ CC = #{CONFIG['CC']}
1314
+ LIBRUBY = #{CONFIG['LIBRUBY']}
1315
+ LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
1316
+ LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
1317
+ LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
1318
+
1319
+ RUBY_EXTCONF_H = #{$extconf_h}
1320
+ CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG
1321
+ INCFLAGS = -I. #$INCFLAGS
1322
+ DEFS = #{CONFIG['DEFS']}
1323
+ CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
1324
+ CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
1325
+ ldflags = #{$LDFLAGS}
1326
+ dldflags = #{$DLDFLAGS}
1327
+ archflag = #{$ARCH_FLAG}
1328
+ DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
1329
+ LDSHARED = #{CONFIG['LDSHARED']}
1330
+ AR = #{CONFIG['AR']}
1331
+ EXEEXT = #{CONFIG['EXEEXT']}
1332
+
1333
+ RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
1334
+ RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
1335
+ arch = #{CONFIG['arch']}
1336
+ sitearch = #{CONFIG['sitearch']}
1337
+ ruby_version = #{RbConfig::CONFIG['ruby_version']}
1338
+ ruby = #{$ruby}
1339
+ 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'}
1343
+ INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
1344
+ INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
1345
+ COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
1346
+
1347
+ #### End of system configuration section. ####
1348
+
1349
+ preload = #{$preload ? $preload.join(' ') : ''}
1350
+ }
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"
1357
+ end
1358
+ end
1359
+ end
1360
+ mk
1361
+ end
1362
+
1363
+ def dummy_makefile(srcdir)
1364
+ configuration(srcdir) << <<RULES << CLEANINGS
1365
+ CLEANFILES = #{$cleanfiles.join(' ')}
1366
+ DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1367
+
1368
+ all install static install-so install-rb: Makefile
1369
+
1370
+ 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
+ end
1444
+
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)
1454
+ end
1455
+ elsif !(srcs = $srcs)
1456
+ srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
1457
+ end
1458
+ $srcs = srcs
1459
+ for i in $objs
1460
+ i.sub!(/\.o\z/, ".#{$OBJEXT}")
1461
+ end
1462
+ $objs = $objs.join(" ")
1463
+
1464
+ target = nil if $objs == ""
1465
+
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"}
1471
+ end
1472
+ else
1473
+ makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
1474
+ end
1475
+ if makedef
1476
+ $distcleanfiles << '$(DEFFILE)'
1477
+ origdef = deffile
1478
+ deffile = "$(TARGET)-$(arch).def"
1479
+ end
1480
+ end
1481
+ origdef ||= ''
1482
+
1483
+ libpath = libpathflag(libpath)
1484
+
1485
+ dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
1486
+ staticlib = target ? "$(TARGET).#$LIBEXT" : ""
1487
+ mfile = open("Makefile", "wb")
1488
+ mfile.print configuration(srcprefix)
1489
+ mfile.print "
1490
+ libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
1491
+ LIBPATH = #{libpath}
1492
+ DEFFILE = #{deffile}
1493
+
1494
+ CLEANFILES = #{$cleanfiles.join(' ')}
1495
+ DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1496
+
1497
+ extout = #{$extout}
1498
+ extout_prefix = #{$extout_prefix}
1499
+ target_prefix = #{target_prefix}
1500
+ LOCAL_LIBS = #{$LOCAL_LIBS}
1501
+ LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
1502
+ SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
1503
+ OBJS = #{$objs}
1504
+ TARGET = #{target}
1505
+ DLLIB = #{dllib}
1506
+ EXTSTATIC = #{$static || ""}
1507
+ STATIC_LIB = #{staticlib unless $static.nil?}
1508
+ #{!$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 "
1513
+ 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
1516
+
1517
+ all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
1518
+ static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
1519
+ "
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"
1543
+ end
1544
+ 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"
1558
+ 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
1576
+ end
1577
+ end
1578
+ end
1579
+ dirs.unshift(sodir) if target and !dirs.include?(sodir)
1580
+ dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}
1581
+
1582
+ mfile.print <<-SITEINSTALL
1583
+
1584
+ site-install: site-install-so site-install-rb
1585
+ site-install-so: install-so
1586
+ site-install-rb: install-rb
1587
+
1588
+ SITEINSTALL
1589
+
1590
+ return unless target
1591
+
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"
1595
+
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)
1600
+ 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)
1606
+ end
1607
+ end
1608
+
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"
1622
+ 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
1675
+ end
1676
+ end
1677
+ unless suffixes.empty?
1678
+ mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
1679
+ 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}}
1686
+ 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
+
1692
+ $makefile_created = true
1693
+ ensure
1694
+ mfile.close if mfile
1695
+ end
1696
+
1697
+ # :stopdoc:
1698
+
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
1755
+
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.
1760
+
1761
+ Provided configuration options:
1762
+ MESSAGE
1763
+
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
1773
+ end
1774
+ end
1775
+
1776
+ # :startdoc:
1777
+
1778
+ init_mkmf
1779
+
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
1789
+
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"]))
1804
+
1805
+ split = Shellwords.method(:shellwords).to_proc
1806
+
1807
+ EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
1808
+
1809
+ hdr = []
1810
+ config_string('COMMON_MACROS') do |s|
1811
+ Shellwords.shellwords(s).each do |w|
1812
+ hdr << "#define " + w.split(/=/, 2).join(" ")
1813
+ 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)"
1834
+ end
1835
+ LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"'
1836
+ RPATHFLAG = config_string('RPATHFLAG') || ''
1837
+ LIBARG = config_string('LIBARG') || '-l%s'
1838
+
1839
+ sep = config_string('BUILD_FILE_SEPARATOR') {|sep| ":/=#{sep}" if sep != "/"} || ""
1840
+ CLEANINGS = "
1841
+ clean:
1842
+ @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})
1843
+
1844
+ distclean: clean
1845
+ @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
1846
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
1847
+
1848
+ realclean: distclean
1849
+ "
1850
+
1851
+ if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
1852
+ END {mkmf_failed($0)}
1853
+ end