一 前言

当完成一个应用的开发以后,往往下一步就是进行源码的编译。如 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

上面的输出主要干了这些事:

  1. 创建编译依赖需要的临时目录。在编译过程中设置一个临时环境变量 WORK,用于编译的工作区并执行编译后的二进制文件。可以通过 GOTMPDIR 设置。
  2. 编译和生产编译所需的依赖。编译如标准库、外部依赖、自身代码,然后生成、链接对应的归档和编译配置文件。
  3. 创建exe目录。 创建并进入编译二进制需要的零食目录。
  4. 生成可执行文件。
  5. 执行可执行文件。如上列中:$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

加上该参数可以查看编译的过程,会继续执行编译后的二进制文件