fiddle 1.0.0 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +52 -1
- data/Rakefile +4 -5
- data/bin/downloader.rb +331 -0
- data/bin/extlibs.rb +262 -0
- data/ext/fiddle/closure.c +5 -4
- data/ext/fiddle/conversions.c +205 -16
- data/ext/fiddle/conversions.h +14 -4
- data/ext/fiddle/depend +85 -0
- data/ext/fiddle/extconf.rb +62 -29
- data/ext/fiddle/extlibs +10 -2
- data/ext/fiddle/fiddle.c +133 -34
- data/ext/fiddle/fiddle.h +96 -32
- data/ext/fiddle/function.c +261 -93
- data/ext/fiddle/handle.c +10 -12
- data/ext/fiddle/memory_view.c +254 -0
- data/ext/fiddle/pinned.c +123 -0
- data/ext/fiddle/pointer.c +147 -24
- data/ext/fiddle/win32/fficonfig.h +0 -0
- data/ext/fiddle/win32/libffi-config.rb +1 -1
- data/ext/fiddle/win32/libffi.mk.tmpl +0 -0
- data/fiddle.gemspec +48 -5
- data/lib/fiddle.rb +3 -1
- data/lib/fiddle/cparser.rb +90 -25
- data/lib/fiddle/function.rb +5 -0
- data/lib/fiddle/import.rb +11 -9
- data/lib/fiddle/pack.rb +14 -7
- data/lib/fiddle/struct.rb +267 -43
- data/lib/fiddle/value.rb +18 -9
- data/lib/fiddle/version.rb +3 -0
- metadata +15 -12
- data/.gitignore +0 -13
- data/.travis.yml +0 -7
- data/Gemfile +0 -4
- data/bin/console +0 -14
- data/bin/setup +0 -8
data/ext/fiddle/closure.c
CHANGED
@@ -13,11 +13,12 @@ typedef struct {
|
|
13
13
|
ffi_type **argv;
|
14
14
|
} fiddle_closure;
|
15
15
|
|
16
|
-
#if defined(
|
17
|
-
#elif defined(__OpenBSD__) || defined(__APPLE__) || defined(__linux__)
|
16
|
+
#if defined(__OpenBSD__)
|
18
17
|
# define USE_FFI_CLOSURE_ALLOC 0
|
19
|
-
#
|
20
|
-
|
18
|
+
#endif
|
19
|
+
|
20
|
+
#if defined(USE_FFI_CLOSURE_ALLOC)
|
21
|
+
#elif !defined(HAVE_FFI_CLOSURE_ALLOC)
|
21
22
|
# define USE_FFI_CLOSURE_ALLOC 0
|
22
23
|
#else
|
23
24
|
# define USE_FFI_CLOSURE_ALLOC 1
|
data/ext/fiddle/conversions.c
CHANGED
@@ -1,7 +1,159 @@
|
|
1
1
|
#include <fiddle.h>
|
2
2
|
|
3
|
+
VALUE
|
4
|
+
rb_fiddle_type_ensure(VALUE type)
|
5
|
+
{
|
6
|
+
VALUE original_type = type;
|
7
|
+
|
8
|
+
if (!RB_SYMBOL_P(type)) {
|
9
|
+
VALUE type_string = rb_check_string_type(type);
|
10
|
+
if (!NIL_P(type_string)) {
|
11
|
+
type = rb_to_symbol(type_string);
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
if (RB_SYMBOL_P(type)) {
|
16
|
+
ID type_id = rb_sym2id(type);
|
17
|
+
ID void_id;
|
18
|
+
ID voidp_id;
|
19
|
+
ID char_id;
|
20
|
+
ID short_id;
|
21
|
+
ID int_id;
|
22
|
+
ID long_id;
|
23
|
+
#ifdef TYPE_LONG_LONG
|
24
|
+
ID long_long_id;
|
25
|
+
#endif
|
26
|
+
#ifdef TYPE_INT8_T
|
27
|
+
ID int8_t_id;
|
28
|
+
#endif
|
29
|
+
#ifdef TYPE_INT16_T
|
30
|
+
ID int16_t_id;
|
31
|
+
#endif
|
32
|
+
#ifdef TYPE_INT32_T
|
33
|
+
ID int32_t_id;
|
34
|
+
#endif
|
35
|
+
#ifdef TYPE_INT64_T
|
36
|
+
ID int64_t_id;
|
37
|
+
#endif
|
38
|
+
ID float_id;
|
39
|
+
ID double_id;
|
40
|
+
ID variadic_id;
|
41
|
+
ID const_string_id;
|
42
|
+
ID size_t_id;
|
43
|
+
ID ssize_t_id;
|
44
|
+
ID ptrdiff_t_id;
|
45
|
+
ID intptr_t_id;
|
46
|
+
ID uintptr_t_id;
|
47
|
+
RUBY_CONST_ID(void_id, "void");
|
48
|
+
RUBY_CONST_ID(voidp_id, "voidp");
|
49
|
+
RUBY_CONST_ID(char_id, "char");
|
50
|
+
RUBY_CONST_ID(short_id, "short");
|
51
|
+
RUBY_CONST_ID(int_id, "int");
|
52
|
+
RUBY_CONST_ID(long_id, "long");
|
53
|
+
#ifdef TYPE_LONG_LONG
|
54
|
+
RUBY_CONST_ID(long_long_id, "long_long");
|
55
|
+
#endif
|
56
|
+
#ifdef TYPE_INT8_T
|
57
|
+
RUBY_CONST_ID(int8_t_id, "int8_t");
|
58
|
+
#endif
|
59
|
+
#ifdef TYPE_INT16_T
|
60
|
+
RUBY_CONST_ID(int16_t_id, "int16_t");
|
61
|
+
#endif
|
62
|
+
#ifdef TYPE_INT32_T
|
63
|
+
RUBY_CONST_ID(int32_t_id, "int32_t");
|
64
|
+
#endif
|
65
|
+
#ifdef TYPE_INT64_T
|
66
|
+
RUBY_CONST_ID(int64_t_id, "int64_t");
|
67
|
+
#endif
|
68
|
+
RUBY_CONST_ID(float_id, "float");
|
69
|
+
RUBY_CONST_ID(double_id, "double");
|
70
|
+
RUBY_CONST_ID(variadic_id, "variadic");
|
71
|
+
RUBY_CONST_ID(const_string_id, "const_string");
|
72
|
+
RUBY_CONST_ID(size_t_id, "size_t");
|
73
|
+
RUBY_CONST_ID(ssize_t_id, "ssize_t");
|
74
|
+
RUBY_CONST_ID(ptrdiff_t_id, "ptrdiff_t");
|
75
|
+
RUBY_CONST_ID(intptr_t_id, "intptr_t");
|
76
|
+
RUBY_CONST_ID(uintptr_t_id, "uintptr_t");
|
77
|
+
if (type_id == void_id) {
|
78
|
+
return INT2NUM(TYPE_VOID);
|
79
|
+
}
|
80
|
+
else if (type_id == voidp_id) {
|
81
|
+
return INT2NUM(TYPE_VOIDP);
|
82
|
+
}
|
83
|
+
else if (type_id == char_id) {
|
84
|
+
return INT2NUM(TYPE_CHAR);
|
85
|
+
}
|
86
|
+
else if (type_id == short_id) {
|
87
|
+
return INT2NUM(TYPE_SHORT);
|
88
|
+
}
|
89
|
+
else if (type_id == int_id) {
|
90
|
+
return INT2NUM(TYPE_INT);
|
91
|
+
}
|
92
|
+
else if (type_id == long_id) {
|
93
|
+
return INT2NUM(TYPE_LONG);
|
94
|
+
}
|
95
|
+
#ifdef TYPE_LONG_LONG
|
96
|
+
else if (type_id == long_long_id) {
|
97
|
+
return INT2NUM(TYPE_LONG_LONG);
|
98
|
+
}
|
99
|
+
#endif
|
100
|
+
#ifdef TYPE_INT8_T
|
101
|
+
else if (type_id == int8_t_id) {
|
102
|
+
return INT2NUM(TYPE_INT8_T);
|
103
|
+
}
|
104
|
+
#endif
|
105
|
+
#ifdef TYPE_INT16_T
|
106
|
+
else if (type_id == int16_t_id) {
|
107
|
+
return INT2NUM(TYPE_INT16_T);
|
108
|
+
}
|
109
|
+
#endif
|
110
|
+
#ifdef TYPE_INT32_T
|
111
|
+
else if (type_id == int32_t_id) {
|
112
|
+
return INT2NUM(TYPE_INT32_T);
|
113
|
+
}
|
114
|
+
#endif
|
115
|
+
#ifdef TYPE_INT64_T
|
116
|
+
else if (type_id == int64_t_id) {
|
117
|
+
return INT2NUM(TYPE_INT64_T);
|
118
|
+
}
|
119
|
+
#endif
|
120
|
+
else if (type_id == float_id) {
|
121
|
+
return INT2NUM(TYPE_FLOAT);
|
122
|
+
}
|
123
|
+
else if (type_id == double_id) {
|
124
|
+
return INT2NUM(TYPE_DOUBLE);
|
125
|
+
}
|
126
|
+
else if (type_id == variadic_id) {
|
127
|
+
return INT2NUM(TYPE_VARIADIC);
|
128
|
+
}
|
129
|
+
else if (type_id == const_string_id) {
|
130
|
+
return INT2NUM(TYPE_CONST_STRING);
|
131
|
+
}
|
132
|
+
else if (type_id == size_t_id) {
|
133
|
+
return INT2NUM(TYPE_SIZE_T);
|
134
|
+
}
|
135
|
+
else if (type_id == ssize_t_id) {
|
136
|
+
return INT2NUM(TYPE_SSIZE_T);
|
137
|
+
}
|
138
|
+
else if (type_id == ptrdiff_t_id) {
|
139
|
+
return INT2NUM(TYPE_PTRDIFF_T);
|
140
|
+
}
|
141
|
+
else if (type_id == intptr_t_id) {
|
142
|
+
return INT2NUM(TYPE_INTPTR_T);
|
143
|
+
}
|
144
|
+
else if (type_id == uintptr_t_id) {
|
145
|
+
return INT2NUM(TYPE_UINTPTR_T);
|
146
|
+
}
|
147
|
+
else {
|
148
|
+
type = original_type;
|
149
|
+
}
|
150
|
+
}
|
151
|
+
|
152
|
+
return rb_to_int(type);
|
153
|
+
}
|
154
|
+
|
3
155
|
ffi_type *
|
4
|
-
|
156
|
+
rb_fiddle_int_to_ffi_type(int type)
|
5
157
|
{
|
6
158
|
int signed_p = 1;
|
7
159
|
|
@@ -33,66 +185,90 @@ int_to_ffi_type(int type)
|
|
33
185
|
return &ffi_type_float;
|
34
186
|
case TYPE_DOUBLE:
|
35
187
|
return &ffi_type_double;
|
188
|
+
case TYPE_CONST_STRING:
|
189
|
+
return &ffi_type_pointer;
|
36
190
|
default:
|
37
191
|
rb_raise(rb_eRuntimeError, "unknown type %d", type);
|
38
192
|
}
|
39
193
|
return &ffi_type_pointer;
|
40
194
|
}
|
41
195
|
|
196
|
+
ffi_type *
|
197
|
+
int_to_ffi_type(int type)
|
198
|
+
{
|
199
|
+
return rb_fiddle_int_to_ffi_type(type);
|
200
|
+
}
|
201
|
+
|
42
202
|
void
|
43
|
-
|
203
|
+
rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst)
|
44
204
|
{
|
45
205
|
switch (type) {
|
46
206
|
case TYPE_VOID:
|
47
207
|
break;
|
48
208
|
case TYPE_VOIDP:
|
49
|
-
dst->pointer = NUM2PTR(rb_Integer(src));
|
209
|
+
dst->pointer = NUM2PTR(rb_Integer(*src));
|
50
210
|
break;
|
51
211
|
case TYPE_CHAR:
|
52
|
-
dst->schar = (signed char)NUM2INT(src);
|
212
|
+
dst->schar = (signed char)NUM2INT(*src);
|
53
213
|
break;
|
54
214
|
case -TYPE_CHAR:
|
55
|
-
dst->uchar = (unsigned char)NUM2UINT(src);
|
215
|
+
dst->uchar = (unsigned char)NUM2UINT(*src);
|
56
216
|
break;
|
57
217
|
case TYPE_SHORT:
|
58
|
-
dst->sshort = (unsigned short)NUM2INT(src);
|
218
|
+
dst->sshort = (unsigned short)NUM2INT(*src);
|
59
219
|
break;
|
60
220
|
case -TYPE_SHORT:
|
61
|
-
dst->sshort = (signed short)NUM2UINT(src);
|
221
|
+
dst->sshort = (signed short)NUM2UINT(*src);
|
62
222
|
break;
|
63
223
|
case TYPE_INT:
|
64
|
-
dst->sint = NUM2INT(src);
|
224
|
+
dst->sint = NUM2INT(*src);
|
65
225
|
break;
|
66
226
|
case -TYPE_INT:
|
67
|
-
dst->uint = NUM2UINT(src);
|
227
|
+
dst->uint = NUM2UINT(*src);
|
68
228
|
break;
|
69
229
|
case TYPE_LONG:
|
70
|
-
dst->slong = NUM2LONG(src);
|
230
|
+
dst->slong = NUM2LONG(*src);
|
71
231
|
break;
|
72
232
|
case -TYPE_LONG:
|
73
|
-
dst->ulong = NUM2ULONG(src);
|
233
|
+
dst->ulong = NUM2ULONG(*src);
|
74
234
|
break;
|
75
235
|
#if HAVE_LONG_LONG
|
76
236
|
case TYPE_LONG_LONG:
|
77
|
-
dst->slong_long = NUM2LL(src);
|
237
|
+
dst->slong_long = NUM2LL(*src);
|
78
238
|
break;
|
79
239
|
case -TYPE_LONG_LONG:
|
80
|
-
dst->ulong_long = NUM2ULL(src);
|
240
|
+
dst->ulong_long = NUM2ULL(*src);
|
81
241
|
break;
|
82
242
|
#endif
|
83
243
|
case TYPE_FLOAT:
|
84
|
-
dst->ffloat = (float)NUM2DBL(src);
|
244
|
+
dst->ffloat = (float)NUM2DBL(*src);
|
85
245
|
break;
|
86
246
|
case TYPE_DOUBLE:
|
87
|
-
dst->ddouble = NUM2DBL(src);
|
247
|
+
dst->ddouble = NUM2DBL(*src);
|
248
|
+
break;
|
249
|
+
case TYPE_CONST_STRING:
|
250
|
+
if (NIL_P(*src)) {
|
251
|
+
dst->pointer = NULL;
|
252
|
+
}
|
253
|
+
else {
|
254
|
+
dst->pointer = rb_string_value_cstr(src);
|
255
|
+
}
|
88
256
|
break;
|
89
257
|
default:
|
90
258
|
rb_raise(rb_eRuntimeError, "unknown type %d", type);
|
91
259
|
}
|
92
260
|
}
|
93
261
|
|
262
|
+
void
|
263
|
+
value_to_generic(int type, VALUE src, fiddle_generic *dst)
|
264
|
+
{
|
265
|
+
/* src isn't safe from GC when type is TYPE_CONST_STRING and src
|
266
|
+
* isn't String. */
|
267
|
+
rb_fiddle_value_to_generic(type, &src, dst);
|
268
|
+
}
|
269
|
+
|
94
270
|
VALUE
|
95
|
-
|
271
|
+
rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval)
|
96
272
|
{
|
97
273
|
int type = NUM2INT(rettype);
|
98
274
|
VALUE cPointer;
|
@@ -131,6 +307,13 @@ generic_to_value(VALUE rettype, fiddle_generic retval)
|
|
131
307
|
return rb_float_new(retval.ffloat);
|
132
308
|
case TYPE_DOUBLE:
|
133
309
|
return rb_float_new(retval.ddouble);
|
310
|
+
case TYPE_CONST_STRING:
|
311
|
+
if (retval.pointer) {
|
312
|
+
return rb_str_new_cstr(retval.pointer);
|
313
|
+
}
|
314
|
+
else {
|
315
|
+
return Qnil;
|
316
|
+
}
|
134
317
|
default:
|
135
318
|
rb_raise(rb_eRuntimeError, "unknown type %d", type);
|
136
319
|
}
|
@@ -138,4 +321,10 @@ generic_to_value(VALUE rettype, fiddle_generic retval)
|
|
138
321
|
UNREACHABLE;
|
139
322
|
}
|
140
323
|
|
324
|
+
VALUE
|
325
|
+
generic_to_value(VALUE rettype, fiddle_generic retval)
|
326
|
+
{
|
327
|
+
return rb_fiddle_generic_to_value(rettype, retval);
|
328
|
+
}
|
329
|
+
|
141
330
|
/* vim: set noet sw=4 sts=4 */
|
data/ext/fiddle/conversions.h
CHANGED
@@ -24,13 +24,23 @@ typedef union
|
|
24
24
|
void * pointer; /* ffi_type_pointer */
|
25
25
|
} fiddle_generic;
|
26
26
|
|
27
|
+
/* Deprecated. Use rb_fiddle_*() version. */
|
28
|
+
VALUE rb_fiddle_type_ensure(VALUE type);
|
29
|
+
ffi_type * rb_fiddle_int_to_ffi_type(int type);
|
30
|
+
void rb_fiddle_value_to_generic(int type, VALUE *src, fiddle_generic *dst);
|
31
|
+
VALUE rb_fiddle_generic_to_value(VALUE rettype, fiddle_generic retval);
|
32
|
+
|
33
|
+
/* Deprecated. Use rb_fiddle_*() version. */
|
27
34
|
ffi_type * int_to_ffi_type(int type);
|
28
|
-
void value_to_generic(int type, VALUE src, fiddle_generic *
|
35
|
+
void value_to_generic(int type, VALUE src, fiddle_generic *dst);
|
29
36
|
VALUE generic_to_value(VALUE rettype, fiddle_generic retval);
|
30
37
|
|
31
|
-
#define VALUE2GENERIC(_type, _src, _dst)
|
32
|
-
|
33
|
-
#define
|
38
|
+
#define VALUE2GENERIC(_type, _src, _dst) \
|
39
|
+
rb_fiddle_value_to_generic((_type), &(_src), (_dst))
|
40
|
+
#define INT2FFI_TYPE(_type) \
|
41
|
+
rb_fiddle_int_to_ffi_type(_type)
|
42
|
+
#define GENERIC2VALUE(_type, _retval) \
|
43
|
+
rb_fiddle_generic_to_value((_type), (_retval))
|
34
44
|
|
35
45
|
#if SIZEOF_VOIDP == SIZEOF_LONG
|
36
46
|
# define PTR2NUM(x) (LONG2NUM((long)(x)))
|
data/ext/fiddle/depend
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
PWD =
|
2
|
+
|
3
|
+
CONFIGURE_LIBFFI = \
|
4
|
+
$(LIBFFI_CONFIGURE) --disable-shared \
|
5
|
+
--host=$(LIBFFI_ARCH) --enable-builddir=$(arch) \
|
6
|
+
CC="$(CC)" CFLAGS="$(LIBFFI_CFLAGS)" \
|
7
|
+
LD="$(LD)" LDFLAGS="$(LIBFFI_LDFLAGS)"
|
8
|
+
|
9
|
+
$(STATIC_LIB) $(RUBYARCHDIR)/$(DLLIB) $(DLLIB): $(LIBFFI_A)
|
10
|
+
|
11
|
+
$(OBJS): $(FFI_H)
|
12
|
+
|
13
|
+
.PHONY: .FORCE hdr
|
14
|
+
|
15
|
+
.FORCE:
|
16
|
+
|
17
|
+
hdr: $(FFI_H)
|
18
|
+
|
19
|
+
configure-libffi build-libffi: .FORCE
|
20
|
+
configure-libffi \
|
21
|
+
$(LIBFFI_DIR)/include/ffi.h \
|
22
|
+
$(LIBFFI_DIR)/include/ffitarget.h \
|
23
|
+
$(LIBFFI_DIR)/fficonfig.h \
|
24
|
+
$(LIBFFI_DIR)/Makefile:
|
25
|
+
$(Q) $(MAKEDIRS) $(LIBFFI_DIR)
|
26
|
+
$(Q) $(CONFIGURE_LIBFFI)
|
27
|
+
|
28
|
+
build-libffi $(LIBFFI_A):
|
29
|
+
$(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG)
|
30
|
+
|
31
|
+
clean-none:
|
32
|
+
clean-libffi:
|
33
|
+
$(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG) clean
|
34
|
+
|
35
|
+
distclean-none:
|
36
|
+
distclean-libffi:
|
37
|
+
$(Q) $(SUBMAKE_PRE) $(MAKE) $(SUBMAKE_ARG) distclean
|
38
|
+
$(Q) $(RM) $(LIBFFI_DIR)/local.exp
|
39
|
+
$(Q) $(RUBY) -rfileutils -e "FileUtils.rmdir(Dir.glob(ARGV[0]+'/**/{,.*/}'), :parents=>true)" $(LIBFFI_DIR)
|
40
|
+
|
41
|
+
realclean-none:
|
42
|
+
realclean-libffi:
|
43
|
+
$(Q) $(RMALL) $(LIBFFI_DIR)
|
44
|
+
|
45
|
+
.PHONY: clean-libffi distclean-libffi realclean-libffi
|
46
|
+
.PHONY: clean-none distclean-none realclean-none
|
47
|
+
|
48
|
+
clean: clean-$(LIBFFI_CLEAN)
|
49
|
+
distclean: distclean-$(LIBFFI_CLEAN)
|
50
|
+
realclean: realclean-$(LIBFFI_CLEAN)
|
51
|
+
|
52
|
+
.PHONY: configure configure-libffi
|
53
|
+
|
54
|
+
closure.o: closure.c
|
55
|
+
closure.o: closure.h
|
56
|
+
closure.o: conversions.h
|
57
|
+
closure.o: fiddle.h
|
58
|
+
closure.o: function.h
|
59
|
+
conversions.o: closure.h
|
60
|
+
conversions.o: conversions.c
|
61
|
+
conversions.o: conversions.h
|
62
|
+
conversions.o: fiddle.h
|
63
|
+
conversions.o: function.h
|
64
|
+
fiddle.o: closure.h
|
65
|
+
fiddle.o: conversions.h
|
66
|
+
fiddle.o: fiddle.c
|
67
|
+
fiddle.o: fiddle.h
|
68
|
+
fiddle.o: function.h
|
69
|
+
function.o: closure.h
|
70
|
+
function.o: conversions.h
|
71
|
+
function.o: fiddle.h
|
72
|
+
function.o: function.c
|
73
|
+
function.o: function.h
|
74
|
+
handle.o: closure.h
|
75
|
+
handle.o: conversions.h
|
76
|
+
handle.o: fiddle.h
|
77
|
+
handle.o: function.h
|
78
|
+
handle.o: handle.c
|
79
|
+
memory_view.o: fiddle.h
|
80
|
+
memory_view.o: memory_view.c
|
81
|
+
pointer.o: closure.h
|
82
|
+
pointer.o: conversions.h
|
83
|
+
pointer.o: fiddle.h
|
84
|
+
pointer.o: function.h
|
85
|
+
pointer.o: pointer.c
|
data/ext/fiddle/extconf.rb
CHANGED
@@ -3,22 +3,32 @@ require 'mkmf'
|
|
3
3
|
|
4
4
|
# :stopdoc:
|
5
5
|
|
6
|
+
libffi_version = nil
|
7
|
+
have_libffi = false
|
6
8
|
bundle = enable_config('bundled-libffi')
|
7
|
-
|
9
|
+
unless bundle
|
8
10
|
dir_config 'libffi'
|
9
11
|
|
10
|
-
pkg_config("libffi")
|
11
|
-
|
12
|
+
if pkg_config("libffi")
|
13
|
+
libffi_version = pkg_config("libffi", "modversion")
|
14
|
+
end
|
12
15
|
|
16
|
+
have_ffi_header = false
|
13
17
|
if have_header(ffi_header = 'ffi.h')
|
14
|
-
true
|
18
|
+
have_ffi_header = true
|
15
19
|
elsif have_header(ffi_header = 'ffi/ffi.h')
|
16
|
-
$defs.push(
|
17
|
-
true
|
18
|
-
end
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
$defs.push('-DUSE_HEADER_HACKS')
|
21
|
+
have_ffi_header = true
|
22
|
+
end
|
23
|
+
if have_ffi_header && (have_library('ffi') || have_library('libffi'))
|
24
|
+
have_libffi = true
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
unless have_libffi
|
29
|
+
# for https://github.com/ruby/fiddle
|
30
|
+
extlibs_rb = File.expand_path("../../bin/extlibs.rb", $srcdir)
|
31
|
+
if bundle && File.exist?(extlibs_rb)
|
22
32
|
require "fileutils"
|
23
33
|
require_relative "../../bin/extlibs"
|
24
34
|
extlibs = ExtLibs.new
|
@@ -27,31 +37,32 @@ begin
|
|
27
37
|
Dir.glob("#{$srcdir}/libffi-*/").each{|dir| FileUtils.rm_rf(dir)}
|
28
38
|
extlibs.run(["--cache=#{cache_dir}", ext_dir])
|
29
39
|
end
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
40
|
+
if bundle != false
|
41
|
+
libffi_package_name = Dir.glob("#{$srcdir}/libffi-*/")
|
42
|
+
.map {|n| File.basename(n)}
|
43
|
+
.max_by {|n| n.scan(/\d+/).map(&:to_i)}
|
44
|
+
end
|
45
|
+
unless libffi_package_name
|
35
46
|
raise "missing libffi. Please install libffi."
|
36
47
|
end
|
37
48
|
|
38
|
-
|
49
|
+
libffi_srcdir = "#{$srcdir}/#{libffi_package_name}"
|
39
50
|
ffi_header = 'ffi.h'
|
40
51
|
libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new
|
41
|
-
libffi.dir =
|
52
|
+
libffi.dir = libffi_package_name
|
42
53
|
if $srcdir == "."
|
43
|
-
libffi.builddir =
|
54
|
+
libffi.builddir = libffi_package_name
|
44
55
|
libffi.srcdir = "."
|
45
56
|
else
|
46
57
|
libffi.builddir = libffi.dir
|
47
|
-
libffi.srcdir = relative_from(
|
58
|
+
libffi.srcdir = relative_from(libffi_srcdir, "..")
|
48
59
|
end
|
49
60
|
libffi.include = "#{libffi.builddir}/include"
|
50
61
|
libffi.lib = "#{libffi.builddir}/.libs"
|
51
62
|
libffi.a = "#{libffi.lib}/libffi_convenience.#{$LIBEXT}"
|
52
63
|
nowarn = CONFIG.merge("warnflags"=>"")
|
53
64
|
libffi.cflags = RbConfig.expand("$(CFLAGS)".dup, nowarn)
|
54
|
-
|
65
|
+
libffi_version = libffi_package_name[/libffi-(.*)/, 1]
|
55
66
|
|
56
67
|
FileUtils.mkdir_p(libffi.dir)
|
57
68
|
libffi.opt = CONFIG['configure_args'][/'(-C)'/, 1]
|
@@ -80,7 +91,6 @@ begin
|
|
80
91
|
args.concat %W[
|
81
92
|
--srcdir=#{libffi.srcdir}
|
82
93
|
--host=#{libffi.arch}
|
83
|
-
--enable-builddir=#{RUBY_PLATFORM}
|
84
94
|
]
|
85
95
|
args << ($enable_shared || !$static ? '--enable-shared' : '--enable-static')
|
86
96
|
args << libffi.opt if libffi.opt
|
@@ -97,7 +107,7 @@ begin
|
|
97
107
|
begin
|
98
108
|
IO.copy_stream(libffi.dir + "/config.log", Logging.instance_variable_get(:@logfile))
|
99
109
|
rescue SystemCallError => e
|
100
|
-
|
110
|
+
Logging.message("%s\n", e.message)
|
101
111
|
end
|
102
112
|
raise "failed to configure libffi. Please install libffi."
|
103
113
|
end
|
@@ -106,15 +116,33 @@ begin
|
|
106
116
|
FileUtils.rm_f("#{libffi.include}/ffitarget.h")
|
107
117
|
end
|
108
118
|
unless File.file?("#{libffi.include}/ffitarget.h")
|
109
|
-
FileUtils.cp("#{
|
119
|
+
FileUtils.cp("#{libffi_srcdir}/src/x86/ffitarget.h", libffi.include, preserve: true)
|
110
120
|
end
|
111
121
|
$INCFLAGS << " -I" << libffi.include
|
112
122
|
end
|
113
123
|
|
114
|
-
if
|
115
|
-
|
116
|
-
|
117
|
-
|
124
|
+
if libffi_version
|
125
|
+
# If libffi_version contains rc version, just ignored.
|
126
|
+
libffi_version = libffi_version.gsub(/-rc\d+/, '')
|
127
|
+
libffi_version = (libffi_version.split('.').map(&:to_i) + [0,0])[0,3]
|
128
|
+
$defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % libffi_version }})
|
129
|
+
warn "libffi_version: #{libffi_version.join('.')}"
|
130
|
+
end
|
131
|
+
|
132
|
+
case
|
133
|
+
when $mswin, $mingw, (libffi_version && (libffi_version <=> [3, 2]) >= 0)
|
134
|
+
$defs << "-DUSE_FFI_CLOSURE_ALLOC=1"
|
135
|
+
when (libffi_version && (libffi_version <=> [3, 2]) < 0)
|
136
|
+
else
|
137
|
+
have_func('ffi_closure_alloc', ffi_header)
|
138
|
+
end
|
139
|
+
|
140
|
+
if libffi_version
|
141
|
+
if (libffi_version <=> [3, 0, 11]) >= 0
|
142
|
+
$defs << "-DHAVE_FFI_PREP_CIF_VAR"
|
143
|
+
end
|
144
|
+
else
|
145
|
+
have_func('ffi_prep_cif_var', ffi_header)
|
118
146
|
end
|
119
147
|
|
120
148
|
have_header 'sys/mman.h'
|
@@ -141,19 +169,24 @@ types.each do |type, signed|
|
|
141
169
|
if /^\#define\s+SIZEOF_#{type}\s+(SIZEOF_(.+)|\d+)/ =~ config
|
142
170
|
if size = $2 and size != 'VOIDP'
|
143
171
|
size = types.fetch(size) {size}
|
144
|
-
$defs <<
|
172
|
+
$defs << "-DTYPE_#{signed||type}=TYPE_#{size}"
|
145
173
|
end
|
146
174
|
if signed
|
147
175
|
check_signedness(type.downcase, "stddef.h")
|
148
176
|
end
|
177
|
+
else
|
178
|
+
check_signedness(type.downcase, "stddef.h")
|
149
179
|
end
|
150
180
|
end
|
151
181
|
|
182
|
+
if have_header("ruby/memory_view.h")
|
183
|
+
have_type("rb_memory_view_t", ["ruby/memory_view.h"])
|
184
|
+
end
|
185
|
+
|
152
186
|
if libffi
|
153
187
|
$LOCAL_LIBS.prepend("./#{libffi.a} ").strip! # to exts.mk
|
154
188
|
$INCFLAGS.gsub!(/-I#{libffi.dir}/, '-I$(LIBFFI_DIR)')
|
155
189
|
end
|
156
|
-
$INCFLAGS << " -I$(top_srcdir)"
|
157
190
|
create_makefile 'fiddle' do |conf|
|
158
191
|
if !libffi
|
159
192
|
next conf << "LIBFFI_CLEAN = none\n"
|