From 55f3cb72c7378336451b27ff97541c1f67f03d43 Mon Sep 17 00:00:00 2001 From: Lamont Granquist Date: Tue, 24 Mar 2015 12:17:56 -0700 Subject: Remove ffi gem as a hard dependency Copies the algorithm out of FFI.map_library_name into the FFI_Yajl#map_library_name function so that when we're loading up the C extension we don't need to also slurp in the ffi gem just to run that. The ffi gem is moved to a hard dependency of only the jruby version of the gem, and its a development dependency for the other ruby VMs (so rake spec will work against the ffi library), but its an optional library to install to make the ffi library work on VMs that support C extensions (MRI, RBX). --- ffi-yajl-universal-java.gemspec | 3 ++- ffi-yajl.gemspec.shared | 2 +- lib/ffi_yajl/ext.rb | 14 +++----------- lib/ffi_yajl/ffi.rb | 17 ++++++++++++----- lib/ffi_yajl/map_library_name.rb | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 lib/ffi_yajl/map_library_name.rb diff --git a/ffi-yajl-universal-java.gemspec b/ffi-yajl-universal-java.gemspec index 35a1ebb..e712372 100644 --- a/ffi-yajl-universal-java.gemspec +++ b/ffi-yajl-universal-java.gemspec @@ -6,5 +6,6 @@ gemspec.platform = "universal-java" # extensions so can we simplify the gemspecs now? #gemspec.extensions = %w{ ext/libyajl2/extconf.rb } -gemspec +gemspec.add_dependency "ffi", "~> 1.5" +gemspec diff --git a/ffi-yajl.gemspec.shared b/ffi-yajl.gemspec.shared index 2226fbd..62fefa0 100644 --- a/ffi-yajl.gemspec.shared +++ b/ffi-yajl.gemspec.shared @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.add_development_dependency "rake-compiler", "~> 0.8.3" # pin mime-types in order to work on ruby 1.8.7 s.add_development_dependency "mime-types", "~> 1.16" - s.add_dependency "ffi", "~> 1.5" + s.add_development_dependency "ffi", "~> 1.5" s.add_dependency "libyajl2", "~> 1.2" s.bindir = "bin" diff --git a/lib/ffi_yajl/ext.rb b/lib/ffi_yajl/ext.rb index 5784023..bc4d410 100644 --- a/lib/ffi_yajl/ext.rb +++ b/lib/ffi_yajl/ext.rb @@ -2,22 +2,14 @@ require 'rubygems' require 'ffi_yajl/encoder' require 'ffi_yajl/parser' -require 'ffi' require 'libyajl2' -require 'ffi_yajl/platform' +require 'ffi_yajl/map_library_name' module FFI_Yajl - extend FFI_Yajl::Platform + extend FFI_Yajl::MapLibraryName - # FIXME: DRY with ffi_yajl/ffi.rb - # FIXME: extract map_library_name from FFI and stop requiring it at the top level - # so that the C-library can be installed without FFI - libname = ::FFI.map_library_name("yajl") - # awful windows patch, but there is an open issue to entirely replace FFI.map_library_name already - libname = "libyajl.so" if windows? + libname = map_library_name libpath = File.expand_path(File.join(Libyajl2.opt_path, libname)) - libpath.gsub!(/dylib/, 'bundle') - libpath = ::FFI.map_library_name("yajl") unless File.exist?(libpath) # # FFS, what exactly was so wrong with DL.dlopen that ruby had to get rid of it??? diff --git a/lib/ffi_yajl/ffi.rb b/lib/ffi_yajl/ffi.rb index 4e685a6..e291ba5 100644 --- a/lib/ffi_yajl/ffi.rb +++ b/lib/ffi_yajl/ffi.rb @@ -1,16 +1,23 @@ require 'rubygems' require 'libyajl2' -require 'ffi' +begin + require 'ffi' +rescue LoadError + puts "FATAL: to use the ffi extension instead of the compiled C extension, the ffi gem must be installed" + puts " (it is optional, so you must include it in your bundle manually)" + exit 1 +end + +require 'ffi_yajl/map_library_name' module FFI_Yajl extend ::FFI::Library - libname = ::FFI.map_library_name("yajl") - # XXX: need to replace ::FFI.map_library_name here as well - libname = "libyajl.so" if libname == "yajl.dll" + extend FFI_Yajl::MapLibraryName + + libname = map_library_name libpath = File.expand_path(File.join(Libyajl2.opt_path, libname)) - libpath.gsub!(/dylib/, 'bundle') if File.file?(libpath) # use our vendored version of libyajl2 if we find it installed diff --git a/lib/ffi_yajl/map_library_name.rb b/lib/ffi_yajl/map_library_name.rb new file mode 100644 index 0000000..3518d07 --- /dev/null +++ b/lib/ffi_yajl/map_library_name.rb @@ -0,0 +1,37 @@ + +require 'ffi_yajl/platform' + +module FFI_Yajl + module MapLibraryName + include FFI_Yajl::Platform + def map_library_name + # this is the right answer for the internally built libyajl on windows + return "libyajl.so" if windows? + + # this is largely copied from the FFI.map_library_name algorithm, we most likely need + # the windows code eventually to support not using the embedded libyajl2-gem + libprefix = + case RbConfig::CONFIG['host_os'].downcase + when /mingw|mswin/ + '' + when /cygwin/ + 'cyg' + else + 'lib' + end + libsuffix = + case RbConfig::CONFIG['host_os'].downcase + when /darwin/ + 'bundle' + when /linux|bsd|solaris|sunos/ + 'so' + when /mingw|mswin|cygwin/ + 'dll' + else + # Punt and just assume a sane unix (i.e. anything but AIX) + 'so' + end + libprefix + "yajl" + ".#{libsuffix}" + end + end +end -- cgit v1.2.1