Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --enable-static option to link icu4c libraries statically #164

Merged
merged 2 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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'
Loading