Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
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
51
Shattered Mirror: An Introduction to Reflect and Unsafe
jbowes
0
1.4k
Cloud Jumping With Kubernetes
jbowes
0
100
Building APIs for an unreliable world
jbowes
0
63
API Design Lessons From Kubernetes
jbowes
0
98
CL_Eye-Catching_User_Interfaces.pdf
jbowes
0
53
Level Triggered and Reconciled: How Kubernetes Manages its State
jbowes
0
140
Higher-Order Deployments: Reducing Boilerplate With Kubernetes Custom Resource Definitions
jbowes
0
56
Other Decks in Programming
See All in Programming
AWS CDK を「作」ってみた 〜フルスクラッチで見えた CDK の裏側〜 / aws-cdk-from-scratch
gotok365
3
2.6k
はてなアカウント基盤 State of the Union
cockscomb
1
1.3k
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
240
yield再入門 #phpcon
o0h
PRO
0
760
jsmini JavaScript Engine を作ってみた話
yosuke_furukawa
PRO
0
240
【SRE NEXT 2026 Lunch Session】一人目専任SREの立ち上げを加速する ― AIと進めたオンボーディングで2分を0.04秒にした話
pkshadeck
PRO
0
3.1k
全PRの83%がAIレビューだけでマージできるようになった開発組織はその後どうなったか
athug
0
450
初めてのKubernetes 本番運用でハマった話
oku053
0
130
What's New in Android 2026
veronikapj
0
210
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
180
分散システム、なんですぐ死んでしまうん?耐障害性を高めたいあなたのためのレジリエンスパターン入門
mshibuya
7
6.9k
Generative UI & AI-Assistants for Your Angular Solutions
manfredsteyer
PRO
1
230
Featured
See All Featured
How to Ace a Technical Interview
jacobian
281
24k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
230
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Designing for humans not robots
tammielis
254
26k
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
350
GitHub's CSS Performance
jonrohan
1033
470k
Everyday Curiosity
cassininazir
0
260
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
The Pragmatic Product Professional
lauravandoore
37
7.4k
Git: the NoSQL Database
bkeepers
PRO
432
67k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
180
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
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