re2 2.4.3 → 2.12.0

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.
data/ext/re2/extconf.rb CHANGED
@@ -1,442 +1,332 @@
1
- # re2 (http://github.com/mudge/re2)
2
- # Ruby bindings to re2, an "efficient, principled regular expression library"
1
+ # frozen_string_literal: true
2
+
3
+ # re2 (https://github.com/mudge/re2)
4
+ # Ruby bindings to RE2, a "fast, safe, thread-friendly alternative to
5
+ # backtracking regular expression engines like those used in PCRE, Perl, and
6
+ # Python".
3
7
  #
4
- # Copyright (c) 2010-2012, Paul Mucur (http://mudge.name)
8
+ # Copyright (c) 2010, Paul Mucur (https://mudge.name)
5
9
  # Released under the BSD Licence, please see LICENSE.txt
6
10
 
7
11
  require 'mkmf'
8
12
  require_relative 'recipes'
9
13
 
10
- RE2_HELP_MESSAGE = <<~HELP
11
- USAGE: ruby #{$0} [options]
14
+ module RE2
15
+ class Extconf
16
+ def configure
17
+ configure_cross_compiler
12
18
 
13
- Flags that are always valid:
19
+ if config_system_libraries?
20
+ build_with_system_libraries
21
+ else
22
+ build_with_vendored_libraries
23
+ end
14
24
 
15
- --enable-system-libraries
16
- Use system libraries instead of building and using the packaged libraries.
25
+ build_extension
17
26
 
18
- --disable-system-libraries
19
- Use the packaged libraries, and ignore the system libraries. This is the default.
27
+ create_makefile("re2")
28
+ end
20
29
 
30
+ def print_help
31
+ print(<<~TEXT)
32
+ USAGE: ruby #{$0} [options]
21
33
 
22
- Flags only used when using system libraries:
34
+ Flags that are always valid:
23
35
 
24
- Related to re2 library:
36
+ --enable-system-libraries
37
+ Use system libraries instead of building and using the packaged libraries.
25
38
 
26
- --with-re2-dir=DIRECTORY
27
- 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.
28
41
 
29
42
 
30
- Flags only used when building and using the packaged libraries:
43
+ Flags only used when using system libraries:
31
44
 
32
- --enable-cross-build
33
- Enable cross-build mode. (You probably do not want to set this manually.)
45
+ Related to re2 library:
34
46
 
47
+ --with-re2-dir=DIRECTORY
48
+ Look for re2 headers and library in DIRECTORY.
35
49
 
36
- Environment variables used:
37
50
 
38
- CC
39
- Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
51
+ Flags only used when building and using the packaged libraries:
40
52
 
41
- CPPFLAGS
42
- 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.)
43
55
 
44
- CFLAGS
45
- If this string is accepted by the compiler, add it to the flags passed to the compiler
46
56
 
47
- LDFLAGS
48
- If this string is accepted by the linker, add it to the flags passed to the linker
57
+ Environment variables used:
49
58
 
50
- LIBS
51
- Add this string to the flags passed to the linker
52
- HELP
59
+ CC
60
+ Use this path to invoke the compiler instead of `RbConfig::CONFIG['CC']`
53
61
 
54
- #
55
- # utility functions
56
- #
57
- def config_system_libraries?
58
- enable_config("system-libraries", ENV.key?('RE2_USE_SYSTEM_LIBRARIES'))
59
- end
62
+ CPPFLAGS
63
+ If this string is accepted by the C preprocessor, add it to the flags passed to the C preprocessor
60
64
 
61
- def config_cross_build?
62
- enable_config("cross-build")
63
- end
65
+ CFLAGS
66
+ If this string is accepted by the compiler, add it to the flags passed to the compiler
64
67
 
65
- def concat_flags(*args)
66
- args.compact.join(" ")
67
- end
68
+ LDFLAGS
69
+ If this string is accepted by the linker, add it to the flags passed to the linker
68
70
 
