Problem installing uplink-ruby: cannot build uplink-c library in Ubuntu 18.04

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