re2 1.7.0 → 2.0.0.beta2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddba6fe8bb8c7e51bcb0b8f4346b39ca903978ff6697a4c14d06702baae10598
4
- data.tar.gz: f8905eeeeff7e4bebc532d23fa19b29f1c3e2a88ea303a5aa879bafb4af4e1ed
3
+ metadata.gz: b84cf6ec8ce5bd9800f96ec578e998e4b8ca5345c1c96eaa699d0a0eebb03e2c
4
+ data.tar.gz: c7e89da8456e80c91f287ee444cf69daad53af97cd604e44e3cdf685f8af34f8
5
5
  SHA512:
6
- metadata.gz: 44184ad41a55746903fcd350fbf473d26266c710e324eaac879b46ff45e3b77120d5100a25f5188e2d938cafbc48caf909506d79cf07c31522ccfb9e789c2ce0
7
- data.tar.gz: eb282abd472e00ebcbb10e38f84c62bbac785bd139c69140647a29a157475600b6845472edb41ed42234caf5729188052cc1459b1ac2775c544ed0e905c6039d
6
+ metadata.gz: 9b018c0bbf42935fc86828b478dc85c4ff3e14ee89a5c27d2fb77ac120bcd1ad65b9277d9a53e031260710669ccd65d508018f70a78ad8a871ee1c21f65c2360
7
+ data.tar.gz: ff2832314da390eab285d44739b01ddfbc35ec4de635284d7886ead84b914b0b4d30dc4c80d50cf4e9cdfb91b3813a239e8206405bd5b12df496ce8b7ec92b25
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem "rake", "> 12.3.2"
data/README.md CHANGED
@@ -4,17 +4,33 @@ re2 [![Build Status](https://github.com/mudge/re2/actions/workflows/tests.yml/ba
4
4
  A Ruby binding to [re2][], an "efficient, principled regular expression
5
5
  library".
6
6
 
7
- **Current version:** 1.7.0
8
- **Supported Ruby versions:** 1.8.7, 1.9.3, 2.0, 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 3.0, 3.1, 3.2
7
+ **Current version:** 2.0.0.beta1
8
+ **Supported Ruby versions:** 2.7, 3.0, 3.1, 3.2
9
+ **Bundled re2 version:** libre2.11 (2023-09-01)
9
10
  **Supported re2 versions:** libre2.0 (< 2020-03-02), libre2.1 (2020-03-02), libre2.6 (2020-03-03), libre2.7 (2020-05-01), libre2.8 (2020-07-06), libre2.9 (2020-11-01), libre2.10 (2022-12-01), libre2.11 (2023-07-01)
10
11
 
11
12
  Installation
12
13
  ------------
13
14
 
14
- You will need [re2][] installed as well as a C++ compiler such as [gcc][] (on
15
- Debian and Ubuntu, this is provided by the [build-essential][] package). If
16
- you are using Mac OS X, I recommend installing re2 with [Homebrew][] by
17
- running the following:
15
+ The gem comes bundled with a version of [re2][] and will compile itself (and
16
+ any dependencies) on install. As compilation can take a while, precompiled
17
+ native gems are available for Linux, Windows and macOS.
18
+
19
+ In v2.0 and later, precompiled native gems are available for Ruby 2.7 to 3.2
20
+ on these platforms:
21
+
22
+ - `aarch64-linux` (requires: glibc >= 2.29)
23
+ - `arm-linux` (requires: glibc >= 2.29)
24
+ - `arm64-darwin`
25
+ - `x64-mingw32` / `x64-mingw-ucrt`
26
+ - `x86-linux` (requires: glibc >= 2.17)
27
+ - `x86_64-darwin`
28
+ - `x86_64-linux` (requires: glibc >= 2.17)
29
+
30
+ If you wish to opt out of using the bundled libraries, you will need re2
31
+ installed as well as a C++ compiler such as [gcc][] (on Debian and Ubuntu, this
32
+ is provided by the [build-essential][] package). If you are using Mac OS X, I
33
+ recommend installing re2 with [Homebrew][] by running the following:
18
34
 
19
35
  $ brew install re2
20
36
 
@@ -22,20 +38,26 @@ If you are using Debian, you can install the [libre2-dev][] package like so:
22
38
 
23
39
  $ sudo apt-get install libre2-dev
24
40
 
25
- Recent versions of re2 require a compiler with C++14 support such as [clang](http://clang.llvm.org/) 3.4 or [gcc](https://gcc.gnu.org/) 5.
41
+ Recent versions of re2 require a compiler with C++14 support such as
42
+ [clang](http://clang.llvm.org/) 3.4 or [gcc](https://gcc.gnu.org/) 5.
26
43
 
27
44
  If you are using a packaged Ruby distribution, make sure you also have the
28
45
  Ruby header files installed such as those provided by the [ruby-dev][] package
29
46
  on Debian and Ubuntu.
30
47
 
31
- You can then install the library via RubyGems with `gem install re2` or `gem
32
- install re2 -- --with-re2-dir=/path/to/re2/prefix` if re2 is not installed in
33
- any of the following default locations:
48
+ You can then install the library via RubyGems with `gem install re2 --platform=ruby --
49
+ --enable-system-libraries` or `gem install re2 --platform=ruby -- --enable-system-libraries
50
+ --with-re2-dir=/path/to/re2/prefix` if re2 is not installed in any of the
51
+ following default locations:
34
52
 
35
53
  * `/usr/local`
36
54
  * `/opt/homebrew`
37
55
  * `/usr`
38
56
 
57
+ If you're using Bundler, you can use the
58
+ [`force_ruby_platform`](https://bundler.io/v2.3/man/gemfile.5.html#FORCE_RUBY_PLATFORM)
59
+ option in your Gemfile.
60
+
39
61
  Documentation
40
62
  -------------
41
63
 
@@ -214,7 +236,7 @@ Contributions
214
236
  * Thanks to [Jason Woods](https://github.com/driskell) who contributed the
215
237
  original implementations of `RE2::MatchData#begin` and `RE2::MatchData#end`;
216
238
  * Thanks to [Stefano Rivera](https://github.com/stefanor) who first contributed C++11 support;
217
- * Thanks to [Stan Hu](https://github.com/stanhu) for reporting a bug with empty patterns and `RE2::Regexp#scan` and for contributing support for libre2.11 (2023-07-01);
239
+ * Thanks to [Stan Hu](https://github.com/stanhu) for reporting a bug with empty patterns and `RE2::Regexp#scan`, contributing support for libre2.11 (2023-07-01) and for vendoring re2 and abseil and compiling native gems in 2.0;
218
240
  * Thanks to [Sebastian Reitenbach](https://github.com/buzzdeee) for reporting
219
241
  the deprecation and removal of the `utf8` encoding option in re2;
220
242
  * Thanks to [Sergio Medina](https://github.com/serch) for reporting a bug when
data/Rakefile CHANGED
@@ -1,10 +1,132 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rake/extensiontask'
2
4
  require 'rspec/core/rake_task'
5
+ require 'rake_compiler_dock'
6
+ require 'yaml'
7
+
8
+ require_relative 'ext/re2/recipes'
9
+
10
+ CLEAN.include FileList['**/*{.o,.so,.dylib,.bundle}'],
11
+ FileList['**/extconf.h'],
12
+ FileList['**/Makefile'],
13
+ FileList['pkg/']
14
+
15
+ CLOBBER.include FileList['**/tmp'],
16
+ FileList['**/*.log'],
17
+ FileList['doc/**'],
18
+ FileList['tmp/']
19
+ CLOBBER.add("ports/*").exclude(%r{ports/archives$})
20
+
21
+ RE2_GEM_SPEC = Gem::Specification.load('re2.gemspec')
22
+
23
+ task :prepare do
24
+ puts "Preparing project for gem building..."
25
+ recipes = load_recipes
26
+ recipes.each { |recipe| recipe.download }
27
+ end
3
28
 
4
- Rake::ExtensionTask.new('re2')
29
+ task gem: :prepare
30
+
31
+ Gem::PackageTask.new(RE2_GEM_SPEC) do |p|
32
+ p.need_zip = false
33
+ p.need_tar = false
34
+ end
35
+
36
+ CROSS_RUBY_VERSIONS = %w[3.2.0 3.1.0 3.0.0 2.7.0 2.6.0].join(':')
37
+ CROSS_RUBY_PLATFORMS = %w[
38
+ aarch64-linux
39
+ arm-linux
40
+ arm64-darwin
41
+ x64-mingw-ucrt
42
+ x64-mingw32
43
+ x86-linux
44
+ x86-mingw32
45
+ x86_64-darwin
46
+ x86_64-linux
47
+ ].freeze
48
+
49
+ ENV['RUBY_CC_VERSION'] = CROSS_RUBY_VERSIONS
50
+
51
+ Rake::ExtensionTask.new('re2', RE2_GEM_SPEC) do |e|
52
+ e.cross_compile = true
53
+ e.cross_config_options << '--enable-cross-build'
54
+ e.config_options << '--disable-system-libraries'
55
+ e.cross_platform = CROSS_RUBY_PLATFORMS
56
+ e.cross_compiling do |spec|
57
+ spec.files.reject! { |path| File.fnmatch?('ports/*', path) }
58
+ spec.dependencies.reject! { |dep| dep.name == 'mini_portile2' }
59
+ end
60
+ end
5
61
 
6
62
  RSpec::Core::RakeTask.new(:spec)
7
63
 
8
- task :spec => :compile
9
- task :default => :spec
64
+ namespace 'gem' do
65
+ def gem_builder(platform)
66
+ # use Task#invoke because the pkg/*gem task is defined at runtime
67
+ Rake::Task["native:#{platform}"].invoke
68
+ Rake::Task["pkg/#{RE2_GEM_SPEC.full_name}-#{Gem::Platform.new(platform)}.gem"].invoke
69
+ end
70
+
71
+ CROSS_RUBY_PLATFORMS.each do |platform|
72
+ # The Linux x86 image (ghcr.io/rake-compiler/rake-compiler-dock-image:1.3.0-mri-x86_64-linux)
73
+ # is based on CentOS 7 and has two versions of cmake installed:
74
+ # a 2.8 version in /usr/bin and a 3.25 in /usr/local/bin. The latter is needed by abseil.
75
+ cmake =
76
+ case platform
77
+ when 'x86_64-linux', 'x86-linux'
78
+ '/usr/local/bin/cmake'
79
+ else
80
+ 'cmake'
81
+ end
82
+
83
+ desc "build native gem for #{platform} platform"
84
+ task platform do
85
+ RakeCompilerDock.sh <<~SCRIPT, platform: platform, verbose: true
86
+ gem install bundler --no-document &&
87
+ bundle &&
88
+ bundle exec rake gem:#{platform}:builder CMAKE=#{cmake}
89
+ SCRIPT
90
+ end
91
+
92
+ namespace platform do
93
+ desc "build native gem for #{platform} platform (guest container)"
94
+ task 'builder' do
95
+ gem_builder(platform)
96
+ end
97
+ end
98
+ end
99
+
100
+ desc 'build all native gems'
101
+ multitask 'native' => CROSS_RUBY_PLATFORMS
102
+ end
103
+
104
+ def add_file_to_gem(relative_source_path)
105
+ dest_path = File.join(gem_build_path, relative_source_path)
106
+ dest_dir = File.dirname(dest_path)
107
+
108
+ mkdir_p dest_dir unless Dir.exist?(dest_dir)
109
+ rm_f dest_path if File.exist?(dest_path)
110
+ safe_ln relative_source_path, dest_path
111
+
112
+ RE2_GEM_SPEC.files << relative_source_path
113
+ end
114
+
115
+ def gem_build_path
116
+ File.join 'pkg', RE2_GEM_SPEC.full_name
117
+ end
118
+
119
+ def add_vendored_libraries
120
+ dependencies = YAML.load_file(File.join(File.dirname(__FILE__), 'dependencies.yml'))
121
+ abseil_archive = File.join('ports', 'archives', "#{dependencies['abseil']['version']}.tar.gz")
122
+ libre2_archive = File.join('ports', 'archives', "re2-#{dependencies['libre2']['version']}.tar.gz")
123
+
124
+ add_file_to_gem(abseil_archive)
125
+ add_file_to_gem(libre2_archive)
126
+ end
127
+
128
+ task gem_build_path do
129
+ add_vendored_libraries
130
+ end
10
131
 
132
+ task default: [:compile, :spec]
data/dependencies.yml ADDED
@@ -0,0 +1,9 @@
1
+ libre2:
2
+ version: "2023-09-01"
3
+ sha256: "5bb6875ae1cd1e9fedde98018c346db7260655f86fdb8837e3075103acd3649b"
4
+ # sha-256 hash provided in https://github.com/google/re2/releases/download/2023-09-01/re2-2023-09-01.tar.gz
5
+
6
+ abseil:
7
+ version: "20230125.3"
8
+ sha256: 5366d7e7fa7ba0d915014d387b66d0d002c03236448e1ba9ef98122c13b35c36
9
+ # sha-256 hash provided in https://github.com/abseil/abseil-cpp/archive/refs/tags/20230125.3.tar.gz
data/ext/re2/extconf.rb CHANGED
@@ -5,6 +5,107 @@
5
5
  # Released under the BSD Licence, please see LICENSE.txt
6
6
 
7
7
  require 'mkmf'
8
+ require_relative 'recipes'
9
+
10
+ RE2_HELP_MESSAGE = <<~HELP
11
+ USAGE: ruby #{$0} [options]
12
+
13
+ Flags that are always valid:
14
+
15
+ --enable-system-libraries
16
+ Use system libraries instead of building and using the packaged libraries.
17
+
18
+ --disable-system-libraries
19
+ Use the packaged libraries, and ignore the system libraries. This is the default.
20
+
21
+
22
+ Flags only used when using system libraries:
23
+
24
+ Related to re2 library:
25
+
26
+ --with-re2-dir=DIRECTORY
27
+ Look for re2 headers and library in DIRECTORY.
28
+
29
+
30
+ Flags only used when building and using the packaged libraries:
31
+
32
+ --enable-cross-build
33
+ Enable cross-build mode. (You probably do not want to set this manually.)
34
+
35
+
36
+ Environment variables used:
37
+
38
+ CC
39
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
40
+
41
+ CPPFLAGS
42
+ If this string is accepted by the C preprocessor, add it to the flags passed to the C preprocessor
43
+
44
+ CFLAGS
45
+ If this string is accepted by the compiler, add it to the flags passed to the compiler
46
+
47
+ LDFLAGS
48
+ If this string is accepted by the linker, add it to the flags passed to the linker
49
+
50
+ LIBS
51
+ Add this string to the flags passed to the linker
52
+ HELP
53
+
54
+ #
55
+ # utility functions
56
+ #
57
+ def config_system_libraries?
58
+ enable_config("system-libraries", ENV.key?('RE2_USE_SYSTEM_LIBRARIES'))
59
+ end
60
+
61
+ def config_cross_build?
62
+ enable_config("cross-build")
63
+ end
64
+
65
+ def concat_flags(*args)
66
+ args.compact.join(" ")
67
+ end
68
+
69
+ def do_help
70
+ print(RE2_HELP_MESSAGE)
71
+ exit!(0)
72
+ end
73
+
74
+ def darwin?
75
+ RbConfig::CONFIG["target_os"].include?("darwin")
76
+ end
77
+
78
+ def windows?
79
+ RbConfig::CONFIG["target_os"].match?(/mingw|mswin/)
80
+ end
81
+
82
+ def freebsd?
83
+ RbConfig::CONFIG["target_os"].include?("freebsd")
84
+ end
85
+
86
+ def target_host
87
+ # We use 'host' to set compiler prefix for cross-compiling. Prefer host_alias over host. And
88
+ # prefer i686 (what external dev tools use) to i386 (what ruby's configure.ac emits).
89
+ host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
90
+ host.gsub(/i386/, "i686")
91
+ end
92
+
93
+ def target_arch
94
+ RbConfig::CONFIG['arch']
95
+ end
96
+
97
+ def with_temp_dir
98
+ Dir.mktmpdir do |temp_dir|
99
+ Dir.chdir(temp_dir) do
100
+ yield
101
+ end
102
+ end
103
+ end
104
+
105
+ #
106
+ # main
107
+ #
108
+ do_help if arg_config('--help')
8
109
 
9
110
  if ENV["CC"]
10
111
  RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"]
@@ -16,70 +117,59 @@ if ENV["CXX"]
16
117
  RbConfig::CONFIG["CXX"] = ENV["CXX"]
17
118
  end
18
119
 
19
- header_dirs = [
20
- "/usr/local/include",
21
- "/opt/homebrew/include",
22
- "/usr/include"
23
- ]
24
-
25
- lib_dirs = [
26
- "/usr/local/lib",
27
- "/opt/homebrew/lib",
28
- "/usr/lib"
29
- ]
30
-
31
- dir_config("re2", header_dirs, lib_dirs)
120
+ def build_extension(static_p = false)
121
+ # Enable optional warnings but disable deprecated register warning for Ruby 2.6 support
122
+ $CFLAGS << " -Wall -Wextra -funroll-loops"
123
+ $CPPFLAGS << " -Wno-register"
32
124
 
33
- $CFLAGS << " -Wall -Wextra -funroll-loops"
125
+ # Pass -x c++ to force gcc to compile the test program
126
+ # as C++ (as it will end in .c by default).
127
+ compile_options = "-x c++"
34
128
 
35
- # Pass -x c++ to force gcc to compile the test program
36
- # as C++ (as it will end in .c by default).
37
- compile_options = "-x c++"
129
+ have_library("stdc++")
130
+ have_header("stdint.h")
131
+ have_func("rb_str_sublen")
38
132
 
39
- have_library("stdc++")
40
- have_header("stdint.h")
41
- have_func("rb_str_sublen")
42
-
43
- unless have_library("re2")
44
- abort "You must have re2 installed and specified with --with-re2-dir, please see https://github.com/google/re2/wiki/Install"
45
- end
133
+ if !static_p and !have_library("re2")
134
+ abort "You must have re2 installed and specified with --with-re2-dir, please see https://github.com/google/re2/wiki/Install"
135
+ end
46
136
 
47
- minimal_program = <<SRC
137
+ minimal_program = <<SRC
48
138
  #include <re2/re2.h>
49
139
  int main() { return 0; }
50
140
  SRC
51
141
 
52
- re2_requires_version_flag = checking_for("re2 that requires explicit C++ version flag") do
53
- !try_compile(minimal_program, compile_options)
54
- end
142
+ re2_requires_version_flag = checking_for("re2 that requires explicit C++ version flag") do
143
+ !try_compile(minimal_program, compile_options)
144
+ end
55
145
 
56
- if re2_requires_version_flag
57
- # Recent versions of re2 depend directly on abseil, which requires a
58
- # compiler with C++14 support (see
59
- # https://github.com/abseil/abseil-cpp/issues/1127 and
60
- # https://github.com/abseil/abseil-cpp/issues/1431). However, the
61
- # `std=c++14` flag doesn't appear to suffice; we need at least
62
- # `std=c++17`.
63
- abort "Cannot compile re2 with your compiler: recent versions require C++14 support." unless %w[c++20 c++17 c++11 c++0x].any? do |std|
64
- checking_for("re2 that compiles with #{std} standard") do
65
- if try_compile(minimal_program, compile_options + " -std=#{std}")
66
- compile_options << " -std=#{std}"
67
- $CPPFLAGS << " -std=#{std}"
146
+ if re2_requires_version_flag
147
+ # Recent versions of re2 depend directly on abseil, which requires a
148
+ # compiler with C++14 support (see
149
+ # https://github.com/abseil/abseil-cpp/issues/1127 and
150
+ # https://github.com/abseil/abseil-cpp/issues/1431). However, the
151
+ # `std=c++14` flag doesn't appear to suffice; we need at least
152
+ # `std=c++17`.
153
+ abort "Cannot compile re2 with your compiler: recent versions require C++14 support." unless %w[c++20 c++17 c++11 c++0x].any? do |std|
154
+ checking_for("re2 that compiles with #{std} standard") do
155
+ if try_compile(minimal_program, compile_options + " -std=#{std}")
156
+ compile_options << " -std=#{std}"
157
+ $CPPFLAGS << " -std=#{std}"
68
158
 
69
- true
159
+ true
160
+ end
70
161
  end
71
162
  end
72
163
  end
73
- end
74
164
 
75
- # Determine which version of re2 the user has installed.
76
- # Revision d9f8806c004d added an `endpos` argument to the
77
- # generic Match() function.
78
- #
79
- # To test for this, try to compile a simple program that uses
80
- # the newer form of Match() and set a flag if it is successful.
81
- checking_for("RE2::Match() with endpos argument") do
82
- test_re2_match_signature = <<SRC
165
+ # Determine which version of re2 the user has installed.
166
+ # Revision d9f8806c004d added an `endpos` argument to the
167
+ # generic Match() function.
168
+ #
169
+ # To test for this, try to compile a simple program that uses
170
+ # the newer form of Match() and set a flag if it is successful.
171
+ checking_for("RE2::Match() with endpos argument") do
172
+ test_re2_match_signature = <<SRC
83
173
  #include <re2/re2.h>
84
174
 
85
175
  int main() {
@@ -91,13 +181,13 @@ int main() {
91
181
  }
92
182
  SRC
93
183
 
94
- if try_compile(test_re2_match_signature, compile_options)
95
- $defs.push("-DHAVE_ENDPOS_ARGUMENT")
184
+ if try_compile(test_re2_match_signature, compile_options)
185
+ $defs.push("-DHAVE_ENDPOS_ARGUMENT")
186
+ end
96
187
  end
97
- end
98
188
 
99
- checking_for("RE2::Set::Match() with error information") do
100
- test_re2_set_match_signature = <<SRC
189
+ checking_for("RE2::Set::Match() with error information") do
190
+ test_re2_set_match_signature = <<SRC
101
191
  #include <vector>
102
192
  #include <re2/re2.h>
103
193
  #include <re2/set.h>
@@ -115,9 +205,234 @@ int main() {
115
205
  }
116
206
  SRC
117
207
 
118
- if try_compile(test_re2_set_match_signature, compile_options)
119
- $defs.push("-DHAVE_ERROR_INFO_ARGUMENT")
208
+ if try_compile(test_re2_set_match_signature, compile_options)
209
+ $defs.push("-DHAVE_ERROR_INFO_ARGUMENT")
210
+ end
120
211
  end
121
212
  end
122
213
 
214
+ def process_recipe(recipe)
215
+ cross_build_p = config_cross_build?
216
+ message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
217
+
218
+ recipe.host = target_host
219
+ # Ensure x64-mingw-ucrt and x64-mingw32 use different library paths since the host
220
+ # is the same (x86_64-w64-mingw32).
221
+ recipe.target = File.join(recipe.target, target_arch) if cross_build_p
222
+
223
+ yield recipe
224
+
225
+ checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
226
+ name = recipe.name
227
+ version = recipe.version
228
+
229
+ if File.exist?(checkpoint)
230
+ message("Building re2 with a packaged version of #{name}-#{version}.\n")
231
+ else
232
+ message(<<~EOM)
233
+ ---------- IMPORTANT NOTICE ----------
234
+ Building re2 with a packaged version of #{name}-#{version}.
235
+ Configuration options: #{recipe.configure_options.shelljoin}
236
+ EOM
237
+
238
+ unless recipe.patch_files.empty?
239
+ message("The following patches are being applied:\n")
240
+
241
+ recipe.patch_files.each do |patch|
242
+ message(" - %s\n" % File.basename(patch))
243
+ end
244
+ end
245
+
246
+ # Use a temporary base directory to reduce filename lengths since
247
+ # Windows can hit a limit of 250 characters (CMAKE_OBJECT_PATH_MAX).
248
+ with_temp_dir { recipe.cook }
249
+
250
+ FileUtils.touch(checkpoint)
251
+ end
252
+
253
+ recipe.activate
254
+ end
255
+
256
+ def build_with_system_libraries
257
+ header_dirs = [
258
+ "/usr/local/include",
259
+ "/opt/homebrew/include",
260
+ "/usr/include"
261
+ ]
262
+
263
+ lib_dirs = [
264
+ "/usr/local/lib",
265
+ "/opt/homebrew/lib",
266
+ "/usr/lib"
267
+ ]
268
+
269
+ dir_config("re2", header_dirs, lib_dirs)
270
+
271
+ build_extension
272
+ end
273
+
274
+ # pkgconf v1.9.3 on Windows incorrectly sorts the output of `pkg-config
275
+ # --libs --static`, resulting in build failures: https://github.com/pkgconf/pkgconf/issues/268.
276
+ # To work around the issue, store the correct order of abseil flags here and add them manually
277
+ # for Windows.
278
+ #
279
+ # Note that `-ldbghelp` is incorrectly added before `-labsl_symbolize` in abseil:
280
+ # https://github.com/abseil/abseil-cpp/issues/1497
281
+ ABSL_LDFLAGS = %w[
282
+ -labsl_flags
283
+ -labsl_flags_internal
284
+ -labsl_flags_marshalling
285
+ -labsl_flags_reflection
286
+ -labsl_flags_private_handle_accessor
287
+ -labsl_flags_commandlineflag
288
+ -labsl_flags_commandlineflag_internal
289
+ -labsl_flags_config
290
+ -labsl_flags_program_name
291
+ -labsl_cord
292
+ -labsl_cordz_info
293
+ -labsl_cord_internal
294
+ -labsl_cordz_functions
295
+ -labsl_cordz_handle
296
+ -labsl_crc_cord_state
297
+ -labsl_crc32c
298
+ -labsl_crc_internal
299
+ -labsl_crc_cpu_detect
300
+ -labsl_hash
301
+ -labsl_city
302
+ -labsl_bad_variant_access
303
+ -labsl_low_level_hash
304
+ -labsl_raw_hash_set
305
+ -labsl_hashtablez_sampler
306
+ -labsl_exponential_biased
307
+ -labsl_bad_optional_access
308
+ -labsl_str_format_internal
309
+ -labsl_synchronization
310
+ -labsl_graphcycles_internal
311
+ -labsl_stacktrace
312
+ -labsl_symbolize
313
+ -ldbghelp
314
+ -labsl_debugging_internal
315
+ -labsl_demangle_internal
316
+ -labsl_malloc_internal
317
+ -labsl_time
318
+ -labsl_civil_time
319
+ -labsl_strings
320
+ -labsl_strings_internal
321
+ -ladvapi32
322
+ -labsl_base
323
+ -labsl_spinlock_wait
324
+ -labsl_int128
325
+ -labsl_throw_delegate
326
+ -labsl_raw_logging_internal
327
+ -labsl_log_severity
328
+ -labsl_time_zone
329
+ ].freeze
330
+
331
+ def libflag_to_filename(ldflag)
332
+ case ldflag
333
+ when /\A-l(.+)/
334
+ "lib#{Regexp.last_match(1)}.#{$LIBEXT}"
335
+ end
336
+ end
337
+
338
+ # This method does a number of things to ensure the final shared library
339
+ # is compiled statically with the vendored libraries:
340
+ #
341
+ # 1. For -L<path> flags, ensure that any `ports` paths are prioritized just
342
+ # in case there are installed libraries that might take precedence.
343
+ # 2. For -l<lib> flags, convert the library to the static library with a
344
+ # full path and substitute the absolute static library. For example,
345
+ # -lre2 maps to /path/to/ports/<arch>/libre2/<version>/lib/libre2.a.
346
+ #
347
+ # This is needed because when building the extension, Ruby appears to
348
+ # insert `-L#{RbConfig::CONFIG['exec_prefix']}/lib` first. If libre2 is
349
+ # in installed in that location then the extension will link against the
350
+ # system library instead of the vendored library.
351
+ def add_flag(arg, lib_paths)
352
+ case arg
353
+ when /\A-L(.+)\z/
354
+ # Prioritize ports' directories
355
+ lib_dir = Regexp.last_match(1)
356
+ $LIBPATH =
357
+ if lib_dir.start_with?(PACKAGE_ROOT_DIR + "/")
358
+ [lib_dir] | $LIBPATH
359
+ else
360
+ $LIBPATH | [lib_dir]
361
+ end
362
+ when /\A-l./
363
+ filename = libflag_to_filename(arg)
364
+
365
+ added = false
366
+ lib_paths.each do |path|
367
+ static_lib = File.join(path, filename)
368
+
369
+ next unless File.exist?(static_lib)
370
+
371
+ $LDFLAGS << " " << static_lib
372
+ added = true
373
+ break
374
+ end
375
+
376
+ append_ldflags(arg.shellescape) unless added
377
+ else
378
+ append_ldflags(arg.shellescape)
379
+ end
380
+ end
381
+
382
+ def add_static_ldflags(flags, lib_paths)
383
+ static_flags = flags.strip.shellsplit
384
+
385
+ if MiniPortile.windows?
386
+ static_flags.each { |flag| add_flag(flag, lib_paths) unless ABSL_LDFLAGS.include?(flag) }
387
+ ABSL_LDFLAGS.each { |flag| add_flag(flag, lib_paths) }
388
+ else
389
+ static_flags.each { |flag| add_flag(flag, lib_paths) }
390
+ end
391
+ end
392
+
393
+ def build_with_vendored_libraries
394
+ message "Building re2 using packaged libraries.\n"
395
+
396
+ abseil_recipe, re2_recipe = load_recipes
397
+
398
+ process_recipe(abseil_recipe) do |recipe|
399
+ recipe.configure_options += ['-DABSL_PROPAGATE_CXX_STD=ON', '-DCMAKE_CXX_VISIBILITY_PRESET=hidden']
400
+ end
401
+
402
+ process_recipe(re2_recipe) do |recipe|
403
+ recipe.configure_options += ["-DCMAKE_PREFIX_PATH=#{abseil_recipe.path}", '-DCMAKE_CXX_FLAGS=-DNDEBUG',
404
+ '-DCMAKE_CXX_VISIBILITY_PRESET=hidden']
405
+ end
406
+
407
+ dir_config("re2", File.join(re2_recipe.path, 'include'), File.join(re2_recipe.path, 'lib'))
408
+ dir_config("abseil", File.join(abseil_recipe.path, 'include'), File.join(abseil_recipe.path, 'lib'))
409
+
410
+ pkg_config_paths = [
411
+ "#{abseil_recipe.path}/lib/pkgconfig",
412
+ "#{re2_recipe.path}/lib/pkgconfig"
413
+ ].join(File::PATH_SEPARATOR)
414
+
415
+ pkg_config_paths = "#{ENV['PKG_CONFIG_PATH']}#{File::PATH_SEPARATOR}#{pkg_config_paths}" if ENV['PKG_CONFIG_PATH']
416
+
417
+ ENV['PKG_CONFIG_PATH'] = pkg_config_paths
418
+ pc_file = File.join(re2_recipe.path, 'lib', 'pkgconfig', 're2.pc')
419
+
420
+ raise 'Please install the `pkg-config` utility!' unless find_executable('pkg-config')
421
+
422
+ # See https://bugs.ruby-lang.org/issues/18490, broken in Ruby 3.1 but fixed in Ruby 3.2.
423
+ flags = xpopen(['pkg-config', '--libs', '--static', pc_file], err: %i[child out], &:read)
424
+
425
+ raise 'Unable to run pkg-config --libs --static' unless $?.success?
426
+
427
+ lib_paths = [File.join(abseil_recipe.path, 'lib'), File.join(re2_recipe.path, 'lib')]
428
+ add_static_ldflags(flags, lib_paths)
429
+ build_extension(true)
430
+ end
431
+
432
+ if config_system_libraries?
433
+ build_with_system_libraries
434
+ else
435
+ build_with_vendored_libraries
436
+ end
437
+
123
438
  create_makefile("re2")
@@ -0,0 +1,43 @@
1
+ PACKAGE_ROOT_DIR = File.expand_path('../..', __dir__)
2
+ REQUIRED_MINI_PORTILE_VERSION = '~> 2.8.4' # keep this version in sync with the one in the gemspec
3
+
4
+ def build_recipe(name, version)
5
+ require 'rubygems'
6
+ gem('mini_portile2', REQUIRED_MINI_PORTILE_VERSION) # gemspec is not respected at install time
7
+ require 'mini_portile2'
8
+
9
+ MiniPortileCMake.new(name, version).tap do |recipe|
10
+ recipe.target = File.join(PACKAGE_ROOT_DIR, 'ports')
11
+ recipe.configure_options += [
12
+ # abseil needs a C++14 compiler
13
+ '-DCMAKE_CXX_STANDARD=17',
14
+ # needed for building the C extension shared library with -fPIC
15
+ '-DCMAKE_POSITION_INDEPENDENT_CODE=ON',
16
+ # ensures pkg-config and installed libraries will be in lib, not lib64
17
+ '-DCMAKE_INSTALL_LIBDIR=lib'
18
+ ]
19
+
20
+ yield recipe
21
+ end
22
+ end
23
+
24
+ def load_recipes
25
+ require 'yaml'
26
+ dependencies = YAML.load_file(File.join(PACKAGE_ROOT_DIR, 'dependencies.yml'))
27
+
28
+ abseil_recipe = build_recipe('abseil', dependencies['abseil']['version']) do |recipe|
29
+ recipe.files = [{
30
+ url: "https://github.com/abseil/abseil-cpp/archive/refs/tags/#{recipe.version}.tar.gz",
31
+ sha256: dependencies['abseil']['sha256']
32
+ }]
33
+ end
34
+
35
+ re2_recipe = build_recipe('libre2', dependencies['libre2']['version']) do |recipe|
36
+ recipe.files = [{
37
+ url: "https://github.com/google/re2/releases/download/#{recipe.version}/re2-#{recipe.version}.tar.gz",
38
+ sha256: dependencies['libre2']['sha256']
39
+ }]
40
+ end
41
+
42
+ [abseil_recipe, re2_recipe]
43
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RE2
4
+ VERSION = "2.0.0.beta2"
5
+ end
data/lib/re2.rb CHANGED
@@ -3,5 +3,12 @@
3
3
  #
4
4
  # Copyright (c) 2010-2014, Paul Mucur (http://mudge.name)
5
5
  # Released under the BSD Licence, please see LICENSE.txt
6
- require "re2.so"
6
+ begin
7
+ ::RUBY_VERSION =~ /(\d+\.\d+)/
8
+ require_relative "#{Regexp.last_match(1)}/re2.so"
9
+ rescue LoadError
10
+ require 're2.so'
11
+ end
12
+
7
13
  require "re2/scanner"
14
+ require "re2/version"
Binary file
data/re2.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ require_relative 'lib/re2/version'
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "re2"
5
+ s.summary = "Ruby bindings to re2."
6
+ s.description = 'Ruby bindings to re2, "an efficient, principled regular expression library".'
7
+ s.version = RE2::VERSION
8
+ s.authors = ["Paul Mucur", "Stan Hu"]
9
+ s.homepage = "https://github.com/mudge/re2"
10
+ s.extensions = ["ext/re2/extconf.rb"]
11
+ s.license = "BSD-3-Clause"
12
+ s.required_ruby_version = ">= 2.6.0"
13
+ s.files = [
14
+ ".rspec",
15
+ "dependencies.yml",
16
+ "ext/re2/extconf.rb",
17
+ "ext/re2/re2.cc",
18
+ "ext/re2/recipes.rb",
19
+ "Gemfile",
20
+ "lib/re2.rb",
21
+ "lib/re2/scanner.rb",
22
+ "lib/re2/string.rb",
23
+ "lib/re2/version.rb",
24
+ "LICENSE.txt",
25
+ "README.md",
26
+ "Rakefile",
27
+ "re2.gemspec"
28
+ ]
29
+ s.test_files = [
30
+ "spec/spec_helper.rb",
31
+ "spec/re2_spec.rb",
32
+ "spec/kernel_spec.rb",
33
+ "spec/re2/regexp_spec.rb",
34
+ "spec/re2/match_data_spec.rb",
35
+ "spec/re2/string_spec.rb",
36
+ "spec/re2/set_spec.rb",
37
+ "spec/re2/scanner_spec.rb"
38
+ ]
39
+ s.add_development_dependency "rake-compiler", "~> 1.2.1"
40
+ s.add_development_dependency "rake-compiler-dock", "~> 1.3.0"
41
+ s.add_development_dependency("rspec", "~> 3.2")
42
+ s.add_runtime_dependency("mini_portile2", "~> 2.8.4") # keep version in sync with extconf.rb
43
+ end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: re2
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.0
4
+ version: 2.0.0.beta2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Mucur
8
- autorequire:
8
+ - Stan Hu
9
+ autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
- date: 2023-07-04 00:00:00.000000000 Z
12
+ date: 2023-09-10 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: rake-compiler
@@ -16,14 +17,28 @@ dependencies:
16
17
  requirements:
17
18
  - - "~>"
18
19
  - !ruby/object:Gem::Version
19
- version: '0.9'
20
+ version: 1.2.1
20
21
  type: :development
21
22
  prerelease: false
22
23
  version_requirements: !ruby/object:Gem::Requirement
23
24
  requirements:
24
25
  - - "~>"
25
26
  - !ruby/object:Gem::Version
26
- version: '0.9'
27
+ version: 1.2.1
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake-compiler-dock
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - "~>"
33
+ - !ruby/object:Gem::Version
34
+ version: 1.3.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - "~>"
40
+ - !ruby/object:Gem::Version
41
+ version: 1.3.0
27
42
  - !ruby/object:Gem::Dependency
28
43
  name: rspec
29
44
  requirement: !ruby/object:Gem::Requirement
@@ -38,21 +53,43 @@ dependencies:
38
53
  - - "~>"
39
54
  - !ruby/object:Gem::Version
40
55
  version: '3.2'
56
+ - !ruby/object:Gem::Dependency
57
+ name: mini_portile2
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - "~>"
61
+ - !ruby/object:Gem::Version
62
+ version: 2.8.4
63
+ type: :runtime
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - "~>"
68
+ - !ruby/object:Gem::Version
69
+ version: 2.8.4
41
70
  description: Ruby bindings to re2, "an efficient, principled regular expression library".
42
- email:
71
+ email:
43
72
  executables: []
44
73
  extensions:
45
74
  - ext/re2/extconf.rb
46
75
  extra_rdoc_files: []
47
76
  files:
77
+ - ".rspec"
78
+ - Gemfile
48
79
  - LICENSE.txt
49
80
  - README.md
50
81
  - Rakefile
82
+ - dependencies.yml
51
83
  - ext/re2/extconf.rb
52
84
  - ext/re2/re2.cc
85
+ - ext/re2/recipes.rb
53
86
  - lib/re2.rb
54
87
  - lib/re2/scanner.rb
55
88
  - lib/re2/string.rb
89
+ - lib/re2/version.rb
90
+ - ports/archives/20230125.3.tar.gz
91
+ - ports/archives/re2-2023-09-01.tar.gz
92
+ - re2.gemspec
56
93
  - spec/kernel_spec.rb
57
94
  - spec/re2/match_data_spec.rb
58
95
  - spec/re2/regexp_spec.rb
@@ -65,7 +102,7 @@ homepage: https://github.com/mudge/re2
65
102
  licenses:
66
103
  - BSD-3-Clause
67
104
  metadata: {}
68
- post_install_message:
105
+ post_install_message:
69
106
  rdoc_options: []
70
107
  require_paths:
71
108
  - lib
@@ -73,15 +110,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
73
110
  requirements:
74
111
  - - ">="
75
112
  - !ruby/object:Gem::Version
76
- version: '0'
113
+ version: 2.6.0
77
114
  required_rubygems_version: !ruby/object:Gem::Requirement
78
115
  requirements:
79
- - - ">="
116
+ - - ">"
80
117
  - !ruby/object:Gem::Version
81
- version: '0'
118
+ version: 1.3.1
82
119
  requirements: []
83
120
  rubygems_version: 3.4.10
84
- signing_key:
121
+ signing_key:
85
122
  specification_version: 4
86
123
  summary: Ruby bindings to re2.
87
124
  test_files: