一 前言
当完成一个应用的开发以后,往往下一步就是进行源码的编译。如 c 语言 gcc 编译一样,Go 在编译后只有一个二进制的文件,所以可以放到任何可支持的机器部署运行。简直就是“拎包入住”,爽的不要不要的。
在 Go 中和编译有关的命令有三个,它们分别是 go run、go build 和 go install。他们有着相似之处,也有着特殊之处。
二 go run
命令格式:go run [可选参数] 。
命令作用:编译完成并马上运行 Go 程序。
特殊说明:go run 只支持属于 main 包的一个或多个文件作为参数,不然是不能进行编译的。如下示例:
1. 有一个属于包 hello 的文件 hello.go。
2. 执行编译 go run hello/hello.go
然后提示错误:go run: cannot run non-main package
常用参数:
参数名 | 格式 | 含义 |
-o | -o file | 指定编译后二进制文件名 |
-importcfg | -importcfg file | 从文件中读取倒入配置 |
-s | -s | 省略符号表并调试信息 |
-w | -w | 省略 DWARF 符号表 |
-buildmode | -buildmode mode | 设置构建模式 - 默认为 exe |
-buildid | -buildid id | 将ID记录为Go工具链的构建ID |
-extld | -extld linker | 设置外部链接器 - 默认为 clang 或者 gcc |
-work | -work | 设置该参数后不会在程序结束后删掉编译的临时文件,可用于参看编译生成的文件 |
-n | -n | 加上该参数可以查看编译的过程,但不会继续执行编译后的二进制文件 |
-x | -x | 加上该参数可以查看编译的过程,会继续执行编译后的二进制文件 |
这里需要对后面两个参数进行额外说明。在使用 go run 编译时候会将二进制文件放到一个临时目录(位置和操作系统或GOTMPDIR有关。),所以想进行查看可以使用 -s 或 -n 命令。这里简单执行如下:
执行:go run -n main.go
输出:(不同的环境和版本可能有一些区别)
mkdir -p $WORK/b001/
cat >$WORK/b001/importcfg.link << 'EOF' # internal
packagefile command-line-arguments=/Users/ucwords/Library/Caches/go-build/f7/f74031c769cada462e650fd08e00423d8919ea05ae938cfd75d6f99042fa40e1-d
packagefile fmt=/usr/local/go/pkg/darwin_arm64/fmt.a
省略一些输出 ....
packagefile path=/usr/local/go/pkg/darwin_arm64/path.a
EOF
mkdir -p $WORK/b001/exe/
cd .
/usr/local/go/pkg/tool/darwin_arm64/link -o $WORK/b001/exe/main -importcfg $WORK/b001/importcfg.link -s -w -buildmode=exe -buildid=Z9AUzA7WCcfq28wnIXya/tTv-fSkYZRl5cgrbF4U7/JQ3FX5d_Usoe1qtn2xPj/Z9AUzA7WCcfq28wnIXya -extld=clang /Users/ucwords/Library/Caches/go-build/f7/f74031c769cada462e650fd08e00423d8919ea05ae938cfd75d6f99042fa40e1-d
$WORK/b001/exe/main
上面的输出主要干了这些事:
- 创建编译依赖需要的临时目录。在编译过程中设置一个临时环境变量 WORK,用于编译的工作区并执行编译后的二进制文件。可以通过 GOTMPDIR 设置。
- 编译和生产编译所需的依赖。编译如标准库、外部依赖、自身代码,然后生成、链接对应的归档和编译配置文件。
- 创建exe目录。 创建并进入编译二进制需要的零食目录。
- 生成可执行文件。
- 执行可执行文件。如上列中:$WORK/b001/exe/main。
三 go build
命令格式:go build [可选参数] 。
命令作用:编译指定的源文件、软件包和其他依赖,但是不会在编译后执行二进制文件。
特殊说明:go build 和 go run 在编译过程中其实是差不多的,不同之处是 go build 会生成编译好二进制文件并删掉编译过程产生的临时目录。若没有-o 指定文件名,则和当前目录名一致。
执行: go build -x main.go
输出:
...
...
mv $WORK/b001/exe/a.out main
// 多了这步
rm -r $WORK/b001/
常用参数:
参数名 | 格式 | 含义 |
-o | -o file | 指定编译后二进制文件名 |
-a | -a | 强制重新编译涉及的依赖 |
-s | -s | 省略符号表并调试信息 |
-w | -w | 省略 DWARF 符号表 |
-p | -p | 指定编译过程中的并发数,默认为CPU数 |
-work | -work | 设置该参数后不会在程序结束后删掉编译的临时文件,可用于参看编译生成的文件 |
-n | -n | 加上该参数可以查看编译的过程,但不会继续执行编译后的二进制文件 |
-x | -x | 加上该参数可以查看编译的过程,会继续执行编译后的二进制文件 |
四 go install
命令格式:go install [可选参数] 。
命令作用:编译并安装源文件、软件包,即把编译后的文件(可执行二进制文件、归档文件等)安装到指定的目录中。
特殊说明:将编译后的文件(可执行二进制文件、归档文件等)安装到指定的目录中。若设置了环境变量 GOBIN ,则把二进制可执行文件移到该目录。若禁用 Go modules 则放到 $GOPATH/pkg/$GOOS_$GOARCH下。
执行: go install -x main.go
输出:
...
mkdir -p /Users/ucwords/go/bin/
...
mv $WORK/b001/exe/a.out /Users/ucwords/go/bin/目标目录(go modules的目录名)
rm -r $WORK/b001/
常用参数:
参数名 | 格式 | 含义 |
-o | -o file | 指定编译后二进制文件名 |
-a | -a | 强制重新编译涉及的依赖 |
-s | -s | 省略符号表并调试信息 |
-w | -w | 省略 DWARF 符号表 |
-p | -p | 指定编译过程中的并发数,默认为CPU数 |
-work | -work | 设置该参数后不会在程序结束后删掉编译的临时文件,可用于参看编译生成的文件 |
-n | -n | 加上该参数可以查看编译的过程,但不会继续执行编译后的二进制文件 |
-x | -x | 加上该参数可以查看编译的过程,会继续执行编译后的二进制文件 |