美文网首页
GO笔记(二)之GO编译流程

GO笔记(二)之GO编译流程

作者: 温岭夹糕 | 来源:发表于2022-07-19 10:22 被阅读0次

前置知识

程序如何到进程和ELF文件格式

1.编译go程序

我们先来追踪一下go build的过程
有如下coding(公寓网炸了,暂时用不了xshell,虚拟机界面太小不好截图,暂用网上例子,后续实验补充)
hello.go

package main

import "fmt"

func main() {
    fmt.Println("Hello World")
}

执行编译命令(-n表示不执行打印,-x表示执行并打印)

go build -n hello.go

打印结果如下

mkdir -p $WORK/b001/
cat >$WORK/b001/importcfg << 'EOF' # internal
# import config
packagefile fmt=/usr/local/go/pkg/darwin_amd64/fmt.a
packagefile runtime=/usr/local/go/pkg/darwin_amd64/runtime.a
EOF
cd /Users/polo/Public/Work/go/src/study/basic/hello
/usr/local/go/pkg/tool/darwin_amd64/compile -o $WORK/b001/_pkg_.a -trimpath $WORK/b001 -p main -complete -buildid fVbBEz0nTJc3r6VxU5ye/fVbBEz0nTJc3r6VxU5ye -goversion go1.11.1 -D _/Users/polo/Public/Work/go/src/study/basic/hello -importcfg $WORK/b001/importcfg -pack -c=4 ./hello.go
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/_pkg_.a # internal
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile command-line-arguments=$WORK/b001/_pkg_.a

...

packagefile internal/race=/usr/local/go/pkg/darwin_amd64/internal/race.a
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_amd64/link -o $WORK/b001/exe/a.out -importcfg $WORK/b001/importcfg.link -buildmode=exe -buildid=P1Y_fbNXAEG6zEEGqFsM/fVbBEz0nTJc3r6VxU5ye/fVbBEz0nTJc3r6VxU5ye/P1Y_fbNXAEG6zEEGqFsM -extld=clang $WORK/b001/_pkg_.a
/usr/local/go/pkg/tool/darwin_amd64/buildid -w $WORK/b001/exe/a.out # internal
mv $WORK/b001/exe/a.out hello

过程分析:
1.创建临时目录(这里的$WORK会临时赋值,我机器上指向的是tmp中临时创建的一个目录)

mkdir -p $WORK/b001/

2.查找依赖源

cat >$WORK/b001/importcfg << ...

3.执行源代码编译

/usr/local/go/pkg/tool/darwin_amd64/compile

4.收集链接库文件

cat >$WORK/b001/importcfg.link

5.生成可执行文件(链接)

/usr/local/go/pkg/tool/darwin_amd64/link -o 

6.移动可执行文件(从临时创建的目录中移出)

mv $WORK/b001/exe/a.out hello

我们可以看到大致过程和c程序的编译是大同小异:预处理->编译->链接。表现为显示过程就是compile与link

1.1Compile工具

从上文可知go build执行过程主要使用了compile和link两个工具,compile简单来说将同一个package的多个文件编译成一个.o文件 image.png

调用该工具使用命令

go tool compile --help

具体该工具干了啥可阅读(该工具本身是用go语言实现的)初识别go compile
大致过程可概括为

解析文件->解析语法->类型检查->编译->写入文件

咱们试一试

go tool compile -S hello.go | more

但生成的文件并不是一个二进制文件ELF格式,而是汇编代码文件(我们用objdump反汇编一下让我们能看懂)

go tool objdump hello.o

(go build -gcflags -S 也可以)

1.2Link工具

go tool link --help
负责将.o目标文件与其他对象组合成一个包档案或直接传给连接器(在上一章的c中动态链接也是靠链接器完成的),并将其组合到可执行的二进制文件中 image.png

1.3run指令

有了上面的知识储备我们再来看看run指令

go run -x hello.go
run指令

与build区别就是在链接完成后并没有移动文件,而是直接执行程序
如何拿到中间文件?使用--work选项

WORK=/var/folders/bw/8yw8h4yj2vb6mxtb6t8t41f00000gn/T/go-build149627400

可以拿到临时目录

1.4执行可执行文件步骤

1.解析ELF Header
2.加载文件内容至内存
3.从entry point开始执行代码(设置CS:IP寄存器)

readelf - h hello
readelf

参考

1.go编译执行流程
2.编译链接过程概述
3.main程序启动过程
4.得到go汇编程序的办法

相关文章

  • GO笔记(二)之GO编译流程

    前置知识 程序如何到进程和ELF文件格式[https://www.jianshu.com/p/d2a99b9169...

  • Golang 基础语法 (1)

    编译运行 代码的编译运行go build : 产生一个可执行二进制文件go run :go install : 会...

  • Go 编译流程

    参考资料 https://github.com/golang/go/blob/master/src/cmd/com...

  • Golang聚合

    教程 Go Web 编程Go语言圣经(中文版) Tips Golang 学习笔记——交叉编译 & 部署Golang...

  • go-day1

    Go 命令 go build :编译Go程序 go build -o "xx.exe" :编译成xx.exe文件 ...

  • Golang中的常用命令

    Go命令行有常用的这几个命令: go build 编译包和依赖 go run 编译和运行go程序 go insta...

  • Go学习笔记

    . 运行GO 编译go源文件go build main.go 执行编译好的文件 (可以再没有go开发环境的设备上运...

  • 交叉编译

    使用go的交叉编译 最后使用go build windows_fping.go 编译出.exe可执行文件 如果编译...

  • GO——学习笔记(三)

    上篇:GO——学习笔记(二) 下篇:GO——学习笔记(四) 参考: https://github.com/asta...

  • 使用 dlv 和 gdb 调试go程序

    编译构建go程序 禁止优化go build -gcflags "-N -l" ... 查看详细的编译命令go bu...

网友评论

      本文标题:GO笔记(二)之GO编译流程

      本文链接:https://www.haomeiwen.com/subject/amxeirtx.html