Golang Works with Shared Object Through cgo (.so Not Found Issue)

jason19970210
3 min readSep 10, 2023

Faced the problem with Golang and cgo for a couple days, so just take a quick note to record what had happened.

Shortcut: Jump to [Key Point], [Solution] section
A quick look in [Gist]

From the beginning, my goal was aim to make Golang works with a shared object file (.so) built from a C code.
Just like others in 2023, I went to ChatGPT for an answer which can help me have a quick look for the solution how to achieve the goal.

Key Point

Noticed from Ref[2]: (the reference is written in Chinese)

1. The `.so` file built from gcc should has the `lib` prefix
example: `libsum.so`, `libcalc.so`

2. The value after `LDFLAGS` should goes with name without `lib`
example:
a) `libsum.so` -> LDFLAGS=sum
a) `libcalc.so` -> LDFLAGS=calc

ChatGPT shows me a sum.c & main.go

// sum.c
#include "sum.h"

int sum(int a, int b) {
return a + b;
}
package main

/*
#cgo LDFLAGS: -L. -lsum
#include "sum.h"
*/

import "C"
import "fmt"

func main() {
// Call the sum function from the shared library
result := C.sum(5, 7)

// Print the result
fmt.Printf("Sum: %d\n", result)
}

I had put the files into following struct:

$ tree <project_folder>
.
├── libs
│ ├── sum.c
│ └── sum.h
└── main.go

With the build script:

$ cd <project_folder>/libs
$ gcc -shared -o libsum.so sum.c

$
cd <project_folder>
$ go build -o go_sum main.go

And here comes the first error:

$ go build -o go_sum main.go

# command-line-arguments
./main.go:5:10: fatal error: sum.h: No such file or directory
5 | #include "sum.h"
| ^~~~~~~
compilation terminated.

It’s not a big deal to us to create a sum.h header file.

// sum.h

#include <stdio.h>

int sum(int a, int b);

There should also put another compile flag: CFLAGS for cgo in main.go , then rebuild the Golang executable file

package main

/*
#cgo CFLAGS: -Ilibs
#cgo LDFLAGS: -Llibs -lsum
#include "sum.h"
*/

import "C"
import "fmt"
...

Once build successfully, just run the executable file with name go_sum

Unfortunately, another error pops !

$ ./go_sum
./go_sum: error while loading shared libraries: libsum.so: cannot open shared object file: No such file or directory

By searching and try-error for hours, I had found the solution which I should make the .so file been found by linker.

Here is the command where we can track the .so file information linked to a executable file:

$ ldd <executable file>

## Results for go_sum
$ ldd go_sum
linux-vdso.so.1 (0x00007ffde1aab000)
libsum.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6a85b55000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6a85d86000)

As the result, the libsum.so has not been recognized, here is nothing consider with the .so itself, but the linker.

Solution

Updated: 2023/09/20

#cgo LDFLAGS: -L./lib -Wl, -rpath, $ORIGIN/libs -lsum
  • By adding the LD_LIBRARY_PATH
$ export LD_LIBRARY_PATH=<project_folder>/lib/

After the line execute, rebuild the Golang executable file, then check again the lib has been recognized with ldd command.

$ go build -o go_sum main.go

$ ldd go_sum
linux-vdso.so.1 (0x00007ffde1aab000)
libsum.so => <project_folder>/libs/libsum.so (0x00007ff959dbb000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6a85b55000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6a85d86000)
$ ./go_sum
Sum: 12

Hope the article can help to save times.

Ref:
[1]: https://segmentfault.com/q/1010000022621510
[2]: https://serverfault.com/a/201711

Sign up to discover human stories that deepen your understanding of the world.

jason19970210
jason19970210

Written by jason19970210

a slashie from Taiwan 🇹🇼! Fields: Software Dev, Networking, Digital Forensics Investigator, SA, UIUX, 3D Design, etc.

Responses (2)

Write a response

Solution

You can use the following directive:
#cgo LDFLAGS: -L./lib -Wl,-rpath,$ORIGIN/lib -lsum
It instructs the linker to put in the executable file the info, that te library libsum should be searched for in the path starting from the location of the program…

10

export LD_LIBRARY_PATH=<project_folder>/libs/