Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to disable or force system libffi and fix stdcall on Win32 #669

Merged
merged 6 commits into from Feb 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitmodules
@@ -1,3 +1,4 @@
[submodule "ext/ffi_c/libffi"]
path = ext/ffi_c/libffi
url = https://github.com/libffi/libffi.git
url = https://github.com/larskanis/libffi.git
branch = fix-stdcall
2 changes: 1 addition & 1 deletion Gemfile
@@ -1,7 +1,7 @@
source 'https://rubygems.org'

group :development do
gem 'rake', '~> 10.1'
gem 'rake', '~> 12.1'
gem 'rake-compiler', '~> 1.0.3'
gem 'rake-compiler-dock', '~> 0.7.0'
gem 'rspec', '~> 3.0'
Expand Down
1 change: 1 addition & 0 deletions Rakefile
Expand Up @@ -137,6 +137,7 @@ file "ext/ffi_c/libffi/autogen.sh" => "ext/ffi_c/libffi" do
warn "Downloading libffi ..."
sh "git submodule update --init --recursive"
end
task :libffi => "ext/ffi_c/libffi/autogen.sh"

LIBFFI_GIT_FILES = `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0")

Expand Down
7 changes: 6 additions & 1 deletion appveyor.yml
Expand Up @@ -12,11 +12,16 @@ install:
- bundle install
build: off
build_script:
- bundle exec rake compile || bundle exec rake compile
- bundle exec rake libffi compile -- %EXTCONFOPTS% || bundle exec rake compile -- %EXTCONFOPTS%
test_script:
- bundle exec rake test
environment:
matrix:
- RUBYVER: "head-x64"
EXTCONFOPTS: "--disable-system-libffi"
- RUBYVER: 24
EXTCONFOPTS: "--disable-system-libffi"
- RUBYVER: 25-x64
EXTCONFOPTS: "--enable-system-libffi"
- RUBYVER: 25
EXTCONFOPTS: "--enable-system-libffi"
40 changes: 26 additions & 14 deletions ext/ffi_c/extconf.rb
Expand Up @@ -3,6 +3,21 @@
if !defined?(RUBY_ENGINE) || RUBY_ENGINE == 'ruby' || RUBY_ENGINE == 'rbx'
require 'mkmf'
require 'rbconfig'

def system_libffi_usable?
# We need pkg_config or ffi.h
libffi_ok = pkg_config("libffi") ||
have_header("ffi.h") ||
find_header("ffi.h", "/usr/local/include", "/usr/include/ffi")

# Ensure we can link to ffi_call
libffi_ok &&= have_library("ffi", "ffi_call", [ "ffi.h" ]) ||
have_library("libffi", "ffi_call", [ "ffi.h" ])

# And we need a libffi version recent enough to provide ffi_closure_alloc
libffi_ok &&= have_func("ffi_closure_alloc")
end

dir_config("ffi_c")

# recent versions of ruby add restrictive ansi and warning flags on a whim - kill them all
Expand All @@ -12,17 +27,13 @@
# solaris 10 needs -c99 for <stdbool.h>
$CFLAGS << " -std=c99" if RbConfig::CONFIG['host_os'] =~ /solaris(!?2\.11)/

if ENV['RUBY_CC_VERSION'].nil? && (pkg_config("libffi") ||
have_header("ffi.h") ||
find_header("ffi.h", "/usr/local/include", "/usr/include/ffi"))

# We need at least ffi_call and ffi_closure_alloc
libffi_ok = have_library("ffi", "ffi_call", [ "ffi.h" ]) ||
have_library("libffi", "ffi_call", [ "ffi.h" ])
libffi_ok &&= have_func("ffi_closure_alloc")
# Check whether we use system libffi
system_libffi = enable_config('system-libffi', :try)

# Check if the raw api is available.
$defs << "-DHAVE_RAW_API" if have_func("ffi_raw_call") && have_func("ffi_prep_raw_closure")
if system_libffi == :try
system_libffi = ENV['RUBY_CC_VERSION'].nil? && system_libffi_usable?
elsif system_libffi
abort "system libffi is not usable" unless system_libffi_usable?
end

have_header('shlwapi.h')
Expand All @@ -31,23 +42,24 @@
have_func('rb_thread_call_with_gvl')
have_func('rb_thread_call_without_gvl')

if libffi_ok
if system_libffi
have_func('ffi_prep_cif_var')
$defs << "-DHAVE_RAW_API" if have_func("ffi_raw_call") && have_func("ffi_prep_raw_closure")
else
$defs << "-DHAVE_FFI_PREP_CIF_VAR"
$defs << "-DUSE_INTERNAL_LIBFFI"
end

$defs << "-DHAVE_EXTCONF_H" if $defs.empty? # needed so create_header works
$defs << "-DUSE_INTERNAL_LIBFFI" unless libffi_ok
$defs << "-DRUBY_1_9" if RUBY_VERSION >= "1.9.0"
$defs << "-DFFI_BUILDING" if RbConfig::CONFIG['host_os'] =~ /mswin/ # for compatibility with newer libffi

create_header

$LOCAL_LIBS << " ./libffi/.libs/libffi_convenience.lib" if !libffi_ok && RbConfig::CONFIG['host_os'] =~ /mswin/
$LOCAL_LIBS << " ./libffi/.libs/libffi_convenience.lib" if !system_libffi && RbConfig::CONFIG['host_os'] =~ /mswin/

create_makefile("ffi_c")
unless libffi_ok
unless system_libffi
File.open("Makefile", "a") do |mf|
mf.puts "LIBFFI_HOST=--host=#{RbConfig::CONFIG['host_alias']}" if RbConfig::CONFIG.has_key?("host_alias")
if RbConfig::CONFIG['host_os'].downcase =~ /darwin/
Expand Down
4 changes: 2 additions & 2 deletions ffi.gemspec
Expand Up @@ -27,9 +27,9 @@ Gem::Specification.new do |s|
s.license = 'BSD-3-Clause'
s.require_paths << 'ext/ffi_c'
s.required_ruby_version = '>= 1.9'
s.add_development_dependency 'rake', '~> 10.1'
s.add_development_dependency 'rake', '~> 12.1'
s.add_development_dependency 'rake-compiler', '~> 1.0'
s.add_development_dependency 'rake-compiler-dock', '~> 0.6.2'
s.add_development_dependency 'rake-compiler-dock', '~> 0.7.0'
s.add_development_dependency 'rspec', '~> 2.14.1'
s.add_development_dependency 'rubygems-tasks', "~> 0.2.4"
end
1 change: 1 addition & 0 deletions spec/ffi/fixtures/PipeHelperWindows.c
Expand Up @@ -6,6 +6,7 @@

#ifdef _WIN32
#include <windows.h>
#include <stdio.h>
#include "PipeHelper.h"

int pipeHelperCreatePipe(FD_TYPE pipefd[2])
Expand Down