69
- def do_help
70
- print(RE2_HELP_MESSAGE)
71
- exit!(0)
72
- end
71
+ LIBS
72
+ Add this string to the flags passed to the linker
73
+ TEXT
74
+ end
73
75
 
74
- def darwin?
75
- RbConfig::CONFIG["target_os"].include?("darwin")
76
- end
76
+ private
77
77
 
78
- def windows?
79
- RbConfig::CONFIG["target_os"].match?(/mingw|mswin/)
80
- 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
81
82
 
82
- def freebsd?
83
- RbConfig::CONFIG["target_os"].include?("freebsd")
84
- end
83
+ def build_with_system_libraries
84
+ header_dirs = [
85
+ "/usr/local/include",
86
+ "/opt/homebrew/include",
87
+ "/usr/include"
88
+ ]
85
89
 
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
90
+ lib_dirs = [
91
+ "/usr/local/lib",
92
+ "/opt/homebrew/lib",
93
+ "/usr/lib"
94
+ ]
92
95
 
93
- def target_arch
94
- RbConfig::CONFIG['arch']
95
- end
96
+ dir_config("re2", header_dirs, lib_dirs)
96
97
 
97
- def with_temp_dir
98
- Dir.mktmpdir do |temp_dir|
99
- Dir.chdir(temp_dir) do
100
- 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
101
101
  end
102
- end
103
- end
104
102
 
105
- #
106
- # main
107
- #
108
- do_help if arg_config('--help')
103
+ def build_with_vendored_libraries
104
+ message "Building re2 using packaged libraries.\n"
109
105
 
110
- if ENV["CC"]
111
- RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"]
112
- RbConfig::CONFIG["CC"] = ENV["CC"]
113
- end
106
+ abseil_recipe, re2_recipe = load_recipes
114
107
 
115
- if ENV["CXX"]
116
- RbConfig::MAKEFILE_CONFIG["CXX"] = ENV["CXX"]
117
- RbConfig::CONFIG["CXX"] = ENV["CXX"]
118
- 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
119
113
 
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"
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
124
121
 
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++"
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
+ ]
128
127
 
129
- have_library("stdc++")
130
- have_header("stdint.h")
131
- have_func("rb_gc_mark_movable") # introduced in Ruby 2.7
128
+ static_pkg_config(pc_file, pkg_config_paths)
129
+ end
132
130
 
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
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"
136
136
 
137
- minimal_program = <<SRC
138
- #include <re2/re2.h>
139
- int main() { return 0; }
140
- 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++"
141
140
 
142
- re2_requires_version_flag = checking_for("re2 that requires explicit C++ version flag") do
143
- !try_compile(minimal_program, compile_options)
144
- end
141
+ have_library("stdc++")
142
+ have_header("stdint.h")
143
+ have_func("rb_gc_mark_movable") # introduced in Ruby 2.7
144
+
145
+ minimal_program = <<~SRC
146
+ #include <re2/re2.h>
147
+ int main() { return 0; }
148
+ SRC
145
149
 
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}"
158
-
159
- true
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
160
170
  end
161
171
  end
162
- end
163
- end
164
172
 
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
173
- #include <re2/re2.h>
174
-
175
- int main() {
176
- RE2 pattern("test");
177
- re2::StringPiece *match;
178
- pattern.Match("test", 0, 0, RE2::UNANCHORED, match, 0);
179
-
180
- return 0;
181
- }
182
- SRC
183
-
184
- if try_compile(test_re2_match_signature, compile_options)
185
- $defs.push("-DHAVE_ENDPOS_ARGUMENT")
186
- end
187
- 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
188
196
 
189
- checking_for("RE2::Set::Match() with error information") do
190
- test_re2_set_match_signature = <<SRC
191
- #include <vector>
192
- #include <re2/re2.h>
193
- #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>
194
202
 
195
- int main() {
196
- RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
197
- s.Add("foo", NULL);
198
- s.Compile();
203
+ int main() {
204
+ RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
205
+ s.Add("foo", NULL);
206
+ s.Compile();
199
207
 
200
- std::vector<int> v;
201
- RE2::Set::ErrorInfo ei;
202
- s.Match("foo", &v, &ei);
208
+ std::vector<int> v;
209
+ RE2::Set::ErrorInfo ei;
210
+ s.Match("foo", &v, &ei);
203
211
 
204
- return 0;
205
- }
206
- SRC
212
+ return 0;
213
+ }
214
+ SRC
207
215
 
