ext/extmk.rb
DEFINITIONS
This source file includes following functions.
1 #! /usr/local/bin/ruby
2 # -*- ruby -*-
3
4 $force_static = nil
5 $install = nil
6 $destdir = nil
7 $clean = nil
8 $nodynamic = nil
9 $extinit = nil
10 $extobjs = nil
11
12 if ARGV[0] == 'static'
13 $force_static = true
14 ARGV.shift
15 elsif ARGV[0] == 'install'
16 $install = true
17 $destdir = ARGV[1] || ''
18 ARGV.shift
19 elsif ARGV[0] == 'clean'
20 $clean = "clean"
21 ARGV.shift
22 elsif ARGV[0] == 'distclean'
23 $clean = "distclean"
24 ARGV.shift
25 elsif ARGV[0] == 'realclean'
26 $clean = "realclean"
27 ARGV.shift
28 end
29
30 $extlist = []
31
32 $:.replace ["."]
33 require 'rbconfig'
34
35 srcdir = Config::CONFIG["srcdir"]
36
37 $:.replace [srcdir, srcdir+"/lib", "."]
38
39 require 'mkmf'
40 require 'find'
41 require 'ftools'
42 require 'shellwords'
43
44 $topdir = File.expand_path(".")
45 $top_srcdir = srcdir
46
47 Object.class_eval do remove_method :create_makefile end
48
49 def create_makefile(target)
50 $target = target
51 if target.include?('/')
52 target_prefix, target = File.split(target)
53 target_prefix[0,0] = '/'
54 else
55 target_prefix = ""
56 end
57 rm_f "conftest*"
58 if CONFIG["DLEXT"] == $OBJEXT
59 libs = $libs.split
60 for lib in libs
61 lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
62 end
63 $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
64 end
65
66 $DLDFLAGS = CONFIG["DLDFLAGS"].dup
67
68 if $configure_args['--enable-shared'] or CONFIG["LIBRUBY"] != CONFIG["LIBRUBY_A"]
69 $libs = CONFIG["LIBRUBYARG"] + " " + $libs
70 $LIBPATH.unshift $topdir
71 end
72
73 defflag = ''
74 if RUBY_PLATFORM =~ /cygwin|mingw/ and not $static
75 if not File.exist? target + '.def'
76 open(target + '.def', 'wb') do |f|
77 f.print "EXPORTS\n", "Init_", target, "\n"
78 end
79 end
80 defflag = target + ".def"
81 elsif RUBY_PLATFORM =~ /bccwin32/
82 deffile = target + '.def'
83 if not File.exist? target + '.def'
84 open(deffile, 'wb') do |f|
85 f.print "EXPORTS\n", "_Init_", target, "\n"
86 end
87 end
88 end
89
90 if RUBY_PLATFORM =~ /mswin32|bccwin32/
91 libpath = $LIBPATH.join(';')
92 else
93 $LIBPATH.each {|d| $DLDFLAGS << " -L" << d}
94 if /netbsdelf/ =~ RUBY_PLATFORM
95 $LIBPATH.each {|d| $DLDFLAGS << " -Wl,-R" + d unless d == $topdir}
96 end
97 end
98
99 $srcdir = File.join($top_srcdir,"ext",$mdir)
100 mfile = open("Makefile", "w")
101 mfile.binmode if /mingw/ =~ RUBY_PLATFORM
102 mfile.printf <<EOL, if $static then "" else CONFIG["CCDLFLAGS"] end, $defs.join(" ")
103 SHELL = /bin/sh
104
105 #### Start of system configuration section. ####
106
107 srcdir = #{$srcdir}
108 VPATH = #{$srcdir}
109
110 topdir = #{$topdir}
111 hdrdir = #{$top_srcdir}
112
113 CC = #{CONFIG['CC']}
114
115 CFLAGS = %s #{CFLAGS} #$CFLAGS
116 CPPFLAGS = -I$(topdir) -I$(hdrdir) %s #$CPPFLAGS
117 #{
118 if /bccwin32/ =~ RUBY_PLATFORM
119 "DLDFLAGS = #$LDFLAGS -L" + '"$(libdir:/=\\);$(topdir:/=\\)"' + "\n" +
120 "LDSHARED = #{CONFIG['LDSHARED']}\n"
121 else
122 "DLDFLAGS = #$DLDFLAGS #$LDFLAGS\n" +
123 "LDSHARED = #{CONFIG['LDSHARED']} #{defflag}\n"
124 end
125 }
126 EOL
127 mfile.puts "LIBPATH = #{libpath}" if libpath
128
129 mfile.puts ".SUFFIXES: .#{CONFIG['OBJEXT']}" unless #{CONFIG['OBJEXT']} == "o"
130
131 mfile.printf "\
132
133 RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
134 RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
135 ruby_version = #{Config::CONFIG["ruby_version"]}
136
137 prefix = #{CONFIG['prefix']}
138 exec_prefix = #{CONFIG['exec_prefix']}
139 libdir = #{CONFIG['libdir']}
140 rubylibdir = $(libdir)/ruby/$(ruby_version)
141 #pkglibdir = $(libdir)/$(RUBY_INSTALL_NAME)/#{CONFIG['MAJOR']}.#{CONFIG['MINOR']}
142 pkglibdir = $(libdir)/ruby/#{CONFIG['MAJOR']}.#{CONFIG['MINOR']}
143 archdir = $(pkglibdir)/#{CONFIG['arch']}
144 target_prefix = #{target_prefix}
145 #{CONFIG['SET_MAKE']}
146
147 #### End of system configuration section. ####
148
149 "
150 mfile.printf "LOCAL_LIBS = %s %s\n", $LOCAL_LIBS, $local_flags
151 if /bccwin32/ =~ RUBY_PLATFORM
152 mfile.printf "LIBS = $(topdir:/=\\)\\%s\n", $libs
153 else
154 mfile.printf "LIBS = %s\n", $libs
155 end
156 mfile.printf "OBJS = "
157 if !$objs or (/bccwin32/ =~ RUBY_PLATFORM) then
158 $objs = []
159 for f in Dir["#{$top_srcdir}/ext/#{$mdir}/*.{#{SRC_EXT.join(%q{,})}}"]
160 f = File.basename(f)
161 f.sub!(/(#{SRC_EXT.join(%q{|})})$/, $OBJEXT)
162 $objs.push f
163 end
164 else
165 for i in $objs
166 i.sub!(/\.o\z/, ".#{$OBJEXT}")
167 end
168 end
169 mfile.printf $objs.join(" ")
170 mfile.printf "\n"
171
172 if /bccwin32/ =~ RUBY_PLATFORM
173 ruby_interpreter = '$(topdir:/=\)/miniruby' + CONFIG['EXEEXT']
174 else
175 ruby_interpreter = "$(topdir)/miniruby" + CONFIG['EXEEXT']
176 if /nmake/i =~ $make
177 ruby_interpreter = '$(topdir:/=\)\miniruby' + CONFIG['EXEEXT']
178 end
179 end
180 if defined? CROSS_COMPILING
181 ruby_interpreter = CONFIG['MINIRUBY']
182 end
183
184 mfile.printf <<EOS
185 TARGET = #{target}
186 DLLIB = $(TARGET).#{$static ? $LIBEXT : CONFIG['DLEXT']}
187
188 RUBY = #{ruby_interpreter} -I$(topdir) -I$(hdrdir)/lib
189 RM = $(RUBY) -rftools -e "File::rm_f(*ARGV.map do|x|Dir[x]end.flatten.uniq)"
190 MAKEDIRS = $(RUBY) -r ftools -e 'File::makedirs(*ARGV)'
191 INSTALL_PROG = $(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0555, true)'
192 INSTALL_DATA = $(RUBY) -r ftools -e 'File::install(ARGV[0], ARGV[1], 0644, true)'
193
194 EXEEXT = CONFIG['EXEEXT']
195
196 all: $(DLLIB)
197
198 clean:
199 @$(RM) *.#{$OBJEXT} *.so *.sl *.#{$LIBEXT} $(DLLIB)
200 #{
201 if /bccwin32/ =~ RUBY_PLATFORM
202 " @$(RM) *.def *.ilc *.ild *.ilf *.ils *.map *.tds *.bak $(CLEANFILES)\n" +
203 " @if exist $(target).def.org ren $(target).def.org $(target).def"
204 else
205 " @$(RM) *.ilk *.exp *.pdb *.bak $(CLEANFILES)"
206 end
207 }
208
209 distclean: clean
210 @$(RM) Makefile extconf.h conftest.*
211 @$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES)
212
213 realclean: distclean
214 EOS
215
216 mfile.printf <<EOS
217
218 install:
219 @$(MAKEDIRS) $(DESTDIR)$(libdir) $(DESTDIR)$(pkglibdir) $(DESTDIR)$(archdir)$(target_prefix)
220 EOS
221 unless $static
222 mfile.printf "\
223 @$(INSTALL_PROG) $(DLLIB) $(DESTDIR)$(archdir)$(target_prefix)/$(DLLIB)
224 "
225 end
226 save_srcdir = Config::CONFIG['srcdir']
227 Config::CONFIG['srcdir'] = $srcdir
228 install_rb(mfile, '$(DESTDIR)$(rubylibdir)$(target_prefix)', '$(srcdir)')
229 Config::CONFIG['srcdir'] = save_srcdir
230 mfile.printf "\n"
231
232 unless /mswin32/ =~ RUBY_PLATFORM
233 if /bccwin32/ =~ RUBY_PLATFORM
234 src = '$(<:\\=/)'
235 else
236 src = '$<'
237 end
238 copt = cxxopt = ''
239 else
240 if /nmake/i =~ $make
241 src = '$(<:\\=/)'
242 else
243 src = '$(subst /,\\\\,$<)'
244 end
245 copt = '-Tc'
246 cxxopt = '-Tp'
247 end
248 unless /nmake/i =~ $make
249 if /bccwin32/ =~ RUBY_PLATFORM
250 mfile.print "
251 {$(srcdir)}.cc{}.#{CONFIG['OBJEXT']}:
252 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
253 {$(srcdir)}.cpp{}.#{CONFIG['OBJEXT']}:
254 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
255 {$(srcdir)}.cxx{}.#{CONFIG['OBJEXT']}:
256 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
257 {$(srcdir)}.c{}.#{CONFIG['OBJEXT']}:
258 $(CC) $(CFLAGS) $(CPPFLAGS) -c #{copt}#{src}
259 "
260 end
261 mfile.puts "
262 .cc.#{CONFIG['OBJEXT']}:
263 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
264 .cpp.#{CONFIG['OBJEXT']}:
265 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
266 .cxx.#{CONFIG['OBJEXT']}:
267 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
268 .C.#{CONFIG['OBJEXT']}:
269 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
270 .c.#{CONFIG['OBJEXT']}:
271 $(CC) $(CFLAGS) $(CPPFLAGS) -c #{copt}#{src}
272 "
273 else
274 mfile.print "
275 {$(srcdir)}.c{}.#{CONFIG['OBJEXT']}:
276 $(CC) -I. -I$(<D) $(CFLAGS) $(CPPFLAGS) -c #{copt}#{src}
277 .c.#{CONFIG['OBJEXT']}:
278 $(CC) $(CFLAGS) $(CPPFLAGS) -c #{copt}#{src}
279 {$(srcdir)}.cc{}.#{CONFIG['OBJEXT']}:
280 $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
281 .cc.#{CONFIG['OBJEXT']}:
282 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
283 {$(srcdir)}.cpp{}.#{CONFIG['OBJEXT']}:
284 $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
285 .cpp.#{CONFIG['OBJEXT']}:
286 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
287 {$(srcdir)}.cxx{}.#{CONFIG['OBJEXT']}:
288 $(CXX) -I. -I$(<D) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
289 .cxx.#{CONFIG['OBJEXT']}:
290 $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c #{cxxopt}#{src}
291 "
292 end
293
294 if $static
295 if CONFIG['AR'] =~ /^lib\b/i
296 mfile.printf "\
297 $(DLLIB): $(OBJS)
298 #{CONFIG['AR']} /OUT:$(DLLIB) $(OBJS)
299 "
300 else
301 mfile.printf "\
302 $(DLLIB): $(OBJS)
303 #{CONFIG['AR']} cru $(DLLIB) $(OBJS)
304 @-#{CONFIG['RANLIB']} $(DLLIB) 2> /dev/null || true
305 "
306 end
307 elsif CONFIG['DLEXT'] != $OBJEXT
308 mfile.print "$(DLLIB): $(OBJS)\n"
309 if /bccwin32/ =~ RUBY_PLATFORM
310 mfile.print "\t$(LDSHARED) $(DLDFLAGS) C0D32.OBJ $(OBJS), $@,, CW32.LIB IMPORT32.LIB WS2_32.LIB $(LIBS), #{deffile}\n"
311 else
312 if /mswin32/ =~ RUBY_PLATFORM
313 if /nmake/i =~ $make
314 mfile.print "\tset LIB=$(LIBPATH:/=\\);$(LIB)\n"
315 else
316 mfile.print "\tenv LIB='$(subst /,\\\\,$(LIBPATH));$(LIB)' \\\n"
317 end
318 end
319 mfile.print "\t$(LDSHARED) $(DLDFLAGS) #{OUTFLAG}$(DLLIB) $(OBJS) $(LIBS) $(LOCAL_LIBS)\n"
320 end
321 elsif RUBY_PLATFORM == "m68k-human"
322 mfile.printf "\
323 $(DLLIB): $(OBJS)
324 ar cru $(DLLIB) $(OBJS)
325 "
326 else
327 mfile.printf "\
328 $(DLLIB): $(OBJS)
329 ld $(DLDFLAGS) -r -o $(DLLIB) $(OBJS)
330 "
331 end
332
333 if File.exist?("#{$srcdir}/depend")
334 dfile = open("#{$srcdir}/depend", "r")
335 mfile.printf "###\n"
336 while line = dfile.gets()
337 line.gsub!(/\.o\b/, ".#{$OBJEXT}")
338 if /bccwin32/ =~ RUBY_PLATFORM
339 line.gsub!(/(\s)([^\s\/]+\.[ch])/, '\1{$(srcdir)}\2')
340 else
341 line.gsub!(/(\s)([^\s\/]+\.[ch])/, '\1{$(srcdir)}\2') if /nmake/i =~ $make
342 end
343 mfile.printf "%s", line.gsub(/\$\(hdrdir\)\/config.h/, '$(topdir)/config.h')
344 end
345 dfile.close
346 end
347 mfile.close
348 end
349
350 def extmake(target)
351 if $force_static or $static_ext[target]
352 $static = target
353 else
354 $static = false
355 end
356
357 unless $install or $clean
358 return if $nodynamic and not $static
359 end
360
361 $OBJEXT = CONFIG['OBJEXT']
362 $LIBEXT = "a"
363 $objs = nil
364 $libs = CONFIG['DLDLIBS'].dup
365 $local_flags = ""
366 if /mswin32/ =~ RUBY_PLATFORM
367 $LIBEXT = "lib"
368 $local_flags = "-link /INCREMENTAL:no /EXPORT:Init_$(TARGET)"
369 elsif /bccwin32/ =~ RUBY_PLATFORM
370 $LIBEXT = "lib"
371 end
372 $LOCAL_LIBS = "" # to be assigned in extconf.rb
373 $CFLAGS = ""
374 $CPPFLAGS = CONFIG['CPPFLAGS']
375 $LDFLAGS = ""
376 $LIBPATH = [$libdir]
377 $INCFLAGS = "-I#{$topdir}"
378
379 dir_config("opt")
380
381 begin
382 dir = Dir.pwd
383 File.mkpath target unless File.directory?(target)
384 Dir.chdir target
385 $target = target
386 $mdir = target
387 unless $install or $clean
388 if $static_ext.size > 0 ||
389 !File.exist?("./Makefile") ||
390 older("./Makefile", $setup) ||
391 older("./Makefile", "#{$top_srcdir}/ext/extmk.rb") ||
392 older("./Makefile", "#{$top_srcdir}/ext/#{target}/makefile.rb") ||
393 older("./Makefile", "#{$top_srcdir}/ext/#{target}/extconf.rb")
394 then
395 $defs = []
396 Logging::logfile 'mkmf.log'
397 if File.exist?("#{$top_srcdir}/ext/#{target}/makefile.rb")
398 load "#{$top_srcdir}/ext/#{target}/makefile.rb"
399 elsif File.exist?("#{$top_srcdir}/ext/#{target}/extconf.rb")
400 load "#{$top_srcdir}/ext/#{target}/extconf.rb"
401 else
402 create_makefile(target)
403 end
404 end
405 end
406 if File.exist?("./Makefile")
407 if $static
408 $extlist.push [$static, $target, File.basename($target)]
409 end
410 if $install
411 if /bccwin32/ =~ RUBY_PLATFORM
412 system "#{$make} -DDESTDIR=#{$destdir} install"
413 else
414 system "#{$make} install DESTDIR=#{$destdir}"
415 end
416 elsif $clean
417 system "#{$make} #{$clean}"
418 else
419 unless system "#{$make} all"
420 if ENV["MAKEFLAGS"] != "k" and ENV["MFLAGS"] != "-k"
421 exit
422 end
423 end
424 end
425 end
426 if $static
427 $extlibs ||= ""
428 $extlibs += " " + $DLDFLAGS if $DLDFLAGS
429 $extlibs += " " + $LDFLAGS unless $LDFLAGS == ""
430 $extlibs += " " + $libs unless $libs == ""
431 $extlibs += " " + $LOCAL_LIBS unless $LOCAL_LIBS == ""
432 end
433 ensure
434 rm_f "conftest*"
435 Dir.chdir dir
436 end
437 end
438
439 $make = ENV["MAKE"]
440 $make ||= with_config("make-prog", "make")
441
442 File::makedirs('ext')
443 Dir::chdir('ext')
444
445 # get static-link modules
446 $static_ext = {}
447 for setup in [CONFIG['setup'], File::join($top_srcdir, "ext", CONFIG['setup'])]
448 if File.file? setup
449 f = open(setup)
450 while line = f.gets()
451 line.chomp!
452 line.sub!(/#.*$/, '')
453 next if /^\s*$/ =~ line
454 if /^option +nodynamic/ =~ line
455 $nodynamic = true
456 next
457 end
458 target = line.split[0]
459 target = target.downcase if /mswin32|bccwin32/ =~ RUBY_PLATFORM
460 $static_ext[target] = true
461 end
462 $setup = setup
463 f.close
464 break
465 end
466 end
467
468 ext_prefix = "#{$top_srcdir}/ext"
469 for d in Dir["#{ext_prefix}/**/*"]
470 File.directory?(d) || next
471 File.file?(d + "/MANIFEST") || next
472
473 d.slice!(0, ext_prefix.length + 1)
474 if $install
475 print "installing ", d, "\n"
476 elsif $clean
477 print "cleaning ", d, "\n"
478 else
479 print "compiling ", d, "\n"
480 if RUBY_PLATFORM =~ /-aix/ and older("../ruby.imp", "../miniruby")
481 load "#{$top_srcdir}/ext/aix_mksym.rb"
482 end
483 end
484 $stdout.flush
485 extmake(d)
486 end
487
488 if $install or $clean
489 Dir.chdir ".."
490 exit
491 end
492 $extinit = "" unless $extinit
493
494 ruby = CONFIG["RUBY_INSTALL_NAME"] + CONFIG["EXEEXT"]
495 miniruby = "miniruby" + CONFIG["EXEEXT"]
496
497 $extobjs = "" unless $extobjs
498 if $extlist.size > 0
499 for s,t,i in $extlist
500 f = format("%s/%s.%s", s, i, $LIBEXT)
501 if File.exist?(f)
502 $extinit += format("\
503 \tInit_%s();\n\
504 \trb_provide(\"%s.so\");\n\
505 ", i, t)
506 $extobjs += "ext/"
507 $extobjs += f
508 $extobjs += " "
509 else
510 false
511 end
512 end
513
514 if older("extinit.c", $setup) || older("extinit.c", "#{$top_srcdir}/ext/extmk.rb")
515 f = open("extinit.c", "w")
516 f.printf "void Init_ext() {\n"
517 f.printf $extinit
518 f.printf "}\n"
519 f.close
520 end
521 if older("extinit.#{$OBJEXT}", "extinit.c")
522 cmd = CONFIG["CC"] + " " + CFLAGS + " -c extinit.c"
523 print cmd, "\n"
524 system cmd or exit 1
525 end
526
527 Dir.chdir ".."
528
529 if older(ruby, $setup) or older(ruby, miniruby)
530 rm_f ruby
531 end
532
533 $extobjs = "ext/extinit.#{$OBJEXT} " + $extobjs
534 if RUBY_PLATFORM =~ /m68k-human|beos/
535 $extlibs.gsub!("-L/usr/local/lib", "") if $extlibs
536 end
537 system format(%[#{$make} #{ruby} EXTOBJS='%s' EXTLIBS='%s'], $extobjs, $extlibs)
538 else
539 Dir.chdir ".."
540 if older(ruby, miniruby)
541 rm_f ruby
542 system("#{$make} #{ruby}")
543 end
544 end
545
546 #Local variables:
547 # mode: ruby
548 #end: