rubysl-mkmf 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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