208
- if try_compile(test_re2_set_match_signature, compile_options)
209
- $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
210
220
  end
211
- end
212
- end
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
221
 
225
- checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
226
- name = recipe.name
227
- version = recipe.version
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') }
228
+
229
+ # Replace all -l flags that can be found in one of the static library
230
+ # paths with the absolute path instead.
231
+ minimal_pkg_config(pc_file, '--libs-only-l', '--static')
232
+ .shellsplit
233
+ .each do |flag|
234
+ lib = "lib#{flag.delete_prefix('-l')}.#{$LIBEXT}"
235
+
236
+ if (static_lib_path = static_library_paths.find { |path| File.exist?(File.join(path, lib)) })
237
+ $libs << ' ' << File.join(static_lib_path, lib).shellescape
238
+ else
239
+ $libs << ' ' << flag.shellescape
240
+ end
241
+ end
228
242
 
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
243
+ append_ldflags(minimal_pkg_config(pc_file, '--libs-only-other', '--static'))
237
244
 
238
- unless recipe.patch_files.empty?
239
- message("The following patches are being applied:\n")
245
+ incflags = minimal_pkg_config(pc_file, '--cflags-only-I')
246
+ $INCFLAGS = [incflags, $INCFLAGS].join(" ").strip
240
247
 
241
- recipe.patch_files.each do |patch|
242
- message(" - %s\n" % File.basename(patch))
243
- end
248
+ cflags = minimal_pkg_config(pc_file, '--cflags-only-other')
249
+ $CFLAGS = [$CFLAGS, cflags].join(" ").strip
250
+ $CXXFLAGS = [$CXXFLAGS, cflags].join(" ").strip
244
251
  end
245
252
 
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 }
253
+ def process_recipe(recipe)
254
+ cross_build_p = config_cross_build?
255
+ message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
249
256
 
250
- FileUtils.touch(checkpoint)
251
- end
252
-
253
- recipe.activate
254
- end
257
+ recipe.host = target_host
258
+ # Ensure x64-mingw-ucrt and x64-mingw32 use different library paths since the host
259
+ # is the same (x86_64-w64-mingw32).
260
+ recipe.target = File.join(recipe.target, target_arch) if cross_build_p
255
261
 
256
- def build_with_system_libraries
257
- header_dirs = [
258
- "/usr/local/include",
259
- "/opt/homebrew/include",
260
- "/usr/include"
261
- ]
262
+ yield recipe
262
263
 
263
- lib_dirs = [
264
- "/usr/local/lib",
265
- "/opt/homebrew/lib",
266
- "/usr/lib"
267
- ]
264
+ checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
265
+ name = recipe.name
266
+ version = recipe.version
268
267
 
269
- dir_config("re2", header_dirs, lib_dirs)
268
+ if File.exist?(checkpoint)
269
+ message("Building re2 with a packaged version of #{name}-#{version}.\n")
270
+ else
271
+ message(<<~EOM)
272
+ ---------- IMPORTANT NOTICE ----------
273
+ Building re2 with a packaged version of #{name}-#{version}.
274
+ Configuration options: #{recipe.configure_options.shelljoin}
275
+ EOM
270
276
 
