1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
require 'mkmf'
# :stopdoc:
if ! enable_config('bundled-libffi', false)
dir_config 'libffi'
pkg_config("libffi")
ver = pkg_config("libffi", "modversion")
if have_header(ffi_header = 'ffi.h')
true
elsif have_header(ffi_header = 'ffi/ffi.h')
$defs.push(format('-DUSE_HEADER_HACKS'))
true
end and (have_library('ffi') || have_library('libffi'))
end or
begin
ver = Dir.glob("#{$srcdir}/libffi-*/")
.map {|n| File.basename(n)}
.max_by {|n| n.scan(/\d+/).map(&:to_i)}
unless ver
raise "missing libffi. Please install libffi."
end
ffi_header = 'ffi.h'
libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new
libffi.dir = ver
if $srcdir == "."
libffi.builddir = "#{ver}/#{RUBY_PLATFORM}"
libffi.srcdir = "."
else
libffi.builddir = libffi.dir
libffi.srcdir = relative_from("#{$srcdir}/#{ver}", "..")
end
libffi.include = "#{libffi.builddir}/include"
libffi.lib = "#{libffi.builddir}/.libs"
libffi.a = "#{libffi.lib}/libffi.#{$LIBEXT}"
libffi.cflags = RbConfig.expand("$(CFLAGS)", CONFIG.merge("warnflags"=>""))
ver = ver[/libffi-(.*)/, 1]
FileUtils.mkdir_p(libffi.dir)
libffi.opt = CONFIG['configure_args'][/'(-C)'/, 1]
libffi.ldflags = RbConfig.expand("$(LDFLAGS) #{libpathflag([relative_from($topdir, "..")])} #{$LIBRUBYARG}")
libffi.arch = RbConfig::CONFIG['host']
args = %W[
#{libffi.srcdir}/configure #{libffi.opt}
--disable-shared
--host=#{libffi.arch} --enable-builddir=#{RUBY_PLATFORM}
CC=#{RbConfig::CONFIG['CC']} CFLAGS=#{libffi.cflags}
LD=#{RbConfig::CONFIG['LD']} LDFLAGS=#{libffi.ldflags}
]
Logging::open do
Logging.message("%p in %s\n", args, libffi.dir)
system(*args, chdir: libffi.dir) or
raise "failed to configure libffi. Please install libffi."
end
$INCFLAGS << " -I" << libffi.include
end
if ver
ver = ver.gsub(/-rc\d+/, '') # If ver contains rc version, just ignored.
ver = (ver.split('.') + [0,0])[0,3]
$defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % ver }})
end
have_header 'sys/mman.h'
if have_header "dlfcn.h"
have_library "dl"
%w{ dlopen dlclose dlsym }.each do |func|
abort "missing function #{func}" unless have_func(func)
end
have_func "dlerror"
elsif have_header "windows.h"
%w{ LoadLibrary FreeLibrary GetProcAddress }.each do |func|
abort "missing function #{func}" unless have_func(func)
end
end
have_const('FFI_STDCALL', ffi_header)
config = File.read(RbConfig.expand(File.join($arch_hdrdir, "ruby/config.h")))
types = {"SIZE_T"=>"SSIZE_T", "PTRDIFF_T"=>nil, "INTPTR_T"=>nil}
types.each do |type, signed|
if /^\#define\s+SIZEOF_#{type}\s+(SIZEOF_(.+)|\d+)/ =~ config
if size = $2 and size != 'VOIDP'
size = types.fetch(size) {size}
$defs << format("-DTYPE_%s=TYPE_%s", signed||type, size)
end
if signed
check_signedness(type.downcase, "stddef.h")
end
end
end
if libffi
$LIBPATH.unshift libffi.lib
$LOCAL_LIBS.prepend("#{libffi.a} ").strip!
end
create_makefile 'fiddle' do |conf|
next conf unless libffi
if $gnumake
submake = "$(MAKE) -C $(LIBFFI_DIR)\n"
else
submake = "cd $(LIBFFI_DIR) && \\\n\t\t" << "#{config_string("exec")} $(MAKE)".strip
end
sep = "/"
seprpl = config_string('BUILD_FILE_SEPARATOR') {|s| sep = s; ":/=#{s}" if s != "/"} || ""
conf << <<-MK.gsub(/^ +| +$/, '')
PWD =
LIBFFI_CONFIGURE = $(LIBFFI_SRCDIR#{seprpl})#{sep}configure #{libffi.opt}
LIBFFI_ARCH = #{libffi.arch}
LIBFFI_SRCDIR = #{libffi.srcdir}
LIBFFI_DIR = #{libffi.dir}
LIBFFI_A = #{libffi.a}
LIBFFI_CFLAGS = #{libffi.cflags}
LIBFFI_LDFLAGS = #{libffi.ldflags}
FFI_H = $(LIBFFI_DIR)/include/ffi.h
SUBMAKE_LIBFFI = #{submake}
MK
end
if libffi
$LIBPATH.pop
$LOCAL_LIBS.prepend("ext/fiddle/")
end
# :startdoc:
|