Skip to content

Commit

Permalink
rbthemis: Extra effort to locate Themis Core library (#917)
Browse files Browse the repository at this point in the history
Just like with PyThemis, migrate RbThemis to the same pattern of loading
Themis Core library dynamically with more attention to versioning.

Detect the platform and load properly versioned libraries first,
reducing the chance for an ABI mismatch. However, keep the 'themis'
as a fallback (and a default action for Windows).

Ruby's "ffi_lib" is in some ways more smart than Python's find_library
(it supports Apple M1 by accident, for example) but in some ways it's
also dumber. Don't depend on ffi's maintainers and hardcode a list of
absolute paths to try first in attempt to make things "just work".
  • Loading branch information
ilammy authored Apr 21, 2022
1 parent ec40635 commit 120ec8f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ _Code:_
- `pythemis.scomparator` and `pythemis.skeygen` are now imported with `from pythemis import *` ([#914](https://github.com/cossacklabs/themis/pull/914)).
- Improved compatibility with non-Homebrew Python installations on Apple M1 ([#915](https://github.com/cossacklabs/themis/pull/915)).

- **Ruby**

- Improved compatibility with non-standard installations on Apple M1 ([#917](https://github.com/cossacklabs/themis/pull/917)).

- **Rust**

- `SecureSessionTransport` implementations are now required to be `Send` ([#898](https://github.com/cossacklabs/themis/pull/898)).
Expand Down
45 changes: 44 additions & 1 deletion src/wrappers/themis/ruby/lib/rbthemis.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,50 @@ def empty?(value)

module ThemisImport
extend FFI::Library
ffi_lib 'themis'

def self.canonical_themis_paths
host_os = RbConfig::CONFIG['host_os']
paths = []
if host_os.start_with? 'linux'
# Default library installation path for "make install"
paths.append '/usr/local/lib/libthemis.so.0'
# Don't bother figuring out the "right" absolute path, since
# that depends on the distro and non-distro-provided Rubies
# don't know about the right paths at all. The ones installed
# via RVM certainly don't. Use soname and let ld figure it out.
paths.append 'libthemis.so.0'
end
if host_os.start_with? 'darwin'
# Default library installation path for "make install"
paths.append '/usr/local/lib/libthemis.0.dylib'
# These are install names of libraries installed via Homebrew
# Add both M1 and Intel paths so that x86 Ruby works on M1
paths.append '/opt/homebrew/opt/libthemis/lib/libthemis.0.dylib'
paths.append '/usr/local/opt/libthemis/lib/libthemis.0.dylib'
# Last try, look for ABI-qualified name
paths.append 'libthemis.0.dylib'
end
return paths
end

def self.load_themis
for path in canonical_themis_paths
begin
return ffi_lib path
rescue LoadError
next
end
end
warn <<~EOF
WARN: failed to load the canonical Themis Core library
Proceeding to find 'themis' library in standard paths.
This might cause ABI mismatch and crash the process.
EOF
return ffi_lib 'themis'
end

load_themis

callback :get_pub_key_by_id_type,
[:pointer, :int, :pointer, :int, :pointer], :int
Expand Down

0 comments on commit 120ec8f

Please sign in to comment.