My problem is the following:
- I have a go binary on a machine
- From that binary I need to compile an external .go file
- Once compiled, I need to link the compiled go file into the current binary so I can use the just-compiled go code.
Do you think that's possible ?
I did a few researches and it does not seem to be possible, but I might have overlooked something.
Thanks :)
The first go binary would contain something like
func main() {
// Here I need to compile an external go file (or package) which contains
// The definition of runFoo()
// Once the file/package is compiled and linked I need to call the compiled code
runFoo()
// Continue the execution process normally here
}
Feature promiced since 1.5 :) http://talks.golang.org/2015/state-of-go-may.slide#23
Update: It is now possible to do this in mainline Go, see Go Execution Modes
From the Go 1.5 release notes:
Old Answer (useful discussion of other options):
It is not currently possible to create dynamically linked libraries* in main line Go. There has been some talk about this, so you may see support in the future. However, there is a 3rd party go project called goandriod that needed the same functionality you need, so they maintain patches that should allow you to patch the official Go code base to support the dynamic linked support you are requesting.
If you want to use a the standard Go run-time, I would recommend the one of the following. Invoke your Go program from your other program, and communicate using:
Each consecutive option will take more effort to setup, be more platform specific, but potentially be more powerful than the previous one.
*Note: That is DLLs in the Windows world, and .so files in the UNIX/Linux world.
I think go plugins could be also related to this question, they are supported from go version 1.8. It allows you to dynamically link go binaries implementing required interfaces at runtime.
For example your code has a dependency for a logging backend, but you'd like to support several of them and resolve it at runtime,
elasticsearch
andsplunk
could fit here. You might need to have 2 files:es.go
andsplunk.go
which should both contain a struct of typeLoggingBackend
implementing a methodWrite(log string)
.To create plugins you need to use buildmode
plugin
during compilation:After that you could pass the needed plugin via command line arguments and load it:
This is very possible, you can even compile it as a native shared library
nm -D --defined-only ./goc | grep "T"
like so (tested on go 1.5.1 linux/arm)
goc.go:
The ability to create shared libraries will be in Go 1.5 in August 2015¹.
From "The State of Go" talk by Andrew Gerrand:
¹ Note,
gccgo
already had limited support for this for some time, Go 1.5 will be the first time this is supported by the regular go build tools.