re2 2.9.0 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be3eb546350524548db3855e8e75c4941805cfd6a27fdec30c39f6bbcdcdca04
4
- data.tar.gz: 7b824cce1ca6731957f9bd066b79fc5fc63afb8c7bdefad29c75a7c41ed9ca2f
3
+ metadata.gz: 00a9fc0559c895d3f37b2059a3ba7bf60b9966e11c6bcba0aec763bb132485cd
4
+ data.tar.gz: c9d9dcdb79d15582216225715eeb4ad73fb45288b4756a88dfdcde60e598af32
5
5
  SHA512:
6
- metadata.gz: c324a2506c302709dd302013cf205630e0b4df5322d1ee3342c7e609cb6a1ed1c405a7ad7f1ee185dc0990d796f979d4d38e22ae35a3dc6c0e08bf984800bc0a
7
- data.tar.gz: 7466a5c1d97c8a4b4247dc30e8691cea0c409fde8ae2196858f59ed1d12f6019fc04ae6f9c25b6e35b2f39d8d03e070e2d960fc36327c04038274cc9dae66d9e
6
+ metadata.gz: f227266a1b165c5d6097658150897fd62b8d315bc231671ad86a971b7f47d5662344585deb9b7d248a2c40202d76554cd5a34e285a01d68bf542dd923f39fc0a
7
+ data.tar.gz: ce4b9e4f33b1818015587f260899acfa5928e54ca09a365ccde316867259cf6c95df6e37cf7d3543b0a9f8418da62e2619ca84bfe5f990bb599bc31d34e9aa2f
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source "https://rubygems.org"
2
4
 
3
5
  gemspec
data/README.md CHANGED
@@ -6,8 +6,8 @@ Python".
6
6
 
