Skip to content

Commit

Permalink
Merge pull request #164 from stanhu/sh-add-static-linking-option
Browse files Browse the repository at this point in the history
Add --enable-static option to link icu4c libraries statically
  • Loading branch information
tenderlove committed Jul 10, 2024
2 parents 466bbb1 + cc93f88 commit dcbf192
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 3 deletions.
9 changes: 7 additions & 2 deletions .github/workflows/macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ jobs:
matrix:
os: [macos]
ruby: [ '3.2', '3.3' ]
compile_opt: [""]
include:
- os: "macos"
ruby: "3.3"
compile_opt: "ENABLE_STATIC=1"

steps:
- name: icu4c
Expand All @@ -23,5 +28,5 @@ jobs:

- name: Install dependencies
run: bundle install
- name: Run tests ${{ matrix.rubyopt }}
run: bundle exec rake RUBYOPT="${{ matrix.rubyopt }}"
- name: "Run tests with compile_opt: ${{ matrix.compile_opt }}, rubyopt: ${{ matrix.rubyopt }}"
run: ${{ matrix.compile_opt }} bundle exec rake RUBYOPT="${{ matrix.rubyopt }}"
3 changes: 2 additions & 1 deletion Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require "rake/extensiontask"

Rake::ExtensionTask.new 'charlock_holmes' do |ext|
ext.lib_dir = File.join 'lib', 'charlock_holmes'
ext.config_options << '--enable-static' if ENV['ENABLE_STATIC']
end

Rake::Task[:test].prerequisites << :compile
Rake::Task[:test].prerequisites << :compile
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 dcbf192

Please sign in to comment.