271
- build_extension
272
- end
277
+ # Use a temporary base directory to reduce filename lengths since
278
+ # Windows can hit a limit of 250 characters (CMAKE_OBJECT_PATH_MAX).
279
+ Dir.mktmpdir { |dir| Dir.chdir(dir) { recipe.cook } }
273
280
 
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_raw_hash_set
301
- -labsl_hash
302
- -labsl_city
303
- -labsl_bad_variant_access
304
- -labsl_low_level_hash
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_kernel_timeout_internal
312
- -labsl_stacktrace
313
- -labsl_symbolize
314
- -ldbghelp
315
- -labsl_debugging_internal
316
- -labsl_demangle_internal
317
- -labsl_malloc_internal
318
- -labsl_time
319
- -labsl_civil_time
320
- -labsl_strings
321
- -labsl_string_view
322
- -labsl_strings_internal
323
- -labsl_base
324
- -ladvapi32
325
- -labsl_spinlock_wait
326
- -labsl_int128
327
- -labsl_throw_delegate
328
- -labsl_raw_logging_internal
329
- -labsl_log_severity
330
- -labsl_time_zone
331
- ].freeze
332
-
333
- def libflag_to_filename(ldflag)
334
- case ldflag
335
- when /\A-l(.+)/
336
- "lib#{Regexp.last_match(1)}.#{$LIBEXT}"
337
- end
338
- end
281
+ FileUtils.touch(checkpoint)
282
+ end
283
+ end
339
284
 
340
- # This method does a number of things to ensure the final shared library
341
- # is compiled statically with the vendored libraries:
342
- #
343
- # 1. For -L<path> flags, ensure that any `ports` paths are prioritized just
344
- # in case there are installed libraries that might take precedence.
345
- # 2. For -l<lib> flags, convert the library to the static library with a
346
- # full path and substitute the absolute static library. For example,
347
- # -lre2 maps to /path/to/ports/<arch>/libre2/<version>/lib/libre2.a.
348
- #
349
- # This is needed because when building the extension, Ruby appears to
350
- # insert `-L#{RbConfig::CONFIG['exec_prefix']}/lib` first. If libre2 is
351
- # in installed in that location then the extension will link against the
352
- # system library instead of the vendored library.
353
- def add_flag(arg, lib_paths)
354
- case arg
355
- when /\A-L(.+)\z/
356
- # Prioritize ports' directories
357
- lib_dir = Regexp.last_match(1)
358
- $LIBPATH =
359
- if lib_dir.start_with?(PACKAGE_ROOT_DIR + "/")
360
- [lib_dir] | $LIBPATH
285
+ # See MiniPortile2's minimal_pkg_config:
286
+ # https://github.com/flavorjones/mini_portile/blob/52fb0bc41c89a10f1ac7b5abcf0157e059194374/lib/mini_portile2/mini_portile.rb#L760-L783
287
+ # and Ruby's pkg_config:
288
+ # https://github.com/ruby/ruby/blob/c505bb0ca0fd61c7ae931d26451f11122a2644e9/lib/mkmf.rb#L1916-L2004
289
+ def minimal_pkg_config(pc_file, *options)
290
+ if ($PKGCONFIG ||=
291
+ (pkgconfig = MakeMakefile.with_config("pkg-config") {MakeMakefile.config_string("PKG_CONFIG") || "pkg-config"}) &&
292
+ MakeMakefile.find_executable0(pkgconfig) && pkgconfig)
293
+ pkgconfig = $PKGCONFIG
361
294
  else
362
- $LIBPATH | [lib_dir]
295
+ raise RuntimeError, "pkg-config is not found"
363
296
  end
364
- when /\A-l./
365
- filename = libflag_to_filename(arg)
366
297
 
367
- added = false
368
- lib_paths.each do |path|
369
- static_lib = File.join(path, filename)
298
+ response = xpopen([pkgconfig, *options, pc_file], err: %i[child out], &:read)
299
+ raise RuntimeError, response unless $?.success?
370
300
 
371
- next unless File.exist?(static_lib)
301
+ response.strip
302
+ end
372
303
 
373
- $LDFLAGS << " " << static_lib
374
- added = true
375
- break
304
+ def config_system_libraries?
305
+ enable_config("system-libraries", ENV.key?('RE2_USE_SYSTEM_LIBRARIES'))
376
306
  end
377
307
 
378
- append_ldflags(arg.shellescape) unless added
379
- else
380
- append_ldflags(arg.shellescape)
381
- end
382
- end
308
+ def config_cross_build?
309
+ enable_config("cross-build")
310
+ end
383
311
 
