Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Write Once, Compile Lots, Run Anywhere

James Bowes
November 08, 2019

Write Once, Compile Lots, Run Anywhere

James Bowes

November 08, 2019
Tweet

More Decks by James Bowes

Other Decks in Programming

Transcript

  1. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
  2. @jrbowes ★ Support For Platforms You Care About $> go

    tool dist list | column aix/ppc64 dragonfly/amd64 linux/arm64 nacl/amd64p32 openbsd/arm64 android/386 freebsd/386 linux/mips nacl/arm plan9/386 android/amd64 freebsd/amd64 linux/mips64 netbsd/386 plan9/amd64 android/arm freebsd/arm linux/mips64le netbsd/amd64 plan9/arm android/arm64 illumos/amd64 linux/mipsle netbsd/arm solaris/amd64 darwin/386 js/wasm linux/ppc64 netbsd/arm64 windows/386 darwin/amd64 linux/386 linux/ppc64le openbsd/386 windows/amd64 darwin/arm linux/amd64 linux/s390x openbsd/amd64 windows/arm darwin/arm64 linux/arm nacl/386 openbsd/arm
  3. @jrbowes ★ Support For Platforms You Care About $> go

    tool dist list | column aix/ppc64 dragonfly/amd64 linux/arm64 nacl/amd64p32 openbsd/arm64 android/386 freebsd/386 linux/mips nacl/arm plan9/386 android/amd64 freebsd/amd64 linux/mips64 netbsd/386 plan9/amd64 android/arm freebsd/arm linux/mips64le netbsd/amd64 plan9/arm android/arm64 illumos/amd64 linux/mipsle netbsd/arm solaris/amd64 darwin/386 js/wasm linux/ppc64 netbsd/arm64 windows/386 darwin/amd64 linux/386 linux/ppc64le openbsd/386 windows/amd64 darwin/arm linux/amd64 linux/s390x openbsd/amd64 windows/arm darwin/arm64 linux/arm nacl/386 openbsd/arm
  4. @jrbowes ★ Support For Platforms You Care About $> go

    tool dist list | column aix/ppc64 dragonfly/amd64 linux/arm64 nacl/amd64p32 openbsd/arm64 android/386 freebsd/386 linux/mips nacl/arm plan9/386 android/amd64 freebsd/amd64 linux/mips64 netbsd/386 plan9/amd64 android/arm freebsd/arm linux/mips64le netbsd/amd64 plan9/arm android/arm64 illumos/amd64 linux/mipsle netbsd/arm solaris/amd64 darwin/386 js/wasm linux/ppc64 netbsd/arm64 windows/386 darwin/amd64 linux/386 linux/ppc64le openbsd/386 windows/amd64 darwin/arm linux/amd64 linux/s390x openbsd/amd64 windows/arm darwin/arm64 linux/arm nacl/386 openbsd/arm
  5. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
  6. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
  7. @jrbowes ★ Simple To Package And Ship $> go build

    -o mybin . $> file mybin mybin: Mach-O 64-bit executable x86_64
  8. @jrbowes ★ Simple To Package And Ship $> go build

    -o mybin . $> file mybin mybin: Mach-O 64-bit executable x86_64 $> go env | grep -e ARCH= -e OS=
  9. @jrbowes ★ Simple To Package And Ship $> go build

    -o mybin . $> file mybin mybin: Mach-O 64-bit executable x86_64 $> go env | grep -e ARCH= -e OS= GOARCH="amd64" GOHOSTARCH="amd64" GOHOSTOS="darwin" GOOS="darwin"
  10. @jrbowes ★ Simple To Package And Ship $> GOOS=linux GOARCH=386

    go build -o mybin . $> file mybin mybin: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, Go BuildID=BsI7W6-gfNe589qm79AK/ HNGwNEScRjtQ48lwr1I_/gaYHO-EnYpDZEfeZfj5y/ mucU2QyPI7SKOAIiU0Ip, not stripped
  11. @jrbowes $> GOOS=linux GOARCH=amd64 go build -o mybin . $>

    cat Dockerfile FROM ubuntu ENTRYPOINT ["/mybin"] COPY mybin /
  12. @jrbowes $> GOOS=linux GOARCH=amd64 go build -o mybin . $>

    cat Dockerfile FROM ubuntu ENTRYPOINT ["/mybin"] COPY mybin / $> docker build -t mybin .
  13. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
  14. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
  15. @jrbowes ★ No Extra Dependencies • Compiles to native code

    — no interpreter or VM • Statically linked — everything in one binary
  16. @jrbowes ★ No Extra Dependencies • Compiles to native code

    — no interpreter or VM • Statically linked — everything in one binary
  17. @jrbowes Static Compilation $> GOOS=linux GOARCH=amd64 go build -o mybin

    . $> file mybin mybin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=9o-4CdGfdGNZI6qjvI3f/ NQvS9hSCir0F4HyOUCfA/NPmlomWGgx9zKs2QPYAW/ dOg15syGcYsIpCSJeV6o, not stripped
  18. @jrbowes Static Compilation $> GOOS=linux GOARCH=amd64 go build -o mybin

    . $> file mybin mybin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=9o-4CdGfdGNZI6qjvI3f/ NQvS9hSCir0F4HyOUCfA/NPmlomWGgx9zKs2QPYAW/ dOg15syGcYsIpCSJeV6o, not stripped $> GOOS=linux GOARCH=amd64 go build -o mybin-native .
  19. @jrbowes Static Compilation $> GOOS=linux GOARCH=amd64 go build -o mybin

    . $> file mybin mybin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=9o-4CdGfdGNZI6qjvI3f/ NQvS9hSCir0F4HyOUCfA/NPmlomWGgx9zKs2QPYAW/ dOg15syGcYsIpCSJeV6o, not stripped $> GOOS=linux GOARCH=amd64 go build -o mybin-native . $> file mybin-native
  20. @jrbowes Static Compilation $> GOOS=linux GOARCH=amd64 go build -o mybin

    . $> file mybin mybin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=9o-4CdGfdGNZI6qjvI3f/ NQvS9hSCir0F4HyOUCfA/NPmlomWGgx9zKs2QPYAW/ dOg15syGcYsIpCSJeV6o, not stripped $> GOOS=linux GOARCH=amd64 go build -o mybin-native . $> file mybin-native mybin-native: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux- x86-64.so.2, Go BuildID=qUlaMGoOyhvXwZau-GGh/ ItQcRvmsh30mFD0AG_Ze/SDeNJVYSF_TOVHk-06Dt/ BTU4CSv7GAsNuZKMxoIq, not stripped
  21. @jrbowes Static Compilation $> GOOS=linux GOARCH=amd64 go build -o mybin

    . $> file mybin mybin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=9o-4CdGfdGNZI6qjvI3f/ NQvS9hSCir0F4HyOUCfA/NPmlomWGgx9zKs2QPYAW/ dOg15syGcYsIpCSJeV6o, not stripped $> GOOS=linux GOARCH=amd64 go build -o mybin-native . $> file mybin-native mybin-native: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux- x86-64.so.2, Go BuildID=qUlaMGoOyhvXwZau-GGh/ ItQcRvmsh30mFD0AG_Ze/SDeNJVYSF_TOVHk-06Dt/ BTU4CSv7GAsNuZKMxoIq, not stripped
  22. @jrbowes Static Compilation $> GOOS=linux GOARCH=amd64 go build -o mybin

    . $> file mybin mybin: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, Go BuildID=9o-4CdGfdGNZI6qjvI3f/ NQvS9hSCir0F4HyOUCfA/NPmlomWGgx9zKs2QPYAW/ dOg15syGcYsIpCSJeV6o, not stripped $> GOOS=linux GOARCH=amd64 go build -o mybin-native . $> file mybin-native mybin-native: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux- x86-64.so.2, Go BuildID=qUlaMGoOyhvXwZau-GGh/ ItQcRvmsh30mFD0AG_Ze/SDeNJVYSF_TOVHk-06Dt/ BTU4CSv7GAsNuZKMxoIq, not stripped
  23. @jrbowes (Not So) Static Compilation $> ldd mybin linux-vdso.so.1 (0x00007fff55fd1000)

    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 … libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 … /lib64/ld-linux-x86-64.so.2 (0x00007f9574ffe000)
  24. @jrbowes (Not So) Static Compilation $> ldd mybin linux-vdso.so.1 (0x00007fff55fd1000)

    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 … libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 … /lib64/ld-linux-x86-64.so.2 (0x00007f9574ffe000)
  25. @jrbowes (Not So) Static Compilation $> ldd mybin linux-vdso.so.1 (0x00007fff55fd1000)

    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 … libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 … /lib64/ld-linux-x86-64.so.2 (0x00007f9574ffe000)
  26. @jrbowes (Not So) Static Compilation $> ldd mybin linux-vdso.so.1 (0x00007fff55fd1000)

    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 … libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 … /lib64/ld-linux-x86-64.so.2 (0x00007f9574ffe000)
  27. @jrbowes (Not So) Static Compilation $> ./my-bin /bin/sh: ./mybin: not

    found $> ./not-real /bin/sh: ./not-real: not found
  28. @jrbowes (Not So) Static Compilation $> file mybin mybin: ELF

    64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=qUlaMGoOyhvXwZau-GGh/ItQcRvmsh30mFD0AG_Ze/ SDeNJVYSF_TOVHk-06Dt/BTU4CSv7GAsNuZKMxoIq, not stripped
  29. @jrbowes (Not So) Static Compilation $> file mybin mybin: ELF

    64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, Go BuildID=qUlaMGoOyhvXwZau-GGh/ItQcRvmsh30mFD0AG_Ze/ SDeNJVYSF_TOVHk-06Dt/BTU4CSv7GAsNuZKMxoIq, not stripped
  30. @jrbowes Static Compilation “The cgo tool is enabled by default

    for native builds on systems where it is expected to work.”
  31. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
  32. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
  33. @jrbowes Platform Specific Logic func (c *Certificate) Verify(opts VerifyOptions)(chains [][]*Certificate,

    err error) type VerifyOptions struct { DNSName string Intermediates *CertPool Roots *CertPool // if nil, the system roots are used …
  34. @jrbowes Platform Specific Logic // Use Windows's own verification and

    chain building. if opts.Roots == nil && runtime.GOOS == "windows" { return c.systemVerify(&opts) }
  35. @jrbowes Platform Specific Logic // root_unix.go func (c *Certificate) systemVerify(opts

    *VerifyOptions) (chains [][]*Certificate, err error) { return nil, nil } // root_windows.go // systemVerify is like Verify, except that it uses CryptoAPI calls // to build certificate chains and verify them. func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { hasDNSName := opts != nil && len(opts.DNSName) > 0 storeCtx, err := createStoreContext(c, opts) …
  36. @jrbowes Build Tags // root_unix.go func (c *Certificate) systemVerify(opts *VerifyOptions)

    (chains [][]*Certificate, err error) { return nil, nil } // root_windows.go // systemVerify is like Verify, except that it uses CryptoAPI calls // to build certificate chains and verify them. func (c *Certificate) systemVerify(opts *VerifyOptions) (chains [][]*Certificate, err error) { hasDNSName := opts != nil && len(opts.DNSName) > 0 storeCtx, err := createStoreContext(c, opts) …
  37. @jrbowes Build Tags // spaces are OR // +build linux

    solaris // ! is NOT // +build !darwin
  38. @jrbowes Build Tags // spaces are OR // +build linux

    solaris // ! is NOT // +build !darwin // , is AND // +build linux,cgo
  39. @jrbowes Build Tags // spaces are OR // +build linux

    solaris // ! is NOT // +build !darwin // , is AND // +build linux,cgo // multi lines are AND // +build linux,darwin // +build cgo
  40. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
  41. @jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care

    About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible