vm_tiny_tds 2.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.codeclimate.yml +20 -0
- data/.gitattributes +1 -0
- data/.gitignore +20 -0
- data/.rubocop.yml +31 -0
- data/.travis.yml +24 -0
- data/BACKERS.md +32 -0
- data/CHANGELOG.md +255 -0
- data/CODE_OF_CONDUCT.md +31 -0
- data/Gemfile +9 -0
- data/ISSUE_TEMPLATE.md +38 -0
- data/MIT-LICENSE +23 -0
- data/README.md +504 -0
- data/Rakefile +53 -0
- data/VERSION +1 -0
- data/appveyor.yml +51 -0
- data/bin/defncopy-ttds +3 -0
- data/bin/tsql-ttds +3 -0
- data/exe/.keep +0 -0
- data/ext/tiny_tds/client.c +451 -0
- data/ext/tiny_tds/client.h +51 -0
- data/ext/tiny_tds/extconf.rb +69 -0
- data/ext/tiny_tds/extconsts.rb +15 -0
- data/ext/tiny_tds/result.c +619 -0
- data/ext/tiny_tds/result.h +32 -0
- data/ext/tiny_tds/tiny_tds_ext.c +12 -0
- data/ext/tiny_tds/tiny_tds_ext.h +17 -0
- data/lib/tiny_tds/bin.rb +104 -0
- data/lib/tiny_tds/client.rb +136 -0
- data/lib/tiny_tds/error.rb +14 -0
- data/lib/tiny_tds/gem.rb +32 -0
- data/lib/tiny_tds/result.rb +7 -0
- data/lib/tiny_tds/version.rb +3 -0
- data/lib/tiny_tds.rb +61 -0
- data/patches/freetds/1.00.27/0001-mingw_missing_inet_pton.diff +34 -0
- data/patches/freetds/1.00.27/0002-Don-t-use-MSYS2-file-libws2_32.diff +28 -0
- data/patches/libiconv/1.14/1-avoid-gets-error.patch +17 -0
- data/tasks/native_gem.rake +14 -0
- data/tasks/package.rake +8 -0
- data/tasks/ports/freetds.rb +37 -0
- data/tasks/ports/libiconv.rb +43 -0
- data/tasks/ports/openssl.rb +78 -0
- data/tasks/ports/recipe.rb +52 -0
- data/tasks/ports.rake +87 -0
- data/tasks/test.rake +9 -0
- data/test/appveyor/dbsetup.ps1 +27 -0
- data/test/appveyor/dbsetup.sql +9 -0
- data/test/benchmark/query.rb +77 -0
- data/test/benchmark/query_odbc.rb +106 -0
- data/test/benchmark/query_tinytds.rb +126 -0
- data/test/bin/install-freetds.sh +20 -0
- data/test/bin/install-openssl.sh +18 -0
- data/test/bin/setup.sh +19 -0
- data/test/client_test.rb +230 -0
- data/test/gem_test.rb +179 -0
- data/test/result_test.rb +773 -0
- data/test/schema/1px.gif +0 -0
- data/test/schema/sqlserver_2000.sql +140 -0
- data/test/schema/sqlserver_2005.sql +140 -0
- data/test/schema/sqlserver_2008.sql +140 -0
- data/test/schema/sqlserver_2014.sql +140 -0
- data/test/schema/sqlserver_2016.sql +140 -0
- data/test/schema/sqlserver_azure.sql +140 -0
- data/test/schema/sybase_ase.sql +138 -0
- data/test/schema_test.rb +443 -0
- data/test/test_helper.rb +217 -0
- data/test/thread_test.rb +98 -0
- data/tiny_tds.gemspec +29 -0
- metadata +225 -0
data/lib/tiny_tds/bin.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require_relative './version'
|
2
|
+
require_relative './gem'
|
3
|
+
require 'shellwords'
|
4
|
+
|
5
|
+
module TinyTds
|
6
|
+
class Bin
|
7
|
+
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def exe(name, *args)
|
12
|
+
bin = new(name)
|
13
|
+
puts bin.info unless args.any? { |x| x == '-q' }
|
14
|
+
bin.run(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(name)
|
19
|
+
@root = Gem.root_path
|
20
|
+
@exts = (ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']) | ['.exe']
|
21
|
+
|
22
|
+
@name = name
|
23
|
+
@binstub = find_bin
|
24
|
+
@exefile = find_exe
|
25
|
+
end
|
26
|
+
|
27
|
+
def run(*args)
|
28
|
+
with_ports_paths do
|
29
|
+
return nil unless path
|
30
|
+
Kernel.system Shellwords.join(args.unshift(path))
|
31
|
+
$CHILD_STATUS.to_i
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def path
|
36
|
+
@path ||= @exefile && File.exist?(@exefile) ? @exefile : which
|
37
|
+
end
|
38
|
+
|
39
|
+
def info
|
40
|
+
"[TinyTds][v#{TinyTds::VERSION}][#{name}]: #{path}"
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def search_paths
|
46
|
+
ENV['PATH'].split File::PATH_SEPARATOR
|
47
|
+
end
|
48
|
+
|
49
|
+
def with_ports_paths
|
50
|
+
old_path = ENV['PATH']
|
51
|
+
|
52
|
+
begin
|
53
|
+
ENV['PATH'] = [
|
54
|
+
Gem.ports_bin_paths,
|
55
|
+
old_path
|
56
|
+
].flatten.join File::PATH_SEPARATOR
|
57
|
+
|
58
|
+
yield if block_given?
|
59
|
+
ensure
|
60
|
+
ENV['PATH'] = old_path
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def find_bin
|
65
|
+
File.join @root, 'bin', name
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_exe
|
69
|
+
Gem.ports_bin_paths.each do |bin|
|
70
|
+
@exts.each do |ext|
|
71
|
+
f = File.join bin, "#{name}#{ext}"
|
72
|
+
return f if File.exist?(f)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def which
|
79
|
+
search_paths.each do |path|
|
80
|
+
@exts.each do |ext|
|
81
|
+
exe = File.expand_path File.join(path, "#{name}#{ext}"), @root
|
82
|
+
next if exe == @binstub
|
83
|
+
next unless File.executable?(exe)
|
84
|
+
next unless binary?(exe)
|
85
|
+
return exe
|
86
|
+
end
|
87
|
+
end
|
88
|
+
nil
|
89
|
+
end
|
90
|
+
|
91
|
+
# Implementation directly copied from ptools.
|
92
|
+
# https://github.com/djberg96/ptools
|
93
|
+
# https://opensource.org/licenses/Artistic-2.0
|
94
|
+
#
|
95
|
+
def binary?(file)
|
96
|
+
bytes = File.stat(file).blksize
|
97
|
+
return false unless bytes
|
98
|
+
bytes = 4096 if bytes > 4096
|
99
|
+
s = (File.read(file, bytes) || '')
|
100
|
+
s = s.encode('US-ASCII', undef: :replace).split(//)
|
101
|
+
((s.size - s.grep(' '..'~').size) / s.size.to_f) > 0.30
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module TinyTds
|
2
|
+
class Client
|
3
|
+
|
4
|
+
@default_query_options = {
|
5
|
+
as: :hash,
|
6
|
+
symbolize_keys: false,
|
7
|
+
cache_rows: true,
|
8
|
+
timezone: :local,
|
9
|
+
empty_sets: true
|
10
|
+
}
|
11
|
+
|
12
|
+
attr_reader :query_options
|
13
|
+
attr_reader :message_handler
|
14
|
+
|
15
|
+
class << self
|
16
|
+
|
17
|
+
attr_reader :default_query_options
|
18
|
+
|
19
|
+
# Most, if not all, iconv encoding names can be found by ruby. Just in case, you can
|
20
|
+
# overide this method to return a string name that Encoding.find would work with. Default
|
21
|
+
# is to return the passed encoding.
|
22
|
+
#
|
23
|
+
def transpose_iconv_encoding(encoding)
|
24
|
+
encoding
|
25
|
+
end
|
26
|
+
|
27
|
+
def local_offset
|
28
|
+
::Time.local(2010).utc_offset.to_r / 86_400
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
# rubocop:disable Metrics/AbcSize
|
34
|
+
# rubocop:disable Metrics/MethodLength
|
35
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
36
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
37
|
+
def initialize(opts = {})
|
38
|
+
if opts[:dataserver].to_s.empty? && opts[:host].to_s.empty?
|
39
|
+
raise ArgumentError, 'missing :host option if no :dataserver given'
|
40
|
+
end
|
41
|
+
|
42
|
+
@message_handler = opts[:message_handler]
|
43
|
+
if @message_handler && !@message_handler.respond_to?(:call)
|
44
|
+
raise ArgumentError, ':message_handler must implement `call` (eg, a Proc or a Method)'
|
45
|
+
end
|
46
|
+
|
47
|
+
opts[:username] = parse_username(opts)
|
48
|
+
@query_options = self.class.default_query_options.dup
|
49
|
+
opts[:password] = opts[:password].to_s if opts[:password] && opts[:password].to_s.strip != ''
|
50
|
+
opts[:appname] ||= 'TinyTds'
|
51
|
+
opts[:tds_version] = tds_versions_setter(opts)
|
52
|
+
opts[:use_utf16] = opts[:use_utf16].nil? || ["true", "1", "yes"].include?(opts[:use_utf16].to_s)
|
53
|
+
opts[:login_timeout] ||= 60
|
54
|
+
opts[:timeout] ||= 5
|
55
|
+
opts[:encoding] = opts[:encoding].nil? || opts[:encoding].casecmp('utf8').zero? ? 'UTF-8' : opts[:encoding].upcase
|
56
|
+
opts[:port] ||= 1433
|
57
|
+
opts[:dataserver] = "#{opts[:host]}:#{opts[:port]}" if opts[:dataserver].to_s.empty?
|
58
|
+
forced_integer_keys = [:login_timeout, :port, :timeout]
|
59
|
+
forced_integer_keys.each { |k| opts[k] = opts[k].to_i if opts[k] }
|
60
|
+
connect(opts)
|
61
|
+
end
|
62
|
+
|
63
|
+
def tds_73?
|
64
|
+
tds_version >= 11
|
65
|
+
end
|
66
|
+
|
67
|
+
def tds_version_info
|
68
|
+
info = TDS_VERSIONS_GETTERS[tds_version]
|
69
|
+
"#{info[:name]} - #{info[:description]}" if info
|
70
|
+
end
|
71
|
+
|
72
|
+
def active?
|
73
|
+
!closed? && !dead?
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def parse_username(opts)
|
79
|
+
host = opts[:host]
|
80
|
+
username = opts[:username]
|
81
|
+
return username if username.nil? || !opts[:azure]
|
82
|
+
return username if username.include?('@') && !username.include?('database.windows.net')
|
83
|
+
user, domain = username.split('@')
|
84
|
+
domain ||= host
|
85
|
+
"#{user}@#{domain.split('.').first}"
|
86
|
+
end
|
87
|
+
|
88
|
+
def tds_versions_setter(opts = {})
|
89
|
+
v = opts[:tds_version] || ENV['TDSVER'] || '7.3'
|
90
|
+
TDS_VERSIONS_SETTERS[v.to_s]
|
91
|
+
end
|
92
|
+
|
93
|
+
# From sybdb.h comments:
|
94
|
+
# DBVERSION_xxx are used with dbsetversion()
|
95
|
+
#
|
96
|
+
TDS_VERSIONS_SETTERS = {
|
97
|
+
'unknown' => 0,
|
98
|
+
'46' => 1,
|
99
|
+
'100' => 2,
|
100
|
+
'42' => 3,
|
101
|
+
'70' => 4,
|
102
|
+
'7.0' => 4,
|
103
|
+
'71' => 5,
|
104
|
+
'7.1' => 5,
|
105
|
+
'80' => 5,
|
106
|
+
'8.0' => 5,
|
107
|
+
'72' => 6,
|
108
|
+
'7.2' => 6,
|
109
|
+
'90' => 6,
|
110
|
+
'9.0' => 6,
|
111
|
+
'73' => 7,
|
112
|
+
'7.3' => 7
|
113
|
+
}.freeze
|
114
|
+
|
115
|
+
# From sybdb.h comments:
|
116
|
+
# DBTDS_xxx are returned by DBTDS()
|
117
|
+
# The integer values of the constants are poorly chosen.
|
118
|
+
#
|
119
|
+
TDS_VERSIONS_GETTERS = {
|
120
|
+
0 => { name: 'DBTDS_UNKNOWN', description: 'Unknown' },
|
121
|
+
1 => { name: 'DBTDS_2_0', description: 'Pre 4.0 SQL Server' },
|
122
|
+
2 => { name: 'DBTDS_3_4', description: 'Microsoft SQL Server (3.0)' },
|
123
|
+
3 => { name: 'DBTDS_4_0', description: '4.0 SQL Server' },
|
124
|
+
4 => { name: 'DBTDS_4_2', description: '4.2 SQL Server' },
|
125
|
+
5 => { name: 'DBTDS_4_6', description: '2.0 OpenServer and 4.6 SQL Server.' },
|
126
|
+
6 => { name: 'DBTDS_4_9_5', description: '4.9.5 (NCR) SQL Server' },
|
127
|
+
7 => { name: 'DBTDS_5_0', description: '5.0 SQL Server' },
|
128
|
+
8 => { name: 'DBTDS_7_0', description: 'Microsoft SQL Server 7.0' },
|
129
|
+
9 => { name: 'DBTDS_7_1/DBTDS_8_0', description: 'Microsoft SQL Server 2000' },
|
130
|
+
10 => { name: 'DBTDS_7_2/DBTDS_9_0', description: 'Microsoft SQL Server 2005' },
|
131
|
+
11 => { name: 'DBTDS_7_3', description: 'Microsoft SQL Server 2008' },
|
132
|
+
12 => { name: 'DBTDS_7_4', description: 'Microsoft SQL Server 2012/2014' }
|
133
|
+
}.freeze
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
data/lib/tiny_tds/gem.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'rbconfig'
|
2
|
+
|
3
|
+
module TinyTds
|
4
|
+
module Gem
|
5
|
+
class << self
|
6
|
+
def root_path
|
7
|
+
File.expand_path '../../..', __FILE__
|
8
|
+
end
|
9
|
+
|
10
|
+
def ports_root_path
|
11
|
+
File.join(root_path,'ports')
|
12
|
+
end
|
13
|
+
|
14
|
+
def ports_bin_paths
|
15
|
+
Dir.glob(File.join(ports_root_path,ports_host,'**','bin'))
|
16
|
+
end
|
17
|
+
|
18
|
+
def ports_lib_paths
|
19
|
+
Dir.glob(File.join(ports_root_path,ports_host,'**','lib'))
|
20
|
+
end
|
21
|
+
|
22
|
+
def ports_host
|
23
|
+
h = RbConfig::CONFIG['host']
|
24
|
+
|
25
|
+
# Our fat binary builds with a i686-w64-mingw32 toolchain
|
26
|
+
# but ruby for windows x32-mingw32 reports i686-pc-mingw32
|
27
|
+
# so correct the host here
|
28
|
+
h.gsub('i686-pc-mingw32', 'i686-w64-mingw32')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/lib/tiny_tds.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'date'
|
3
|
+
require 'bigdecimal'
|
4
|
+
require 'rational'
|
5
|
+
|
6
|
+
require 'tiny_tds/version'
|
7
|
+
require 'tiny_tds/error'
|
8
|
+
require 'tiny_tds/client'
|
9
|
+
require 'tiny_tds/result'
|
10
|
+
require 'tiny_tds/gem'
|
11
|
+
|
12
|
+
# Support multiple ruby versions, fat binaries under Windows.
|
13
|
+
if RUBY_PLATFORM =~ /mingw|mswin/ && RUBY_VERSION =~ /(\d+.\d+)/
|
14
|
+
ver = Regexp.last_match(1)
|
15
|
+
|
16
|
+
add_dll_path = proc do |path, &block|
|
17
|
+
begin
|
18
|
+
require 'ruby_installer/runtime'
|
19
|
+
RubyInstaller::Runtime.add_dll_directory(path, &block)
|
20
|
+
rescue LoadError
|
21
|
+
old_path = ENV['PATH']
|
22
|
+
ENV['PATH'] = "#{path};#{old_path}"
|
23
|
+
begin
|
24
|
+
block.call
|
25
|
+
ensure
|
26
|
+
ENV['PATH'] = old_path
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
add_dll_paths = proc do |paths, &block|
|
32
|
+
if path=paths.shift
|
33
|
+
add_dll_path.call(path) do
|
34
|
+
add_dll_paths.call(paths, &block)
|
35
|
+
end
|
36
|
+
else
|
37
|
+
block.call
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Temporary add bin directories for DLL search, so that freetds DLLs can be found.
|
42
|
+
add_dll_paths.call( TinyTds::Gem.ports_bin_paths ) do
|
43
|
+
begin
|
44
|
+
require "tiny_tds/#{ver}/tiny_tds"
|
45
|
+
rescue LoadError
|
46
|
+
require 'tiny_tds/tiny_tds'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
else
|
50
|
+
# Load dependent shared libraries into the process, so that they are already present,
|
51
|
+
# when tiny_tds.so is loaded. This ensures, that shared libraries are loaded even when
|
52
|
+
# the path is different between build and run time (e.g. Heroku).
|
53
|
+
ports_libs = File.join(TinyTds::Gem.ports_root_path,
|
54
|
+
"#{RbConfig::CONFIG['host']}/lib/*.so")
|
55
|
+
Dir[ports_libs].each do |lib|
|
56
|
+
require 'fiddle'
|
57
|
+
Fiddle.dlopen(lib)
|
58
|
+
end
|
59
|
+
|
60
|
+
require 'tiny_tds/tiny_tds'
|
61
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
diff --git a/src/tds/tls.c b/src/tds/tls.c
|
2
|
+
index 09e7fa0..1da18f6 100644
|
3
|
+
--- a/src/tds/tls.c
|
4
|
+
+++ b/src/tds/tls.c
|
5
|
+
@@ -101,6 +101,29 @@
|
6
|
+
#define SSL_PTR BIO_get_data(bio)
|
7
|
+
#endif
|
8
|
+
|
9
|
+
+/*
|
10
|
+
+ * Add a workaround for older Mingw versions without inet_pton().
|
11
|
+
+ * This means RubyInstallers DevKit-4.7.2 in particular.
|
12
|
+
+ */
|
13
|
+
+#if defined(__MINGW32__) && !defined(InetPtonA)
|
14
|
+
+ #include <windows.h>
|
15
|
+
+
|
16
|
+
+ static HMODULE ws2_32 = NULL;
|
17
|
+
+ typedef INT (WINAPI * __inet_pton)(INT Family, LPCWSTR pStringBuf, PVOID pAddr);
|
18
|
+
+ static __inet_pton _inet_pton = NULL;
|
19
|
+
+
|
20
|
+
+ INT WINAPI inet_pton(INT Family, LPCWSTR pStringBuf, PVOID pAddr)
|
21
|
+
+ {
|
22
|
+
+ if (_inet_pton == NULL) {
|
23
|
+
+ ws2_32 = LoadLibraryEx("Ws2_32.dll", NULL, 0);
|
24
|
+
+
|
25
|
+
+ _inet_pton = (__inet_pton)GetProcAddress(ws2_32, "inet_pton");
|
26
|
+
+ }
|
27
|
+
+
|
28
|
+
+ return (_inet_pton)(Family, pStringBuf, pAddr);
|
29
|
+
+ }
|
30
|
+
+#endif
|
31
|
+
+
|
32
|
+
static SSL_RET
|
33
|
+
tds_pull_func_login(SSL_PULL_ARGS)
|
34
|
+
{
|
@@ -0,0 +1,28 @@
|
|
1
|
+
From 56e8972f66c3e948e2ad6885595c58fd23dcdb37 Mon Sep 17 00:00:00 2001
|
2
|
+
From: Lars Kanis <kanis@comcard.de>
|
3
|
+
Date: Thu, 6 Jul 2017 17:09:40 +0200
|
4
|
+
Subject: [PATCH] Don't use MSYS2 file libws2_32.a for MINGW build
|
5
|
+
|
6
|
+
This file is intended for MSYS2/cygwin builds and blocks OpenSSL
|
7
|
+
detection of freetds on i686.
|
8
|
+
---
|
9
|
+
configure | 2 --
|
10
|
+
configure.ac | 2 --
|
11
|
+
2 files changed, 4 deletions(-)
|
12
|
+
|
13
|
+
diff --git a/configure b/configure
|
14
|
+
index 9495a49..31eb01d 100644
|
15
|
+
--- a/configure
|
16
|
+
+++ b/configure
|
17
|
+
@@ -15915,8 +15915,6 @@ case $host in
|
18
|
+
tds_mingw=yes
|
19
|
+
if test "$host_cpu" = "x86_64"; then
|
20
|
+
LIBS="-lws2_32"
|
21
|
+
- elif test -r /usr/lib/w32api/libws2_32.a; then
|
22
|
+
- LIBS="-L/usr/lib/w32api -lws2_32"
|
23
|
+
else
|
24
|
+
LIBS="-lws2_32"
|
25
|
+
fi
|
26
|
+
--
|
27
|
+
2.6.2.windows.1
|
28
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
--- a/srclib/stdio.in.h 2017-01-22 01:23:00.000000000 -0400
|
2
|
+
+++ b/srclib/stdio.in.h 2017-01-22 01:24:00.000000000 -0400
|
3
|
+
@@ -695,8 +695,14 @@
|
4
|
+
/* It is very rare that the developer ever has full control of stdin,
|
5
|
+
so any use of gets warrants an unconditional warning. Assume it is
|
6
|
+
always declared, since it is required by C89. */
|
7
|
+
+#if defined(__GLIBC__) && !defined(__UCLIBC__)
|
8
|
+
+# ifdef __GLIBC_PREREQ
|
9
|
+
+# if !__GLIBC_PREREQ(2, 16)
|
10
|
+
_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
|
11
|
+
+# endif
|
12
|
+
+# endif
|
13
|
+
+#endif
|
14
|
+
#endif
|
15
|
+
|
16
|
+
|
17
|
+
#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
desc 'Build the windows binary gems per rake-compiler-dock'
|
4
|
+
task 'gem:windows' => ['ports:cross'] do
|
5
|
+
require 'rake_compiler_dock'
|
6
|
+
|
7
|
+
# make sure to install our bundle
|
8
|
+
build = ['bundle']
|
9
|
+
|
10
|
+
# and finally build the native gem
|
11
|
+
build << 'rake cross native gem RUBY_CC_VERSION=2.5.0:2.4.0:2.3.0:2.2.2:2.1.6:2.0.0 CFLAGS="-Wall" MAKE="make -j`nproc`"'
|
12
|
+
|
13
|
+
RakeCompilerDock.sh build.join(' && ')
|
14
|
+
end
|
data/tasks/package.rake
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
require_relative './recipe'
|
2
|
+
|
3
|
+
module Ports
|
4
|
+
class Freetds < Recipe
|
5
|
+
def initialize(version)
|
6
|
+
super('freetds', version)
|
7
|
+
|
8
|
+
set_patches
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def configure_defaults
|
14
|
+
opts = super
|
15
|
+
|
16
|
+
opts << '--with-pic'
|
17
|
+
opts << '--disable-odbc'
|
18
|
+
|
19
|
+
if version =~ /0\.91/
|
20
|
+
opts << '--with-tdsver=7.1'
|
21
|
+
else
|
22
|
+
opts << '--with-tdsver=7.3'
|
23
|
+
end
|
24
|
+
|
25
|
+
if windows?
|
26
|
+
opts << '--sysconfdir=C:/Sites'
|
27
|
+
opts << '--enable-sspi'
|
28
|
+
end
|
29
|
+
|
30
|
+
opts
|
31
|
+
end
|
32
|
+
|
33
|
+
def set_patches
|
34
|
+
self.patch_files.concat get_patches(name, version)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require_relative './recipe'
|
2
|
+
|
3
|
+
module Ports
|
4
|
+
class Libiconv < Recipe
|
5
|
+
def initialize(version)
|
6
|
+
super('libiconv', version)
|
7
|
+
|
8
|
+
set_patches
|
9
|
+
end
|
10
|
+
|
11
|
+
def cook
|
12
|
+
chdir_for_build do
|
13
|
+
super
|
14
|
+
end
|
15
|
+
self
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# When using rake-compiler-dock on Windows, the underlying Virtualbox shared
|
21
|
+
# folders don't support symlinks, but libiconv expects it for a build on
|
22
|
+
# Linux. We work around this limitation by using the temp dir for cooking.
|
23
|
+
def chdir_for_build
|
24
|
+
build_dir = ENV['RCD_HOST_RUBY_PLATFORM'].to_s =~ /mingw|mswin|cygwin/ ? '/tmp' : '.'
|
25
|
+
Dir.chdir(build_dir) do
|
26
|
+
yield
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def configure_defaults
|
31
|
+
[
|
32
|
+
"--host=#{@host}",
|
33
|
+
'--disable-static',
|
34
|
+
'--enable-shared',
|
35
|
+
'CFLAGS=-fPIC -O2'
|
36
|
+
]
|
37
|
+
end
|
38
|
+
|
39
|
+
def set_patches
|
40
|
+
self.patch_files.concat get_patches(name, version)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require_relative './recipe'
|
2
|
+
|
3
|
+
module Ports
|
4
|
+
class Openssl < Recipe
|
5
|
+
def initialize(version)
|
6
|
+
super('openssl', version)
|
7
|
+
|
8
|
+
set_patches
|
9
|
+
end
|
10
|
+
|
11
|
+
def configure
|
12
|
+
return if configured?
|
13
|
+
|
14
|
+
md5_file = File.join(tmp_path, 'configure.md5')
|
15
|
+
digest = Digest::MD5.hexdigest(computed_options.to_s)
|
16
|
+
File.open(md5_file, "w") { |f| f.write digest }
|
17
|
+
|
18
|
+
# Windows doesn't recognize the shebang so always explicitly use sh
|
19
|
+
execute('configure', "sh -c \"./Configure #{computed_options.join(' ')}\"")
|
20
|
+
end
|
21
|
+
|
22
|
+
def install
|
23
|
+
unless installed?
|
24
|
+
execute('install', %Q(#{make_cmd} install_sw install_ssldirs))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def execute(action, command, options={})
|
31
|
+
# OpenSSL Requires Perl >= 5.10, while the Ruby devkit uses MSYS1 with Perl 5.8.8.
|
32
|
+
# To overcome this, prepend Git's usr/bin to the PATH.
|
33
|
+
# It has MSYS2 with a recent version of perl.
|
34
|
+
prev_path = ENV['PATH']
|
35
|
+
if host =~ /mingw/ && IO.popen(["perl", "-e", "print($])"], &:read).to_f < 5.010
|
36
|
+
git_perl = 'C:/Program Files/Git/usr/bin'
|
37
|
+
if File.directory?(git_perl)
|
38
|
+
ENV['PATH'] = "#{git_perl}#{File::PATH_SEPARATOR}#{ENV['PATH']}"
|
39
|
+
ENV['PERL'] = 'perl'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
super
|
44
|
+
ENV['PATH'] = prev_path
|
45
|
+
end
|
46
|
+
|
47
|
+
def configure_defaults
|
48
|
+
opts = [
|
49
|
+
'shared',
|
50
|
+
target_arch
|
51
|
+
]
|
52
|
+
|
53
|
+
if cross_build?
|
54
|
+
opts << "--cross-compile-prefix=#{host}-"
|
55
|
+
end
|
56
|
+
|
57
|
+
opts
|
58
|
+
end
|
59
|
+
|
60
|
+
def target_arch
|
61
|
+
if windows?
|
62
|
+
arch = ''
|
63
|
+
arch = '64' if host=~ /x86_64/
|
64
|
+
|
65
|
+
"mingw#{arch}"
|
66
|
+
else
|
67
|
+
arch = 'x32'
|
68
|
+
arch = 'x86_64' if host=~ /x86_64/
|
69
|
+
|
70
|
+
"linux-#{arch}"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def set_patches
|
75
|
+
self.patch_files.concat get_patches(name, version)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require 'mini_portile2'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'rbconfig'
|
5
|
+
|
6
|
+
module Ports
|
7
|
+
class Recipe < MiniPortile
|
8
|
+
def cook
|
9
|
+
checkpoint = "ports/#{name}-#{version}-#{host}.installed"
|
10
|
+
|
11
|
+
unless File.exist? checkpoint
|
12
|
+
super
|
13
|
+
FileUtils.touch checkpoint
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def configure_defaults
|
20
|
+
[
|
21
|
+
"--host=#{@host}",
|
22
|
+
'--disable-static',
|
23
|
+
'--enable-shared'
|
24
|
+
]
|
25
|
+
end
|
26
|
+
|
27
|
+
def windows?
|
28
|
+
host =~ /mswin|mingw32/
|
29
|
+
end
|
30
|
+
|
31
|
+
def system_host
|
32
|
+
RbConfig::CONFIG['host']
|
33
|
+
end
|
34
|
+
|
35
|
+
def cross_build?
|
36
|
+
host != system_host
|
37
|
+
end
|
38
|
+
|
39
|
+
def get_patches(libname, version)
|
40
|
+
patches = []
|
41
|
+
|
42
|
+
patch_path = File.expand_path(
|
43
|
+
File.join('..','..','..','patches',libname,version),
|
44
|
+
__FILE__
|
45
|
+
)
|
46
|
+
|
47
|
+
patches.concat(Dir[File.join(patch_path, '*.patch')].sort)
|
48
|
+
patches.concat(Dir[File.join(patch_path, '*.diff')].sort)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|