7
7
  [![Build Status](https://github.com/mudge/re2/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/mudge/re2/actions)
8
8
 
9
- **Current version:** 2.9.0
10
- **Bundled RE2 version:** libre2.11 (2024-03-01)
9
+ **Current version:** 2.10.0
10
+ **Bundled RE2 version:** libre2.11 (2024-04-01)
11
11
 
12
12
  ```ruby
13
13
  RE2('h.*o').full_match?("hello") #=> true
@@ -261,7 +261,7 @@ This gem requires the following to run:
261
261
 
262
262
  It supports the following RE2 ABI versions:
263
263
 
264
- * libre2.0 (prior to release 2020-03-02) to libre2.11 (2023-07-01 to 2024-03-01)
264
+ * libre2.0 (prior to release 2020-03-02) to libre2.11 (2023-07-01 to 2024-04-01)
265
265
 
266
266
  ### Native gems
267
267
 
@@ -279,18 +279,18 @@ Where possible, a pre-compiled native gem will be provided for the following pla
279
279
  SHA256 checksums are included in the [release notes](https://github.com/mudge/re2/releases) for each version and can be checked with `sha256sum`, e.g.
280
280
 
281
281
  ```console
282
- $ gem fetch re2 -v 2.8.0
283
- Fetching re2-2.8.0-arm64-darwin.gem
284
- Downloaded re2-2.8.0-arm64-darwin
285
- $ sha256sum re2-2.8.0-arm64-darwin.gem
286
- 962bad5c8de0757b059eff8922c3de31830a6710c418a83f2eab2b8253b8a0bf re2-2.8.0-arm64-darwin.gem
282
+ $ gem fetch re2 -v 2.9.0
283
+ Fetching re2-2.9.0-arm64-darwin.gem
284
+ Downloaded re2-2.9.0-arm64-darwin
285
+ $ sha256sum re2-2.9.0-arm64-darwin.gem
286
+ 91dcc103257d7abb0ee832d673267cee48be7194883fed502b1407d2779c3499 re2-2.9.0-arm64-darwin.gem
287
287
  ```
288
288
 
289
289
  [GPG](https://www.gnupg.org/) signatures are attached to each release (the assets ending in `.sig`) and can be verified if you import [our signing key `0x39AC3530070E0F75`](https://mudge.name/39AC3530070E0F75.asc) (or fetch it from a public keyserver, e.g. `gpg --keyserver keyserver.ubuntu.com --recv-key 0x39AC3530070E0F75`):
290
290
 
291
291
  ```console
292
- $ gpg --verify re2-2.8.0-arm64-darwin.gem.sig re2-2.8.0-arm64-darwin.gem
293
- gpg: Signature made Wed 31 Jan 15:02:06 2024 GMT
292
+ $ gpg --verify re2-2.9.0-arm64-darwin.gem.sig re2-2.9.0-arm64-darwin.gem
293
+ gpg: Signature made Thu 29 Feb 14:00:55 2024 GMT
294
294
  gpg: using RSA key 702609D9C790F45B577D7BEC39AC3530070E0F75
295
295
  gpg: Good signature from "Paul Mucur <mudge@mudge.name>" [unknown]
296
296
  gpg: aka "Paul Mucur <paul@ghostcassette.com>" [unknown]
data/dependencies.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  libre2:
3
- version: '2024-03-01'
4
- sha256: 7b2b3aa8241eac25f674e5b5b2e23d4ac4f0a8891418a2661869f736f03f57f4
3
+ version: '2024-04-01'
4
+ sha256: 3f6690c3393a613c3a0b566309cf04dc381d61470079b653afc47c67fb898198
5
5
  abseil:
6
6
  version: '20240116.1'
7
7
  sha256: 3c743204df78366ad2eaf236d6631d83f6bc928d1705dd0000b872e53b73dc6a
data/ext/re2/extconf.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # re2 (https://github.com/mudge/re2)
2
4
  # Ruby bindings to RE2, a "fast, safe, thread-friendly alternative to
3
5
  # backtracking regular expression engines like those used in PCRE, Perl, and
@@ -9,370 +11,324 @@
9
11
  require 'mkmf'
10
12
  require_relative 'recipes'
11
13
 
12
- RE2_HELP_MESSAGE = <<~HELP
13
- USAGE: ruby #{$0} [options]
14
+ module RE2
15
+ class Extconf
16
+ def configure
17
+ configure_cross_compiler
14
18
 
15
- Flags that are always valid:
19
+ if config_system_libraries?
20
+ build_with_system_libraries
21
+ else
22
+ build_with_vendored_libraries
23
+ end
16
24
 
17
- --enable-system-libraries
18
- Use system libraries instead of building and using the packaged libraries.
25
+ build_extension
19
26
 
20
- --disable-system-libraries
21
- Use the packaged libraries, and ignore the system libraries. This is the default.
27
+ create_makefile("re2")
28
+ end
22
29
 
30
+ def print_help
31
+ print(<<~TEXT)
32
+ USAGE: ruby #{$0} [options]
23
33
 
24
- Flags only used when using system libraries:
34
+ Flags that are always valid:
25
35
 
26
- Related to re2 library:
36
+ --enable-system-libraries
37
+ Use system libraries instead of building and using the packaged libraries.
27
38
 
28
- --with-re2-dir=DIRECTORY
29
- Look for re2 headers and library in DIRECTORY.
39
+ --disable-system-libraries
40
+ Use the packaged libraries, and ignore the system libraries. This is the default.
30
41
 
31
42
 
32
- Flags only used when building and using the packaged libraries:
43
+ Flags only used when using system libraries:
33
44
 
34
- --enable-cross-build
35
- Enable cross-build mode. (You probably do not want to set this manually.)
45
+ Related to re2 library:
36
46
 
47
+ --with-re2-dir=DIRECTORY
48
+ Look for re2 headers and library in DIRECTORY.
37
49
 
38
- Environment variables used:
39
50
 
40
- CC
41
- Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
51
+ Flags only used when building and using the packaged libraries:
42
52
 
43
- CPPFLAGS
44
- If this string is accepted by the C preprocessor, add it to the flags passed to the C preprocessor
53
+ --enable-cross-build
54
+ Enable cross-build mode. (You probably do not want to set this manually.)
45
55
 
46
- CFLAGS
47
- If this string is accepted by the compiler, add it to the flags passed to the compiler
48
56
 
49
- LDFLAGS
50
- If this string is accepted by the linker, add it to the flags passed to the linker
57
+ Environment variables used:
51
58
 
52
- LIBS
53
- Add this string to the flags passed to the linker
54
- HELP
59
+ CC
60
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
55
61
 
56
- #
57
- # utility functions
58
- #
59
- def config_system_libraries?
60
- enable_config("system-libraries", ENV.key?('RE2_USE_SYSTEM_LIBRARIES'))
61
- end
62
+ CPPFLAGS
63
+ If this string is accepted by the C preprocessor, add it to the flags passed to the C preprocessor
62
64
 
63
- def config_cross_build?
64
- enable_config("cross-build")
65
- end
65
+ CFLAGS
66
+ If this string is accepted by the compiler, add it to the flags passed to the compiler
66
67
 
67
- def concat_flags(*args)
68
- args.compact.join(" ")
69
- end
68
+ LDFLAGS
69
+ If this string is accepted by the linker, add it to the flags passed to the linker
70
70
 
71
- def do_help
72
- print(RE2_HELP_MESSAGE)
73
- exit!(0)
74
- end
71
+ LIBS
72
+ Add this string to the flags passed to the linker
73
+ TEXT
74
+ end
75
75
 
76
- def darwin?
77
- RbConfig::CONFIG["target_os"].include?("darwin")
78
- end
76
+ private
79
77
 
80
- def windows?
81
- RbConfig::CONFIG["target_os"].match?(/mingw|mswin/)
82
- end
78
+ def configure_cross_compiler
79
+ RbConfig::CONFIG["CC"] = RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"] if ENV["CC"]
80
+ RbConfig::CONFIG["CXX"] = RbConfig::MAKEFILE_CONFIG["CXX"] = ENV["CXX"] if ENV["CXX"]
81
+ end
83
82
 
84
- def freebsd?
85
- RbConfig::CONFIG["target_os"].include?("freebsd")
86
- end
83
+ def build_with_system_libraries
84
+ header_dirs = [
85
+ "/usr/local/include",
86
+ "/opt/homebrew/include",
87
+ "/usr/include"
88
+ ]
87
89
 
88
- def target_host
89
- # We use 'host' to set compiler prefix for cross-compiling. Prefer host_alias over host. And
90
- # prefer i686 (what external dev tools use) to i386 (what ruby's configure.ac emits).
91
- host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
92
- host.gsub(/i386/, "i686")
93
- end
90
+ lib_dirs = [
91
+ "/usr/local/lib",
92
+ "/opt/homebrew/lib",
93
+ "/usr/lib"
94
+ ]
94
95
 
95
- def target_arch
96
- RbConfig::CONFIG['arch']
97
- end
96
+ dir_config("re2", header_dirs, lib_dirs)
98
97
 
99
- def with_temp_dir
100
- Dir.mktmpdir do |temp_dir|
101
- Dir.chdir(temp_dir) do
102
- yield
98
+ unless have_library("re2")
99
+ abort "You must have re2 installed and specified with --with-re2-dir, please see https://github.com/google/re2/wiki/Install"
100
+ end
103
101
  end
104
- end
105
- end
106
102
 
107
- #
108
- # main
109
- #
110
- do_help if arg_config('--help')
103
+ def build_with_vendored_libraries
104
+ message "Building re2 using packaged libraries.\n"
111
105
 
112
- if ENV["CC"]
113
- RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"]
114
- RbConfig::CONFIG["CC"] = ENV["CC"]
115
- end
106
+ abseil_recipe, re2_recipe = load_recipes
116
107
 
117
- if ENV["CXX"]
118
- RbConfig::MAKEFILE_CONFIG["CXX"] = ENV["CXX"]
119
- RbConfig::CONFIG["CXX"] = ENV["CXX"]
120
- end
108
+ process_recipe(abseil_recipe) do |recipe|
109
+ recipe.configure_options << '-DABSL_PROPAGATE_CXX_STD=ON'
110
+ # Workaround for https://github.com/abseil/abseil-cpp/issues/1510
111
+ recipe.configure_options << '-DCMAKE_CXX_FLAGS=-DABSL_FORCE_WAITER_MODE=4' if MiniPortile.windows?
112
+ end
121
113
 
122
- def build_extension(static_p = false)
123
- # Enable optional warnings but disable deprecated register warning for Ruby 2.6 support
124
- $CFLAGS << " -Wall -Wextra -funroll-loops"
125
- $CPPFLAGS << " -Wno-register"
114
+ process_recipe(re2_recipe) do |recipe|
115
+ recipe.configure_options += [
116
+ # Specify Abseil's path so RE2 will prefer that over any system Abseil
117
+ "-DCMAKE_PREFIX_PATH=#{abseil_recipe.path}",
118
+ '-DCMAKE_CXX_FLAGS=-DNDEBUG'
119
+ ]
120
+ end
126
121
 
127
- # Pass -x c++ to force gcc to compile the test program
128
- # as C++ (as it will end in .c by default).
129
- compile_options = "-x c++"
122
+ pc_file = File.join(re2_recipe.lib_path, 'pkgconfig', 're2.pc')
123
+ pkg_config_paths = [
124
+ File.join(abseil_recipe.lib_path, 'pkgconfig'),
125
+ File.join(re2_recipe.lib_path, 'pkgconfig')
126
+ ]
130
127
 
131
- have_library("stdc++")
132
- have_header("stdint.h")
133
- have_func("rb_gc_mark_movable") # introduced in Ruby 2.7
128
+ static_pkg_config(pc_file, pkg_config_paths)
129
+ end
134
130
 
135
- if !static_p and !have_library("re2")
136
- abort "You must have re2 installed and specified with --with-re2-dir, please see https://github.com/google/re2/wiki/Install"
137
- end
131
+ def build_extension
132
+ # Enable optional warnings but disable deprecated register warning for Ruby 2.6 support
133
+ $CFLAGS << " -Wall -Wextra -funroll-loops"
134
+ $CXXFLAGS << " -Wall -Wextra -funroll-loops"
135
+ $CPPFLAGS << " -Wno-register"
138
136
 
139
- minimal_program = <<SRC
140
- #include <re2/re2.h>
141
- int main() { return 0; }
142
- SRC
137
+ # Pass -x c++ to force gcc to compile the test program
138
+ # as C++ (as it will end in .c by default).
139
+ compile_options = +"-x c++"
143
140
 
144
- re2_requires_version_flag = checking_for("re2 that requires explicit C++ version flag") do
145
- !try_compile(minimal_program, compile_options)
146
- end
141
+ have_library("stdc++")
142
+ have_header("stdint.h")
143
+ have_func("rb_gc_mark_movable") # introduced in Ruby 2.7
147
144
 
148
- if re2_requires_version_flag
149
- # Recent versions of re2 depend directly on abseil, which requires a
150
- # compiler with C++14 support (see
151
- # https://github.com/abseil/abseil-cpp/issues/1127 and
152
- # https://github.com/abseil/abseil-cpp/issues/1431). However, the
153
- # `std=c++14` flag doesn't appear to suffice; we need at least
154
- # `std=c++17`.
155
- 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|
156
- checking_for("re2 that compiles with #{std} standard") do
157
- if try_compile(minimal_program, compile_options + " -std=#{std}")
158
- compile_options << " -std=#{std}"
159
- $CPPFLAGS << " -std=#{std}"
160
-
161
- true
145
+ minimal_program = <<~SRC
146
+ #include <re2/re2.h>
147
+ int main() { return 0; }
148
+ SRC
149
+
150
+ re2_requires_version_flag = checking_for("re2 that requires explicit C++ version flag") do
151
+ !try_compile(minimal_program, compile_options)
152
+ end
153
+
154
+ if re2_requires_version_flag
155
+ # Recent versions of re2 depend directly on abseil, which requires a
156
+ # compiler with C++14 support (see
157
+ # https://github.com/abseil/abseil-cpp/issues/1127 and
158
+ # https://github.com/abseil/abseil-cpp/issues/1431). However, the
159
+ # `std=c++14` flag doesn't appear to suffice; we need at least
160
+ # `std=c++17`.
161
+ 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|
162
+ checking_for("re2 that compiles with #{std} standard") do
163
+ if try_compile(minimal_program, compile_options + " -std=#{std}")
164
+ compile_options << " -std=#{std}"
165
+ $CPPFLAGS << " -std=#{std}"
166
+
167
+ true
168
+ end
169
+ end
162
170
  end
163
171
  end
164
- end
165
- end
166
172
 
167
- # Determine which version of re2 the user has installed.
168
- # Revision d9f8806c004d added an `endpos` argument to the
169
- # generic Match() function.
170
- #
171
- # To test for this, try to compile a simple program that uses
172
- # the newer form of Match() and set a flag if it is successful.
173
- checking_for("RE2::Match() with endpos argument") do
174
- test_re2_match_signature = <<SRC
175
- #include <re2/re2.h>
176
-
177
- int main() {
178
- RE2 pattern("test");
179
- re2::StringPiece *match;
180
- pattern.Match("test", 0, 0, RE2::UNANCHORED, match, 0);
181
-
182
- return 0;
183
- }
184
- SRC
185
-
186
- if try_compile(test_re2_match_signature, compile_options)
187
- $defs.push("-DHAVE_ENDPOS_ARGUMENT")
188
- end
189
- end
173
+ # Determine which version of re2 the user has installed.
174
+ # Revision d9f8806c004d added an `endpos` argument to the
175
+ # generic Match() function.
176
+ #
177
+ # To test for this, try to compile a simple program that uses
178
+ # the newer form of Match() and set a flag if it is successful.
179
+ checking_for("RE2::Match() with endpos argument") do
180
+ test_re2_match_signature = <<~SRC
181
+ #include <re2/re2.h>
182
+
183
+ int main() {
184
+ RE2 pattern("test");
185
+ re2::StringPiece *match;
186
+ pattern.Match("test", 0, 0, RE2::UNANCHORED, match, 0);
187
+
188
+ return 0;
189
+ }
190
+ SRC
191
+
192
+ if try_compile(test_re2_match_signature, compile_options)
193
+ $defs.push("-DHAVE_ENDPOS_ARGUMENT")
194
+ end
195
+ end
190
196
 
191
- checking_for("RE2::Set::Match() with error information") do
192
- test_re2_set_match_signature = <<SRC
193
- #include <vector>
194
- #include <re2/re2.h>
195
- #include <re2/set.h>
197
+ checking_for("RE2::Set::Match() with error information") do
198
+ test_re2_set_match_signature = <<~SRC
199
+ #include <vector>
200
+ #include <re2/re2.h>
201
+ #include <re2/set.h>
196
202
 
197
- int main() {
198
- RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
199
- s.Add("foo", NULL);
200
- s.Compile();
203
+ int main() {
204
+ RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
205
+ s.Add("foo", NULL);
206
+ s.Compile();
201
207
 
202
- std::vector<int> v;
203
- RE2::Set::ErrorInfo ei;
204
- s.Match("foo", &v, &ei);
208
+ std::vector<int> v;
209
+ RE2::Set::ErrorInfo ei;
210
+ s.Match("foo", &v, &ei);
205
211
 
206
- return 0;
207
- }
208
- SRC
212
+ return 0;
213
+ }
214
+ SRC
209
215
 
210
- if try_compile(test_re2_set_match_signature, compile_options)
211
- $defs.push("-DHAVE_ERROR_INFO_ARGUMENT")
216
+ if try_compile(test_re2_set_match_signature, compile_options)
217
+ $defs.push("-DHAVE_ERROR_INFO_ARGUMENT")
218
+ end
219
+ end
212
220
  end
213
- end
214
- end
215
221
 
216
- def process_recipe(recipe)
217
- cross_build_p = config_cross_build?
218
- message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
222
+ def static_pkg_config(pc_file, pkg_config_paths)
223
+ ENV["PKG_CONFIG_PATH"] = [*pkg_config_paths, ENV["PKG_CONFIG_PATH"]].compact.join(File::PATH_SEPARATOR)
224
+
225
+ static_library_paths = minimal_pkg_config(pc_file, '--libs-only-L', '--static')
226
+ .shellsplit
227
+ .map { |flag| flag.delete_prefix('-L') }
219
228
 
220
- recipe.host = target_host
221
- # Ensure x64-mingw-ucrt and x64-mingw32 use different library paths since the host
222
- # is the same (x86_64-w64-mingw32).
223
- recipe.target = File.join(recipe.target, target_arch) if cross_build_p
229
+ $LIBPATH = static_library_paths | $LIBPATH
224
230
 
225
- yield recipe
231
+ # Replace all -l flags that can be found in one of the static library
232
+ # paths with the absolute path instead.
233
+ minimal_pkg_config(pc_file, '--libs-only-l', '--static')
234
+ .shellsplit
235
+ .each do |flag|
236
+ lib = "lib#{flag.delete_prefix('-l')}.#{$LIBEXT}"
226
237
 
227
- checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
228
- name = recipe.name
229
- version = recipe.version
238
+ if (static_lib_path = static_library_paths.find { |path| File.exist?(File.join(path, lib)) })
239
+ $libs << ' ' << File.join(static_lib_path, lib).shellescape
240
+ else
241
+ $libs << ' ' << flag.shellescape
242
+ end
243
+ end
230
244
 
231
- if File.exist?(checkpoint)
232
- message("Building re2 with a packaged version of #{name}-#{version}.\n")
233
- else
234
- message(<<~EOM)
235
- ---------- IMPORTANT NOTICE ----------
236
- Building re2 with a packaged version of #{name}-#{version}.
237
- Configuration options: #{recipe.configure_options.shelljoin}
238
- EOM
245
+ append_ldflags(minimal_pkg_config(pc_file, '--libs-only-other', '--static'))
239
246
 
240
- unless recipe.patch_files.empty?
241
- message("The following patches are being applied:\n")
247
+ incflags = minimal_pkg_config(pc_file, '--cflags-only-I')
248
+ $INCFLAGS = [incflags, $INCFLAGS].join(" ").strip
242
249
 
243
- recipe.patch_files.each do |patch|
244
- message(" - %s\n" % File.basename(patch))
245
- end
250
+ cflags = minimal_pkg_config(pc_file, '--cflags-only-other')
251
+ $CFLAGS = [$CFLAGS, cflags].join(" ").strip
252
+ $CXXFLAGS = [$CXXFLAGS, cflags].join(" ").strip
246
253
  end
247
254
 
248
- # Use a temporary base directory to reduce filename lengths since
249
- # Windows can hit a limit of 250 characters (CMAKE_OBJECT_PATH_MAX).
250
- with_temp_dir { recipe.cook }
255
+ def process_recipe(recipe)
256
+ cross_build_p = config_cross_build?
257
+ message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
251
258
 
252
- FileUtils.touch(checkpoint)
253
- end
254
-
255
- recipe.activate
256
- end
259
+ recipe.host = target_host
260
+ # Ensure x64-mingw-ucrt and x64-mingw32 use different library paths since the host
261
+ # is the same (x86_64-w64-mingw32).
262
+ recipe.target = File.join(recipe.target, target_arch) if cross_build_p
257
263
 
258
- def build_with_system_libraries
259
- header_dirs = [
260
- "/usr/local/include",
261
- "/opt/homebrew/include",
262
- "/usr/include"
263
- ]
264
+ yield recipe
264
265
 
265
- lib_dirs = [
266
- "/usr/local/lib",
267
- "/opt/homebrew/lib",
268
- "/usr/lib"
269
- ]
266
+ checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
267
+ name = recipe.name
268
+ version = recipe.version
270
269
 
271
- dir_config("re2", header_dirs, lib_dirs)
270
+ if File.exist?(checkpoint)
271
+ message("Building re2 with a packaged version of #{name}-#{version}.\n")
272
+ else
273
+ message(<<~EOM)
274
+ ---------- IMPORTANT NOTICE ----------
275
+ Building re2 with a packaged version of #{name}-#{version}.
276
+ Configuration options: #{recipe.configure_options.shelljoin}
277
+ EOM
272
278
 
273
- build_extension
274
- end
279
+ # Use a temporary base directory to reduce filename lengths since
280
+ # Windows can hit a limit of 250 characters (CMAKE_OBJECT_PATH_MAX).
281
+ Dir.mktmpdir { |dir| Dir.chdir(dir) { recipe.cook } }
275
282
 
276
- def libflag_to_filename(ldflag)
277
- case ldflag
278
- when /\A-l(.+)/
279
- "lib#{Regexp.last_match(1)}.#{$LIBEXT}"
280
- end
281
- end
283
+ FileUtils.touch(checkpoint)
284
+ end
285
+ end
282
286
 
283
- # This method does a number of things to ensure the final shared library
284
- # is compiled statically with the vendored libraries:
285
- #
286
- # 1. For -L<path> flags, ensure that any `ports` paths are prioritized just
287
- # in case there are installed libraries that might take precedence.
288
- # 2. For -l<lib> flags, convert the library to the static library with a
289
- # full path and substitute the absolute static library. For example,
290
- # -lre2 maps to /path/to/ports/<arch>/libre2/<version>/lib/libre2.a.
291
- #
292
- # This is needed because when building the extension, Ruby appears to
293
- # insert `-L#{RbConfig::CONFIG['exec_prefix']}/lib` first. If libre2 is
294
- # in installed in that location then the extension will link against the
295
- # system library instead of the vendored library.
296
- def add_flag(arg, lib_paths)
297
- case arg
298
- when /\A-L(.+)\z/
299
- # Prioritize ports' directories
300
- lib_dir = Regexp.last_match(1)
301
- $LIBPATH =
302
- if lib_dir.start_with?(PACKAGE_ROOT_DIR + "/")
303
- [lib_dir] | $LIBPATH
287
+ # See MiniPortile2's minimal_pkg_config:
288
+ # https://github.com/flavorjones/mini_portile/blob/52fb0bc41c89a10f1ac7b5abcf0157e059194374/lib/mini_portile2/mini_portile.rb#L760-L783
289
+ # and Ruby's pkg_config:
290
+ # https://github.com/ruby/ruby/blob/c505bb0ca0fd61c7ae931d26451f11122a2644e9/lib/mkmf.rb#L1916-L2004
291
+ def minimal_pkg_config(pc_file, *options)
292
+ if ($PKGCONFIG ||=
293
+ (pkgconfig = MakeMakefile.with_config("pkg-config") {MakeMakefile.config_string("PKG_CONFIG") || "pkg-config"}) &&
294
+ MakeMakefile.find_executable0(pkgconfig) && pkgconfig)
295
+ pkgconfig = $PKGCONFIG
304
296
  else
305
- $LIBPATH | [lib_dir]
297
+ raise RuntimeError, "pkg-config is not found"
306
298
  end
307
- when /\A-l./
308
- filename = libflag_to_filename(arg)
309
-
310
- added = false
311
- lib_paths.each do |path|
312
- static_lib = File.join(path, filename)
313
299
 
314
- next unless File.exist?(static_lib)
300
+ response = xpopen([pkgconfig, *options, pc_file], err: %i[child out], &:read)
301
+ raise RuntimeError, response unless $?.success?
315
302
 
316
- $LDFLAGS << " " << static_lib
317
- added = true
318
- break
303
+ response.strip
319
304
  end
320
305
 
321
- append_ldflags(arg.shellescape) unless added
322
- else
323
- append_ldflags(arg.shellescape)
324
- end
325
- end
326
-
327
- def add_static_ldflags(flags, lib_paths)
328
- flags.strip.shellsplit.each { |flag| add_flag(flag, lib_paths) }
329
- end
330
-
331
- def build_with_vendored_libraries
332
- message "Building re2 using packaged libraries.\n"
306
+ def config_system_libraries?
307
+ enable_config("system-libraries", ENV.key?('RE2_USE_SYSTEM_LIBRARIES'))
308
+ end
333
309
 
334
- abseil_recipe, re2_recipe = load_recipes
310
+ def config_cross_build?
311
+ enable_config("cross-build")
312
+ end
335
313
 
336
- process_recipe(abseil_recipe) do |recipe|
337
- recipe.configure_options += ['-DABSL_PROPAGATE_CXX_STD=ON', '-DCMAKE_CXX_VISIBILITY_PRESET=hidden']
338
- # Workaround for https://github.com/abseil/abseil-cpp/issues/1510
339
- recipe.configure_options += ['-DCMAKE_CXX_FLAGS=-DABSL_FORCE_WAITER_MODE=4'] if windows?
340
- end
314
+ # We use 'host' to set compiler prefix for cross-compiling. Prefer host_alias over host. And
315
+ # prefer i686 (what external dev tools use) to i386 (what ruby's configure.ac emits).
316
+ def target_host
317
+ host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
318
+ host.gsub(/i386/, "i686")
319
+ end
341
320
 
342
- process_recipe(re2_recipe) do |recipe|
343
- recipe.configure_options += ["-DCMAKE_PREFIX_PATH=#{abseil_recipe.path}", '-DCMAKE_CXX_FLAGS=-DNDEBUG',
344
- '-DCMAKE_CXX_VISIBILITY_PRESET=hidden']
321
+ def target_arch
322
+ RbConfig::CONFIG['arch']
323
+ end
345
324
  end
346
-
347
- dir_config("re2", File.join(re2_recipe.path, 'include'), File.join(re2_recipe.path, 'lib'))
348
- dir_config("abseil", File.join(abseil_recipe.path, 'include'), File.join(abseil_recipe.path, 'lib'))
349
-
350
- pkg_config_paths = [
351
- "#{abseil_recipe.path}/lib/pkgconfig",
352
- "#{re2_recipe.path}/lib/pkgconfig"
353
- ].join(File::PATH_SEPARATOR)
354
-
355
- pkg_config_paths = "#{ENV['PKG_CONFIG_PATH']}#{File::PATH_SEPARATOR}#{pkg_config_paths}" if ENV['PKG_CONFIG_PATH']
356
-
357
- ENV['PKG_CONFIG_PATH'] = pkg_config_paths
358
- pc_file = File.join(re2_recipe.path, 'lib', 'pkgconfig', 're2.pc')
359
-
360
- raise 'Please install the `pkg-config` utility!' unless find_executable('pkg-config')
361
-
362
- # See https://bugs.ruby-lang.org/issues/18490, broken in Ruby 3.1 but fixed in Ruby 3.2.
363
- flags = xpopen(['pkg-config', '--libs', '--static', pc_file], err: %i[child out], &:read)
364
-
365
- raise 'Unable to run pkg-config --libs --static' unless $?.success?
366
-
367
- lib_paths = [File.join(abseil_recipe.path, 'lib'), File.join(re2_recipe.path, 'lib')]
368
- add_static_ldflags(flags, lib_paths)
369
- build_extension(true)
370
325
  end
371
326
 
372
- if config_system_libraries?
373
- build_with_system_libraries
374
- else
375
- build_with_vendored_libraries
327
+ extconf = RE2::Extconf.new
328
+
329
+ if arg_config('--help')
330
+ extconf.print_help
331
+ exit!(true)
376
332
  end
377
333
 
378
- create_makefile("re2")
334
+ extconf.configure
data/ext/re2/recipes.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # re2 (https://github.com/mudge/re2)
2
4
  # Ruby bindings to RE2, a "fast, safe, thread-friendly alternative to
3
5
  # backtracking regular expression engines like those used in PCRE, Perl, and
@@ -9,26 +11,6 @@
9
11
  PACKAGE_ROOT_DIR = File.expand_path('../..', __dir__)
10
12
  REQUIRED_MINI_PORTILE_VERSION = '~> 2.8.5' # keep this version in sync with the one in the gemspec
11
13
 
12
- def build_recipe(name, version)
13
- require 'rubygems'
14
- gem('mini_portile2', REQUIRED_MINI_PORTILE_VERSION) # gemspec is not respected at install time
15
- require 'mini_portile2'
16
-
17
- MiniPortileCMake.new(name, version).tap do |recipe|
18
- recipe.target = File.join(PACKAGE_ROOT_DIR, 'ports')
19
- recipe.configure_options += [
20
- # abseil needs a C++14 compiler
21
- '-DCMAKE_CXX_STANDARD=14',
22
- # needed for building the C extension shared library with -fPIC
23
- '-DCMAKE_POSITION_INDEPENDENT_CODE=ON',
24
- # ensures pkg-config and installed libraries will be in lib, not lib64
25
- '-DCMAKE_INSTALL_LIBDIR=lib'
26
- ]
27
-
28
- yield recipe
29
- end
30
- end
31
-
32
14
  def load_recipes
33
15
  require 'yaml'
34
16
  dependencies = YAML.load_file(File.join(PACKAGE_ROOT_DIR, 'dependencies.yml'))
@@ -49,3 +31,24 @@ def load_recipes
49
31
 
50
32
  [abseil_recipe, re2_recipe]
51
33
  end
34
+
35
+ def build_recipe(name, version)
36
+ require 'rubygems'
37
+ gem('mini_portile2', REQUIRED_MINI_PORTILE_VERSION) # gemspec is not respected at install time
38
+ require 'mini_portile2'
39
+
40
+ MiniPortileCMake.new(name, version).tap do |recipe|
41
+ recipe.target = File.join(PACKAGE_ROOT_DIR, 'ports')
42
+ recipe.configure_options += [
43
+ # abseil needs a C++14 compiler
44
+ '-DCMAKE_CXX_STANDARD=14',
45
+ # needed for building the C extension shared library with -fPIC
46
+ '-DCMAKE_POSITION_INDEPENDENT_CODE=ON',
47
+ # ensures pkg-config and installed libraries will be in lib, not lib64
48
+ '-DCMAKE_INSTALL_LIBDIR=lib',
49
+ '-DCMAKE_CXX_VISIBILITY_PRESET=hidden'
50
+ ]
51
+
52
+ yield recipe
53
+ end
54
+ end
data/lib/re2/regexp.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # re2 (https://github.com/mudge/re2)
2
4
  # Ruby bindings to RE2, a "fast, safe, thread-friendly alternative to
3
5
  # backtracking regular expression engines like those used in PCRE, Perl, and
data/lib/re2/scanner.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # re2 (https://github.com/mudge/re2)
2
4
  # Ruby bindings to RE2, a "fast, safe, thread-friendly alternative to
3
5
  # backtracking regular expression engines like those used in PCRE, Perl, and
data/lib/re2/string.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # re2 (https://github.com/mudge/re2)
2
4
  # Ruby bindings to RE2, a "fast, safe, thread-friendly alternative to
3
5
  # backtracking regular expression engines like those used in PCRE, Perl, and
data/lib/re2/version.rb CHANGED
@@ -10,5 +10,5 @@
10
10
 
11
11
 
12
12
  module RE2
13
- VERSION = "2.9.0"
13
+ VERSION = "2.10.0"
14
14
  end
data/lib/re2.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # re2 (https://github.com/mudge/re2)
2
4
  # Ruby bindings to RE2, a "fast, safe, thread-friendly alternative to
3
5
  # backtracking regular expression engines like those used in PCRE, Perl, and
data/re2.gemspec CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'lib/re2/version'
2
4
 
3
5
  Gem::Specification.new do |s|
data/spec/kernel_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe Kernel do
2
4
  describe ".RE2" do
3
5
  it "returns an RE2::Regexp instance given a pattern" do
@@ -1,4 +1,5 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
+
2
3
  require 'objspace'
3
4
 
4
5
  RSpec.describe RE2::MatchData do
@@ -142,7 +143,7 @@ RSpec.describe RE2::MatchData do
142
143
  end
143
144
 
144
145
  it "returns a copy, not the actual original" do
145
- string = "bob"
146
+ string = +"bob"
146
147
  re = RE2::Regexp.new('(\D+)').match(string)
147
148
 
148
149
  expect(re.string).to_not equal(string)
@@ -155,7 +156,7 @@ RSpec.describe RE2::MatchData do
155
156
  end
156
157
 
157
158
  it "does not copy the string if it was already frozen" do
158
- string = "bob".freeze
159
+ string = "bob"
159
160
  re = RE2::Regexp.new('(\D+)').match(string)
160
161
 
161
162
  expect(re.string).to equal(string)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe RE2::Regexp do
2
4
  describe "#initialize" do
3
5
  it "returns an instance given only a pattern" do
@@ -1,4 +1,4 @@
1
- # encoding: utf-8
1
+ # frozen_string_literal: true
2
2
 
3
3
  RSpec.describe RE2::Scanner do
4
4
  describe "#regexp" do
data/spec/re2/set_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe RE2::Set do
2
4
  describe "#initialize" do
3
5
  it "returns an instance given no args" do
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "re2/string"
2
4
 
3
5
  class String
data/spec/re2_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  RSpec.describe RE2 do
2
4
  describe ".Replace" do
3
5
  it "only replaces the first occurrence of the pattern" do
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "re2"
2
4
 
3
5
  # To test passing objects that can be coerced to a String.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: re2
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.9.0
4
+ version: 2.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Mucur
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-02-29 00:00:00.000000000 Z
12
+ date: 2024-04-01 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake-compiler
@@ -91,7 +91,7 @@ files:
91
91
  - lib/re2/string.rb
92
92
  - lib/re2/version.rb
93
93
  - ports/archives/20240116.1.tar.gz
94
- - ports/archives/re2-2024-03-01.tar.gz
94
+ - ports/archives/re2-2024-04-01.tar.gz
95
95
  - re2.gemspec
96
96
  - spec/kernel_spec.rb
97
97
  - spec/re2/match_data_spec.rb
Binary file