vm_tiny_tds 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +20 -0
  3. data/.gitattributes +1 -0
  4. data/.gitignore +20 -0
  5. data/.rubocop.yml +31 -0
  6. data/.travis.yml +24 -0
  7. data/BACKERS.md +32 -0
  8. data/CHANGELOG.md +255 -0
  9. data/CODE_OF_CONDUCT.md +31 -0
  10. data/Gemfile +9 -0
  11. data/ISSUE_TEMPLATE.md +38 -0
  12. data/MIT-LICENSE +23 -0
  13. data/README.md +504 -0
  14. data/Rakefile +53 -0
  15. data/VERSION +1 -0
  16. data/appveyor.yml +51 -0
  17. data/bin/defncopy-ttds +3 -0
  18. data/bin/tsql-ttds +3 -0
  19. data/exe/.keep +0 -0
  20. data/ext/tiny_tds/client.c +451 -0
  21. data/ext/tiny_tds/client.h +51 -0
  22. data/ext/tiny_tds/extconf.rb +69 -0
  23. data/ext/tiny_tds/extconsts.rb +15 -0
  24. data/ext/tiny_tds/result.c +619 -0
  25. data/ext/tiny_tds/result.h +32 -0
  26. data/ext/tiny_tds/tiny_tds_ext.c +12 -0
  27. data/ext/tiny_tds/tiny_tds_ext.h +17 -0
  28. data/lib/tiny_tds/bin.rb +104 -0
  29. data/lib/tiny_tds/client.rb +136 -0
  30. data/lib/tiny_tds/error.rb +14 -0
  31. data/lib/tiny_tds/gem.rb +32 -0
  32. data/lib/tiny_tds/result.rb +7 -0
  33. data/lib/tiny_tds/version.rb +3 -0
  34. data/lib/tiny_tds.rb +61 -0
  35. data/patches/freetds/1.00.27/0001-mingw_missing_inet_pton.diff +34 -0
  36. data/patches/freetds/1.00.27/0002-Don-t-use-MSYS2-file-libws2_32.diff +28 -0
  37. data/patches/libiconv/1.14/1-avoid-gets-error.patch +17 -0
  38. data/tasks/native_gem.rake +14 -0
  39. data/tasks/package.rake +8 -0
  40. data/tasks/ports/freetds.rb +37 -0
  41. data/tasks/ports/libiconv.rb +43 -0
  42. data/tasks/ports/openssl.rb +78 -0
  43. data/tasks/ports/recipe.rb +52 -0
  44. data/tasks/ports.rake +87 -0
  45. data/tasks/test.rake +9 -0
  46. data/test/appveyor/dbsetup.ps1 +27 -0
  47. data/test/appveyor/dbsetup.sql +9 -0
  48. data/test/benchmark/query.rb +77 -0
  49. data/test/benchmark/query_odbc.rb +106 -0
  50. data/test/benchmark/query_tinytds.rb +126 -0
  51. data/test/bin/install-freetds.sh +20 -0
  52. data/test/bin/install-openssl.sh +18 -0
  53. data/test/bin/setup.sh +19 -0
  54. data/test/client_test.rb +230 -0
  55. data/test/gem_test.rb +179 -0
  56. data/test/result_test.rb +773 -0
  57. data/test/schema/1px.gif +0 -0
  58. data/test/schema/sqlserver_2000.sql +140 -0
  59. data/test/schema/sqlserver_2005.sql +140 -0
  60. data/test/schema/sqlserver_2008.sql +140 -0
  61. data/test/schema/sqlserver_2014.sql +140 -0
  62. data/test/schema/sqlserver_2016.sql +140 -0
  63. data/test/schema/sqlserver_azure.sql +140 -0
  64. data/test/schema/sybase_ase.sql +138 -0
  65. data/test/schema_test.rb +443 -0
  66. data/test/test_helper.rb +217 -0
  67. data/test/thread_test.rb +98 -0
  68. data/tiny_tds.gemspec +29 -0
  69. metadata +225 -0
@@ -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
@@ -0,0 +1,14 @@
1
+ module TinyTds
2
+ class Error < StandardError
3
+
4
+ attr_accessor :source, :severity, :db_error_number, :os_error_number
5
+
6
+ def initialize(message)
7
+ super
8
+ @severity = nil
9
+ @db_error_number = nil
10
+ @os_error_number = nil
11
+ end
12
+
13
+ end
14
+ end
@@ -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
@@ -0,0 +1,7 @@
1
+ module TinyTds
2
+ class Result
3
+
4
+ include Enumerable
5
+
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module TinyTds
2
+ VERSION = File.read(File.expand_path('../../../VERSION', __FILE__)).chomp
3
+ 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
@@ -0,0 +1,8 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems/package_task'
3
+
4
+ Gem::PackageTask.new(SPEC) do |pkg|
5
+ pkg.need_tar = false
6
+ pkg.need_zip = false
7
+ end
8
+
@@ -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
+