[Libguestfs] [PATCH libnbd v2 2/3] Add outline framework for Go language bindings (golang).

Daniel P. Berrangé berrange at redhat.com
Wed Mar 18 09:32:50 UTC 2020


On Tue, Mar 17, 2020 at 09:20:12PM +0000, Richard W.M. Jones wrote:
> +
> +/*
> +#cgo CFLAGS:
> +#cgo LDFLAGS: -lnbd

I assume you support pkg-config for libnbd, and thus you
should just do

#cgo pkg-config: libnbd


> +
> +#include <config.h>
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include \"libnbd.h\"
> +
> +struct error {
> +  char *error;
> +  int errnum;
> +};
> +
> +static void
> +save_error (struct error *err)
> +{
> +  err->error = strdup (nbd_get_error ());
> +  err->errnum = nbd_get_errno ();
> +}
> +
> +static void
> +free_error (struct error *err)
> +{
> +  free (err->error);
> +}
> +
> +static struct nbd_handle *
> +_nbd_create_wrapper (struct error *err)
> +{
> +  struct nbd_handle *r;
> +
> +  r = nbd_create ();
> +  if (r == NULL)
> +    save_error (err);
> +  return r;
> +}
> +
> +// There must be no blank line between end comment and import!
> +// https://github.com/golang/go/issues/9733
> +*/
> +import \"C\"
> +
> +import (
> +    \"fmt\"
> +    \"runtime\"
> +    \"syscall\"
> +)
> +
> +/* Handle. */
> +type Libnbd struct {
> +    h *C.struct_nbd_handle
> +}
> +
> +/* Convert handle to string (just for debugging). */
> +func (h *Libnbd) String () string {
> +    return \"&Libnbd{}\"
> +}
> +
> +/* All functions (except Close) return ([result,] LibnbdError). */
> +type LibnbdError struct {
> +    Op string                // operation which failed
> +    Errmsg string            // string (nbd_get_error)
> +    Errno syscall.Errno      // errno (nbd_get_errno)
> +}
> +
> +func (e *LibnbdError) String() string {
> +    if e.Errno != 0 {
> +        return fmt.Sprintf (\"%%s: %%s\", e.Op, e.Errmsg);
> +    } else {
> +        return fmt.Sprintf (\"%%s: %%s: %%s\", e.Op, e.Errmsg, e.Errno);
> +    }
> +}
> +
> +/* Implement the error interface */
> +func (e *LibnbdError) Error() string {
> +     return e.String()
> +}
> +
> +func get_error (op string, c_err C.struct_error) *LibnbdError {
> +    errmsg := C.GoString (c_err.error)
> +    errno := syscall.Errno (c_err.errnum)
> +    return &LibnbdError{ Op : op, Errmsg : errmsg, Errno : errno }
> +}
> +
> +func closed_handle_error (op string) *LibnbdError {
> +    return &LibnbdError{ Op : op, Errmsg : \"handle is closed\",
> +                         Errno : syscall.Errno (0) }
> +}
> +
> +/* Create a new handle. */
> +func Create () (*Libnbd, error) {
> +    c_err := C.struct_error{}
> +    c_h := C._nbd_create_wrapper (&c_err)
> +    if c_h == nil {
> +        err := get_error (\"create\", c_err)
> +        C.free_error (&c_err)
> +        return nil, err
> +    }
> +    h := &Libnbd{h : c_h}
> +    // Finalizers aren't guaranteed to run, but try having one anyway ...
> +    runtime.SetFinalizer (h, (*Libnbd).Close)
> +    return h, nil
> +}
> +
> +/* Close the handle. */
> +func (h *Libnbd) Close () *LibnbdError {
> +    if h.h == nil {
> +        return closed_handle_error (\"close\")
> +    }
> +    C.nbd_close (h.h)
> +    h.h = nil
> +    return nil
> +}
> +
> +";
> diff --git a/generator/GoLang.mli b/generator/GoLang.mli
> new file mode 100644
> index 0000000..b8ec1b5
> --- /dev/null
> +++ b/generator/GoLang.mli
> @@ -0,0 +1,19 @@
> +(* nbd client library in userspace: generator
> + * Copyright (C) 2013-2020 Red Hat Inc.
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + *)
> +
> +val generate_golang_libnbd_go : unit -> unit
> diff --git a/generator/Makefile.am b/generator/Makefile.am
> index e499ca8..0389d70 100644
> --- a/generator/Makefile.am
> +++ b/generator/Makefile.am
> @@ -57,6 +57,8 @@ sources = \
>  	Python.ml \
>  	OCaml.mli \
>  	OCaml.ml \
> +	GoLang.mli \
> +	GoLang.ml \
>  	generator.ml \
>  	$(NULL)
>  
> diff --git a/generator/generator.ml b/generator/generator.ml
> index 1c97492..817c032 100755
> --- a/generator/generator.ml
> +++ b/generator/generator.ml
> @@ -55,3 +55,6 @@ let () =
>    output_to "ocaml/NBD.mli" OCaml.generate_ocaml_nbd_mli;
>    output_to "ocaml/NBD.ml" OCaml.generate_ocaml_nbd_ml;
>    output_to "ocaml/nbd-c.c" OCaml.generate_ocaml_nbd_c;
> +
> +  output_to "golang/src/libguestfs.org/libnbd/libnbd.go"
> +    GoLang.generate_golang_libnbd_go;
> diff --git a/golang/Makefile.am b/golang/Makefile.am
> new file mode 100644
> index 0000000..47234ff
> --- /dev/null
> +++ b/golang/Makefile.am
> @@ -0,0 +1,58 @@
> +# nbd client library in userspace
> +# Copyright (C) 2013-2020 Red Hat Inc.
> +#
> +# This library is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU Lesser General Public
> +# License as published by the Free Software Foundation; either
> +# version 2 of the License, or (at your option) any later version.
> +#
> +# This library is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +# Lesser General Public License for more details.
> +#
> +# You should have received a copy of the GNU Lesser General Public
> +# License along with this library; if not, write to the Free Software
> +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> +
> +include $(top_srcdir)/subdir-rules.mk
> +
> +# http://golang.org/doc/code.html#Organization
> +pkg = libguestfs.org/libnbd
> +
> +source_files = \
> +	src/$(pkg)/libnbd.go \
> +	src/$(pkg)/libnbd_*_test.go
> +
> +generator_built = \
> +	$(source_files)
> +
> +EXTRA_DIST = \
> +	src/$(pkg)/.gitignore \
> +	$(generator_built) \
> +	config-test.go \
> +	run-tests.sh
> +
> +if HAVE_GOLANG
> +
> +golangpkgdir = $(GOROOT)/pkg/$(GOOS)_$(GOARCH)/$(pkg)
> +golangsrcdir = $(GOROOT)/src/pkg/$(pkg)
> +
> +golangpkg_DATA = \
> +	pkg/$(GOOS)_$(GOARCH)/$(pkg).a
> +
> +pkg/$(GOOS)_$(GOARCH)/$(pkg).a: src/$(pkg)/libnbd.go
> +	$(top_builddir)/run $(GOLANG) install $(pkg)
> +
> +golangsrc_DATA = $(source_files)
> +
> +TESTS_ENVIRONMENT = pkg=$(pkg) LIBNBD_DEBUG=1
> +LOG_COMPILER = $(top_builddir)/run
> +TESTS = run-tests.sh
> +
> +endif
> +
> +CLEANFILES += src/$(pkg)/*~
> +
> +clean-local:
> +	rm -rf pkg
> diff --git a/golang/config-test.go b/golang/config-test.go
> new file mode 100644
> index 0000000..e104c71
> --- /dev/null
> +++ b/golang/config-test.go
> @@ -0,0 +1,34 @@
> +/* libnbd Go configuration test
> + * Copyright (C) 2013-2020 Red Hat Inc.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +/* This is called from ./configure to check that golang works
> + * and is above the minimum required version.
> + */
> +
> +package main
> +
> +func main() {
> +	/* XXX Check for minimum runtime.Version() >= "go1.1.1"
> +         * Unfortunately go version numbers are not easy to parse.
> +         * They have the 3 formats "goX.Y.Z", "release.rN" or
> +         * "weekly.YYYY-MM-DD".  The latter two formats are mostly
> +         * useless, and the first one is hard to parse.  See also
> +         * cmpGoVersion in
> +         * http://web.archive.org/web/20130402235148/http://golang.org/src/cmd/go/get.go?m=text
> +         */

I believe you can just achieve the version check using a build tag
comment at the top of the source file

eg to mandate go 1.10 or later:

 // +build go1.10

See build constraints here:

  https://golang.org/pkg/go/build/

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the Libguestfs mailing list