Skip to content

Commit f16e7ff

Browse files
authored
Support MSWIN (#43)
1 parent 8e910ab commit f16e7ff

File tree

5 files changed

+59
-43
lines changed

5 files changed

+59
-43
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
- head
2424
include:
2525
- { os: windows , ruby: mingw }
26-
# - { os: windows , ruby: mswin } this fails with missing libffi
26+
- { os: windows , ruby: mswin }
2727
exclude:
2828
- { os: windows , ruby: head }
2929

@@ -36,18 +36,12 @@ jobs:
3636
ruby-version: ${{ matrix.ruby }}
3737
mingw: _upgrade_ libffi
3838

39-
- name: bundle install
40-
run: bundle install
39+
- run: bundle install
4140

42-
- name: rake compile
43-
run: rake compile
41+
- run: rake compile
4442

45-
- name: rake install
46-
run: rake install
43+
- run: rake install
4744

48-
- name: rake test
45+
- run: rake test
4946
env:
5047
RUBYOPT: --disable=gems
51-
run: |
52-
ruby -v
53-
rake test

ext/fiddle/extconf.rb

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,32 @@
33

44
# :stopdoc:
55

6+
libffi_version = nil
7+
have_libffi = false
68
bundle = enable_config('bundled-libffi')
7-
if ! bundle
9+
unless bundle
810
dir_config 'libffi'
911

10-
pkg_config("libffi") and
11-
ver = pkg_config("libffi", "modversion")
12+
if pkg_config("libffi")
13+
libffi_version = pkg_config("libffi", "modversion")
14+
end
1215

16+
have_ffi_header = false
1317
if have_header(ffi_header = 'ffi.h')
14-
true
18+
have_ffi_header = true
1519
elsif have_header(ffi_header = 'ffi/ffi.h')
1620
$defs.push('-DUSE_HEADER_HACKS')
17-
true
18-
end and (have_library('ffi') || have_library('libffi'))
19-
end or
20-
begin
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
2129
# for https://github.com/ruby/fiddle
22-
if bundle && File.exist?("../../bin/extlibs.rb")
30+
extlibs_rb = File.expand_path("../../bin/extlibs.rb", $srcdir)
31+
if bundle && File.exist?(extlibs_rb)
2332
require "fileutils"
2433
require_relative "../../bin/extlibs"
2534
extlibs = ExtLibs.new
@@ -28,31 +37,32 @@
2837
Dir.glob("#{$srcdir}/libffi-*/").each{|dir| FileUtils.rm_rf(dir)}
2938
extlibs.run(["--cache=#{cache_dir}", ext_dir])
3039
end
31-
ver = bundle != false &&
32-
Dir.glob("#{$srcdir}/libffi-*/")
33-
.map {|n| File.basename(n)}
34-
.max_by {|n| n.scan(/\d+/).map(&:to_i)}
35-
unless ver
40+
if bundle
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
3646
raise "missing libffi. Please install libffi."
3747
end
3848

39-
srcdir = "#{$srcdir}/#{ver}"
49+
libffi_srcdir = "#{$srcdir}/#{libffi_package_name}"
4050
ffi_header = 'ffi.h'
4151
libffi = Struct.new(*%I[dir srcdir builddir include lib a cflags ldflags opt arch]).new
42-
libffi.dir = ver
52+
libffi.dir = libffi_package_name
4353
if $srcdir == "."
44-
libffi.builddir = "#{ver}/#{RUBY_PLATFORM}"
54+
libffi.builddir = libffi_package_name
4555
libffi.srcdir = "."
4656
else
4757
libffi.builddir = libffi.dir
48-
libffi.srcdir = relative_from(srcdir, "..")
58+
libffi.srcdir = relative_from(libffi_srcdir, "..")
4959
end
5060
libffi.include = "#{libffi.builddir}/include"
5161
libffi.lib = "#{libffi.builddir}/.libs"
5262
libffi.a = "#{libffi.lib}/libffi_convenience.#{$LIBEXT}"
5363
nowarn = CONFIG.merge("warnflags"=>"")
5464
libffi.cflags = RbConfig.expand("$(CFLAGS)".dup, nowarn)
55-
ver = ver[/libffi-(.*)/, 1]
65+
libffi_version = libffi_package_name[/libffi-(.*)/, 1]
5666

5767
FileUtils.mkdir_p(libffi.dir)
5868
libffi.opt = CONFIG['configure_args'][/'(-C)'/, 1]
@@ -81,7 +91,6 @@
8191
args.concat %W[
8292
--srcdir=#{libffi.srcdir}
8393
--host=#{libffi.arch}
84-
--enable-builddir=#{RUBY_PLATFORM}
8594
]
8695
args << ($enable_shared || !$static ? '--enable-shared' : '--enable-static')
8796
args << libffi.opt if libffi.opt
@@ -98,7 +107,7 @@
98107
begin
99108
IO.copy_stream(libffi.dir + "/config.log", Logging.instance_variable_get(:@logfile))
100109
rescue SystemCallError => e
101-
Logfile.message("%s\n", e.message)
110+
Logging.message("%s\n", e.message)
102111
end
103112
raise "failed to configure libffi. Please install libffi."
104113
end
@@ -107,27 +116,32 @@
107116
FileUtils.rm_f("#{libffi.include}/ffitarget.h")
108117
end
109118
unless File.file?("#{libffi.include}/ffitarget.h")
110-
FileUtils.cp("#{srcdir}/src/x86/ffitarget.h", libffi.include, preserve: true)
119+
FileUtils.cp("#{libffi_srcdir}/src/x86/ffitarget.h", libffi.include, preserve: true)
111120
end
112121
$INCFLAGS << " -I" << libffi.include
113122
end
114123

115-
if ver
116-
ver = ver.gsub(/-rc\d+/, '') # If ver contains rc version, just ignored.
117-
ver = (ver.split('.').map(&:to_i) + [0,0])[0,3]
118-
$defs.push(%{-DRUBY_LIBFFI_MODVERSION=#{ '%d%03d%03d' % ver }})
119-
warn "libffi_version: #{ver.join('.')}"
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('.')}"
120130
end
121131

122132
case
123-
when $mswin, $mingw, (ver && (ver <=> [3, 2]) >= 0)
133+
when $mswin, $mingw, (libffi_version && (libffi_version <=> [3, 2]) >= 0)
124134
$defs << "-DUSE_FFI_CLOSURE_ALLOC=1"
125-
when (ver && (ver <=> [3, 2]) < 0)
135+
when (libffi_version && (libffi_version <=> [3, 2]) < 0)
126136
else
127137
have_func('ffi_closure_alloc', ffi_header)
128138
end
129139

130-
have_func('ffi_prep_cif_var', ffi_header)
140+
if libffi
141+
$defs << "-DHAVE_FFI_PREP_CIF_VAR"
142+
else
143+
have_func('ffi_prep_cif_var', ffi_header)
144+
end
131145

132146
have_header 'sys/mman.h'
133147

ext/fiddle/win32/libffi-config.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
end
3333
end
3434

35-
builddir = srcdir == "." ? enable['builddir'] : "."
35+
builddir = srcdir == "." ? (enable['builddir'] || ".") : "."
3636
conf['TARGET'] = /^x64/ =~ host ? "X86_WIN64" : "X86_WIN32"
3737

3838
FileUtils.mkdir_p([builddir, "#{builddir}/include", "#{builddir}/src/x86"])

fiddle.gemspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@ Gem::Specification.new do |spec|
2020
"LICENSE.txt",
2121
"README.md",
2222
"Rakefile",
23+
"bin/downloader.rb",
24+
"bin/extlibs.rb",
2325
"ext/fiddle/closure.c",
2426
"ext/fiddle/closure.h",
2527
"ext/fiddle/conversions.c",
2628
"ext/fiddle/conversions.h",
29+
"ext/fiddle/depend",
2730
"ext/fiddle/extconf.rb",
2831
"ext/fiddle/extlibs",
2932
"ext/fiddle/fiddle.c",

test/fiddle/test_func.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ def test_snprintf
8686
else
8787
snprintf_name = "snprintf"
8888
end
89-
snprintf = Function.new(@libc[snprintf_name],
89+
begin
90+
snprintf_pointer = @libc[snprintf_name]
91+
rescue Fiddle::DLError
92+
skip "Can't find #{snprintf_name}: #{$!.message}"
93+
end
94+
snprintf = Function.new(snprintf_pointer,
9095
[
9196
TYPE_VOIDP,
9297
TYPE_SIZE_T,

0 commit comments

Comments
 (0)