re2 2.4.3 → 2.10.0

Sign up to get free protection for your applications and to get access to all the features.
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