mac-robot 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -14,8 +14,6 @@ A Library to Automate User Interactions
14
14
  robot.mouse_move(250, 250)
15
15
  robot.mouse_release
16
16
 
17
- === Post Notification
18
-
19
17
  == Contributing to mac-robot
20
18
 
21
19
  * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -1,3 +1,7 @@
1
+ if RUBY_VERSION < '1.9.0'
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+ end
4
+
1
5
  require "mkmf"
2
6
 
3
7
  # Name your extension
@@ -0,0 +1,1837 @@
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 = Config::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
+ topdir = File.dirname(libdir = File.dirname(__FILE__))
134
+ extdir = File.expand_path("ext", topdir)
135
+ $extmk = File.expand_path($0)[0, extdir.size+1] == extdir+"/"
136
+ if not $extmk and File.exist?(($hdrdir = Config::CONFIG["archdir"]) + "/ruby.h")
137
+ $topdir = $hdrdir
138
+ elsif File.exist?(($hdrdir = ($top_srcdir ||= topdir)) + "/ruby.h") and
139
+ File.exist?(($topdir ||= Config::CONFIG["topdir"]) + "/config.h")
140
+ else
141
+ abort "mkmf.rb can't find header files for ruby at #{$hdrdir}/ruby.h"
142
+ end
143
+
144
+ OUTFLAG = CONFIG['OUTFLAG']
145
+ CPPOUTFILE = CONFIG['CPPOUTFILE']
146
+
147
+ CONFTEST_C = "conftest.c"
148
+
149
+ class String
150
+ # Wraps a string in escaped quotes if it contains whitespace.
151
+ def quote
152
+ /\s/ =~ self ? "\"#{self}\"" : "#{self}"
153
+ end
154
+
155
+ # Generates a string used as cpp macro name.
156
+ def tr_cpp
157
+ strip.upcase.tr_s("^A-Z0-9_", "_")
158
+ end
159
+ end
160
+ class Array
161
+ # Wraps all strings in escaped quotes if they contain whitespace.
162
+ def quote
163
+ map {|s| s.quote}
164
+ end
165
+ end
166
+
167
+ def rm_f(*files)
168
+ FileUtils.rm_f(Dir[files.join("\0")])
169
+ end
170
+
171
+ # Returns time stamp of the +target+ file if it exists and is newer
172
+ # than or equal to all of +times+.
173
+ def modified?(target, times)
174
+ (t = File.mtime(target)) rescue return nil
175
+ Array === times or times = [times]
176
+ t if times.all? {|n| n <= t}
177
+ end
178
+
179
+ def merge_libs(*libs)
180
+ libs.inject([]) do |x, y|
181
+ xy = x & y
182
+ xn = yn = 0
183
+ y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
184
+ y.each_with_index do |v, yi|
185
+ if xy.include?(v)
186
+ xi = [x.index(v), xn].max()
187
+ x[xi, 1] = y[yn..yi]
188
+ xn, yn = xi + (yi - yn + 1), yi + 1
189
+ end
190
+ end
191
+ x.concat(y[yn..-1] || [])
192
+ end
193
+ end
194
+
195
+ # This is a custom logging module. It generates an mkmf.log file when you
196
+ # run your extconf.rb script. This can be useful for debugging unexpected
197
+ # failures.
198
+ #
199
+ # This module and its associated methods are meant for internal use only.
200
+ #
201
+ module Logging
202
+ @log = nil
203
+ @logfile = 'mkmf.log'
204
+ @orgerr = $stderr.dup
205
+ @orgout = $stdout.dup
206
+ @postpone = 0
207
+ @quiet = $extmk
208
+
209
+ def self::open
210
+ @log ||= File::open(@logfile, 'w')
211
+ @log.sync = true
212
+ $stderr.reopen(@log)
213
+ $stdout.reopen(@log)
214
+ yield
215
+ ensure
216
+ $stderr.reopen(@orgerr)
217
+ $stdout.reopen(@orgout)
218
+ end
219
+
220
+ def self::message(*s)
221
+ @log ||= File::open(@logfile, 'w')
222
+ @log.sync = true
223
+ @log.printf(*s)
224
+ end
225
+
226
+ def self::logfile file
227
+ @logfile = file
228
+ if @log and not @log.closed?
229
+ @log.flush
230
+ @log.close
231
+ @log = nil
232
+ end
233
+ end
234
+
235
+ def self::postpone
236
+ tmplog = "mkmftmp#{@postpone += 1}.log"
237
+ open do
238
+ log, *save = @log, @logfile, @orgout, @orgerr
239
+ @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
240
+ begin
241
+ log.print(open {yield})
242
+ @log.close
243
+ File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
244
+ ensure
245
+ @log, @logfile, @orgout, @orgerr = log, *save
246
+ @postpone -= 1
247
+ rm_f tmplog
248
+ end
249
+ end
250
+ end
251
+
252
+ class << self
253
+ attr_accessor :quiet
254
+ end
255
+ end
256
+
257
+ def xsystem command
258
+ varpat = /\$\((\w+)\)|\$\{(\w+)\}/
259
+ if varpat =~ command
260
+ vars = Hash.new {|h, k| h[k] = ''; ENV[k]}
261
+ command = command.dup
262
+ nil while command.gsub!(varpat) {vars[$1||$2]}
263
+ end
264
+ Logging::open do
265
+ puts command.quote
266
+ system(command)
267
+ end
268
+ end
269
+
270
+ def xpopen command, *mode, &block
271
+ Logging::open do
272
+ case mode[0]
273
+ when nil, /^r/
274
+ puts "#{command} |"
275
+ else
276
+ puts "| #{command}"
277
+ end
278
+ IO.popen(command, *mode, &block)
279
+ end
280
+ end
281
+
282
+ def log_src(src)
283
+ src = src.split(/^/)
284
+ fmt = "%#{src.size.to_s.size}d: %s"
285
+ Logging::message <<"EOM"
286
+ checked program was:
287
+ /* begin */
288
+ EOM
289
+ src.each_with_index {|line, no| Logging::message fmt, no+1, line}
290
+ Logging::message <<"EOM"
291
+ /* end */
292
+
293
+ EOM
294
+ end
295
+
296
+ def create_tmpsrc(src)
297
+ src = yield(src) if block_given?
298
+ src = src.gsub(/[ \t]+$/, '').gsub(/\A\n+|^\n+$/, '').sub(/[^\n]\z/, "\\&\n")
299
+ open(CONFTEST_C, "wb") do |cfile|
300
+ cfile.print src
301
+ end
302
+ src
303
+ end
304
+
305
+ def try_do(src, command, &b)
306
+ src = create_tmpsrc(src, &b)
307
+ xsystem(command)
308
+ ensure
309
+ log_src(src)
310
+ end
311
+
312
+ def link_command(ldflags, opt="", libpath=$DEFLIBPATH|$LIBPATH)
313
+ conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote,
314
+ 'src' => CONFTEST_C,
315
+ 'INCFLAGS' => $INCFLAGS,
316
+ 'CPPFLAGS' => $CPPFLAGS,
317
+ 'CFLAGS' => "#$CFLAGS",
318
+ 'ARCH_FLAG' => "#$ARCH_FLAG",
319
+ 'LDFLAGS' => "#$LDFLAGS #{ldflags}",
320
+ 'LIBPATH' => libpathflag(libpath),
321
+ 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
322
+ 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS")
323
+ Config::expand(TRY_LINK.dup, conf)
324
+ end
325
+
326
+ def cc_command(opt="")
327
+ conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
328
+ Config::expand("$(CC) #$INCFLAGS #$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} -c #{CONFTEST_C}",
329
+ conf)
330
+ end
331
+
332
+ def cpp_command(outfile, opt="")
333
+ conf = Config::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote)
334
+ Config::expand("$(CPP) #$INCFLAGS #$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}".gsub(/-arch \w+/, ""),
335
+ conf)
336
+ end
337
+
338
+ def libpathflag(libpath=$DEFLIBPATH|$LIBPATH)
339
+ libpath.map{|x|
340
+ case x
341
+ when "$(topdir)", /\A\./
342
+ LIBPATHFLAG
343
+ else
344
+ LIBPATHFLAG+RPATHFLAG
345
+ end % x.quote
346
+ }.join
347
+ end
348
+
349
+ def try_link0(src, opt="", &b)
350
+ try_do(src, link_command("", opt), &b)
351
+ end
352
+
353
+ def try_link(src, opt="", &b)
354
+ try_link0(src, opt, &b)
355
+ ensure
356
+ rm_f "conftest*", "c0x32*"
357
+ end
358
+
359
+ def try_compile(src, opt="", &b)
360
+ try_do(src, cc_command(opt), &b)
361
+ ensure
362
+ rm_f "conftest*"
363
+ end
364
+
365
+ def try_cpp(src, opt="", &b)
366
+ try_do(src, cpp_command(CPPOUTFILE, opt), &b)
367
+ ensure
368
+ rm_f "conftest*"
369
+ end
370
+
371
+ def cpp_include(header)
372
+ if header
373
+ header = [header] unless header.kind_of? Array
374
+ header.map {|h| "#include <#{h}>\n"}.join
375
+ else
376
+ ""
377
+ end
378
+ end
379
+
380
+ def with_cppflags(flags)
381
+ cppflags = $CPPFLAGS
382
+ $CPPFLAGS = flags
383
+ ret = yield
384
+ ensure
385
+ $CPPFLAGS = cppflags unless ret
386
+ end
387
+
388
+ def with_cflags(flags)
389
+ cflags = $CFLAGS
390
+ $CFLAGS = flags
391
+ ret = yield
392
+ ensure
393
+ $CFLAGS = cflags unless ret
394
+ end
395
+
396
+ def with_ldflags(flags)
397
+ ldflags = $LDFLAGS
398
+ $LDFLAGS = flags
399
+ ret = yield
400
+ ensure
401
+ $LDFLAGS = ldflags unless ret
402
+ end
403
+
404
+ def try_static_assert(expr, headers = nil, opt = "", &b)
405
+ headers = cpp_include(headers)
406
+ try_compile(<<SRC, opt, &b)
407
+ #{COMMON_HEADERS}
408
+ #{headers}
409
+ /*top*/
410
+ int conftest_const[(#{expr}) ? 1 : -1];
411
+ SRC
412
+ end
413
+
414
+ def try_constant(const, headers = nil, opt = "", &b)
415
+ includes = cpp_include(headers)
416
+ if CROSS_COMPILING
417
+ if try_static_assert("#{const} > 0", headers, opt)
418
+ # positive constant
419
+ elsif try_static_assert("#{const} < 0", headers, opt)
420
+ neg = true
421
+ const = "-(#{const})"
422
+ elsif try_static_assert("#{const} == 0", headers, opt)
423
+ return 0
424
+ else
425
+ # not a constant
426
+ return nil
427
+ end
428
+ upper = 1
429
+ lower = 0
430
+ until try_static_assert("#{const} <= #{upper}", headers, opt)
431
+ lower = upper
432
+ upper <<= 1
433
+ end
434
+ return nil unless lower
435
+ while upper > lower + 1
436
+ mid = (upper + lower) / 2
437
+ if try_static_assert("#{const} > #{mid}", headers, opt)
438
+ lower = mid
439
+ else
440
+ upper = mid
441
+ end
442
+ end
443
+ upper = -upper if neg
444
+ return upper
445
+ else
446
+ src = %{#{COMMON_HEADERS}
447
+ #{includes}
448
+ #include <stdio.h>
449
+ /*top*/
450
+ int conftest_const = (int)(#{const});
451
+ int main() {printf("%d\\n", conftest_const); return 0;}
452
+ }
453
+ if try_link0(src, opt, &b)
454
+ xpopen("./conftest") do |f|
455
+ return Integer(f.gets)
456
+ end
457
+ end
458
+ end
459
+ nil
460
+ end
461
+
462
+ def try_func(func, libs, headers = nil, &b)
463
+ headers = cpp_include(headers)
464
+ try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b)
465
+ #{COMMON_HEADERS}
466
+ #{headers}
467
+ /*top*/
468
+ int main() { return 0; }
469
+ int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }
470
+ SRC
471
+ #{headers}
472
+ /*top*/
473
+ int main() { return 0; }
474
+ int t() { #{func}(); return 0; }
475
+ SRC
476
+ end
477
+
478
+ def try_var(var, headers = nil, &b)
479
+ headers = cpp_include(headers)
480
+ try_compile(<<"SRC", &b)
481
+ #{COMMON_HEADERS}
482
+ #{headers}
483
+ /*top*/
484
+ int main() { return 0; }
485
+ int t() { const volatile void *volatile p; p = &(&#{var})[0]; return 0; }
486
+ SRC
487
+ end
488
+
489
+ def egrep_cpp(pat, src, opt = "", &b)
490
+ src = create_tmpsrc(src, &b)
491
+ xpopen(cpp_command('', opt)) do |f|
492
+ if Regexp === pat
493
+ puts(" ruby -ne 'print if #{pat.inspect}'")
494
+ f.grep(pat) {|l|
495
+ puts "#{f.lineno}: #{l}"
496
+ return true
497
+ }
498
+ false
499
+ else
500
+ puts(" egrep '#{pat}'")
501
+ begin
502
+ stdin = $stdin.dup
503
+ $stdin.reopen(f)
504
+ system("egrep", pat)
505
+ ensure
506
+ $stdin.reopen(stdin)
507
+ end
508
+ end
509
+ end
510
+ ensure
511
+ rm_f "conftest*"
512
+ log_src(src)
513
+ end
514
+
515
+ # This is used internally by the have_macro? method.
516
+ def macro_defined?(macro, src, opt = "", &b)
517
+ src = src.sub(/[^\n]\z/, "\\&\n")
518
+ try_compile(src + <<"SRC", opt, &b)
519
+ /*top*/
520
+ #ifndef #{macro}
521
+ # error
522
+ >>>>>> #{macro} undefined <<<<<<
523
+ #endif
524
+ SRC
525
+ end
526
+
527
+ def try_run(src, opt = "", &b)
528
+ if try_link0(src, opt, &b)
529
+ xsystem("./conftest")
530
+ else
531
+ nil
532
+ end
533
+ ensure
534
+ rm_f "conftest*"
535
+ end
536
+
537
+ def install_files(mfile, ifiles, map = nil, srcprefix = nil)
538
+ ifiles or return
539
+ ifiles.empty? and return
540
+ srcprefix ||= '$(srcdir)'
541
+ Config::expand(srcdir = srcprefix.dup)
542
+ dirs = []
543
+ path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
544
+ ifiles.each do |files, dir, prefix|
545
+ dir = map_dir(dir, map)
546
+ prefix &&= %r|\A#{Regexp.quote(prefix)}/?|
547
+ if /\A\.\// =~ files
548
+ # install files which are in current working directory.
549
+ files = files[2..-1]
550
+ len = nil
551
+ else
552
+ # install files which are under the $(srcdir).
553
+ files = File.join(srcdir, files)
554
+ len = srcdir.size
555
+ end
556
+ f = nil
557
+ Dir.glob(files) do |f|
558
+ f[0..len] = "" if len
559
+ case File.basename(f)
560
+ when *$NONINSTALLFILES
561
+ next
562
+ end
563
+ d = File.dirname(f)
564
+ d.sub!(prefix, "") if prefix
565
+ d = (d.empty? || d == ".") ? dir : File.join(dir, d)
566
+ f = File.join(srcprefix, f) if len
567
+ path[d] << f
568
+ end
569
+ unless len or f
570
+ d = File.dirname(files)
571
+ d.sub!(prefix, "") if prefix
572
+ d = (d.empty? || d == ".") ? dir : File.join(dir, d)
573
+ path[d] << files
574
+ end
575
+ end
576
+ dirs
577
+ end
578
+
579
+ def install_rb(mfile, dest, srcdir = nil)
580
+ install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
581
+ end
582
+
583
+ def append_library(libs, lib) # :no-doc:
584
+ format(LIBARG, lib) + " " + libs
585
+ end
586
+
587
+ def message(*s)
588
+ unless Logging.quiet and not $VERBOSE
589
+ printf(*s)
590
+ $stdout.flush
591
+ end
592
+ end
593
+
594
+ # This emits a string to stdout that allows users to see the results of the
595
+ # various have* and find* methods as they are tested.
596
+ #
597
+ # Internal use only.
598
+ #
599
+ def checking_for(m, fmt = nil)
600
+ f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim
601
+ m = "checking #{/\Acheck/ =~ f ? '' : 'for '}#{m}... "
602
+ message "%s", m
603
+ a = r = nil
604
+ Logging::postpone do
605
+ r = yield
606
+ a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
607
+ "#{f}#{m}-------------------- #{a}\n"
608
+ end
609
+ message(a)
610
+ Logging::message "--------------------\n\n"
611
+ r
612
+ end
613
+
614
+ def checking_message(target, place = nil, opt = nil)
615
+ [["in", place], ["with", opt]].inject("#{target}") do |msg, (pre, noun)|
616
+ if noun
617
+ [[:to_str], [:join, ","], [:to_s]].each do |meth, *args|
618
+ if noun.respond_to?(meth)
619
+ break noun = noun.send(meth, *args)
620
+ end
621
+ end
622
+ msg << " #{pre} #{noun}" unless noun.empty?
623
+ end
624
+ msg
625
+ end
626
+ end
627
+
628
+ # :startdoc:
629
+
630
+ # Returns whether or not +macro+ is defined either in the common header
631
+ # files or within any +headers+ you provide.
632
+ #
633
+ # Any options you pass to +opt+ are passed along to the compiler.
634
+ #
635
+ def have_macro(macro, headers = nil, opt = "", &b)
636
+ checking_for checking_message(macro, headers, opt) do
637
+ macro_defined?(macro, cpp_include(headers), opt, &b)
638
+ end
639
+ end
640
+
641
+ # Returns whether or not the given entry point +func+ can be found within
642
+ # +lib+. If +func+ is nil, the 'main()' entry point is used by default.
643
+ # If found, it adds the library to list of libraries to be used when linking
644
+ # your extension.
645
+ #
646
+ # If +headers+ are provided, it will include those header files as the
647
+ # header files it looks in when searching for +func+.
648
+ #
649
+ # The real name of the library to be linked can be altered by
650
+ # '--with-FOOlib' configuration option.
651
+ #
652
+ def have_library(lib, func = nil, headers = nil, &b)
653
+ func = "main" if !func or func.empty?
654
+ lib = with_config(lib+'lib', lib)
655
+ checking_for checking_message("#{func}()", LIBARG%lib) do
656
+ if COMMON_LIBS.include?(lib)
657
+ true
658
+ else
659
+ libs = append_library($libs, lib)
660
+ if try_func(func, libs, headers, &b)
661
+ $libs = libs
662
+ true
663
+ else
664
+ false
665
+ end
666
+ end
667
+ end
668
+ end
669
+
670
+ # Returns whether or not the entry point +func+ can be found within the library
671
+ # +lib+ in one of the +paths+ specified, where +paths+ is an array of strings.
672
+ # If +func+ is nil , then the main() function is used as the entry point.
673
+ #
674
+ # If +lib+ is found, then the path it was found on is added to the list of
675
+ # library paths searched and linked against.
676
+ #
677
+ def find_library(lib, func, *paths, &b)
678
+ func = "main" if !func or func.empty?
679
+ lib = with_config(lib+'lib', lib)
680
+ paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
681
+ checking_for "#{func}() in #{LIBARG%lib}" do
682
+ libpath = $LIBPATH
683
+ libs = append_library($libs, lib)
684
+ begin
685
+ until r = try_func(func, libs, &b) or paths.empty?
686
+ $LIBPATH = libpath | [paths.shift]
687
+ end
688
+ if r
689
+ $libs = libs
690
+ libpath = nil
691
+ end
692
+ ensure
693
+ $LIBPATH = libpath if libpath
694
+ end
695
+ r
696
+ end
697
+ end
698
+
699
+ # Returns whether or not the function +func+ can be found in the common
700
+ # header files, or within any +headers+ that you provide. If found, a
701
+ # macro is passed as a preprocessor constant to the compiler using the
702
+ # function name, in uppercase, prepended with 'HAVE_'.
703
+ #
704
+ # For example, if have_func('foo') returned true, then the HAVE_FOO
705
+ # preprocessor macro would be passed to the compiler.
706
+ #
707
+ def have_func(func, headers = nil, &b)
708
+ checking_for checking_message("#{func}()", headers) do
709
+ if try_func(func, $libs, headers, &b)
710
+ $defs.push(format("-DHAVE_%s", func.tr_cpp))
711
+ true
712
+ else
713
+ false
714
+ end
715
+ end
716
+ end
717
+
718
+ # Returns whether or not the variable +var+ can be found in the common
719
+ # header files, or within any +headers+ that you provide. If found, a
720
+ # macro is passed as a preprocessor constant to the compiler using the
721
+ # variable name, in uppercase, prepended with 'HAVE_'.
722
+ #
723
+ # For example, if have_var('foo') returned true, then the HAVE_FOO
724
+ # preprocessor macro would be passed to the compiler.
725
+ #
726
+ def have_var(var, headers = nil, &b)
727
+ checking_for checking_message(var, headers) do
728
+ if try_var(var, headers, &b)
729
+ $defs.push(format("-DHAVE_%s", var.tr_cpp))
730
+ true
731
+ else
732
+ false
733
+ end
734
+ end
735
+ end
736
+
737
+ # Returns whether or not the given +header+ file can be found on your system.
738
+ # If found, a macro is passed as a preprocessor constant to the compiler using
739
+ # the header file name, in uppercase, prepended with 'HAVE_'.
740
+ #
741
+ # For example, if have_header('foo.h') returned true, then the HAVE_FOO_H
742
+ # preprocessor macro would be passed to the compiler.
743
+ #
744
+ def have_header(header, &b)
745
+ checking_for header do
746
+ if try_cpp(cpp_include(header), &b)
747
+ $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
748
+ true
749
+ else
750
+ false
751
+ end
752
+ end
753
+ end
754
+
755
+ # Instructs mkmf to search for the given +header+ in any of the +paths+
756
+ # provided, and returns whether or not it was found in those paths.
757
+ #
758
+ # If the header is found then the path it was found on is added to the list
759
+ # of included directories that are sent to the compiler (via the -I switch).
760
+ #
761
+ def find_header(header, *paths)
762
+ message = checking_message(header, paths)
763
+ header = cpp_include(header)
764
+ checking_for message do
765
+ if try_cpp(header)
766
+ true
767
+ else
768
+ found = false
769
+ paths.each do |dir|
770
+ opt = "-I#{dir}".quote
771
+ if try_cpp(header, opt)
772
+ $INCFLAGS << " " << opt
773
+ found = true
774
+ break
775
+ end
776
+ end
777
+ found
778
+ end
779
+ end
780
+ end
781
+
782
+ # Returns whether or not the struct of type +type+ contains +member+. If
783
+ # it does not, or the struct type can't be found, then false is returned. You
784
+ # may optionally specify additional +headers+ in which to look for the struct
785
+ # (in addition to the common header files).
786
+ #
787
+ # If found, a macro is passed as a preprocessor constant to the compiler using
788
+ # the member name, in uppercase, prepended with 'HAVE_ST_'.
789
+ #
790
+ # For example, if have_struct_member('struct foo', 'bar') returned true, then the
791
+ # HAVE_ST_BAR preprocessor macro would be passed to the compiler.
792
+ #
793
+ def have_struct_member(type, member, headers = nil, &b)
794
+ checking_for checking_message("#{type}.#{member}", headers) do
795
+ if try_compile(<<"SRC", &b)
796
+ #{COMMON_HEADERS}
797
+ #{cpp_include(headers)}
798
+ /*top*/
799
+ int main() { return 0; }
800
+ int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
801
+ SRC
802
+ $defs.push(format("-DHAVE_ST_%s", member.tr_cpp))
803
+ true
804
+ else
805
+ false
806
+ end
807
+ end
808
+ end
809
+
810
+ def try_type(type, headers = nil, opt = "", &b)
811
+ if try_compile(<<"SRC", opt, &b)
812
+ #{COMMON_HEADERS}
813
+ #{cpp_include(headers)}
814
+ /*top*/
815
+ typedef #{type} conftest_type;
816
+ int conftestval[sizeof(conftest_type)?1:-1];
817
+ SRC
818
+ $defs.push(format("-DHAVE_TYPE_%s", type.tr_cpp))
819
+ true
820
+ else
821
+ false
822
+ end
823
+ end
824
+
825
+ # Returns whether or not the static type +type+ is defined. You may
826
+ # optionally pass additional +headers+ to check against in addition to the
827
+ # common header files.
828
+ #
829
+ # You may also pass additional flags to +opt+ which are then passed along to
830
+ # the compiler.
831
+ #
832
+ # If found, a macro is passed as a preprocessor constant to the compiler using
833
+ # the type name, in uppercase, prepended with 'HAVE_TYPE_'.
834
+ #
835
+ # For example, if have_type('foo') returned true, then the HAVE_TYPE_FOO
836
+ # preprocessor macro would be passed to the compiler.
837
+ #
838
+ def have_type(type, headers = nil, opt = "", &b)
839
+ checking_for checking_message(type, headers, opt) do
840
+ try_type(type, headers, opt, &b)
841
+ end
842
+ end
843
+
844
+ # Returns where the static type +type+ is defined.
845
+ #
846
+ # You may also pass additional flags to +opt+ which are then passed along to
847
+ # the compiler.
848
+ #
849
+ # See also +have_type+.
850
+ #
851
+ def find_type(type, opt, *headers, &b)
852
+ opt ||= ""
853
+ fmt = "not found"
854
+ def fmt.%(x)
855
+ x ? x.respond_to?(:join) ? x.join(",") : x : self
856
+ end
857
+ checking_for checking_message(type, nil, opt), fmt do
858
+ headers.find do |h|
859
+ try_type(type, h, opt, &b)
860
+ end
861
+ end
862
+ end
863
+
864
+ def try_const(const, headers = nil, opt = "", &b)
865
+ const, type = *const
866
+ if try_compile(<<"SRC", opt, &b)
867
+ #{COMMON_HEADERS}
868
+ #{cpp_include(headers)}
869
+ /*top*/
870
+ typedef #{type || 'int'} conftest_type;
871
+ conftest_type conftestval = #{type ? '' : '(int)'}#{const};
872
+ SRC
873
+ $defs.push(format("-DHAVE_CONST_%s", const.tr_cpp))
874
+ true
875
+ else
876
+ false
877
+ end
878
+ end
879
+
880
+ # Returns whether or not the constant +const+ is defined. You may
881
+ # optionally pass the +type+ of +const+ as <code>[const, type]</code>,
882
+ # like as:
883
+ #
884
+ # have_const(%w[PTHREAD_MUTEX_INITIALIZER pthread_mutex_t], "pthread.h")
885
+ #
886
+ # You may also pass additional +headers+ to check against in addition
887
+ # to the common header files, and additional flags to +opt+ which are
888
+ # then passed along to the compiler.
889
+ #
890
+ # If found, a macro is passed as a preprocessor constant to the compiler using
891
+ # the type name, in uppercase, prepended with 'HAVE_CONST_'.
892
+ #
893
+ # For example, if have_const('foo') returned true, then the HAVE_CONST_FOO
894
+ # preprocessor macro would be passed to the compiler.
895
+ #
896
+ def have_const(const, headers = nil, opt = "", &b)
897
+ checking_for checking_message([*const].compact.join(' '), headers, opt) do
898
+ try_const(const, headers, opt, &b)
899
+ end
900
+ end
901
+
902
+ # Returns the size of the given +type+. You may optionally specify additional
903
+ # +headers+ to search in for the +type+.
904
+ #
905
+ # If found, a macro is passed as a preprocessor constant to the compiler using
906
+ # the type name, in uppercase, prepended with 'SIZEOF_', followed by the type
907
+ # name, followed by '=X' where 'X' is the actual size.
908
+ #
909
+ # For example, if check_sizeof('mystruct') returned 12, then the
910
+ # SIZEOF_MYSTRUCT=12 preprocessor macro would be passed to the compiler.
911
+ #
912
+ def check_sizeof(type, headers = nil, &b)
913
+ expr = "sizeof(#{type})"
914
+ fmt = "%d"
915
+ def fmt.%(x)
916
+ x ? super : "failed"
917
+ end
918
+ checking_for checking_message("size of #{type}", headers), fmt do
919
+ if size = try_constant(expr, headers, &b)
920
+ $defs.push(format("-DSIZEOF_%s=%d", type.tr_cpp, size))
921
+ size
922
+ end
923
+ end
924
+ end
925
+
926
+ # :stopdoc:
927
+
928
+ # Used internally by the what_type? method to determine if +type+ is a scalar
929
+ # pointer.
930
+ def scalar_ptr_type?(type, member = nil, headers = nil, &b)
931
+ try_compile(<<"SRC", &b) # pointer
932
+ #{COMMON_HEADERS}
933
+ #{cpp_include(headers)}
934
+ /*top*/
935
+ volatile #{type} conftestval;
936
+ int main() { return 0; }
937
+ int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
938
+ SRC
939
+ end
940
+
941
+ # Used internally by the what_type? method to determine if +type+ is a scalar
942
+ # pointer.
943
+ def scalar_type?(type, member = nil, headers = nil, &b)
944
+ try_compile(<<"SRC", &b) # pointer
945
+ #{COMMON_HEADERS}
946
+ #{cpp_include(headers)}
947
+ /*top*/
948
+ volatile #{type} conftestval;
949
+ int main() { return 0; }
950
+ int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
951
+ SRC
952
+ end
953
+
954
+ def what_type?(type, member = nil, headers = nil, &b)
955
+ m = "#{type}"
956
+ name = type
957
+ if member
958
+ m << "." << member
959
+ name = "(((#{type} *)0)->#{member})"
960
+ end
961
+ fmt = "seems %s"
962
+ def fmt.%(x)
963
+ x ? super : "unknown"
964
+ end
965
+ checking_for checking_message(m, headers), fmt do
966
+ if scalar_ptr_type?(type, member, headers, &b)
967
+ if try_static_assert("sizeof(*#{name}) == 1", headers)
968
+ "string"
969
+ end
970
+ elsif scalar_type?(type, member, headers, &b)
971
+ if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
972
+ "long long"
973
+ elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
974
+ "long"
975
+ elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
976
+ "int"
977
+ elsif try_static_assert("sizeof(#{name}) > 1", headers)
978
+ "short"
979
+ else
980
+ "char"
981
+ end
982
+ end
983
+ end
984
+ end
985
+
986
+ # This method is used internally by the find_executable method.
987
+ #
988
+ # Internal use only.
989
+ #
990
+ def find_executable0(bin, path = nil)
991
+ ext = config_string('EXEEXT')
992
+ if File.expand_path(bin) == bin
993
+ return bin if File.executable?(bin)
994
+ ext and File.executable?(file = bin + ext) and return file
995
+ return nil
996
+ end
997
+ if path ||= ENV['PATH']
998
+ path = path.split(File::PATH_SEPARATOR)
999
+ else
1000
+ path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
1001
+ end
1002
+ file = nil
1003
+ path.each do |dir|
1004
+ return file if File.executable?(file = File.join(dir, bin))
1005
+ return file if ext and File.executable?(file << ext)
1006
+ end
1007
+ nil
1008
+ end
1009
+
1010
+ # :startdoc:
1011
+
1012
+ # Searches for the executable +bin+ on +path+. The default path is your
1013
+ # PATH environment variable. If that isn't defined, it will resort to
1014
+ # searching /usr/local/bin, /usr/ucb, /usr/bin and /bin.
1015
+ #
1016
+ # If found, it will return the full path, including the executable name,
1017
+ # of where it was found.
1018
+ #
1019
+ # Note that this method does not actually affect the generated Makefile.
1020
+ #
1021
+ def find_executable(bin, path = nil)
1022
+ checking_for checking_message(bin, path) do
1023
+ find_executable0(bin, path)
1024
+ end
1025
+ end
1026
+
1027
+ # :stopdoc:
1028
+
1029
+ def arg_config(config, *defaults, &block)
1030
+ $arg_config << [config, *defaults]
1031
+ defaults << nil if !block and defaults.empty?
1032
+ $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
1033
+ end
1034
+
1035
+ # :startdoc:
1036
+
1037
+ # Tests for the presence of a --with-<tt>config</tt> or --without-<tt>config</tt>
1038
+ # option. Returns true if the with option is given, false if the without
1039
+ # option is given, and the default value otherwise.
1040
+ #
1041
+ # This can be useful for adding custom definitions, such as debug information.
1042
+ #
1043
+ # Example:
1044
+ #
1045
+ # if with_config("debug")
1046
+ # $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1047
+ # end
1048
+ #
1049
+ def with_config(config, *defaults)
1050
+ config = config.sub(/^--with[-_]/, '')
1051
+ val = arg_config("--with-"+config) do
1052
+ if arg_config("--without-"+config)
1053
+ false
1054
+ elsif block_given?
1055
+ yield(config, *defaults)
1056
+ else
1057
+ break *defaults
1058
+ end
1059
+ end
1060
+ case val
1061
+ when "yes"
1062
+ true
1063
+ when "no"
1064
+ false
1065
+ else
1066
+ val
1067
+ end
1068
+ end
1069
+
1070
+ # Tests for the presence of an --enable-<tt>config</tt> or
1071
+ # --disable-<tt>config</tt> option. Returns true if the enable option is given,
1072
+ # false if the disable option is given, and the default value otherwise.
1073
+ #
1074
+ # This can be useful for adding custom definitions, such as debug information.
1075
+ #
1076
+ # Example:
1077
+ #
1078
+ # if enable_config("debug")
1079
+ # $defs.push("-DOSSL_DEBUG") unless $defs.include? "-DOSSL_DEBUG"
1080
+ # end
1081
+ #
1082
+ def enable_config(config, *defaults)
1083
+ if arg_config("--enable-"+config)
1084
+ true
1085
+ elsif arg_config("--disable-"+config)
1086
+ false
1087
+ elsif block_given?
1088
+ yield(config, *defaults)
1089
+ else
1090
+ return *defaults
1091
+ end
1092
+ end
1093
+
1094
+ # Generates a header file consisting of the various macro definitions generated
1095
+ # by other methods such as have_func and have_header. These are then wrapped in
1096
+ # a custom #ifndef based on the +header+ file name, which defaults to
1097
+ # 'extconf.h'.
1098
+ #
1099
+ # For example:
1100
+ #
1101
+ # # extconf.rb
1102
+ # require 'mkmf'
1103
+ # have_func('realpath')
1104
+ # have_header('sys/utime.h')
1105
+ # create_header
1106
+ # create_makefile('foo')
1107
+ #
1108
+ # The above script would generate the following extconf.h file:
1109
+ #
1110
+ # #ifndef EXTCONF_H
1111
+ # #define EXTCONF_H
1112
+ # #define HAVE_REALPATH 1
1113
+ # #define HAVE_SYS_UTIME_H 1
1114
+ # #endif
1115
+ #
1116
+ # Given that the create_header method generates a file based on definitions
1117
+ # set earlier in your extconf.rb file, you will probably want to make this
1118
+ # one of the last methods you call in your script.
1119
+ #
1120
+ def create_header(header = "extconf.h")
1121
+ message "creating %s\n", header
1122
+ sym = header.tr("a-z./\055", "A-Z___")
1123
+ hdr = ["#ifndef #{sym}\n#define #{sym}\n"]
1124
+ for line in $defs
1125
+ case line
1126
+ when /^-D([^=]+)(?:=(.*))?/
1127
+ hdr << "#define #$1 #{$2 ? Shellwords.shellwords($2)[0] : 1}\n"
1128
+ when /^-U(.*)/
1129
+ hdr << "#undef #$1\n"
1130
+ end
1131
+ end
1132
+ hdr << "#endif\n"
1133
+ hdr = hdr.join
1134
+ unless (IO.read(header) == hdr rescue false)
1135
+ open(header, "w") do |hfile|
1136
+ hfile.write(hdr)
1137
+ end
1138
+ end
1139
+ $extconf_h = header
1140
+ end
1141
+
1142
+ # Sets a +target+ name that the user can then use to configure various 'with'
1143
+ # options with on the command line by using that name. For example, if the
1144
+ # target is set to "foo", then the user could use the --with-foo-dir command
1145
+ # line option.
1146
+ #
1147
+ # You may pass along additional 'include' or 'lib' defaults via the +idefault+
1148
+ # and +ldefault+ parameters, respectively.
1149
+ #
1150
+ # Note that dir_config only adds to the list of places to search for libraries
1151
+ # and include files. It does not link the libraries into your application.
1152
+ #
1153
+ def dir_config(target, idefault=nil, ldefault=nil)
1154
+ if dir = with_config(target + "-dir", (idefault unless ldefault))
1155
+ defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
1156
+ idefault = ldefault = nil
1157
+ end
1158
+
1159
+ idir = with_config(target + "-include", idefault)
1160
+ $arg_config.last[1] ||= "${#{target}-dir}/include"
1161
+ ldir = with_config(target + "-lib", ldefault)
1162
+ $arg_config.last[1] ||= "${#{target}-dir}/lib"
1163
+
1164
+ idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
1165
+ if defaults
1166
+ idirs.concat(defaults.collect {|dir| dir + "/include"})
1167
+ idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
1168
+ end
1169
+ unless idirs.empty?
1170
+ idirs.collect! {|dir| "-I" + dir}
1171
+ idirs -= Shellwords.shellwords($CPPFLAGS)
1172
+ unless idirs.empty?
1173
+ $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
1174
+ end
1175
+ end
1176
+
1177
+ ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
1178
+ if defaults
1179
+ ldirs.concat(defaults.collect {|dir| dir + "/lib"})
1180
+ ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
1181
+ end
1182
+ $LIBPATH = ldirs | $LIBPATH
1183
+
1184
+ [idir, ldir]
1185
+ end
1186
+
1187
+ # :stopdoc:
1188
+
1189
+ # Handles meta information about installed libraries. Uses your platform's
1190
+ # pkg-config program if it has one.
1191
+ def pkg_config(pkg)
1192
+ if pkgconfig = with_config("#{pkg}-config") and find_executable0(pkgconfig)
1193
+ # iff package specific config command is given
1194
+ get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1195
+ elsif ($PKGCONFIG ||=
1196
+ (pkgconfig = with_config("pkg-config", ("pkg-config" unless CROSS_COMPILING))) &&
1197
+ find_executable0(pkgconfig) && pkgconfig) and
1198
+ system("#{$PKGCONFIG} --exists #{pkg}")
1199
+ # default to pkg-config command
1200
+ get = proc {|opt| `#{$PKGCONFIG} --#{opt} #{pkg}`.chomp}
1201
+ elsif find_executable0(pkgconfig = "#{pkg}-config")
1202
+ # default to package specific config command, as a last resort.
1203
+ get = proc {|opt| `#{pkgconfig} --#{opt}`.chomp}
1204
+ end
1205
+ if get
1206
+ cflags = get['cflags']
1207
+ ldflags = get['libs']
1208
+ libs = get['libs-only-l']
1209
+ ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
1210
+ $CFLAGS += " " << cflags
1211
+ $LDFLAGS += " " << ldflags
1212
+ $libs += " " << libs
1213
+ Logging::message "package configuration for %s\n", pkg
1214
+ Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
1215
+ cflags, ldflags, libs
1216
+ [cflags, ldflags, libs]
1217
+ else
1218
+ Logging::message "package configuration for %s is not found\n", pkg
1219
+ nil
1220
+ end
1221
+ end
1222
+
1223
+ def with_destdir(dir)
1224
+ dir = dir.sub($dest_prefix_pattern, '')
1225
+ /\A\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
1226
+ end
1227
+
1228
+ # Converts forward slashes to backslashes. Aimed at MS Windows.
1229
+ #
1230
+ # Internal use only.
1231
+ #
1232
+ def winsep(s)
1233
+ s.tr('/', '\\')
1234
+ end
1235
+
1236
+ # Converts native path to format acceptable in Makefile
1237
+ #
1238
+ # Internal use only.
1239
+ #
1240
+ if !CROSS_COMPILING
1241
+ case CONFIG['build_os']
1242
+ when 'mingw32'
1243
+ def mkintpath(path)
1244
+ # mingw uses make from msys and it needs special care
1245
+ # converts from C:\some\path to /C/some/path
1246
+ path = path.dup
1247
+ path.tr!('\\', '/')
1248
+ path.sub!(/\A([A-Za-z]):(?=\/)/, '/\1')
1249
+ path
1250
+ end
1251
+ end
1252
+ end
1253
+ unless defined?(mkintpath)
1254
+ def mkintpath(path)
1255
+ path
1256
+ end
1257
+ end
1258
+
1259
+ def configuration(srcdir)
1260
+ mk = []
1261
+ vpath = %w[$(srcdir) $(topdir) $(hdrdir)]
1262
+ if !CROSS_COMPILING
1263
+ case CONFIG['build_os']
1264
+ when 'cygwin'
1265
+ if CONFIG['target_os'] != 'cygwin'
1266
+ vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')}
1267
+ end
1268
+ when 'msdosdjgpp'
1269
+ CONFIG['PATH_SEPARATOR'] = ';'
1270
+ end
1271
+ end
1272
+ mk << %{
1273
+ SHELL = /bin/sh
1274
+
1275
+ #### Start of system configuration section. ####
1276
+ #{
1277
+ if $extmk
1278
+ "top_srcdir = " + $top_srcdir.sub(%r"\A#{Regexp.quote($topdir)}/", "$(topdir)/")
1279
+ end
1280
+ }
1281
+ srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {mkintpath(CONFIG[$1||$2])}.quote}
1282
+ topdir = #{mkintpath($extmk ? CONFIG["topdir"] : $topdir).quote}
1283
+ hdrdir = #{$extmk ? mkintpath(CONFIG["hdrdir"]).quote : '$(topdir)'}
1284
+ VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
1285
+ }
1286
+ if $extmk
1287
+ mk << "RUBYLIB = -\nRUBYOPT = -rpurelib.rb\n"
1288
+ end
1289
+ if destdir = CONFIG["prefix"][$dest_prefix_pattern, 1]
1290
+ mk << "\nDESTDIR = #{destdir}\n"
1291
+ end
1292
+ CONFIG.each do |key, var|
1293
+ next unless /prefix$/ =~ key
1294
+ mk << "#{key} = #{with_destdir(var)}\n"
1295
+ end
1296
+ CONFIG.each do |key, var|
1297
+ next if /^abs_/ =~ key
1298
+ next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1
1299
+ mk << "#{key} = #{with_destdir(var)}\n"
1300
+ end
1301
+ if !$extmk and !$configure_args.has_key?('--ruby') and
1302
+ sep = config_string('BUILD_FILE_SEPARATOR')
1303
+ sep = ":/=#{sep}"
1304
+ else
1305
+ sep = ""
1306
+ end
1307
+ extconf_h = $extconf_h ? "-DRUBY_EXTCONF_H=\\\"$(RUBY_EXTCONF_H)\\\" " : $defs.join(" ")<<" "
1308
+ mk << %{
1309
+ CC = #{CONFIG['CC']}
1310
+ LIBRUBY = #{CONFIG['LIBRUBY']}
1311
+ LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
1312
+ LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
1313
+ LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
1314
+
1315
+ RUBY_EXTCONF_H = #{$extconf_h}
1316
+ CFLAGS = #{$static ? '' : CONFIG['CCDLFLAGS']} #$CFLAGS #$ARCH_FLAG
1317
+ INCFLAGS = -I. #$INCFLAGS
1318
+ DEFS = #{CONFIG['DEFS']}
1319
+ CPPFLAGS = #{extconf_h}#{$CPPFLAGS}
1320
+ CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
1321
+ ldflags = #{$LDFLAGS}
1322
+ dldflags = #{$DLDFLAGS}
1323
+ archflag = #{$ARCH_FLAG}
1324
+ DLDFLAGS = $(ldflags) $(dldflags) $(archflag)
1325
+ LDSHARED = #{CONFIG['LDSHARED']}
1326
+ AR = #{CONFIG['AR']}
1327
+ EXEEXT = #{CONFIG['EXEEXT']}
1328
+
1329
+ RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
1330
+ RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
1331
+ arch = #{CONFIG['arch']}
1332
+ sitearch = #{CONFIG['sitearch']}
1333
+ ruby_version = #{Config::CONFIG['ruby_version']}
1334
+ ruby = #{$ruby}
1335
+ RUBY = $(ruby#{sep})
1336
+ RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}
1337
+ MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}
1338
+ INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}
1339
+ INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
1340
+ INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
1341
+ COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
1342
+
1343
+ #### End of system configuration section. ####
1344
+
1345
+ preload = #{$preload ? $preload.join(' ') : ''}
1346
+ }
1347
+ if $nmake == ?b
1348
+ mk.each do |x|
1349
+ x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
1350
+ "!ifndef " + $1 + "\n" +
1351
+ $& +
1352
+ "!endif\n"
1353
+ end
1354
+ end
1355
+ end
1356
+ mk
1357
+ end
1358
+
1359
+ def dummy_makefile(srcdir)
1360
+ configuration(srcdir) << <<RULES << CLEANINGS
1361
+ CLEANFILES = #{$cleanfiles.join(' ')}
1362
+ DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1363
+
1364
+ all install static install-so install-rb: Makefile
1365
+
1366
+ RULES
1367
+ end
1368
+ # :startdoc:
1369
+
1370
+ # Generates the Makefile for your extension, passing along any options and
1371
+ # preprocessor constants that you may have generated through other methods.
1372
+ #
1373
+ # The +target+ name should correspond the name of the global function name
1374
+ # defined within your C extension, minus the 'Init_'. For example, if your
1375
+ # C extension is defined as 'Init_foo', then your target would simply be 'foo'.
1376
+ #
1377
+ # If any '/' characters are present in the target name, only the last name
1378
+ # is interpreted as the target name, and the rest are considered toplevel
1379
+ # directory names, and the generated Makefile will be altered accordingly to
1380
+ # follow that directory structure.
1381
+ #
1382
+ # For example, if you pass 'test/foo' as a target name, your extension will
1383
+ # be installed under the 'test' directory. This means that in order to
1384
+ # load the file within a Ruby program later, that directory structure will
1385
+ # have to be followed, e.g. "require 'test/foo'".
1386
+ #
1387
+ # The +srcprefix+ should be used when your source files are not in the same
1388
+ # directory as your build script. This will not only eliminate the need for
1389
+ # you to manually copy the source files into the same directory as your build
1390
+ # script, but it also sets the proper +target_prefix+ in the generated
1391
+ # Makefile.
1392
+ #
1393
+ # Setting the +target_prefix+ will, in turn, install the generated binary in
1394
+ # a directory under your Config::CONFIG['sitearchdir'] that mimics your local
1395
+ # filesystem when you run 'make install'.
1396
+ #
1397
+ # For example, given the following file tree:
1398
+ #
1399
+ # ext/
1400
+ # extconf.rb
1401
+ # test/
1402
+ # foo.c
1403
+ #
1404
+ # And given the following code:
1405
+ #
1406
+ # create_makefile('test/foo', 'test')
1407
+ #
1408
+ # That will set the +target_prefix+ in the generated Makefile to 'test'. That,
1409
+ # in turn, will create the following file tree when installed via the
1410
+ # 'make install' command:
1411
+ #
1412
+ # /path/to/ruby/sitearchdir/test/foo.so
1413
+ #
1414
+ # It is recommended that you use this approach to generate your makefiles,
1415
+ # instead of copying files around manually, because some third party
1416
+ # libraries may depend on the +target_prefix+ being set properly.
1417
+ #
1418
+ # The +srcprefix+ argument can be used to override the default source
1419
+ # directory, i.e. the current directory . It is included as part of the VPATH
1420
+ # and added to the list of INCFLAGS.
1421
+ #
1422
+ def create_makefile(target, srcprefix = nil)
1423
+ $target = target
1424
+ libpath = $DEFLIBPATH|$LIBPATH
1425
+ message "creating Makefile\n"
1426
+ rm_f "conftest*"
1427
+ if CONFIG["DLEXT"] == $OBJEXT
1428
+ for lib in libs = $libs.split
1429
+ lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
1430
+ end
1431
+ $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
1432
+ end
1433
+
1434
+ if target.include?('/')
1435
+ target_prefix, target = File.split(target)
1436
+ target_prefix[0,0] = '/'
1437
+ else
1438
+ target_prefix = ""
1439
+ end
1440
+
1441
+ srcprefix ||= '$(srcdir)'
1442
+ Config::expand(srcdir = srcprefix.dup)
1443
+
1444
+ if not $objs
1445
+ $objs = []
1446
+ srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
1447
+ for f in srcs
1448
+ obj = File.basename(f, ".*") << ".o"
1449
+ $objs.push(obj) unless $objs.index(obj)
1450
+ end
1451
+ elsif !(srcs = $srcs)
1452
+ srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
1453
+ end
1454
+ $srcs = srcs
1455
+ for i in $objs
1456
+ i.sub!(/\.o\z/, ".#{$OBJEXT}")
1457
+ end
1458
+ $objs = $objs.join(" ")
1459
+
1460
+ target = nil if $objs == ""
1461
+
1462
+ if target and EXPORT_PREFIX
1463
+ if File.exist?(File.join(srcdir, target + '.def'))
1464
+ deffile = "$(srcdir)/$(TARGET).def"
1465
+ unless EXPORT_PREFIX.empty?
1466
+ makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
1467
+ end
1468
+ else
1469
+ makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
1470
+ end
1471
+ if makedef
1472
+ $distcleanfiles << '$(DEFFILE)'
1473
+ origdef = deffile
1474
+ deffile = "$(TARGET)-$(arch).def"
1475
+ end
1476
+ end
1477
+ origdef ||= ''
1478
+
1479
+ libpath = libpathflag(libpath)
1480
+
1481
+ dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
1482
+ staticlib = target ? "$(TARGET).#$LIBEXT" : ""
1483
+ mfile = open("Makefile", "wb")
1484
+ mfile.print configuration(srcprefix)
1485
+ mfile.print "
1486
+ libpath = #{($DEFLIBPATH|$LIBPATH).join(" ")}
1487
+ LIBPATH = #{libpath}
1488
+ DEFFILE = #{deffile}
1489
+
1490
+ CLEANFILES = #{$cleanfiles.join(' ')}
1491
+ DISTCLEANFILES = #{$distcleanfiles.join(' ')}
1492
+
1493
+ extout = #{$extout}
1494
+ extout_prefix = #{$extout_prefix}
1495
+ target_prefix = #{target_prefix}
1496
+ LOCAL_LIBS = #{$LOCAL_LIBS}
1497
+ LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
1498
+ SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
1499
+ OBJS = #{$objs}
1500
+ TARGET = #{target}
1501
+ DLLIB = #{dllib}
1502
+ EXTSTATIC = #{$static || ""}
1503
+ STATIC_LIB = #{staticlib unless $static.nil?}
1504
+ #{!$extout && defined?($installed_list) ? "INSTALLED_LIST = #{$installed_list}\n" : ""}
1505
+ "
1506
+ install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
1507
+ n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'
1508
+ mfile.print "
1509
+ TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
1510
+ CLEANLIBS = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map
1511
+ CLEANOBJS = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak
1512
+
1513
+ all: #{$extout ? "install" : target ? "$(DLLIB)" : "Makefile"}
1514
+ static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
1515
+ "
1516
+ mfile.print CLEANINGS
1517
+ dirs = []
1518
+ mfile.print "install: install-so install-rb\n\n"
1519
+ sodir = (dir = "$(RUBYARCHDIR)").dup
1520
+ mfile.print("install-so: ")
1521
+ if target
1522
+ f = "$(DLLIB)"
1523
+ dest = "#{dir}/#{f}"
1524
+ mfile.puts dir, "install-so: #{dest}"
1525
+ unless $extout
1526
+ mfile.print "#{dest}: #{f}\n"
1527
+ if (sep = config_string('BUILD_FILE_SEPARATOR'))
1528
+ f.gsub!("/", sep)
1529
+ dir.gsub!("/", sep)
1530
+ sep = ":/="+sep
1531
+ f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1532
+ f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1533
+ dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
1534
+ dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
1535
+ end
1536
+ mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
1537
+ if defined?($installed_list)
1538
+ mfile.print "\t@echo #{dir}/#{File.basename(f)}>>$(INSTALLED_LIST)\n"
1539
+ end
1540
+ end
1541
+ else
1542
+ mfile.puts "Makefile"
1543
+ end
1544
+ mfile.print("install-rb: pre-install-rb install-rb-default\n")
1545
+ mfile.print("install-rb-default: pre-install-rb-default\n")
1546
+ mfile.print("pre-install-rb: Makefile\n")
1547
+ mfile.print("pre-install-rb-default: Makefile\n")
1548
+ for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
1549
+ files = install_files(mfile, i, nil, srcprefix) or next
1550
+ for dir, *files in files
1551
+ unless dirs.include?(dir)
1552
+ dirs << dir
1553
+ mfile.print "pre-install-rb#{sfx}: #{dir}\n"
1554
+ end
1555
+ files.each do |f|
1556
+ dest = "#{dir}/#{File.basename(f)}"
1557
+ mfile.print("install-rb#{sfx}: #{dest}\n")
1558
+ mfile.print("#{dest}: #{f} #{dir}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
1559
+ sep = config_string('BUILD_FILE_SEPARATOR')
1560
+ if sep
1561
+ f = f.gsub("/", sep)
1562
+ sep = ":/="+sep
1563
+ f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
1564
+ f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
1565
+ else
1566
+ sep = ""
1567
+ end
1568
+ mfile.print("#{f} $(@D#{sep})\n")
1569
+ if defined?($installed_list) and !$extout
1570
+ mfile.print("\t@echo #{dest}>>$(INSTALLED_LIST)\n")
1571
+ end
1572
+ end
1573
+ end
1574
+ end
1575
+ dirs.unshift(sodir) if target and !dirs.include?(sodir)
1576
+ dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}
1577
+
1578
+ mfile.print <<-SITEINSTALL
1579
+
1580
+ site-install: site-install-so site-install-rb
1581
+ site-install-so: install-so
1582
+ site-install-rb: install-rb
1583
+
1584
+ SITEINSTALL
1585
+
1586
+ return unless target
1587
+
1588
+ mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
1589
+ mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
1590
+ mfile.print "\n"
1591
+
1592
+ CXX_EXT.each do |ext|
1593
+ COMPILE_RULES.each do |rule|
1594
+ mfile.printf(rule, ext, $OBJEXT)
1595
+ mfile.printf("\n\t%s\n\n", COMPILE_CXX)
1596
+ end
1597
+ end
1598
+ # add .m
1599
+ %w[c m].each do |ext|
1600
+ COMPILE_RULES.each do |rule|
1601
+ mfile.printf(rule, ext, $OBJEXT)
1602
+ mfile.printf("\n\t%s\n\n", COMPILE_C)
1603
+ end
1604
+ end
1605
+
1606
+ mfile.print "$(RUBYARCHDIR)/" if $extout
1607
+ mfile.print "$(DLLIB): "
1608
+ mfile.print "$(DEFFILE) " if makedef
1609
+ mfile.print "$(OBJS) Makefile\n"
1610
+ mfile.print "\t@-$(RM) $@\n"
1611
+ mfile.print "\t@-$(MAKEDIRS) $(@D)\n" if $extout
1612
+ link_so = LINK_SO.gsub(/^/, "\t")
1613
+ mfile.print link_so, "\n\n"
1614
+ unless $static.nil?
1615
+ mfile.print "$(STATIC_LIB): $(OBJS)\n\t"
1616
+ mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
1617
+ config_string('RANLIB') do |ranlib|
1618
+ mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
1619
+ end
1620
+ end
1621
+ mfile.print "\n\n"
1622
+ if makedef
1623
+ mfile.print "$(DEFFILE): #{origdef}\n"
1624
+ mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
1625
+ end
1626
+
1627
+ depend = File.join(srcdir, "depend")
1628
+ if File.exist?(depend)
1629
+ suffixes = []
1630
+ depout = []
1631
+ open(depend, "r") do |dfile|
1632
+ mfile.printf "###\n"
1633
+ cont = implicit = nil
1634
+ impconv = proc do
1635
+ COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
1636
+ implicit = nil
1637
+ end
1638
+ ruleconv = proc do |line|
1639
+ if implicit
1640
+ if /\A\t/ =~ line
1641
+ implicit[1] << line
1642
+ next
1643
+ else
1644
+ impconv[]
1645
+ end
1646
+ end
1647
+ if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
1648
+ suffixes << m[1] << m[2]
1649
+ implicit = [[m[1], m[2]], [m.post_match]]
1650
+ next
1651
+ elsif RULE_SUBST and /\A(?!\s*\w+\s*=)[$\w][^#]*:/ =~ line
1652
+ line.gsub!(%r"(\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {$1 + RULE_SUBST % $2}
1653
+ end
1654
+ depout << line
1655
+ end
1656
+ while line = dfile.gets()
1657
+ line.gsub!(/\.o\b/, ".#{$OBJEXT}")
1658
+ line.gsub!(/\$\((?:hdr|top)dir\)\/config.h/, $config_h) if $config_h
1659
+ if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
1660
+ (cont ||= []) << line
1661
+ next
1662
+ elsif cont
1663
+ line = (cont << line).join
1664
+ cont = nil
1665
+ end
1666
+ ruleconv.call(line)
1667
+ end
1668
+ if cont
1669
+ ruleconv.call(cont.join)
1670
+ elsif implicit
1671
+ impconv.call
1672
+ end
1673
+ end
1674
+ unless suffixes.empty?
1675
+ mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
1676
+ end
1677
+ mfile.print "$(OBJS): $(RUBY_EXTCONF_H)\n\n" if $extconf_h
1678
+ mfile.print depout
1679
+ else
1680
+ headers = %w[ruby.h defines.h]
1681
+ if RULE_SUBST
1682
+ headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}
1683
+ end
1684
+ headers << $config_h if $config_h
1685
+ headers << "$(RUBY_EXTCONF_H)" if $extconf_h
1686
+ mfile.print "$(OBJS): ", headers.join(' '), "\n"
1687
+ end
1688
+
1689
+ $makefile_created = true
1690
+ ensure
1691
+ mfile.close if mfile
1692
+ end
1693
+
1694
+ # :stopdoc:
1695
+
1696
+ def init_mkmf(config = CONFIG)
1697
+ $makefile_created = false
1698
+ $arg_config = []
1699
+ $enable_shared = config['ENABLE_SHARED'] == 'yes'
1700
+ $defs = []
1701
+ $extconf_h = nil
1702
+ $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
1703
+ $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
1704
+ $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
1705
+ $LDFLAGS = with_config("ldflags", arg_config("LDFLAGS", config["LDFLAGS"])).dup
1706
+ $INCFLAGS = "-I$(topdir) -I$(hdrdir) -I$(srcdir)"
1707
+ $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
1708
+ $LIBEXT = config['LIBEXT'].dup
1709
+ $OBJEXT = config["OBJEXT"].dup
1710
+ $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
1711
+ $LIBRUBYARG = ""
1712
+ $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
1713
+ $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
1714
+ $DEFLIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"]
1715
+ $DEFLIBPATH.unshift(".")
1716
+ $LIBPATH = []
1717
+ $INSTALLFILES = []
1718
+ $NONINSTALLFILES = [/~\z/, /\A#.*#\z/, /\A\.#/, /\.bak\z/i, /\.orig\z/, /\.rej\z/, /\.l[ao]\z/, /\.o\z/]
1719
+
1720
+ $objs = nil
1721
+ $srcs = nil
1722
+ $libs = ""
1723
+ if $enable_shared or Config.expand(config["LIBRUBY"].dup) != Config.expand(config["LIBRUBY_A"].dup)
1724
+ $LIBRUBYARG = config['LIBRUBYARG']
1725
+ end
1726
+
1727
+ $LOCAL_LIBS = ""
1728
+
1729
+ $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
1730
+ $cleanfiles << "mkmf.log"
1731
+ $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
1732
+
1733
+ $extout ||= nil
1734
+ $extout_prefix ||= nil
1735
+
1736
+ $arg_config.clear
1737
+ dir_config("opt")
1738
+ end
1739
+
1740
+ FailedMessage = <<MESSAGE
1741
+ Could not create Makefile due to some reason, probably lack of
1742
+ necessary libraries and/or headers. Check the mkmf.log file for more
1743
+ details. You may need configuration options.
1744
+
1745
+ Provided configuration options:
1746
+ MESSAGE
1747
+
1748
+ # Returns whether or not the Makefile was successfully generated. If not,
1749
+ # the script will abort with an error message.
1750
+ #
1751
+ # Internal use only.
1752
+ #
1753
+ def mkmf_failed(path)
1754
+ unless $makefile_created or File.exist?("Makefile")
1755
+ opts = $arg_config.collect {|t, n| "\t#{t}#{n ? "=#{n}" : ""}\n"}
1756
+ abort "*** #{path} failed ***\n" + FailedMessage + opts.join
1757
+ end
1758
+ end
1759
+
1760
+ # :startdoc:
1761
+
1762
+ init_mkmf
1763
+
1764
+ $make = with_config("make-prog", ENV["MAKE"] || "make")
1765
+ make, = Shellwords.shellwords($make)
1766
+ $nmake = nil
1767
+ case
1768
+ when $mswin
1769
+ $nmake = ?m if /nmake/i =~ make
1770
+ when $bccwin
1771
+ $nmake = ?b if /Borland/i =~ `#{make} -h`
1772
+ end
1773
+
1774
+ Config::CONFIG["srcdir"] = CONFIG["srcdir"] =
1775
+ $srcdir = arg_config("--srcdir", File.dirname($0))
1776
+ $configure_args["--topsrcdir"] ||= $srcdir
1777
+ if $curdir = arg_config("--curdir")
1778
+ Config.expand(curdir = $curdir.dup)
1779
+ else
1780
+ curdir = $curdir = "."
1781
+ end
1782
+ unless File.expand_path(Config::CONFIG["topdir"]) == File.expand_path(curdir)
1783
+ CONFIG["topdir"] = $curdir
1784
+ Config::CONFIG["topdir"] = curdir
1785
+ end
1786
+ $configure_args["--topdir"] ||= $curdir
1787
+ $ruby = arg_config("--ruby", File.join(Config::CONFIG["bindir"], CONFIG["ruby_install_name"]))
1788
+
1789
+ split = Shellwords.method(:shellwords).to_proc
1790
+
1791
+ EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
1792
+
1793
+ hdr = []
1794
+ config_string('COMMON_MACROS') do |s|
1795
+ Shellwords.shellwords(s).each do |w|
1796
+ hdr << "#define " + w.split(/=/, 2).join(" ")
1797
+ end
1798
+ end
1799
+ config_string('COMMON_HEADERS') do |s|
1800
+ Shellwords.shellwords(s).each {|s| hdr << "#include <#{s}>"}
1801
+ end
1802
+ COMMON_HEADERS = hdr.join("\n")
1803
+ COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
1804
+
1805
+ COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
1806
+ RULE_SUBST = config_string('RULE_SUBST')
1807
+ COMPILE_C = config_string('COMPILE_C') || '$(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $<'
1808
+ COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $<'
1809
+ TRY_LINK = config_string('TRY_LINK') ||
1810
+ "$(CC) #{OUTFLAG}conftest $(INCFLAGS) $(CPPFLAGS) " \
1811
+ "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
1812
+ LINK_SO = config_string('LINK_SO') ||
1813
+ if CONFIG["DLEXT"] == $OBJEXT
1814
+ "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
1815
+ else
1816
+ "$(LDSHARED) #{OUTFLAG}$@ $(OBJS) " \
1817
+ "$(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS)"
1818
+ end
1819
+ LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"'
1820
+ RPATHFLAG = config_string('RPATHFLAG') || ''
1821
+ LIBARG = config_string('LIBARG') || '-l%s'
1822
+
1823
+ sep = config_string('BUILD_FILE_SEPARATOR') {|sep| ":/=#{sep}" if sep != "/"} || ""
1824
+ CLEANINGS = "
1825
+ clean:
1826
+ @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})
1827
+
1828
+ distclean: clean
1829
+ @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log
1830
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
1831
+
1832
+ realclean: distclean
1833
+ "
1834
+
1835
+ if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
1836
+ END {mkmf_failed($0)}
1837
+ end