Pack your program and it's external dependents to single-file!
Go projects will lose deployed-as-single-file when using CGO libraries, this gopack library can get it back!
You can also use this library to deploy C/C++, Java, Python and other programs as single-file!
Go version: go1.16 later.
Now you have the libvalue.c file
//libvalue.c
int getValue() { return 96; }It will generate the libvalue.so:
gcc -shared -fPIC -o libvalue.so libvalue.cAnd you want call getValue in Go:
//main.go
package main
//#cgo LDFLAG: -L. -lvalue
//extern int getValue();
import "C"
func main() {
value := int(C.getValue())
println(value)
}Compile Go program:
go build -o main.run main.goThe Go program will dependent the libvalue.so:
./main.run
#./main.run: error while loading shared libraries: libvalue.so: cannot open shared object file: No such file or directory
ldd main.run
#libvalue.so => not foundYou need to provide both main.run and libvalue.so , and instructions for settings the LD_LIBRARY_PATH environment variable :(
But gopack solves for now!
Look the single.go:
package main
import (
_ "embed"
"github.com/xuges/gopack"
)
//go:embed libvalue.so
var lib []byte
//go:embed main.run
var run []byte
func main() {
gopack.SetUnpackPath("unpacked")
gopack.AddDependency("lib/libvalue.so", lib)
gopack.AddExecutable("bin/main.run", run)
gopack.SetWorkerDir("extract/bin")
gopack.AddEnv("LD_LIBRARY_PATH=../lib")
err := gopack.Unpack()
if err != nil {
panic(err)
}
code, err := gopack.Run()
if err != nil {
panic(err)
}
println("program exit code:", code)
}Compile the single.go and run it:
go build -o single.run single.go
./single.run
#program exit code: 96The single.run packed main.run and libvalue.so, and then runs main.run after unpacking at runtime.
Now main.run can be deployed as a single file :)
ldd single.run
#not a dynamic executable