Skip to content

Build Golang Binding

Claudia Misale edited this page Mar 23, 2021 · 9 revisions

In this page I am showing the steps I follow to build the Go binding on Mac.

Code can be found https://github.com/cmisale/flux-sched.git, in gobind-dev branch. Code for reapi_cli can be found here: https://github.com/milroy/flux-sched/tree/gobind-dev.

Disclaimer

The steps in this wiki assume you are using the above mentioned fork, as there are changes in the bionic Dockerfile. This build process is using GOPATH, but we might want to use go modules in the future. We need to find a more elegant way to build the binding, so that it can be integrated in the build process. Help/Feedback is welcome, of course.

Build Flux-Sched

First step is to build and run the flux-sched docker container. Notice that I use --no-home flag, as it allows me to avoid updating Go cache files local to my machine.

cd flux-sched
./src/test/docker/docker-run-checks.sh -I --no-home  --   ## this will run a container with all the dependencies, mounting the current folder
./autogen
./configure
make 

Build the Binding

Golang binaries

Golang is installed as a dependency in the container. The version available for bionic is 1.13, which is a bit old. For a newer version, you can find information here https://golang.org/doc/install.

Otherwise, you can find Golang binaries and GOPATHs in $PATH and $GOPATH, respectively.

Binding internals

To build the binding, we need the C binding to be already built, as we will use it from Go.

In resources/hlapi/bindings/go there are a few files

$ cd resource/hlapi/bindings/go/
$ tree
.
└── src
    ├── fluxcli
    │   ├── reapi_cli.go
    │   └── reapi_cli_test.go
    └── main
        └── main.go

The main.go is our development environment. The fluxcli folder contains the reapi_cli.go file, which is the root for the fluxcli package that we can import in main.go. There is also some dummy code for testing in reapi_cli_test.go. The fluxcli package contains the implementation of the same reapi_cli function names we find in the reapi_cli.h, which are actually called in Go by accessing the reapi_cli.la library in resource/hlapi/bindings/c/.libs.

For example

func NewReapiCli() *ReapiCtx {
	return (*ReapiCtx)(C.reapi_cli_new())
}

with C. syntax, we can access the functions defined reapi_cli library, and we can create objects defined in the library (like reapi_cli_ctx) that we can access in Go, as well as C types. For instance, here we create a typedef for an easy access to the reapi_cli_ctx_t struct defined in the reapi_cli library:

type (
	ReapiCtx C.struct_reapi_cli_ctx_t
)

Install the binding

First, we need to build the cli package. Notice that we need to specify the absolute path when including C binding header files and the libraries. Relative paths don't work.

Once in the flux-sched container, your current working directory should be usr/src. From there:

CGO_CFLAGS="-I/usr/src/resource/hlapi/bindings/c -I/usr/include" CGO_LDFLAGS="-L/usr/src/resource/hlapi/bindings/c/.libs -lreapi_cli -L/usr/lib -L/usr/src/resource/.libs -lresource -lstdc++ -lczmq -ljansson -lhwloc -lboost_system -lflux-hostlist -lboost_graph -lyaml-cpp" GOPATH="/usr/src/resource/hlapi/bindings/go" go install fluxcli

This will create the fluxcli package and install it in the GOPATH, which is set to the go binding folder. You should see something like that

cmisale@docker-desktop:/usr/src/resource/hlapi/bindings/go$ echo $GOPATH
/usr/src/resource/hlapi/bindings/go/
cmisale@docker-desktop:/usr/src/resource/hlapi/bindings/go$ tree
.
├── pkg
│   └── linux_amd64
│       └── fluxcli.a
└── src
    ├── fluxcli
    │   ├── reapi_cli.go
    │   └── reapi_cli_test.go
    └── main
        └── main.go

5 directories, 4 files

We can also try the test, to see if it works

CGO_CFLAGS="-I/usr/src/resource/hlapi/bindings/c -I/usr/include" CGO_LDFLAGS="-L/usr/src/resource/hlapi/bindings/c/.libs -lreapi_cli -L/usr/lib -L/usr/src/resource/.libs -lresource -lstdc++ -lczmq -ljansson -lhwloc -lboost_system -lflux-hostlist -lboost_graph -lyaml-cpp" GOPATH="/usr/src/resource/hlapi/bindings/go" go test
PASS
ok  	fluxcli	0.011s

Let's try out the main program. It is creating a cli context struct and prints it. Again, to build it I need to specify where Flux components are.

cd ../main

CGO_CFLAGS="-I/usr/src/resource/hlapi/bindings/c -I/usr/include" CGO_LDFLAGS="-L/usr/src/resource/hlapi/bindings/c/.libs -lreapi_cli -L/usr/lib -L/usr/src/resource/.libs -lresource -lstdc++ -lczmq -ljansson -lhwloc -lboost_system -lflux-hostlist -lboost_graph -lyaml-cpp" GOPATH="/usr/src/resource/hlapi/bindings/go" go build

./main --jgf=/usr/src/t/data/resource/jgfs/tiny.json --jobspec=/usr/src/t/data/resource/jobspecs/basics/test001.yaml

Troubleshooting

You may also need the GO111MODULE environment variable set to off to build main, e.g. in my (Dan's) container:

# GO111MODULE=off CGO_CFLAGS="-I/root/flux-sched/resource/hlapi/bindings/c -I/root/flux-install/include" CGO_LDFLAGS="-L/root/flux-sched/resource/hlapi/bindings/c/.libs -lreapi_cli -lstdc++" GOPATH="/root/flux-sched/resource/hlapi/bindings/go" go build -o main.go