re2 2.4.3 → 2.10.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,334 @@
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
221
 
214
- def process_recipe(recipe)
215
- cross_build_p = config_cross_build?
216
- 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)
217
224
 
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
225
+ static_library_paths = minimal_pkg_config(pc_file, '--libs-only-L', '--static')
226
+ .shellsplit
227
+ .map { |flag| flag.delete_prefix('-L') }
222
228
 
223
- yield recipe
229
+ $LIBPATH = static_library_paths | $LIBPATH
224
230
 
225
- checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
226
- name = recipe.name
227
- version = recipe.version
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}"
228
237
 
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
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
237
244
 
238
- unless recipe.patch_files.empty?
239
- message("The following patches are being applied:\n")
245
+ append_ldflags(minimal_pkg_config(pc_file, '--libs-only-other', '--static'))
240
246
 
241
- recipe.patch_files.each do |patch|
242
- message(" - %s\n" % File.basename(patch))
243
- end
247
+ incflags = minimal_pkg_config(pc_file, '--cflags-only-I')
248
+ $INCFLAGS = [incflags, $INCFLAGS].join(" ").strip
249
+
250
+ cflags = minimal_pkg_config(pc_file, '--cflags-only-other')
251
+ $CFLAGS = [$CFLAGS, cflags].join(" ").strip
252
+ $CXXFLAGS = [$CXXFLAGS, cflags].join(" ").strip
244
253
  end
245
254
 
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 }
255
+ def process_recipe(recipe)
256
+ cross_build_p = config_cross_build?
257
+ message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n"
249
258
 
250
- FileUtils.touch(checkpoint)
251
- 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
252
263
 
253
- recipe.activate
254
- end
264
+ yield recipe
255
265
 
256
- def build_with_system_libraries
257
- header_dirs = [
258
- "/usr/local/include",
259
- "/opt/homebrew/include",
260
- "/usr/include"
261
- ]
266
+ checkpoint = "#{recipe.target}/#{recipe.name}-#{recipe.version}-#{recipe.host}.installed"
267
+ name = recipe.name
268
+ version = recipe.version
262
269
 
263
- lib_dirs = [
264
- "/usr/local/lib",
265
- "/opt/homebrew/lib",
266
- "/usr/lib"
267
- ]
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
268
278
 
269
- dir_config("re2", header_dirs, lib_dirs)
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 } }
270
282
 
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_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
283
+ FileUtils.touch(checkpoint)
284
+ end
285
+ end
339
286
 
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
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
361
296
  else
362
- $LIBPATH | [lib_dir]
297
+ raise RuntimeError, "pkg-config is not found"
363
298
  end
364
- when /\A-l./
365
- filename = libflag_to_filename(arg)
366
299
 
367
- added = false
368
- lib_paths.each do |path|
369
- static_lib = File.join(path, filename)
300
+ response = xpopen([pkgconfig, *options, pc_file], err: %i[child out], &:read)
301
+ raise RuntimeError, response unless $?.success?
370
302
 
371
- next unless File.exist?(static_lib)
303
+ response.strip
304
+ end
372
305
 
373
- $LDFLAGS << " " << static_lib
374
- added = true
375
- break
306
+ def config_system_libraries?
307
+ enable_config("system-libraries", ENV.key?('RE2_USE_SYSTEM_LIBRARIES'))
376
308
  end
377
309
 
378
- append_ldflags(arg.shellescape) unless added
379
- else
380
- append_ldflags(arg.shellescape)
381
- end
382
- end
310
+ def config_cross_build?
311
+ enable_config("cross-build")
312
+ end
383
313
 
384
- def add_static_ldflags(flags, lib_paths)
385
- static_flags = flags.strip.shellsplit
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
386
320
 
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) }
321
+ def target_arch
322
+ RbConfig::CONFIG['arch']
323
+ end
392
324
  end
393
325
  end
394
326
 
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
327
+ extconf = RE2::Extconf.new
435
328
 
436
- if config_system_libraries?
437
- build_with_system_libraries
438
- else
439
- build_with_vendored_libraries
329
+ if arg_config('--help')
330
+ extconf.print_help
331
+ exit!(true)
440
332
  end
441
333
 
442
- create_makefile("re2")
334
+ extconf.configure