Skip to content

Commit

Permalink
Add --enable-static option to link icu4c libraries statically
Browse files Browse the repository at this point in the history
Homebrew in macOS updates the `icu4c` library quite often, which often
breaks this gem because the dyanmically-loaded library no longer
exists.

To avoid this hassle, this gem can be compiled with `--enable-static`
so that the resulting `charlock_holmes.bundle` will have all the
required libraries statically linked.
  • Loading branch information
stanhu committed Jul 10, 2024
1 parent 466bbb1 commit 206839d
Showing 1 changed file with 63 additions and 0 deletions.
63 changes: 63 additions & 0 deletions ext/charlock_holmes/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,67 @@
end
end

def libflag_to_filename(ldflag)
case ldflag
when /\A-l(.+)/
"lib#{Regexp.last_match(1)}.#{$LIBEXT}"
end
end

def resolve_static_library(libflag, dirs)
filename = libflag_to_filename(libflag)

dir = dirs.find { |path| File.exist?(File.join(path, filename)) }

raise "Unable to find #{filename} in #{dirs}" unless dir

File.join(dir, filename)
end

def substitute_static_libs(packages)
packages.each do |pkg|
unless pkg_config(pkg)
message = <<~MSG
Unable to run `pkg-config #{pkg}`.
Check that PKG_CONFIG_PATH includes #{pkg}.pc (or unset it if it's already set).
Current environment:
PKG_CONFIG_PATH=#{ENV['PKG_CONFIG_PATH']}
MSG

raise message
end
end

# First, find all the -l<lib> flags added by pkg-config. We want to drop
# these dynamically linked libraries and substitute them with the static libraries.
libflags = packages.map do |pkg|
pkg_config(pkg, 'libs-only-l')&.strip&.split(' ')
end.flatten.uniq

# To find where the static libraries live, we need to search the
# library paths given by the -L flag from pkg-config.
lib_paths = packages.map do |pkg|
include_path = pkg_config(pkg, 'libs-only-L')&.strip
include_path&.split(' ')&.map { |lib| lib.gsub(/^-L/, '') }
end.flatten.uniq

# Drop the -l<lib> flags and add in the static libraries.
new_libs = $libs.shellsplit
new_libs.reject! { |arg| libflags.include?(arg) }
libflags.each { |flag| new_libs << resolve_static_library(flag, lib_paths) }
$libs = new_libs.uniq.shelljoin
end

static_p = enable_config('static', false)
message "Static linking is #{static_p ? 'enabled' : 'disabled'}.\n"

if static_p
$CXXFLAGS << ' -fPIC'
ENV['PKG_CONFIG_ALLOW_SYSTEM_LIBS'] = '1'

substitute_static_libs(%w[icu-i18n icu-io icu-uc])
end

create_makefile 'charlock_holmes/charlock_holmes'

0 comments on commit 206839d

Please sign in to comment.