re2 2.0.0-arm64-darwin

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