Last active
August 29, 2015 14:10
-
-
Save shannonwells/70f50b2df94dd0cbb319 to your computer and use it in GitHub Desktop.
This is an edited and annotated tiny_tds extconf.rb with changes needed to get tiny_tds to build as a platform-specific linux gem, statically linked with a custom build of freetds with openssl. It is intended to allow encrypted connections with MS SQL Server. Please use the tiny_tds_ports.rake Gist or else this code will not work.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ENV['RC_ARCHS'] = '' if RUBY_PLATFORM =~ /darwin/ | |
# :stopdoc: | |
require 'mkmf' | |
# Shamelessly copied from nokogiri | |
# | |
# All my notes are tagged with --shannonwells. | |
# I was able to compile platform-specfic gems on OS X Mavericks, AWS-linux AMI and AWS ubuntu AMI. | |
# Please feel free to pm me here or on Twitter (@shannonewells) if you want help. --shannonwells | |
# Commented this line out --shannonwells | |
#FREETDSDIR = ENV['FREETDS_DIR'] | |
# I needed to create a platform-specific gem for heroku, which uses openssl. That means freetds has to be built | |
# and statically linked, so here I just force tiny_tds to use the one it downloads. --shannonwells | |
MYDIR = File.dirname(__FILE__) | |
FREETDSDIR = "#{MYDIR}/../../ports/x86_64-unknown-linux-gnu/freetds/0.91/" | |
if FREETDSDIR.nil? || FREETDSDIR.empty? | |
LIBDIR = RbConfig::CONFIG['libdir'] | |
INCLUDEDIR = RbConfig::CONFIG['includedir'] | |
else | |
puts "Will use #{FREETDSDIR}" | |
LIBDIR = "#{FREETDSDIR}/lib" | |
INCLUDEDIR = "#{FREETDSDIR}/include" | |
end | |
$CFLAGS << " #{ENV["CFLAGS"]}" | |
$LDFLAGS << " #{ENV["LDFLAGS"]}" | |
$LIBS << " #{ENV["LIBS"]}" | |
SEARCHABLE_PATHS = begin | |
eop_regexp = /#{File::SEPARATOR}bin$/ | |
paths = ENV['PATH'] | |
paths = paths.gsub(File::ALT_SEPARATOR, File::SEPARATOR) if File::ALT_SEPARATOR | |
paths = paths.split(File::PATH_SEPARATOR) | |
bin_paths = paths.select{ |p| p =~ eop_regexp } | |
bin_paths.map{ |p| p.sub(eop_regexp,'') }.compact.reject{ |p| p.empty? }.uniq | |
end | |
def searchable_paths_with_directories(*directories) | |
SEARCHABLE_PATHS.map do |path| | |
directories.map do |paths| | |
dir = File.join path, *paths | |
File.directory?(dir) ? dir : nil | |
end.flatten.compact | |
end.flatten.compact | |
end | |
# TRAP: lib_prefix is DEFINITELY NOT 'lib' on UNIXes. Setting it to such will mess up your compiler options. --shannonwells | |
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('iconv', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS) | |
dir_config('freetds', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS) | |
# I had to add these two lines to get the find_library/find_header tests to pass. | |
dir_config('sybdb', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS) | |
dir_config('ct', FREETDS_HEADER_DIRS, FREETDS_LIB_DIRS) | |
else | |
dir_config('iconv') | |
dir_config('freetds') | |
# remove LDFLAGS | |
$LDFLAGS = ENV.fetch("LDFLAGS", "") | |
end | |
def asplode(lib) | |
abort "-----\n#{lib} is missing.\n-----" | |
end | |
asplode 'libiconv' unless have_func('iconv_open', 'iconv.h') || have_library('iconv', 'iconv_open', 'iconv.h') | |
asplode 'freetds' unless have_header('sybfront.h') && have_header('sybdb.h') | |
# I ran some test code to figure out why the original lines of this were failing. Once I got that code working, I | |
# used it here. You must comment out the line in the ports.rake file that says "--without-odbc", because otherwise | |
# these entry points are not found. Also watch out for tdsdbopen to be defined as dbopen instead (this is a configure | |
# option). I saw this on OS X. You can test this by just changing tdsdbopen to dbopen, below. --shannonwells | |
asplode 'freetds' unless find_library("#{lib_prefix}ct", 'ct_bind', FREETDS_LIB_DIRS.join(File::PATH_SEPARATOR) ) | |
asplode 'freetds' unless find_library("#{lib_prefix}sybdb", 'tdsdbopen', FREETDS_LIB_DIRS.join(File::PATH_SEPARATOR) ) | |
create_makefile('tiny_tds/tiny_tds') | |
# :startdoc: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment