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
wget https://golang.org/dl/go1.20.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.20.linux-amd64.tar.gz
go version
cd lib
git clone https://github.com/storj/uplink-c.git
cd uplink-c
git fetch --tags
git checkout tags/v1.8.0
make build
Result:
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 bash
did.
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 #!/bin/sh
by #!/bin/bash
.
2 Likes
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:
export LD_LIBRARY_PATH=/home/my_username/code/our_project/lib/uplink-c/.build:$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.
1 Like
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.
1 Like