I am trying to get the uplink-ruby gem installed in my current project (Rails 6/Ruby 3). I have followed the instructions in the Readme and the gem does install successfully. However if I require it, I get an error that the
libuplink.so library cannot be found. If I try to build uplink-c myself I encounter issues. Could anyone give me more information?
In my gemfile:
gem 'uplink-ruby', git: 'https://github.com/storj-thirdparty/uplink-ruby', tag: 'v1.8.0'
Steps taken to install uplink-c
sudo apt-get update -qq && apt-get -y upgrade && apt-get install
sudo tar -C /usr/local -xzf go1.20.linux-amd64.tar.gz
git clone https://github.com/storj/uplink-c.git
git fetch --tags
git checkout tags/v1.8.0
go build -ldflags="-s -w" -buildmode c-shared -o .build/uplink.so .
go build -ldflags="-s -w" -buildmode c-archive -o .build/uplink.a .
mv .build/uplink.so .build/libuplink.so
mv .build/uplink.a .build/libuplink.a
mkdir -p .build/uplink
mv .build/*.h .build/uplink
cp uplink_definitions.h .build/uplink
cp uplink_compat.h .build/uplink
./scripts/gen-pkg-config > .build/libuplink.pc
./scripts/version: 10: ./scripts/version: Bad substitution
NB. Previously it would not build at all with earlier versions of go. With v 1.20 it appears to build there’s just this weird problem setting the version in a script and the build doesn’t finish. That said it does create the
libuplink.so library, but I cannot get Ruby to use this for some reason.
I executed the same as you in a fresh Linux container Ubuntu 22.04 with Go 1.19 and got the same error as you got with Go 1.20. So, I couldn’t reproduce what you got with Go 1.19.
The issue that you got with Go 1.20 is that the
scripts/version uses a shell parameter expansion that isn’t valid in the
sh shell. We using
bash, however for being more compatible with build systems they were migrated to
sh in this PR Improve cross-platform compatibility of the build system by DarkKirb · Pull Request #24 · storj/uplink-c · GitHub and it introduced this bug.
The issue that the bug causes is that the generated
libuplink.pc contains in a
v in the version field, that’s
Version: v1.8.0 and it should be
Version: 1.18.0, that’s what
I’m going to send a patch, but meanwhile, if you have bash installed in that machine, you can just modify
scripts/version to use
bash, that’s replacing the first line
Thanks for your reply. If I do replace the first line with
#!/bin/bash then the library does build, which is great. However I still can’t require the gem from Ruby, which was why I was trying to build this in the first place.
After running make build, I have added the LD_LIBRARY_PATH:
From the rails console, if I do
require 'uplink' I get the following error:
FFI::NotFoundError: Function 'uplink_parse_access' not found in [/lib/x86_64-linux-gnu/libc.so.6]
from /home/my_username/.rvm/gems/ruby-3.1.2/gems/ffi-1.15.5/lib/ffi/library.rb:273:in `attach_function'
I can verify from the ruby console that it has the LD_LIBRARY_PATH env var set correctly so the gem should be pointing to this file I’ve built. The same thing happens if I download the amd_64 binary file and put that in my path instead.
To Summarize my issue:
If I add the gem to the gem file and run bundle, it succeeds, but I cannot require uplink from the console as the library is not found
If I build the library myself on a version of go <1.20 I encounter build errors
If I build the library on v 1.20 it will succeed given your workaround pending a bug fix, however the Ruby gem still will not require the library correctly.
These questions would be best answered by the author of uplink-ruby - as this is a third party library. Hopefully @joslinm can give some input to these issues.
It seems to me that the library isn’t compiling correctly though or not exposing the expected methods. We aren’t 100% set on using the Ruby gem, we just want to be able to create Access grants and S3 Creds programmatically in our Ruby on Rails application without writing a client in any other language.