def build
so_name = self.so_name
so_exists = File.file? so_name
unless so_exists and File.mtime(rb_file) < File.mtime(so_name)
src_name = "#{Inline.directory}/#{module_name}.c"
old_src_name = "#{src_name}.old"
should_compare = File.write_with_backup(src_name) do |io|
if @include_ruby_first
@inc.unshift "#include \"ruby.h\""
else
@inc.push "#include \"ruby.h\""
end
io.puts
io.puts @inc.join("\n")
io.puts
io.puts @src.join("\n\n")
io.puts
io.puts
io.puts "#ifdef __cplusplus"
io.puts "extern \"C\" {"
io.puts "#endif"
io.puts " __declspec(dllexport)" if WINDOZE
io.puts " void Init_#{module_name}() {"
io.puts " VALUE c = rb_cObject;"
io.puts @mod.name.split("::").map { |n|
" c = rb_const_get_at(c,rb_intern(\"#{n}\"));"
}.join("\n")
@sig.keys.sort.each do |name|
arity, singleton, method_name = @sig[name]
if singleton then
io.print " rb_define_singleton_method(c, \"#{method_name}\", "
else
io.print " rb_define_method(c, \"#{method_name}\", "
end
io.puts "(VALUE(*)(ANYARGS))#{name}, #{arity});"
end
io.puts @init_extra.join("\n") unless @init_extra.empty?
io.puts
io.puts " }"
io.puts "#ifdef __cplusplus"
io.puts "}"
io.puts "#endif"
io.puts
end
recompile = true
if so_exists and should_compare and
File::compare(old_src_name, src_name, $DEBUG) then
recompile = false
t = Time.now
File.utime(t, t, src_name, old_src_name, so_name)
end
if recompile then
hdrdir = %w(srcdir archdir).map { |name|
dir = Config::CONFIG[name]
}.find { |dir|
dir and File.exist? File.join(dir, "/ruby.h")
} or abort "ERROR: Can't find header dir for ruby. Exiting..."
flags = @flags.join(' ')
libs = @libs.join(' ')
cmd = "#{Config::CONFIG['LDSHARED']} #{flags} #{Config::CONFIG['CCDLFLAGS']} #{Config::CONFIG['CFLAGS']} -I #{hdrdir} -I #{Config::CONFIG['includedir']} -o \"#{so_name}\" \"#{File.expand_path(src_name)}\" #{libs}" + crap_for_windoze
cmd += " 2> #{DEV_NULL}" if $TESTING and not $DEBUG
$stderr.puts "Building #{so_name} with '#{cmd}'" if $DEBUG
result = `#{cmd}`
$stderr.puts "Output:\n#{result}" if $DEBUG
if $? != 0 then
bad_src_name = src_name + ".bad"
File.rename src_name, bad_src_name
raise CompilationError, "error executing #{cmd}: #{$?}\nRenamed #{src_name} to #{bad_src_name}"
end
if WINDOZE then
Dir.chdir Inline.directory do
cmd = "mt /manifest lib.so.manifest /outputresource:so.dll;#2"
$stderr.puts "Embedding manifest with '#{cmd}'" if $DEBUG
result = `#{cmd}`
$stderr.puts "Output:\n#{result}" if $DEBUG
if $? != 0 then
raise CompilationError, "error executing #{cmd}: #{$?}"
end
end
end
$stderr.puts "Built successfully" if $DEBUG
end
else
$stderr.puts "#{so_name} is up to date" if $DEBUG
end
end