From 71f3bd539f97f1235ed84b18a2136118a8cc6948 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Thu, 27 Jul 2023 14:31:32 -0700 Subject: [PATCH 1/2] Ensure different Windows flavors build their own abseil library Previously if you ran: ``` bundle exec rake gem:x64-mingw-ucrt bundle exec rake gem:x64-mingw32 ``` The latter would fail with undefined symbols: ``` linking shared-object re2.so /usr/bin/x86_64-w64-mingw32-ld: /tmp/re2/ports/x86_64-w64-mingw32/abseil/20230125.3/lib/libabsl_time_zone.a(time_zone_libc.cc.obj):time_zone_libc.cc:(.text+0x97): undefined reference to `__imp___timezone' /usr/bin/x86_64-w64-mingw32-ld: /tmp/re2/ports/x86_64-w64-mingw32/abseil/20230125.3/lib/libabsl_time_zone.a(time_zone_libc.cc.obj):time_zone_libc.cc:(.text+0xa8): undefined reference to `__imp___dstbias' /usr/bin/x86_64-w64-mingw32-ld: /tmp/re2/ports/x86_64-w64-mingw32/abseil/20230125.3/lib/libabsl_time_zone.a(time_zone_libc.cc.obj):time_zone_libc.cc:(.text+0xde): undefined reference to `__imp___tzname' collect2: error: ld returned 1 exit status make: *** [Makefile:262: re2.so] Error 1 ``` The `timezone`, `dstbias`, and `tzname` symbols come from the Microsoft Runtime library. This happened because the abseil C++ library would be installed for `x64-mingw-ucrt` and `x64-mingw32` in the same directory based on the `host` value (`x86_64-w64-mingw32`). As a result, if `x64-mingw-ucrt` were built first, then the abseil libraries will link against the Universal C Runtime (UCRT). When `rake gem:x64-mingw32` is attempted after `rake gem:x64-mingw-ucrt`, then it will fail to link those symbols because the abseil library in `ports/x86_64-w64-mingw32` directory expects UCRT to be used. To avoid this mess, append the `RbConfig::CONFIG['arch']` to the mini_portile recipe to ensure `x64-mingw-ucrt` and `x64-mingw32` builds use different library paths. --- ext/re2/extconf.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ext/re2/extconf.rb b/ext/re2/extconf.rb index d3b53a4..5abf832 100644 --- a/ext/re2/extconf.rb +++ b/ext/re2/extconf.rb @@ -82,6 +82,10 @@ def target_host host.gsub(/i386/, "i686") end +def target_arch + RbConfig::CONFIG['arch'] +end + def with_temp_dir Dir.mktmpdir do |temp_dir| Dir.chdir(temp_dir) do @@ -205,7 +209,11 @@ def process_recipe(name, version) MiniPortileCMake.new(name, version).tap do |recipe| recipe.host = target_host - recipe.target = File.join(PACKAGE_ROOT_DIR, "ports") + target_dir = File.join(PACKAGE_ROOT_DIR, "ports") + # Ensure x64-mingw-ucrt and x64-mingw32 use different library paths since the host + # is the same (x86_64-w64-mingw32). + target_dir = File.join(target_dir, target_arch) if windows? && !target_arch.empty? + recipe.target = target_dir recipe.configure_options += [ # abseil needs a C++14 compiler From cbe6dc6f5e08a431d7b81f4c9dd232f80896ba27 Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Fri, 28 Jul 2023 09:23:54 -0700 Subject: [PATCH 2/2] Use --enable-cross-build flag to determine whether to use arch subdir Using this flag will enable us to keep the vendored libraries in `ports/archives` rather than `ports//archives`. --- ext/re2/extconf.rb | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ext/re2/extconf.rb b/ext/re2/extconf.rb index 5abf832..3571c46 100644 --- a/ext/re2/extconf.rb +++ b/ext/re2/extconf.rb @@ -29,6 +29,13 @@ --with-re2-dir=DIRECTORY Look for re2 headers and library in DIRECTORY. + + Flags only used when building and using the packaged libraries: + + --enable-cross-build + Enable cross-build mode. (You probably do not want to set this manually.) + + Environment variables used: CC @@ -54,6 +61,10 @@ def config_system_libraries? enable_config("system-libraries", ENV.key?('RE2_USE_SYSTEM_LIBRARIES')) end +def config_cross_build? + enable_config("cross-build") +end + def concat_flags(*args) args.compact.join(" ") end @@ -207,12 +218,15 @@ def process_recipe(name, version) require "mini_portile2" message("Using mini_portile version #{MiniPortile::VERSION}\n") + cross_build_p = config_cross_build? + message "Cross build is #{cross_build_p ? "enabled" : "disabled"}.\n" + MiniPortileCMake.new(name, version).tap do |recipe| recipe.host = target_host target_dir = File.join(PACKAGE_ROOT_DIR, "ports") # Ensure x64-mingw-ucrt and x64-mingw32 use different library paths since the host # is the same (x86_64-w64-mingw32). - target_dir = File.join(target_dir, target_arch) if windows? && !target_arch.empty? + target_dir = File.join(target_dir, target_arch) if cross_build_p recipe.target = target_dir recipe.configure_options += [