Сборка статического бинарного файла с использованием cgo, LuaJIT и musl
После прочтения статически скомпилированных программ Go, всегда, даже с cgo, используя musl, я пытаюсь использовать описанный метод для статической связи LuaJIT.
- Используя https://github.com/aarzilli/golua go bindings
- Предполагая, что musl и golua уже установлены
Перейти код, который я пытаюсь построить:
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)
}
Команда построения с параметрами и выводом:
$ 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
С помощью LD_DEBUG=all
Я могу получить больше информации ( более 8000 строк).
Мой вопрос: в чем проблема и как ее решить? Я думаю, что здесь может быть какая-то подсказка, но я не могу понять это.
Я предпринял следующие шаги:
1. Создайте статическую библиотеку LuaJIT с помощью musl.
$ make STATIC_CC="/usr/local/musl/bin/musl-gcc" CCOPT="-static -fPIC" BUILDMODE="static"
...
==== Successfully built LuaJIT 2.0.4 ====
2. Создайте динамическую библиотеку LuaJIT с помощью musl.
$ make DYNAMIC_CC="/usr/local/musl/bin/musl-gcc" BUILDMODE="dynamic"
...
==== Successfully built LuaJIT 2.0.4 ====
3. Проверьте сборку.
$ find . -iname *.a -o -iname *.so
./src/libluajit.a
./src/libluajit.so
4. Установите его.
$ sudo make install
...
==== Successfully installed LuaJIT 2.0.4 to /usr/local ====
5. Проверьте установку.
$ pkg-config luajit --cflags
-I/usr/include/luajit-2.0
$ pkg-config luajit --libs
-lluajit-5.1
6. Изменить golua lua.go
файл для использования в жестком коде cgo
параметры.
У меня были проблемы с переопределением этих значений, поэтому я просто модифицировал исходный код.
старый C
комментировать с cgo
параметры:
/*
#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"
новые:
/*
#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. Постройте пример
Как показано в начале вопроса.
Где был установлен LuaJIT:
$ 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
РЕДАКТИРОВАТЬ 1
Я следовал putu комментарием putu и изменил #cgo LDFLAGS
в
#cgo LDFLAGS: -L/usr/local/lib -lluajit-5.1
Теперь у меня есть
$ 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 ответ
putu указал мне правильное направление, все, что мне нужно было сделать, это настроить CFLAGS
включать musl
,
Убрано C
комментировать в lua.go
:
/*
#cgo CFLAGS: -I/usr/include/luajit-2.0 -I/usr/local/musl/include/
#cgo LDFLAGS: -L/usr/local/lib -lluajit-5.1
#include <lua.h>
#include <stdlib.h>
#include "golua.h"
*/
import "C"
Похоже, что все строит просто отлично:
$ CC="/usr/local/musl/bin/musl-gcc" go build --ldflags '-linkmode external -extldflags "-static"' basic.go
$ file basic
basic: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
$ ./basic
Hello World!
test2 arg: 42
from bottom: 42
hello world! from go!
hello world! from go!
hello world! from go!
Ciao [string "test2(42)"]:1: attempt to call global 'test2' (a nil value)