I am trying to build a binary that will contain different modules, but at the same time, I want the user to be able to choose what modules will be included in the generated binary.
I have also asked in SE stackoverflow: https://softwareengineering.stackexchange.com/questions/378319/building-object-with-arbitrary-functionalities
I think this is out of my knowledge and I might need some help with this.
I am thinking about writing another Go Program that strip out functions from the go files before compilation. I have never done/heard about this before and it seems to be a bit hacky. Just wondering what will be the best approach to this problem.
Thanks! I have also attached a testing code that I used.
package main
import (
"strings"
"fmt"
"bufio"
"os"
"reflect"
"./f"
"./g"
)
func main() {
// assume this is user input, enable f and disable g
var options = map[string]bool{
"f":true,
"g":false,
}
// a map for all the functions
m := map[string]interface{}{
"f": f.F,
"g": g.G,
}
// remove disabled function from the map
for k,v := range options {
if v == false{
delete(m, k)
}
}
// and now if user wanna use function g, it will return not ok since it is disabled in setting
// and function f will work
fmt.Println("Enter Options(f/g)")
reader := bufio.NewReader(os.Stdin)
user_input, _ := reader.ReadString('
')
user_input = strings.TrimSuffix(user_input, "
")
fmt.Println(user_input)
// take input from user... f
if x,ok := m[user_input]; ok {
function := reflect.ValueOf(x)
function_input := make([]reflect.Value, 1)
function_input[0]=reflect.ValueOf("123")
function.Call(function_input)
fmt.Println("OK")
} else {
fmt.Println("Option doesnt exist or disabled.")
}
}
Package g
package g
import "fmt"
func G(p string) { // removed second arguemt
fmt.Println("function g parameters:", p)
}
Package f
package f
import "fmt"
func F(p string) {
fmt.Println("function f parameter:", p)
}
What I did was just run env GOOS=linux GOARCH=386 go build test.go
and run objdump -t test
to see if the function is included in the binary after flipping the option values.
And you can see f and g are included in the binary, no matter the value of the option is true or false.
080bef10 g F .text 000000a7 main.f
080befc0 g F .text 000000c0 main.g
080bf080 g F .text 00000544 main.main
080bf5d0 g F .text 00000052 main.init
You can use Build Constraints You need to place each of your modules in separate file(s) . They don't need to be in a separate package.
At the top of each file in the foo
module you place:
// +build foo
And at top of each file in the bar
package you place
// +build bar
You can now build your binary with the foo module,
go build -tags foo ...
Or both
go build -tags 'foo bar' ...