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
110
Building APIs for an unreliable world
jbowes
0
64
API Design Lessons From Kubernetes
jbowes
0
99
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
58
Other Decks in Programming
See All in Programming
Lean は証明の正しさを確認するためだけのツールって思ってませんか?
inoueasei
1
160
170k Jobs a Day on GKE: Scaling Mercari's CI Platform - and What's Next for AI-Native Development
junyaokabe
0
110
AI Readyの正体はデータマネジメントだ メダリオン2.0の最前線
freee
PRO
0
270
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
200
Go 1.27 における memory allocation の高速化
andpad
0
190
生成AIで帳票OCRが「簡単に」作れる時代になった?
kon_shou
0
1k
AI Engineeringは、AIプロダクトだけのものか? 〜AIがソフトウェアを作る時代の新しい当たり前〜 / No AI in your product. AI Engineering in your development.
rkaga
4
450
SlackアプリとLambdaの 連携を構築した話
pawn_4_s
1
120
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
4.6k
yield再入門 #phpcon
o0h
PRO
0
1.1k
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
5
1.7k
【やさしく解説 設計編・中級 #6】良いアーキテクチャとは ~ 一本の登り道の、行き先 ~
panda728
PRO
0
210
Featured
See All Featured
Groundhog Day: Seeking Process in Gaming for Health
codingconduct
0
280
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
490
Lightning Talk: Beautiful Slides for Beginners
inesmontani
PRO
2
630
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
530
Rails Girls Zürich Keynote
gr2m
96
14k
The Cost Of JavaScript in 2023
addyosmani
55
10k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
290
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
400
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
350
Thoughts on Productivity
jonyablonski
76
5.3k
Dominate Local Search Results - an insider guide to GBP, reviews, and Local SEO
greggifford
PRO
0
290
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