0

my desktop use Arch Linux and my servers are usually Ubuntus. When I compile my application go build . it does not work on my servers.

root@vps38292:~# API_PORT=8000 SQLITE_FILE=conc2d.db ./conc2d-api 
./conc2d-api: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by ./conc2d-api)
./conc2d-api: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by ./conc2d-api)
./conc2d-api: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by ./conc2d-api)

I tried the flag CGO_ENABLED=0 but I'm using a lib (go-sqlite3) that requires it:

root@vps38292:~# API_PORT=8000 SQLITE_FILE=conc2d.db ./conc2d-api 
2022/05/09 13:32:11 [API] 2022-05-09T13:32:11Z failure to create table stmt into sqlite3 dbBinary was compiled with 'CGO_ENABLED=0', go-sqlite3 requires cgo to work. This is a stub

I tried GOOS=linux GOARCH=amd64 but didn't change a thing.

Must I compile it from an Ubuntu?

doobdargent
  • 630
  • 5
  • 14
  • 3
    `cgo` relies on `libc`, and the version of `libc` on your Arch host appears to be different enough from that on your servers. Basically "the trick" is to make the compilation (actually, linking) process on your desktop see the correct—or at least compatible—versions of the required C libs. … – kostix May 09 '22 at 14:02
  • 4
    … I can think of the two ways to do that 1) Have appropriate `.a` files from your target system available on your local system and then use the appropriate value of the [`LDFLAGS` env. variable when compiling](https://pkg.go.dev/cmd/cgo) so that the linker sees those libraries; 2) Use something like `cdebootstrap` (may be [this](https://aur.archlinux.org/packages/cdebootstrap-static) to have a minimal compilation environment matching the target system, and compile using its tools and libs. Well, and a full-blown virtual machine guest or a container will do, too. – kostix May 09 '22 at 14:06
  • 2
    As to `LDFLAGS`, usually you use the `-L` command line variable to force the linker search the specified path for the libraries (you can pass that option any number of times, they add up). You can grab those `.a` files from the appropriate `*-dev` packages from your target system—for instance, `libc6-dev` should contain the libc. You can start [there](https://packages.ubuntu.com/). – kostix May 09 '22 at 14:08
  • Thanks @kostix for the replies. I tried to install glibc_2.31 on my arch (this is the version used on the servers) by following [that answer](https://stackoverflow.com/questions/2856438/how-can-i-link-to-a-specific-glibc-version) but the compilation fails. I did not want to use containers but it looks like it's the easiest (to me). – doobdargent May 09 '22 at 14:34
  • 1
    You could possibly ask another question regarding that specific compilation problem. Be sure to produce exact commands you're using and exact error messages. Also note that it's best to do the compilation while passing `go build` the `-x` command-line flag to make it print all the commands it executes, and their output. – kostix May 09 '22 at 14:46
  • 2
    …and while we're at it, you could look at [`gitlab.com/cznic/sqlite`](https://gitlab.com/cznic/sqlite/) which is a C-to-Go SQLite source-code conversion project which, as of now, is quite mature (so that the test suite passes even on windows/amd64). It's still slower than the C library but naturally requires no `cgo`. – kostix May 09 '22 at 14:48
  • 1
    I would take a step back: Go is so nice because normally one doesn't have to think about shared libraries and shared library versioning, it just works. I understand you need cgo due to sqlite. Arch Linux is a rolling upgrade distribution, this is probably why the libc is more recent than the Ubuntu targets. Personally I would just develop on Arch Linux and build for Ubuntu, from Arch, in a Docker container. Go with the flow of Go :-) – marco.m May 09 '22 at 15:45

0 Answers0