ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/ # :stopdoc: require 'mkmf' require 'fileutils' # The gem version constraint in the gemspec is not respected at install time. # Keep this version in sync with the one in the gemspec ! gem 'mini_portile2', '~> 2.0' require 'mini_portile2' require_relative './extconsts' OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE # Shamelessly copied from nokogiri # def do_help print <&1` if $?.success? output "OK" else # tar on windows returns error exit code, because it can not extract symlinks output "ERROR (ignored)" end end def configure config = if host=~/mingw/ host=~/x86_64/ ? 'mingw64' : 'mingw' end args = [ "CFLAGS=-DDSO_WIN32", "./Configure", "no-shared", configure_prefix, config, ] args.unshift("CROSS_COMPILE=#{host}-") if enable_config("cross-build") execute "configure", "sh -c \"#{args.join(" ")}\"" end def compile super # OpenSSL DLLs are called "libeay32.dll" and "ssleay32.dll" per default, # regardless to the version. This is best suited to meet the Windows DLL hell. # To avoid any conflicts we do a static build and build DLLs afterwards, # with our own naming scheme. execute "mkdef-libeay32", "(perl util/mkdef.pl 32 libeay >libeay32.def)" execute "mkdef-ssleay32", "(perl util/mkdef.pl 32 ssleay >ssleay32.def)" dllwrap = consolidated_host(RbConfig::CONFIG["DLLWRAP"]) execute "dllwrap-libeay32", "#{dllwrap} --dllname libeay32-#{version}-#{host}.dll --output-lib libcrypto.dll.a --def libeay32.def libcrypto.a -lwsock32 -lgdi32 -lcrypt32" execute "dllwrap-ssleay32", "#{dllwrap} --dllname ssleay32-#{version}-#{host}.dll --output-lib libssl.dll.a --def ssleay32.def libssl.a libcrypto.dll.a" end def install super FileUtils.cp "#{work_path}/libeay32-#{version}-#{host}.dll", "#{path}/bin/" FileUtils.cp "#{work_path}/ssleay32-#{version}-#{host}.dll", "#{path}/bin/" FileUtils.cp "#{work_path}/libcrypto.dll.a", "#{path}/lib/" FileUtils.cp "#{work_path}/libssl.dll.a", "#{path}/lib/" end end end end def define_libiconv_recipe(host) BuildRecipe.new("libiconv", ICONV_VERSION, [ICONV_SOURCE_URI]).tap do |recipe| # always produce position independent code recipe.configure_options << "CFLAGS=-fPIC" end end def define_freetds_recipe(host, libiconv, libssl, gnutls) BuildRecipe.new("freetds", FREETDS_VERSION, [FREETDS_SOURCE_URI]).tap do |recipe| with_tdsver = FREETDS_VERSION =~ /0\.91/ ? "--with-tdsver=7.1" : "--with-tdsver=7.3" for_windows = recipe.host =~ /mswin|mingw/i recipe.configure_options << '--with-pic' recipe.configure_options << "--with-libiconv-prefix=#{libiconv.path}" if libiconv if true == libssl recipe.configure_options << "--with-openssl" elsif libssl recipe.configure_options << "--with-openssl=#{libssl.path}" end recipe.configure_options << "--with-gnutls" if gnutls recipe.configure_options << '--sysconfdir=C:\Sites' if for_windows recipe.configure_options << '--enable-sspi' if for_windows recipe.configure_options << "--disable-odbc" recipe.configure_options << with_tdsver if libiconv # For some reason freetds doesn't honor --with-libiconv-prefix # so we have do add it by hand: recipe.configure_options << "CFLAGS=-I#{libiconv.path}/include" recipe.configure_options << "LDFLAGS=-L#{libiconv.path}/lib -liconv" end class << recipe def install super_value = super # Install binstub target binaries. if super_value bin_path = File.expand_path File.join(path, 'bin') exe_path = File.expand_path File.join(target, '..', 'exe') return unless File.directory?(bin_path) ['tsql', 'defncopy'].each do |bin| ['.exe', ''].each do |ext| exe = File.join bin_path, "#{bin}#{ext}" next unless File.exists?(exe) next unless File.executable?(exe) FileUtils.cp exe, exe_path end end end super_value end end end end if RbConfig::CONFIG['target_os'] =~ /mswin32|mingw32/ lib_prefix = 'lib' unless RbConfig::CONFIG['target_os'] =~ /mingw32/ # There's no default include/lib dir on Windows. Let's just add the Ruby ones # and resort on the search path specified by INCLUDE and LIB environment # variables HEADER_DIRS = [INCLUDEDIR] LIB_DIRS = [LIBDIR] else lib_prefix = '' HEADER_DIRS = [ # First search /opt/local for macports '/opt/local/include', # Then search /usr/local for people that installed from source '/usr/local/include', # Check the ruby install locations INCLUDEDIR, # Finally fall back to /usr '/usr/include' ].reject{ |dir| !File.directory?(dir) } LIB_DIRS = [ # First search /opt/local for macports '/opt/local/lib', # Then search /usr/local for people that installed from source '/usr/local/lib', # Check the ruby install locations LIBDIR, # Finally fall back to /usr '/usr/lib', ].reject{ |dir| !File.directory?(dir) } end FREETDS_HEADER_DIRS = (searchable_paths_with_directories(['include'],['include','freetds']) + HEADER_DIRS).uniq FREETDS_LIB_DIRS = (searchable_paths_with_directories(['lib'],['lib','freetds']) + LIB_DIRS).uniq # lookup over searchable paths is great for native compilation, however, when # cross compiling we need to specify our own paths. if enable_config("lookup", true) dir_config('freetds', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS) else dir_config('freetds') # remove LDFLAGS $LDFLAGS = ENV.fetch("LDFLAGS", "") end def asplode(lib) abort "-----\n#{lib} is missing.\n-----" end def freetds_usable?(lib_prefix) have_header('sybfront.h') && have_header('sybdb.h') && find_library("#{lib_prefix}sybdb", 'tdsdbopen') && find_library("#{lib_prefix}ct", 'ct_bind') end # We use freetds, when available already, and fallback to compilation of ports system_freetds = enable_config('system-freetds', ENV['TINYTDS_SKIP_PORTS'] || freetds_usable?(lib_prefix)) # We expect to have iconv and OpenSSL available on non-Windows systems host = RbConfig::CONFIG["host"] system_iconv = enable_config('system-iconv', host =~ /mingw|mswin/ ? false : true) system_openssl = enable_config('system-openssl', host =~ /mingw|mswin/ ? false : true ) enable_gnutls = enable_config('gnutls', false ) enable_openssl = enable_config('openssl', !enable_gnutls ) unless system_freetds libssl = define_libssl_recipe(host).cook_and_activate unless system_openssl libiconv = define_libiconv_recipe(host).cook_and_activate unless system_iconv freetds = define_freetds_recipe(host, libiconv, libssl || enable_openssl, enable_gnutls).cook_and_activate dir_config('freetds', freetds.path + "/include", freetds.path + "/lib") end asplode 'freetds' unless freetds_usable?(lib_prefix) create_makefile('tiny_tds/tiny_tds') # :startdoc: