Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Write Once, Compile Lots, Run Anywhere
Search
James Bowes
November 08, 2019
Programming
220
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Write Once, Compile Lots, Run Anywhere
James Bowes
November 08, 2019
More Decks by James Bowes
See All by James Bowes
A Token Of Respect: Implementing Microservice Identity And Access Management In Go
jbowes
0
250
Shattered Mirror: An Introduction to Reflect and Unsafe
jbowes
0
53
Shattered Mirror: An Introduction to Reflect and Unsafe
jbowes
0
1.4k
Cloud Jumping With Kubernetes
jbowes
0
110
Building APIs for an unreliable world
jbowes
0
67
API Design Lessons From Kubernetes
jbowes
0
110
CL_Eye-Catching_User_Interfaces.pdf
jbowes
0
55
Level Triggered and Reconciled: How Kubernetes Manages its State
jbowes
0
150
Higher-Order Deployments: Reducing Boilerplate With Kubernetes Custom Resource Definitions
jbowes
0
58
Other Decks in Programming
See All in Programming
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
170
Embedded Swiftで作る自作USBデバイス によるiOSデバイスの自動テスト / iOSDC Japan 2026 glassfiber
glassfiber
0
310
re:Inventに行く前に知っておきたい現地参加のノウハウ
nokomoro3
0
390
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Rails World 2026, Austin, Texas
marcoroth
0
190
iOS 27でニュースアプリはどう変わる!? 〜日経電子版の新機能対応と、開発事例から〜
lynnswap
7
13k
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
580
Agentic Software Factoryに、すごく賢いIF文を。 / super smart IF statement into the Agentic Software Factory.
rkaga
8
2k
[2026-09-26]空論ジェネリックプロセス~テスト資産とAIで紡ぐ、再現可能なパフォーマンスチューニングの話~
tosite
0
260
Streamlitで実現する自然言語データアプリ開発
ayumu_yamaguchi
1
350
KiroのSpecで「五目並べ」を作ってみる
satoshi256kbyte
1
360
Domain-Driven Transformation
hschwentner
2
2.3k
外から家のPCの電源入れたい!をPHPで解決する
kawashimo0
1
120
Featured
See All Featured
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
720
Chasing Engaging Ingredients in Design
codingconduct
0
350
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
540
Ruling the World: When Life Gets Gamed
codingconduct
0
390
Game over? The fight for quality and originality in the time of robots
wayneb77
1
300
The Pragmatic Product Professional
lauravandoore
37
7.5k
Heart Work Chapter 1 - Part 1
lfama
PRO
10
37k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
510
How to Talk to Developers About Accessibility
jct
2
570
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.7k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.2k
Navigating Team Friction
lara
192
16k
Transcript
@jrbowes Compile Lots, Write Once, Run Anywhere
@jrbowes Write Once, Run Anywhere
@jrbowes Write Once, Run Anywhere
@jrbowes
@jrbowes
@jrbowes
@jrbowes
@jrbowes
@jrbowes
@jrbowes
@jrbowes
@jrbowes
@jrbowes
@jrbowes
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@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
@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
@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
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@jrbowes ★ Simple To Package And Ship
@jrbowes ★ Simple To Package And Ship $> go build
-o mybin .
@jrbowes ★ Simple To Package And Ship $> go build
-o mybin . $> file mybin mybin: Mach-O 64-bit executable x86_64
@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=
@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"
@jrbowes ★ Simple To Package And Ship
@jrbowes ★ Simple To Package And Ship $> GOOS=linux GOARCH=386
go build -o mybin .
@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
@jrbowes Use GoReleaser
@jrbowes Use GoReleaser QR Codes: Created in 1994
@jrbowes
@jrbowes
@jrbowes $> GOOS=linux GOARCH=amd64 go build -o mybin .
@jrbowes $> GOOS=linux GOARCH=amd64 go build -o mybin . $>
cat Dockerfile FROM ubuntu ENTRYPOINT ["/mybin"] COPY mybin /
@jrbowes $> GOOS=linux GOARCH=amd64 go build -o mybin . $>
cat Dockerfile FROM ubuntu ENTRYPOINT ["/mybin"] COPY mybin / $> docker build -t mybin .
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@jrbowes ★ No Extra Dependencies • Compiles to native code
— no interpreter or VM • Statically linked — everything in one binary
@jrbowes ★ No Extra Dependencies • Compiles to native code
— no interpreter or VM • Statically linked — everything in one binary
@jrbowes Asset Bundling
@jrbowes Asset Bundling
@jrbowes Asset Bundling
@jrbowes Asset Bundling
@jrbowes Try Pkger
@jrbowes Try Pkger Mark Bates: Also created in 1994
@jrbowes Static Compilation
@jrbowes Static Compilation $> GOOS=linux GOARCH=amd64 go build -o mybin
.
@jrbowes Static Compilation $> GOOS=linux GOARCH=amd64 go build -o mybin
. $> file mybin
@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
@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 .
@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
@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
@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
@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
@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)
@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)
@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)
@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)
@jrbowes (Not So) Static Compilation
@jrbowes (Not So) Static Compilation $> ./my-bin
@jrbowes (Not So) Static Compilation $> ./my-bin /bin/sh: ./mybin: not
found
@jrbowes (Not So) Static Compilation $> ./my-bin /bin/sh: ./mybin: not
found $> ./not-real
@jrbowes (Not So) Static Compilation $> ./my-bin /bin/sh: ./mybin: not
found $> ./not-real /bin/sh: ./not-real: not found
@jrbowes (Not So) Static Compilation
@jrbowes (Not So) Static Compilation $> file mybin
@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
@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
@jrbowes Static Compilation “The cgo tool is enabled by default
for native builds on systems where it is expected to work.”
@jrbowes Disable cgo for easier distribution $> CGO_ENABLED=0 GOOS=linux GOARCH=386
\ go build -o mybin .
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@jrbowes ★ Broadly Compatible • Consistent behaviour across platforms •
Consistent support for features and packages
@jrbowes ★ Broadly Compatible The bright side of Not Invented
Here syndrome
@jrbowes Platform Specific Logic
@jrbowes Platform Specific Logic func (c *Certificate) Verify(opts VerifyOptions)(chains [][]*Certificate,
err error)
@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 …
@jrbowes Platform Specific Logic // Use Windows's own verification and
chain building. if opts.Roots == nil && runtime.GOOS == "windows" { return c.systemVerify(&opts) }
@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) …
@jrbowes Build Tags • Implicit: GOOS, GOARCH, go version… •
Explicit: go build -tags 'mytag'
@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) …
@jrbowes
@jrbowes
@jrbowes Build Tags
@jrbowes Build Tags // spaces are OR // +build linux
solaris
@jrbowes Build Tags // spaces are OR // +build linux
solaris // ! is NOT // +build !darwin
@jrbowes Build Tags // spaces are OR // +build linux
solaris // ! is NOT // +build !darwin // , is AND // +build linux,cgo
@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
@jrbowes Build Tags
@jrbowes Build Tags // +build aix dragonfly freebsd js,wasm linux
nacl netbsd openbsd solaris
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@jrbowes Good Multi-Platform Distribution ★ Support For Platforms You Care
About ★ Simple To Package And Ship ★ No Extra Dependencies ★ Broadly Compatible
@jrbowes Go: Thumbs up!
@jrbowes Go: Thumbs up!
@jrbowes Thank you! FIND ME github.com/jbowes twitter.com/jrbowes manifold.co