CGO ld: Undefined symbols

Skip to first unread message


Feb 19, 2024, 5:51:56 AMFeb 19
to golang-nuts
Hello all,

I try to build a Go library that uses Lua. This library will be used together with an executable that contains the Lua functions, so I (believe) I don't need to have the dynamic Lua library.

My code:

package main

#include <lauxlib.h>
#include <lua.h>
#include <lualib.h>
#include <stdlib.h>

#cgo CFLAGS: -I/opt/homebrew/opt/lua@5.3/include/lua
import "C"
import "fmt"

func foo(L *C.lua_State) int {
    return 0

func main() {}

and the command line to compile (on the latest macOS X)

go build -buildmode=c-shared mylib.go

but the output is:

# command-line-arguments
/opt/homebrew/Cellar/go/1.21.0/libexec/pkg/tool/darwin_arm64/link: running cc failed: exit status 1
ld: Undefined symbols:
  _lua_gettop, referenced from:
      __cgo_513e18cdc587_Cfunc_lua_gettop in 000001.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

How can I fix this?

I know I can set the environment variable CGO_LDFLAGS to "-undefined dynamic_lookup"  before running the compile command, but this 1) does not sound like a good fix and 2) doesn't work for my cross commpile environment using migw on linux.

Any suggestions?

Thank you very much


Feb 19, 2024, 8:20:49 AMFeb 19
to golang-nuts
I'd like to state my observations (this is not a definitive answer).

On macOS it is okay to ignore the undefined symbols with -undefined dynamic_lookup
On Windows you need to link with a library containing the symbols 
On Linux you don't need to care at all... as long as the binary during runtime sees the symbols.

So my build script is something like this:

switch goos {
    case "darwin":
        cmd.Env = append(cmd.Env, "CGO_CFLAGS: -I/opt/homebrew/opt/lua@5.3/include/lua")
        cmd.Env = append(cmd.Env, "CGO_LDFLAGS=-undefined dynamic_lookup")
    case "linux":
        cmd.Env = append(cmd.Env, "CGO_CFLAGS=-I/usr/include/lua5.3")
    case "windows":
        cmd.Env = append(cmd.Env, "CGO_CFLAGS=-I/usr/include/lua5.3")
        cmd.Env = append(cmd.Env, "CGO_LDFLAGS=-llua53w64 -L/path/to/binary/with/lua/symbols/")

With this (don't forget GOOS, GOARCH and CGO_ENABLED) everything compiles (and runs) fine. But there might be pitfalls ignoring all the undefined symbols. 


Reply all
Reply to author
0 new messages