384
- def add_static_ldflags(flags, lib_paths)
385
- static_flags = flags.strip.shellsplit
312
+ # We use 'host' to set compiler prefix for cross-compiling. Prefer host_alias over host. And
313
+ # prefer i686 (what external dev tools use) to i386 (what ruby's configure.ac emits).
314
+ def target_host
315
+ host = RbConfig::CONFIG["host_alias"].empty? ? RbConfig::CONFIG["host"] : RbConfig::CONFIG["host_alias"]
316
+ host.gsub(/i386/, "i686")
317
+ end
386
318
 
387
- if MiniPortile.windows?
388
- static_flags.each { |flag| add_flag(flag, lib_paths) unless ABSL_LDFLAGS.include?(flag) }
389
- ABSL_LDFLAGS.each { |flag| add_flag(flag, lib_paths) }
390
- else
391
- static_flags.each { |flag| add_flag(flag, lib_paths) }
319
+ def target_arch
320
+ RbConfig::CONFIG['arch']
321
+ end
392
322
  end
393
323
  end
394
324
 
395
- def build_with_vendored_libraries
396
- message "Building re2 using packaged libraries.\n"
397
-
398
- abseil_recipe, re2_recipe = load_recipes
399
-
400
- process_recipe(abseil_recipe) do |recipe|
401
- recipe.configure_options += ['-DABSL_PROPAGATE_CXX_STD=ON', '-DCMAKE_CXX_VISIBILITY_PRESET=hidden']
402
- # Workaround for https://github.com/abseil/abseil-cpp/issues/1510
403
- recipe.configure_options += ['-DCMAKE_CXX_FLAGS=-DABSL_FORCE_WAITER_MODE=4'] if windows?
404
- end
405
-
406
- process_recipe(re2_recipe) do |recipe|
407
- recipe.configure_options += ["-DCMAKE_PREFIX_PATH=#{abseil_recipe.path}", '-DCMAKE_CXX_FLAGS=-DNDEBUG',
408
- '-DCMAKE_CXX_VISIBILITY_PRESET=hidden']
409
- end
410
-
411
- dir_config("re2", File.join(re2_recipe.path, 'include'), File.join(re2_recipe.path, 'lib'))
412
- dir_config("abseil", File.join(abseil_recipe.path, 'include'), File.join(abseil_recipe.path, 'lib'))
413
-
414
- pkg_config_paths = [
415
- "#{abseil_recipe.path}/lib/pkgconfig",
416
- "#{re2_recipe.path}/lib/pkgconfig"
417
- ].join(File::PATH_SEPARATOR)
418
-
419
- pkg_config_paths = "#{ENV['PKG_CONFIG_PATH']}#{File::PATH_SEPARATOR}#{pkg_config_paths}" if ENV['PKG_CONFIG_PATH']
420
-
421
- ENV['PKG_CONFIG_PATH'] = pkg_config_paths
422
- pc_file = File.join(re2_recipe.path, 'lib', 'pkgconfig', 're2.pc')
423
-
424
- raise 'Please install the `pkg-config` utility!' unless find_executable('pkg-config')
425
-
426
- # See https://bugs.ruby-lang.org/issues/18490, broken in Ruby 3.1 but fixed in Ruby 3.2.
427
- flags = xpopen(['pkg-config', '--libs', '--static', pc_file], err: %i[child out], &:read)
428
-
429
- raise 'Unable to run pkg-config --libs --static' unless $?.success?
430
-
431
- lib_paths = [File.join(abseil_recipe.path, 'lib'), File.join(re2_recipe.path, 'lib')]
432
- add_static_ldflags(flags, lib_paths)
433
- build_extension(true)
434
- end
325
+ extconf = RE2::Extconf.new
435
326
 
436
- if config_system_libraries?
437
- build_with_system_libraries
438
- else
439
- build_with_vendored_libraries
327
+ if arg_config('--help')
328
+ extconf.print_help
329
+ exit!(true)
440
330
  end
441
331
 
442
- create_makefile("re2")
332
+ extconf.configure