Skip to content

Commit df29e33

Browse files
committed
golang编译知识
1 parent 8b6f336 commit df29e33

File tree

2 files changed

+121
-3
lines changed

2 files changed

+121
-3
lines changed

golang/README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,124 @@ go1.13.9 download 下载源码到用户目录下的sdk/go1.13.9 下
4242

4343
`-w, --workdir string` 指定工作目录
4444

45+
46+
## 动态链接和静态链接
47+
```
48+
$file helloworld-default
49+
helloworld-default: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
50+
$ldd helloworld-default
51+
不是动态可执行文件
52+
```
53+
54+
开启 CGO_ENABLED=1
55+
```
56+
// go-compilation/main-with-os-user.go
57+
58+
package main
59+
60+
import (
61+
"fmt"
62+
_ "os/user"
63+
)
64+
65+
func main() {
66+
fmt.Println("hello, world")
67+
}
68+
```
69+
70+
```
71+
$file helloworld-with-os-user
72+
helloworld-with-os-user: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
73+
74+
$ldd helloworld-with-os-user
75+
linux-vdso.so.1 => (0x00007ffcb8fd4000)
76+
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb5d6fce000)
77+
libc.so.6 => /lib64/libc.so.6 (0x00007fb5d6c00000)
78+
/lib64/ld-linux-x86-64.so.2 (0x00007fb5d71ea000)
79+
```
80+
通过nm命令我们还可以查看Go程序依赖了哪些C库的符号:
81+
```
82+
$nm -a helloworld-with-os-user |grep " U "
83+
U abort
84+
U __errno_location
85+
U fprintf
86+
U fputc
87+
U free
88+
U fwrite
89+
U malloc
90+
U mmap
91+
U munmap
92+
U nanosleep
93+
U pthread_attr_destroy
94+
U pthread_attr_getstack
95+
U pthread_attr_getstacksize
96+
U pthread_attr_init
97+
U pthread_cond_broadcast
98+
U pthread_cond_wait
99+
U pthread_create
100+
U pthread_detach
101+
U pthread_getattr_np
102+
U pthread_key_create
103+
U pthread_mutex_lock
104+
U pthread_mutex_unlock
105+
U pthread_self
106+
U pthread_setspecific
107+
U pthread_sigmask
108+
U setenv
109+
U sigaction
110+
U sigaddset
111+
U sigemptyset
112+
U sigfillset
113+
U sigismember
114+
U stderr
115+
U strerror
116+
U unsetenv
117+
U vfprintf
118+
```
119+
120+
### 依赖使用cgo的外部go包(静态链接)
121+
要想实现静态链接,我们需要找出外部go依赖的所有c库的.a文件(静态共享库)。以我们的go-sqlite3示例为例,go-sqlite3是sqlite库的go binding,它依赖sqlite库,同时所有第三方c库都依赖libc,我们还要准备一份libc的.a文件,下面我们就先安装这些:
122+
```
123+
$yum install -y gcc glibc-static sqlite-devel
124+
... ...
125+
126+
已安装:
127+
sqlite-devel.x86_64 0:3.7.17-8.el7_7.1
128+
129+
更新完毕:
130+
glibc-static.x86_64 0:2.17-326.el7_9.3
131+
```
132+
接下来,我们就来以静态链接的方式在go-compilation/go-sqlite3-static下编译一下:
133+
```
134+
$go build -tags 'sqlite_omit_load_extension' -ldflags '-linkmode external -extldflags "-static"' demo
135+
136+
$file ./demo
137+
./demo: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=c779f5c3eaa945d916de059b56d94c23974ce61c, not stripped
138+
```
139+
这里命令行中的`-tags 'sqlite_omit_load_extension'`用于禁用SQLite3的动态加载功能,确保更好的静态链接兼容性。而`-ldflags '-linkmode external -extldflags "-static"'`的含义是使用外部链接器(比如gcc linker),并强制静态链接所有库。
140+
141+
### 优化可执行文件的大小
142+
- 去除符号表和调试信息
143+
在编译时使用-ldflags="-s -w"标志可以去除符号表和调试符号,其中-s用于去掉符号表和调试信息,-w用于去掉DWARF调试信息,这样能显著减小文件体积。
144+
```
145+
$go build -ldflags="-s -w" -o helloworld-default-nosym main.go
146+
```
147+
148+
149+
- 使用tinygo
150+
[TinyGo](https://github.com/tinygo-org/tinygo)是一个Go语言的编译器,它专为资源受限的环境而设计,例如微控制器、WebAssembly和其他嵌入式设备。TinyGo的目标是提供一个轻量级的、能在小型设备上运行的Go运行时,同时尽可能支持Go语言的特性。tinygo的一大优点就是生成的二进制文件通常比标准Go编译器生成的文件小得多:
151+
```
152+
$tinygo build -o helloworld-tinygo main.go
153+
```
154+
155+
### 依赖CGO依赖CGO
156+
```
157+
go list -deps -f '{{.ImportPath}}: {{.CgoFiles}}' ./... | grep -v '\[\]'
158+
159+
go list -deps -f '{{.ImportPath}}: {{.CgoFiles}}' main-with-os-user.go | grep -v '\[\]'
160+
```
161+
162+
45163
## 其它
46164
https://go.dev/
47165

linux/tools.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,10 @@ scriptreplay -t time.txt session.typescript
296296
https://www.vanheusden.com/multitail/
297297

298298
### HTTP benchmarking tool压测工具
299-
wrk : https://github.com/wg/wrk 29.7k c
299+
wrk : https://github.com/wg/wrk 38k c
300300
ab : apachebench,Apache 网站服务器自带的
301-
hey : https://github.com/rakyll/hey 11.5k golang
302-
vegeta: https://github.com/tsenart/vegeta 17.7k golang
301+
hey : https://github.com/rakyll/hey 18.2k golang
302+
vegeta: https://github.com/tsenart/vegeta 23.6k golang
303303
ali: https://github.com/nakabonne/ali 2.8k golang (这款工具基于 vegeta,但使用起来更傻瓜式,而且实时进行分析,图形化展示。)
304304
plow: https://github.com/six-ddc/plow 2.3k golang 内部采用了性能出色的fasthttp而不是 Go 的默认net/http, 支持实时WebUI数据展示
305305

0 commit comments

Comments
 (0)