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
52
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
64
API Design Lessons From Kubernetes
jbowes
0
100
CL_Eye-Catching_User_Interfaces.pdf
jbowes
0
54
Level Triggered and Reconciled: How Kubernetes Manages its State
jbowes
0
140
Higher-Order Deployments: Reducing Boilerplate With Kubernetes Custom Resource Definitions
jbowes
0
58
Other Decks in Programming
See All in Programming
Building an Out-of-Order CPU
latte72
0
450
My Marp Sample
sinoue0108
0
140
GraphRAGのKnowledge Graphを 直接!見る/View-GraphRAG's-KnowledgeGraph-directly!
tyumugi1113
0
140
Hello, Hiroshima Geospatial Data! — Exploring DoboX with Python
ra0kley
0
160
Can LLMs Replicate 4 Years of Compose Migration? Exploring the boundaries of automation with 279 XML files from a real product
makun
0
130
FDEとは、何者なのか?
masapyon1212
0
120
AIの中の人になってみる
htkym
0
150
go-spidermonkeyでAIエージェントのCode Modeを実装する
syumai
3
1.5k
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
150
書籍「プロフェッショナルAI駆動開発」紹介スライド
juntaromatsumoto
0
940
Go を使い始めて 2 ヶ月の学び / My first two months with Go
contour_gara
0
410
Flow は今どうなっているか
mizdra
PRO
0
860
Featured
See All Featured
The Spectacular Lies of Maps
axbom
PRO
1
970
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
460
Writing Fast Ruby
sferik
630
63k
Accessibility Awareness
sabderemane
1
190
RailsConf 2023
tenderlove
30
1.5k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.8k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.3k
Rails Girls Zürich Keynote
gr2m
96
14k
Music & Morning Musume
bryan
47
7.4k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
850
GraphQLとの向き合い方2022年版
quramy
50
15k
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