Build static binary with cgo, LuaJIT and musl

Viewed 2277

After reading Statically compiled Go programs, always, even with cgo, using musl I'm trying to use described method to statically link LuaJIT.

Go code I try to build:

package main

import "github.com/aarzilli/golua/lua"
import "fmt"

func test(L *lua.State) int {
    fmt.Println("hello world! from go!")
    return 0
}

func test2(L *lua.State) int {
    arg := L.CheckInteger(-1)
    argfrombottom := L.CheckInteger(1)
    fmt.Print("test2 arg: ")
    fmt.Println(arg)
    fmt.Print("from bottom: ")
    fmt.Println(argfrombottom)
    return 0
}

func main() {
    L := lua.NewState()
    defer L.Close()
    L.OpenLibs()

    L.GetField(lua.LUA_GLOBALSINDEX, "print")
    L.PushString("Hello World!")
    L.Call(1, 0)

    L.PushGoFunction(test)
    L.PushGoFunction(test)
    L.PushGoFunction(test)
    L.PushGoFunction(test)

    L.PushGoFunction(test2)
    L.PushInteger(42)
    L.Call(1, 0)

    L.Call(0, 0)
    L.Call(0, 0)
    L.Call(0, 0)

    // this will fail as we didn't register test2 function
    err := L.DoString("test2(42)")

    fmt.Printf("Ciao %v\n", err)
}

Build command with parameters and output:

$ CC="/usr/local/musl/bin/musl-gcc" go build --ldflags '-linkmode external -extldflags "-static"' basic.go
# command-line-arguments
/usr/local/go/pkg/tool/linux_amd64/link: running /usr/local/musl/bin/musl-gcc failed: exit status 1
/usr/bin/ld: cannot find -lluajit-5.1
collect2: error: ld returned 1 exit status

Using LD_DEBUG=all I can get more information (8000+ lines).

My question: what is the problem and how to solve it? I think there can be some hint here but I can't quite grasp it.

I took following steps:

1. Build static LuaJIT library with musl.

$ make STATIC_CC="/usr/local/musl/bin/musl-gcc" CCOPT="-static -fPIC" BUILDMODE="static"
...
==== Successfully built LuaJIT 2.0.4 ====

2. Build dynamic LuaJIT library with musl.

$ make DYNAMIC_CC="/usr/local/musl/bin/musl-gcc" BUILDMODE="dynamic"
...
==== Successfully built LuaJIT 2.0.4 ====

3. Check build.

$ find . -iname *.a -o -iname *.so
./src/libluajit.a
./src/libluajit.so

4. Install it.

$ sudo make install
...
==== Successfully installed LuaJIT 2.0.4 to /usr/local ====

5. Check installation.

$ pkg-config luajit --cflags
-I/usr/include/luajit-2.0
$ pkg-config luajit --libs
-lluajit-5.1

6. Modify golua lua.go file to use hardcoded cgo parameters.

I had problems overriding those values so I simply modify source code.

old C comment with cgo parameters:

/*
#cgo CFLAGS: -I ${SRCDIR}/lua
#cgo llua LDFLAGS: -llua
#cgo luaa LDFLAGS: -llua -lm -ldl
#cgo linux,!llua,!luaa LDFLAGS: -llua5.1
#cgo darwin,!luaa pkg-config: lua5.1
#cgo freebsd,!luaa LDFLAGS: -llua-5.1
#cgo windows,!llua LDFLAGS: -L${SRCDIR} -llua -lmingwex -lmingw32
#include <lua.h>
#include <stdlib.h>
#include "golua.h"
*/
import "C"

new:

/*
#cgo CFLAGS: -I/usr/include/luajit-2.0 -I${SRCDIR}/lua
#cgo LDFLAGS: -lluajit-5.1
#include <lua.h>
#include <stdlib.h>
#include "golua.h"
*/
import "C"

7. Build some example

As shown at the beggining of question.

Where LuaJIT got installed:

$ find / -iname libluajit* 2> /dev/null
/usr/local/lib/libluajit-5.1.so.2
/usr/local/lib/libluajit-5.1.a
/usr/local/lib/libluajit-5.1.so
/usr/local/lib/libluajit-5.1.so.2.0.4
/usr/lib/libluajit-5.1.so.2.0.5
/usr/lib/libluajit-5.1.so.2
/usr/lib/libluajit-5.1.a
/usr/lib/libluajit-5.1.so
/usr/lib/libluajit.s

EDIT 1

I've followed @putu's comment and changed #cgo LDFLAGS to

#cgo LDFLAGS: -L/usr/local/lib -lluajit-5.1

now I have

$ CC="/usr/local/musl/bin/musl-gcc" go build --ldflags '-linkmode external -extldflags "-static -fPIC"' basic.go
# command-line-arguments
/usr/local/go/pkg/tool/linux_amd64/link: running /usr/local/musl/bin/musl-gcc failed: exit status 1
/tmp/go-link-916770907/000000.o: In function `printf':
/usr/include/x86_64-linux-gnu/bits/stdio2.h:104: undefined reference to `__printf_chk'
collect2: error: ld returned 1 exit status
1 Answers
Related