![](https://box.kancloud.cn/5b41838b1c6cbbd0a1a5f1c0ea8053bc_675x503.png)
~~~
-a: 强行对所有涉及到的代码包(包含标准库中的代码包)进行重新构建,即使它们已经是最新的了。 |
-n | 打印编译期间所用到的其它命令,但是并不真正执行它们。 |
-p n | 指定编译过程中执行各任务的并行数量(确切地说应该是并发数量)。在默认情况下,该数量等于CPU的逻辑核数。但是在`darwin/arm`平台(即iPhone和iPad所用的平台)下,该数量默认是`1`。 |
-race | 开启竞态条件的检测。不过此标记目前仅在`linux/amd64`、`freebsd/amd64`、`darwin/amd64`和`windows/amd64`平台下受到支持。 |
-v | 打印出那些被编译的代码包的名字。 |
-work | 打印出编译时生成的临时工作目录的路径,并在编译结束时保留它。在默认情况下,编译结束时会删除该目录。 |
-x 打印编译期间所用到的其它命令。注意它与-n标记的区别。
~~~
下面我们就用其中几个标记来查看一下在构建代码包`logging`时创建的临时工作目录的路径:
~~~bash
hc@ubt:~/golang/goc2p/src$ go build -v -work logging
WORK=/tmp/go-build888760008
logging
~~~
上面命令的结果输出的第一行是为了编译`logging`包,Go创建的一个临时工作目录,这个目录被创建到了Linux的临时目录下。输出的第二行是对标记`-v`的响应。这意味着此次命令执行时仅编译了`logging`包。关于临时工作目录的用途和内容,我们会在讲解`go run`命令和`go test`命令的时候详细说明。
现在我们再来看看如果强制重新编译会涉及到哪些代码包:
~~~bash
hc@ubt:~/golang/goc2p/src$ go build -a -v -work logging
WORK=/tmp/go-build929017331
runtime
errors
sync/atomic
math
unicode/utf8
unicode
sync
io
syscall
strings
time
strconv
reflect
os
fmt
log
logging
~~~
怎么会多编译了这么多代码包呢?可以确定的是,代码包`logging`中的代码直接依赖了标准库中的`runtime`包、`strings`包、`fmt`包和`log`包。那么其他的代码包为什么也会被重新编译呢?
从代码包编译的角度来说,如果代码包A依赖代码包B,则称代码包B是代码包A的依赖代码包(以下简称依赖包),代码包A是代码包B的触发代码包(以下简称触发包)。
标记`-p n`可以限制编译过程中任务执行的并发数量,`n`默认为当前计算机的CPU逻辑核数。如果在执行`go build`命令时加入标记`-p 1`,那么就可以保证代码包编译顺序严格按照预先设定好的优先级进行。现在我们再来编译`logging`包:
~~~bash
hc@ubt:~/golang/goc2p/src$ go build -a -v -work -p 1 logging
WORK=/tmp/go-build114039681
runtime
errors
sync/atomic
sync
io
math
syscall
time
os
unicode/utf8
strconv
reflect
fmt
log
unicode
strings
logging
~~~
我们可以认为,以上示例中所显示的代码包的顺序,就是`logging`包直接或间接依赖的代码包按照优先级从高到低排列后的排序。
另外,如果在命令中加入标记`-n`,那么编译程序只会输出所用到的命令而不会真正运行。在这种情况下,编译过程不会使用并发模式。
在本节的最后,我们对一些并不太常用的标记进行简要的说明:
* `-asmflags`
此标记可以后跟另外一些标记,如`-D`、`-I`、`-S`等。这些后跟的标记用于控制Go语言编译器编译汇编语言文件时的行为。
* `-buildmode`
此标记用于指定编译模式,使用方式如`-buildmode=default`(这等同于默认情况下的设置)。此标记支持的编译模式目前有6种。借此,我们可以控制编译器在编译完成后生成静态链接库(即.a文件,也就是我们之前说的归档文件)、动态链接库(即.so文件)或/和可执行文件(在Windows下是.exe文件)。
* `-compiler`
此标记用于指定当前使用的编译器的名称。其值可以为`gc`或`gccgo`。其中,gc编译器即为Go语言自带的编辑器,而gccgo编译器则为GCC提供的Go语言编译器。而GCC则是GNU项目出品的编译器套件。GNU是一个众所周知的自由软件项目。在开源软件界不应该有人不知道它。好吧,如果你确实不知道它,赶紧去google吧。
* `-gccgoflags`
此标记用于指定需要传递给gccgo编译器或链接器的标记的列表。
* `-gcflags`
此标记用于指定需要传递给`go tool compile`命令的标记的列表。
* `-installsuffix`
为了使当前的输出目录与默认的编译输出目录分离,可以使用这个标记。此标记的值会作为结果文件的父目录名称的后缀。其实,如果使用了`-race`标记,这个标记会被自动追加且其值会为`race`。如果我们同时使用了`-race`标记和`-installsuffix`,那么在`-installsuffix`标记的值的后面会再被追加`_race`,并以此来作为实际使用的后缀。
* `-ldflags`
此标记用于指定需要传递给`go tool link`命令的标记的列表。
首先加上编译参数`-ldflags`
`-s`相当于strip掉符号表, 但是以后就没办法在gdb里查看行号和文件了。`-w`告知连接器放弃所有debug信息
~~~
$ go build -ldflags '-w -s'
~~~
* `-linkshared`
此标记用于与`-buildmode=shared`一同使用。后者会使作为编译目标的非`main`代码包都被合并到一个动态链接库文件中,而前者则会在此之上进行链接操作。
* `-pkgdir`
使用此标记可以指定一个目录。编译器会只从该目录中加载代码包的归档文件,并会把编译可能会生成的代码包归档文件放置在该目录下。
* `-tags`
此标记用于指定在实际编译期间需要受理的编译标签(也可被称为编译约束)的列表。这些编译标签一般会作为源码文件开始处的注释的一部分,例如,在`$GOROOT/src/os/file_posix.go`开始处的注释为:
~~~go
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris windows
~~~
最后一行注释即包含了与编译标签有关的内容。大家可以查看代码包`go/build`的文档已获得更多的关于编译标签的信息。
* `-toolexec`
此标记可以让我们去自定义在编译期间使用一些Go语言自带工具(如`vet`、`asm`等)的方式。
- 基础
- 简介
- 主要特征
- 变量和常量
- 编码转换
- 数组
- byte与rune
- big
- sort接口
- 和mysql类型对应
- 函数
- 闭包
- 工作区
- 复合类型
- 指针
- 切片
- map
- 结构体
- sync.Map
- 随机数
- 面向对象
- 匿名组合
- 方法
- 接口
- 权限
- 类型查询
- 异常处理
- error
- panic
- recover
- 自定义错误
- 字符串处理
- 正则表达式
- json
- 文件操作
- os
- 文件读写
- 目录
- bufio
- ioutil
- gob
- 栈帧的内存布局
- shell
- 时间处理
- time详情
- time使用
- new和make的区别
- container
- list
- heap
- ring
- 测试
- 单元测试
- Mock依赖
- delve
- 命令
- TestMain
- path和filepath包
- log日志
- 反射
- 详解
- plugin包
- 信号
- goto
- 协程
- 简介
- 创建
- 协程退出
- runtime
- channel
- select
- 死锁
- 互斥锁
- 读写锁
- 条件变量
- 嵌套
- 计算单个协程占用内存
- 执行规则
- 原子操作
- WaitGroup
- 定时器
- 对象池
- sync.once
- 网络编程
- 分层模型
- socket
- tcp
- udp
- 服务端
- 客户端
- 并发服务器
- Http
- 简介
- http服务器
- http客户端
- 爬虫
- 平滑重启
- context
- httptest
- 优雅中止
- web服务平滑重启
- beego
- 安装
- 路由器
- orm
- 单表增删改查
- 多级表
- orm使用
- 高级查询
- 关系查询
- SQL查询
- 元数据二次定义
- 控制器
- 参数解析
- 过滤器
- 数据输出
- 表单数据验证
- 错误处理
- 日志
- 模块
- cache
- task
- 调试模块
- config
- 部署
- 一些包
- gjson
- goredis
- collection
- sjson
- redigo
- aliyunoss
- 密码
- 对称加密
- 非对称加密
- 单向散列函数
- 消息认证
- 数字签名
- mysql优化
- 常见错误
- go run的错误
- 新手常见错误
- 中级错误
- 高级错误
- 常用工具
- 协程-泄露
- go env
- gometalinter代码检查
- go build
- go clean
- go test
- 包管理器
- go mod
- gopm
- go fmt
- pprof
- 提高编译
- go get
- 代理
- 其他的知识
- go内存对齐
- 细节总结
- nginx路由匹配
- 一些博客
- redis为什么快
- cpu高速缓存
- 常用命令
- Go 永久阻塞的方法
- 常用技巧
- 密码加密解密
- for 循环迭代变量
- 备注
- 垃圾回收
- 协程和纤程
- tar-gz
- 红包算法
- 解决golang.org/x 下载失败
- 逃逸分析
- docker
- 镜像
- 容器
- 数据卷
- 网络管理
- 网络模式
- dockerfile
- docker-composer
- 微服务
- protoBuf
- GRPC
- tls
- consul
- micro
- crontab
- shell调用
- gorhill/cronexpr
- raft
- go操作etcd
- mongodb