Porting applications to z/OS

This topic contains information about porting Go applications to z/OS®. To achieve execution of Go modules on z/OS, porting has to occur especially for modules of significant size. Porting Go is free of the endianness issues found in C/C++ and other statically compiled languages, but you nevertheless need to change or copy certain files for certain modules.

For example, build tags and file naming are two techniques used in Go that determine what platforms to build on. A file with a comment //+build zos or //go:build zos at the beginning will build on z/OS, a file with a tag of !zos will not build on z/OS, and a file with a name myfile_zos_s390x.go will build only on z/OS. Sometimes files will list platforms other than z/OS, in this case you may have to add zos to the list of platforms in the list. You need to determine whether to add tags or change names to certain files in the module. If not, you might run into undefined symbol errors during the build.

If the module has many dependent modules, you also need to port some of them by modifying their go.mod files.

Workspaces support

IBM® Open Enterprise SDK for Go has augmented the way module porting can work. You can modify the modules within workspaces, which is an easier way to have local changes to dependencies without changing your go.mod file. When porting modules, you must add any dependencies and sub-dependencies that require porting to your workspace and modify them there. The Go build and run commands will automatically pick up those changed modules.

For more details, see Controlling dependencies with workspaces.

Basic steps to port a dependent package

To port a dependent package to z/OS, take the following steps:

  1. Start with a clean environment with the following command:
    go clean; go clean -cache -modcache
  2. Download the package source using your preferred method (such as `git clone`).
  3. Check for go.mod file and update the version for any of the following extended modules by running go get module_path@latest:
    golang.org/x/crypto, golang.org/x/net, golang.org/x/sys, golang.org/x/term
    Note: For vendor directory, each time you update the go.mod file, you must execute the following command:
    go mod vendor
  4. Build the Go package with the following line:
    go build

    The version number for the extended module will be updated automatically to the latest.

  5. Check for build errors.
  6. If constants or functions are undefined, look for a place to add a zos build tag.
  7. Port this package and any additional dependent packages.
  8. Keep iterating and porting until the build is clean.
Tips:
  • Look for files with names like ..._linux.go. They are likely to be copied or modified for z/OS.
  • Look for files with build tags like 'go:build linux' or 'go:build !linux', which might need to add zos to the build tag: //go:build linux zos or //go:build !linux,!zos.
  • Look for go.mod file and update the version number to the word latest for crypto, net, sys, and term packages.
    Note: Perform go install after the updates are done so that the version number will be updated automatically to the latest.
  • For sycalls, modules often contain calls to the raw Syscall functions (Syscall, RawSyscall, Syscall6, RawSyscall6) on Linux®, which should be replaced with calls to the associated published APIs. For example, a call like:
    syscall.Syscall(SYS_FSTAT, uintptr(fd), uintptr(unsafe.Pointer(stat)), 0)

    will give an undefined syscall.Syscall build error on z/OS, but the equivalent call to the API syscall.Fstat(...) will work fine.

Clipboard porting example

Port git clone github.com/atotto/clipboard.git to z/OS by taking the following steps:

  1. Start with a clean environment with the following command:
    go clean; go clean -cache -modcache
  2. Download the Clipboard package with the following command:
    
    git clone git@github.com:atotto/clipboard.git
    cd clipboard
  3. Execute the following command:
    go build
    Note: The undefined constants:
    
    ./clipboard.go:10:9: undefined: readAll
    ./clipboard.go:15:9: undefined: writeAll
    Add zos to the build tag comment in:
    clipboard_unix.go
    It now reads as follows:
    //+build  freebsd linux netbsd openbsd solaris dragonfly zos
  4. Install the package with the following command:
    go install ./...

    The package is correctly built and installed.