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
210
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
50
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
62
API Design Lessons From Kubernetes
jbowes
0
97
CL_Eye-Catching_User_Interfaces.pdf
jbowes
0
52
Level Triggered and Reconciled: How Kubernetes Manages its State
jbowes
0
130
Higher-Order Deployments: Reducing Boilerplate With Kubernetes Custom Resource Definitions
jbowes
0
55
Other Decks in Programming
See All in Programming
Observability in Practice:Grafana 與 Edge Device SRE 的那些事
blueswen
0
120
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
140
Lemonade + Foundry Toolkit でお手軽アプリ開発
seosoft
1
310
AI時代の仕事技芸論 — ソフトウェア開発で「遊ぶように働く」職人的熟達のすすめ
kuranuki
1
610
New "Type" system on PicoRuby
pocke
1
470
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.3k
Lessons from Spec-Driven Development
simas
PRO
0
140
TAKTでAI駆動開発の品質を設計する
j5ik2o
6
930
ふつうのFeature Flag実践入門
irof
7
3.6k
The Arts and Crafts of Work in the AI Era — Toward Mastery in Software Development
kuranuki
1
720
AI駆動開発で崩れていくコードベースを立て直す
kyoko_nr_nr
1
440
Spec Driven Development | AI Summit Lisbon
danielsogl
PRO
0
150
Featured
See All Featured
Building the Perfect Custom Keyboard
takai
2
780
New Earth Scene 8
popppiees
3
2.3k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
410
End of SEO as We Know It (SMX Advanced Version)
ipullrank
3
4.2k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.7k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.9k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
320
Effective software design: The role of men in debugging patriarchy in IT @ Voxxed Days AMS
baasie
0
390
ラッコキーワード サービス紹介資料
rakko
1
3.5M
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
770
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
160
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