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

Support static linking of re2 library #64

Closed
wants to merge 1 commit into from
Closed
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
52 changes: 48 additions & 4 deletions ext/re2/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# Released under the BSD Licence, please see LICENSE.txt

require 'mkmf'
require 'shellwords'

if ENV["CC"]
RbConfig::MAKEFILE_CONFIG["CC"] = ENV["CC"]
Expand All @@ -22,13 +23,40 @@
"/usr/include"
]

lib_dirs = [
LIB_DIRS = [
"/usr/local/lib",
"/opt/homebrew/lib",
"/usr/lib"
]
"/usr/lib",
"/usr/lib/x86_64-linux-gnu"
].select { |dir| Dir.exist?(dir) }

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

dir_config("re2", header_dirs, lib_dirs)
def resolve_static_library(arg)
libs_path = pkg_config('re2', 'libs-only-L')
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On Linux, this appears to return an empty list.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the static library isn't shipped in the libre2-5 package.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, the static library is shipped in libre2-dev under /usr/lib/x86_64-linux-gnu/libre2.a.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, still getting:

g++ -shared -o re2.so re2.o -L. -L/home/stanhu/.rbenv/versions/2.7.5/lib -Wl,-rpath,/home/stanhu/.rbenv/versions/2.7.5/lib -L/usr/local/lib -Wl,-rpath,/usr/local/lib -L/opt/homebrew/lib -Wl,-rpath,/opt/homebrew/lib -L/usr/lib -Wl,-rpath,/usr/lib -L/usr/lib/x86_64-linux-gnu -Wl,-rpath,/usr/lib/x86_64-linux-gnu -L. -L/home/stanhu/.rbenv/versions/2.7.5/lib  -fstack-protector-strong -rdynamic -Wl,-export-dynamic -L/home/stanhu/.rbenv/versions/2.7.5/lib  -Wl,--compress-debug-sections=zlib    -Wl,-rpath,/home/stanhu/.rbenv/versions/2.7.5/lib -L/home/stanhu/.rbenv/versions/2.7.5/lib -lruby /usr/lib/x86_64-linux-gnu/libre2.a -lstdc++ -lm   -lc
/usr/bin/ld: /usr/lib/x86_64-linux-gnu/libre2.a(re2.o): relocation R_X86_64_PC32 against symbol `_ZTVSt9basic_iosIcSt11char_traitsIcEE@@GLIBCXX_3.4' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value
collect2: error: ld returned 1 exit status

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be related to Ubuntu's compilation: google/re2#178

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we're better off doing #61.

Copy link
Collaborator Author

@stanhu stanhu Jan 6, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Confirmed that the installed Ubuntu shared library appears to be missing -fPIC in some objects. Recompiling with CPPFLAGS=-fPIC make seems to work.

It's not the default because here we're making a shared object from a static library: https://stackoverflow.com/a/4036497


re2_dirs =
if libs_path.nil? || libs_path.empty?
LIB_DIRS
else
# There should only be one path, but assume there can be multiple.
libs_path.strip.split(' ').map { |lib| lib.gsub(/^-L/, '') }
end

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

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

File.join(dir, filename)
end

dir_config("re2", header_dirs, LIB_DIRS)

$CFLAGS << " -Wall -Wextra -funroll-loops"

Expand Down Expand Up @@ -112,4 +140,20 @@
end
end

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

if static_p
append_cppflags('-fPIC')

$libs = $libs.shellsplit.map do |arg|
case arg
when '-lre2'
resolve_static_library(arg)
else
arg
end
end.shelljoin
end

create_makefile("re2")