Permalink
Fetching contributors…
Cannot retrieve contributors at this time
271 lines (227 sloc) 9.39 KB
require 'fileutils'
require 'mkmf'
# Eager check devs tools
have_devel? if respond_to?(:have_devel?)
def check_libs libs = [], fatal = false
libs.all? { |lib| have_library(lib) || (abort("could not find library: #{lib}") if fatal) }
end
def check_heads heads = [], fatal = false
heads.all? { |head| have_header(head) || (abort("could not find header: #{head}") if fatal)}
end
def add_define(name)
$defs.push("-D#{name}")
end
##
# OpenSSL:
# override append_library, so it actually appends (instead of prepending)
# this fixes issues with linking ssl, since libcrypto depends on symbols in libssl
def append_library(libs, lib)
libs + " " + format(LIBARG, lib)
end
SSL_HEADS = %w(openssl/ssl.h openssl/err.h)
SSL_LIBS = %w(crypto ssl)
# OpenSSL 1.1.0 and above for Windows use the Unix library names
# OpenSSL 0.9.8 and 1.0.x for Windows use the *eay32 library names
SSL_LIBS_WIN = RUBY_PLATFORM =~ /mswin|mingw|bccwin/ ? %w(ssleay32 libeay32) : []
def dir_config_wrapper(pretty_name, name, idefault=nil, ldefault=nil)
inc, lib = dir_config(name, idefault, ldefault)
if inc && lib
# TODO: Remove when 2.0.0 is the minimum supported version
# Ruby versions not incorporating the mkmf fix at
# https://bugs.ruby-lang.org/projects/ruby-trunk/repository/revisions/39717
# do not properly search for lib directories, and must be corrected
unless lib && lib[-3, 3] == 'lib'
@libdir_basename = 'lib'
inc, lib = dir_config(name, idefault, ldefault)
end
unless idefault && ldefault
abort "-----\nCannot find #{pretty_name} include path #{inc}\n-----" unless inc && inc.split(File::PATH_SEPARATOR).any? { |dir| File.directory?(dir) }
abort "-----\nCannot find #{pretty_name} library path #{lib}\n-----" unless lib && lib.split(File::PATH_SEPARATOR).any? { |dir| File.directory?(dir) }
warn "-----\nUsing #{pretty_name} in path #{File.dirname inc}\n-----"
end
true
end
end
def dir_config_search(pretty_name, name, paths, &b)
paths.each do |p|
if dir_config_wrapper('OpenSSL', 'ssl', p + '/include', p + '/lib') && yield
warn "-----\nFound #{pretty_name} in path #{p}\n-----"
return true
end
end
false
end
def pkg_config_wrapper(pretty_name, name)
cflags, ldflags, libs = pkg_config(name)
unless [cflags, ldflags, libs].any?(&:nil?) || [cflags, ldflags, libs].any?(&:empty?)
warn "-----\nUsing #{pretty_name} from pkg-config #{cflags} && #{ldflags} && #{libs}\n-----"
true
end
end
if ENV['CROSS_COMPILING']
openssl_version = ENV.fetch("OPENSSL_VERSION", "1.0.2e")
openssl_dir = File.expand_path("~/.rake-compiler/builds/openssl-#{openssl_version}/")
if File.exist?(openssl_dir)
FileUtils.mkdir_p Dir.pwd+"/openssl/"
FileUtils.cp Dir[openssl_dir+"/include/openssl/*.h"], Dir.pwd+"/openssl/", :verbose => true
FileUtils.cp Dir[openssl_dir+"/lib*.a"], Dir.pwd, :verbose => true
$INCFLAGS << " -I#{Dir.pwd}" # for the openssl headers
add_define "WITH_SSL"
else
STDERR.puts
STDERR.puts "**************************************************************************************"
STDERR.puts "**** Cross-compiled OpenSSL not found"
STDERR.puts "**** Run: hg clone http://bitbucket.org/ged/ruby-pg && cd ruby-pg && rake openssl_libs"
STDERR.puts "**************************************************************************************"
STDERR.puts
end
elsif dir_config_wrapper('OpenSSL', 'ssl')
# If the user has provided a --with-ssl-dir argument, we must respect it or fail.
add_define 'WITH_SSL' if (check_libs(SSL_LIBS) || check_libs(SSL_LIBS_WIN)) && check_heads(SSL_HEADS)
elsif pkg_config_wrapper('OpenSSL', 'openssl')
# If we can detect OpenSSL by pkg-config, use it as the next-best option
add_define 'WITH_SSL' if (check_libs(SSL_LIBS) || check_libs(SSL_LIBS_WIN)) && check_heads(SSL_HEADS)
elsif (check_libs(SSL_LIBS) || check_libs(SSL_LIBS_WIN)) && check_heads(SSL_HEADS)
# If we don't even need any options to find a usable OpenSSL, go with it
add_define 'WITH_SSL'
elsif dir_config_search('OpenSSL', 'ssl', ['/usr/local', '/opt/local', '/usr/local/opt/openssl']) do
(check_libs(SSL_LIBS) || check_libs(SSL_LIBS_WIN)) && check_heads(SSL_HEADS)
end
# Finally, look for OpenSSL in alternate locations including MacPorts and HomeBrew
add_define 'WITH_SSL'
end
add_define 'BUILD_FOR_RUBY'
# Ruby features:
have_var('rb_trap_immediate', ['ruby.h', 'rubysig.h'])
have_func('rb_thread_blocking_region')
have_func('rb_thread_call_without_gvl', 'ruby/thread.h')
have_func('rb_thread_fd_select')
have_type('rb_fdset_t', 'ruby/intern.h')
have_func('rb_wait_for_single_fd')
have_func('rb_enable_interrupt')
have_func('rb_time_new')
# System features:
add_define('HAVE_INOTIFY') if inotify = have_func('inotify_init', 'sys/inotify.h')
add_define('HAVE_OLD_INOTIFY') if !inotify && have_macro('__NR_inotify_init', 'sys/syscall.h')
have_func('writev', 'sys/uio.h')
have_func('pipe2', 'unistd.h')
have_func('accept4', 'sys/socket.h')
have_const('SOCK_CLOEXEC', 'sys/socket.h')
# Minor platform details between *nix and Windows:
if RUBY_PLATFORM =~ /(mswin|mingw|bccwin)/
GNU_CHAIN = ENV['CROSS_COMPILING'] || $1 == 'mingw'
OS_WIN32 = true
add_define "OS_WIN32"
else
GNU_CHAIN = true
OS_UNIX = true
add_define 'OS_UNIX'
add_define "HAVE_KQUEUE" if have_header("sys/event.h") && have_header("sys/queue.h")
end
# Adjust number of file descriptors (FD) on Windows
if RbConfig::CONFIG["host_os"] =~ /mingw/
found = RbConfig::CONFIG.values_at("CFLAGS", "CPPFLAGS").
any? { |v| v.include?("FD_SETSIZE") }
add_define "FD_SETSIZE=32767" unless found
end
# Main platform invariances:
case RUBY_PLATFORM
when /mswin32/, /mingw32/, /bccwin32/
check_heads(%w[windows.h winsock.h], true)
check_libs(%w[kernel32 rpcrt4 gdi32], true)
if GNU_CHAIN
CONFIG['LDSHAREDXX'] = "$(CXX) -shared -static-libgcc -static-libstdc++"
else
$defs.push "-EHs"
$defs.push "-GR"
end
# Newer versions of Ruby already define _WIN32_WINNT, which is needed
# to get access to newer POSIX networking functions (e.g. getaddrinfo)
add_define '_WIN32_WINNT=0x0501' unless have_func('getaddrinfo')
when /solaris/
add_define 'OS_SOLARIS8'
check_libs(%w[nsl socket], true)
# If Ruby was compiled for 32-bits, then select() can only handle 1024 fds
# There is an alternate function, select_large_fdset, that supports more.
have_func('select_large_fdset', 'sys/select.h')
if CONFIG['CC'] == 'cc' && (
`cc -flags 2>&1` =~ /Sun/ || # detect SUNWspro compiler
`cc -V 2>&1` =~ /Sun/ # detect Solaris Studio compiler
)
# SUN CHAIN
add_define 'CC_SUNWspro'
$preload = ["\nCXX = CC"] # hack a CXX= line into the makefile
$CFLAGS = CONFIG['CFLAGS'] = "-KPIC"
CONFIG['CCDLFLAGS'] = "-KPIC"
CONFIG['LDSHARED'] = "$(CXX) -G -KPIC -lCstd"
CONFIG['LDSHAREDXX'] = "$(CXX) -G -KPIC -lCstd"
else
# GNU CHAIN
# on Unix we need a g++ link, not gcc.
CONFIG['LDSHARED'] = "$(CXX) -shared"
end
when /openbsd/
# OpenBSD branch contributed by Guillaume Sellier.
# on Unix we need a g++ link, not gcc. On OpenBSD, linking against libstdc++ have to be explicitly done for shared libs
CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++ -fPIC"
CONFIG['LDSHAREDXX'] = "$(CXX) -shared -lstdc++ -fPIC"
when /darwin/
add_define 'OS_DARWIN'
# on Unix we need a g++ link, not gcc.
# Ff line contributed by Daniel Harple.
CONFIG['LDSHARED'] = "$(CXX) " + CONFIG['LDSHARED'].split[1..-1].join(' ')
when /linux/
add_define 'HAVE_EPOLL' if have_func('epoll_create', 'sys/epoll.h')
# on Unix we need a g++ link, not gcc.
CONFIG['LDSHARED'] = "$(CXX) -shared"
when /aix/
CONFIG['LDSHARED'] = "$(CXX) -Wl,-bstatic -Wl,-bdynamic -Wl,-G -Wl,-brtl"
when /cygwin/
# For rubies built with Cygwin, CXX may be set to CC, which is just
# a wrapper for gcc.
# This will compile, but it will not link to the C++ std library.
# Explicitly set CXX to use g++.
CONFIG['CXX'] = "g++"
# on Unix we need a g++ link, not gcc.
CONFIG['LDSHARED'] = "$(CXX) -shared"
else
# on Unix we need a g++ link, not gcc.
CONFIG['LDSHARED'] = "$(CXX) -shared"
end
# Platform-specific time functions
if have_func('clock_gettime')
# clock_gettime is POSIX, but the monotonic clocks are not
have_const('CLOCK_MONOTONIC_RAW', 'time.h') # Linux
have_const('CLOCK_MONOTONIC', 'time.h') # Linux, Solaris, BSDs
else
have_func('gethrtime') # Older Solaris and HP-UX
end
# Hack so that try_link will test with a C++ compiler instead of a C compiler
TRY_LINK.sub!('$(CC)', '$(CXX)')
# This is our wishlist. We use whichever flags work on the host.
# In the future, add -Werror to make sure all warnings are resolved.
# deprecated-declarations are used in OS X OpenSSL
# ignored-qualifiers are used by the Bindings (would-be void *)
# unused-result because GCC 4.6 no longer silences (void) ignore_this(function)
# address because on Windows, rb_fd_select checks if &fds is non-NULL, which it cannot be
%w(
-Wall
-Wextra
-Wno-deprecated-declarations
-Wno-ignored-qualifiers
-Wno-unused-result
-Wno-address
).select do |flag|
try_link('int main() {return 0;}', flag)
end.each do |flag|
CONFIG['CXXFLAGS'] << ' ' << flag
end
puts "CXXFLAGS=#{CONFIG['CXXFLAGS']}"
# Solaris C++ compiler doesn't have make_pair()
add_define 'HAVE_MAKE_PAIR' if try_link(<<SRC, '-lstdc++')
#include <utility>
using namespace std;
int main(){ pair<const int,int> tuple = make_pair(1,2); }
SRC
TRY_LINK.sub!('$(CXX)', '$(CC)')
create_makefile "rubyeventmachine"