Jan 1, 2019

[Go] Execution modes

Reference:

Go Execution Modes - Ian Lance Taylor  https://goo.gl/mrzwCz
https://golang.org/cmd/link/
https://golang.org/cmd/go/#hdr-Build_modes
https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies
https://github.com/golang/go/issues/18246
https://blog.ksub.org/bytes/2017/02/12/exploring-shared-objects-in-go/


Legacy Go(v1.4.0) support 3 execution modes:

  1. A statically linked Go binary.
    Default for program does not import the net or os/user packages and does not use cgo or SWIG.
  2. A dynamically linked Go binary.
    Default for program imports the net or os/user packages and does not otherwise use cgo or SWIG
  3. A Go binary linked with arbitrary non-Go code.
    Default for program uses cgo or SWIG.
    The interface between Go and non-Go code is a C style API
    (SWIG permits calling between C++ and Go, but this is implemented using a C style API).
    Can be selected with -ldflags -linkmode=external. (obsolete)


API styles

  1. Go
  2. C, i.e extern "C"



Design in mind

  • Go code that is combined into a single executable image must be built with the same version of the Go toolchain.
  • We require further that if any Go package appears more than once in the executable image,
    it must be built from the same source code. (Same as C++'s header file)
  • This restriction comes from both ways: Golang <-> C



Go runtime:

  • All Go code shares a single runtime. 
  • All Go code uses the same memory allocator.
  • The same goroutine scheduler.
  • In general acts as though it were linked into a single Go program.



New execution modes:

  • Go code linked into, and called from, a non-Go program. (Go v.1.5.0)
    Go code acts as a library that may be called by a non-Go program.
    A single Go library will be an archive, a .a file on Unix,
    or as a shared library, a .so file on Unix, providing a C style API.
    This mode supports people who must work with large existing programs, especially in C/C++.
    It permits them to extend those existing programs with new packages written in Go.
    i.e the binary code is sheer an ELF format.
  • Go code linked into a shared library loaded as a plugin by a program (Go or non-Go) that supports a C style plugin API. (Go v1.6.0)
    i.e dlopen/dlmopen (dlmopen appears in glibc 2.3.4 for linker's namespace)
    https://sourceware.org/glibc/wiki/LinkerNamespaces
    Golang binary code in .so ELF format can be dlopened by C/C++.
  • Go code linked into a shared library loaded as a plugin by a Go program that supports a general Go style plugin API.
    A shared library can be dlopened by Golang.
    https://golang.org/pkg/plugin/
  • A Go program that uses a plugin interface, either C style or Go style, where plugins are implemented as shared libraries.
    Golang can dlopen any C/C++ .so libraries.
  • Building a Go package, or collection of packages, as a shared library that may be linked into a Go program. (Go v1.6.0)
    Single/Multiple Golang packages build into single shared library, which can be linked to other Golang program.
    Updating the Go run-time to a new version requires rebuilding all Go programs that use it.
  • A Go program built as a PIE--a Position Independent Executable. (Go v1.6.0)
    Go program is built as usual, but the resulting executable is position-independent, and may be relocated at run time.
    (i.e -fPIC in C/C++)



Go tool flags:

  • -buildmode
archive:
Default build mode for a package that is not main.
Builds the package into a .a file.

c-archive: (Go v1.5.0)
Requires a main package, but the main function is ignored (init functions are run as usual).
Build the main package, plus all packages that it imports, into a single C archive file.
The only callable symbols will be those functions marked as exported.

shared: (Go v1.6.0)
Combine all the listed packages into a single shared library that will be used when building with the -linkshared option.

c-shared: (Go v1.6.0)
Requires a main package as for -buildmode=c-archive
Build the main package, plus all packages that it imports, into a single C shared library.
The only callable symbols will be those functions marked as exported.

plugin:
Requires a main package as for -buildmode=c-archive
Build the main package, plus all packages that it imports, into a single shared library that may be loaded as a run-time plugin.

exe:
Default build mode for a package named main.

pie: (Go v1.6.0)
This is like -buildmode=exe , but it builds a Position Independent Executable.


-linkshared:

Directs to Go tool to use link against shared libraries when available.
When no shared library is available for some imported package, the ordinary archive will be used instead.
The -linkshared flag may be used with
-buildmode=shared, exe, pie
As the name suggests, -linkshared is NOT used for -buildmode=archive or c-archive


Hands on:

Build Golang's std library into shared library.
$ go install -buildmode=shared std

Build the shared code:
$ go install -buildmode=shared -linkshared github.com/your/lib/code

Use the shared library:
$ go install -linkshared github.com/your/main/code  // which imports "github.com/your/lib/code"

With a SONAME, and beware to put the compiled binary into the POSIX SONAME location/version.
$ go install \
-ldflags '-extldflags -Wl,-soname,libpikachu.so.0' \
-buildmode=shared \
-linkshared \
github.com/your/lib/code

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.