环境变量 GOPATH 的值可以是一个目录的路径,也可以包含多个目录路径,每个目录都代表 Go 语言的一个工作区(workspace)。这些工作区用于放置 Go 语言的源码文件(source file),以及安装(install)后的归档文件(archive file,也就是以“.a”为扩展名的文件)和可执行文件(executable file)。

1.GO语言源码的组织形式

Go 语言的源码是以代码包为基本组织单位的。在文件系统中,这些代码包其实是与目录一一对应的。目录可以有子目录,所以代码包也可以有子包。

一个代码包中可以包含任意个以.go 为扩展名的源码文件,这些源码文件都需要被声明为属于同一个代码包。代码包的名称一般会与这些源码文件所在的目录同名。如果不同名,那么在构建、安装的过程中会以代码包名称为准。

每个代码包都会有导入路径。代码包的导入路径是其他代码在使用该包中的程序实体时需要引入的路径。在实际使用程序实体之前,我们必须先导入其所在的代码包。具体的方式就是import该代码包的导入路径。就像这样:

import "github.com/labstack/echo"

在工作区中,一个代码包的导入路径实际上就是从 src 子目录,到该包的实际存储位置的相对路径。

所以说,Go 语言源码的组织方式就是以环境变量 GOPATH、工作区、src 目录和代码包为主线的。一般情况下,Go 语言的源码文件都需要被存放在环境变量 GOPATH 包含的某个工作区(目录)中的 src 目录下的某个代码包(目录)中。

2. 了解源码安装后的结果

我们都知道,源码文件通常会被放在某个工作区的 src 子目录下。那么在安装后如果产生了归档文件,就会放进该工作区的 pkg 子目录;如果产生了可执行文件,就可能会放进该工作区的 bin子目录。

源码文件会以代码包的形式组织起来,一个代码包其实就对应一个目录。安装某个代码包而产生的归档文件是与这个代码包同名的。放置它的相对目录就是该代码包的导入路径的直接父级。比如,一个已存在的代码包的导入路径是:

github.com/labstack/echo,

那么执行命令:

go install github.com/labstack/echo

生成的归档文件的相对目录就是 github.com/labstack, 文件名为 echo.a。

顺便说一下,上面这个代码包导入路径还有另外一层含义,那就是:该代码包的源码文件存在于 GitHub 网站的 labstack 组的代码仓库 echo 中。

归档文件的相对目录与 pkg 目录之间还有一级目录,叫做平台相关目录。平台相关目录的名称是由 build(也称“构建”)的目标操作系统、下划线和目标计算架构的代号组成的。

比如,构建某个代码包时的目标操作系统是 Linux,目标计算架构是 64 位的,那么对应的平台相关目录就是 linux_amd64。

因此,上述代码包的归档文件就会被放置在当前工作区的子目录 pkg/linux_amd64/github.com/labstack中。

总之,某个工作区的 src 子目录下的源码文件在安装后一般会被放置到当前工作区的 pkg 子目录下对应的目录中,或者被直接放置到该工作区的 bin 子目录中。

3. 理解构建和安装 Go 程序的过程

构建使用命令go build,安装使用命令go install。构建和安装代码包的时候都会执行编译、打包等操作,并且这些操作生成的任何文件都会先被保存到某个临时的目录中。

如果构建的是库源码文件,那么操作的结果文件只会存在于临时目录中。这里的构建的主要意义在于检查和验证。

如果构建的是命令源码文件,那么操作的结果文件会被搬运到那个源码文件所在的目录中。

安装操作会先执行构建,然后还会进行链接操作,并且把结果文件搬运到指定目录。进一步说,如果安装的是库源码文件,那么结果文件会被搬运到它所在工作区的+pkg+目录下的某个子目录中。

如果安装的是命令源码文件,那么结果文件会被搬运到它所在工作区的+bin+目录中,或者环境变量GOBIN指向的目录中。

这里需要记住的是,构建和安装的不同之处,以及执行相应命令后得到的结果文件都会出现在哪里。

4.go build命令一些可选项的用途和用法

在运行go build命令的时候,默认不会编译目标代码包所依赖的那些代码包。当然,如果被依赖的代码包的归档文件不存在,或者源码文件有了变化,那它还是会被编译。

如果要强制编译它们,可以在执行命令的时候加入标记-a。此时,不但目标代码包总是会被编译,它依赖的代码包也总会被编译,即使依赖的是标准库中的代码包也是如此。

另外,如果不但要编译依赖的代码包,还要安装它们的归档文件,那么可以加入标记-i。

那么我们怎么确定哪些代码包被编译了呢?有两种方法。

1.运行go build命令时加入标记-x,这样可以看到go build命令具体都执行了哪些操作。另外也可以加入标记-n,这样可以只查看具体操作而不执行它们。

2.运行go+build命令时加入标记-v,这样可以看到go+build命令编译的代码包的名称。它在与-a标记搭配使用时很有用。

下面再说一说与 Go 源码的安装联系很紧密的一个命令:go get。

命令go get会自动从一些主流公用代码仓库(比如 GitHub)下载目标代码包,并把它们安装到环境变量GOPATH包含的第 1 工作区的相应目录中。如果存在环境变量GOBIN,那么仅包含命令源码文件的代码包会被安装到GOBIN指向的那个目录。

最常用的几个标记有下面几种。

-u:下载并安装代码包,不论工作区中是否已存在它们。

-d:只下载代码包,不安装代码包。

-fix:在下载代码包后先运行一个用于根据当前 Go 语言版本修正代码的工具,然后再安装代码包。

-t:同时下载测试所需的代码包。

-insecure:允许通过非安全的网络协议下载和安装代码包。HTTP+就是这样的协议。

Go 语言官方提供的go get命令是比较基础的,其中并没有提供依赖管理的功能。目前+GitHub+上有很多提供这类功能的第三方工具,比如glide、gb以及官方出品的dep、vgo等等,它们在内部大都会直接使用go get。

有时候,我们可能会出于某种目的变更存储源码的代码仓库或者代码包的相对路径。这时,为了让代码包的远程导入路径不受此类变更的影响,我们会使用自定义的代码包导入路径。

对代码包的远程导入路径进行自定义的方法是:在该代码包中的库源码文件的包声明语句的右边加入导入注释,像这样:

package semaphore // import "golang.org/x/sync/semaphore"

这个代码包原本的完整导入路径是github.com/golang/sync/semaphore。这与实际存储它的网络地址对应的。该代码包的源码实际存在GitHub 网站的 golang 组的 sync 代码仓的 semaphore 目录下。而加入导入注释之后,用以下命令即可下载并安装该代码包了:

go get golang.org/x/sync/semaphore

而 Go 语言官网 golang.org 下的路径/x/sync/semaphore 并不是存放semaphore包的真实地址。我们称之为代码包的自定义导入路径。不过,这还需要在 golang.org 这个域名背后的服务端程序上添加一些支持才能使这条命令成功。

什么是归档文件?

归档文件在Linux下就是扩展名是.a的文件,也就是archive文件。写过C程序的朋友都知道,这是程序编译后生成的静态库文件。

GOPATH的更多相关文章

  1. GOPATH 使用总结

    GOPATH 环境变量用于指定这样一些目录:除 $GOROOT 之外的包含 Go 项目源代码和二进制文件的目录.go install 和 go 工具会用到 GOPATH:作为编译后二进制的存放目的地 ...

  2. 如何安装 第三方 Go 离线包? (GOPATH、 go install)

    有时候 go get 比较慢,可以考虑用迅雷等下载工具下载下来,然后再本地安装, 如:code.google.com/p/go.net/websocket,如何安装这些离线包? 先在你的 GOPATH ...

  3. 【Go入门教程1】Go 安装,GOROOT,GOPATH,Go工作空间

    Go安装 Windows 安装 访问Golang Code下载页,32 位请选择名称中包含 windows-386 的 msi 安装包,64 位请选择名称中包含 windows-amd64 的.下载好 ...

  4. Go语言的GOPATH与工作目录详解

    这篇文章主要介绍了Go语言的GOPATH与工作目录详解,本文详细讲解了GOPATH设置.应用目录结构.编译应用等内容,需要的朋友可以参考下 GOPATH设置 go 命令依赖一个重要的环境变量:$GOP ...

  5. Golang gopath

    golang 的gopath 至关重要,会影响到我们import package. golang 支持以相对路径的方式import,但是这种方式是不推荐的. 推荐的做法是在gopath中添加我们的项目 ...

  6. 【GoLang】GoLang GOPATH 工程管理 最佳实践

    参考资料: MAC下 Intellij IDEA GO语言插件安装及简单案例:http://blog.csdn.net/fenglailea/article/details/53054502 关于wi ...

  7. 再看GOPATH

    原本不打算介绍GOPATH,然而,总是有初学者问一些关于GOPATH的问题,因此在这里再介绍一下GOPATH GOPATH环境变量用于指定这样一些目录:除$GOROOT之外的包含Go项目源代码和二进制 ...

  8. go: GOPATH entry is relative; must be absolute path: "".

    安装:vscode-go出现以下提示: go: GOPATH entry is relative; must be absolute path: "".Run 'go help g ...

  9. macos系统下共语言gopath变量的设置

    一.问题 在macos下安装golang开发环境,想更改gopath路径,通过export GOPATH=/Volume/E/go 在vscode中通过go env命令查看GOPATH还是原始默认的, ...

  10. 初学者没有搞明白的GOROOT,GOPATH,GOBIN,project目录

    我们接下来一个一个来看关于Go语言中的三个目录的详细解释先通过go env查看go的环境变量(我这里是mac的环境,所以可能和你的不同) localhost:~ zhaofan$ go env GOA ...

随机推荐

  1. css的再深入7(更新中···)

    1.transparent  透明的 2.placeholder  提示语 写页面 搞清结构层次, 保证模块化,让他们之间不能受到影响 (1) 元素性质 (2) 标准流 浮动带来的脱离文档流撑不起父级 ...

  2. P3327 [SDOI2015]约数个数和

    思路 做这题先要知道一个性质, \[ d_{ij}=\sum_{x|i}\sum_{y|j}[(x,y)=1] \] 然后上莫比乌斯反演颓柿子就好了 \[ \begin{align}&\sum ...

  3. 一些有趣的 js 包

    https://github.com/octalmage/robotjs Node.js桌面自动化.控制鼠标,键盘和屏幕. http://robotjs.io

  4. FI 创建资产接口AS01

    FUNCTION ZREIP_CREATE_AS01TSET. *"------------------------------------------------------------- ...

  5. vue--音乐播放器

    github: https://github.com/vinieo/vue-music 效果: 基础组件: 1.confirm:确认对话框组件 2.listview:通讯录列表组件 3.loading ...

  6. 论Object.keys(), Object.getOwnPropertyNames(), for in, Object.getOwnPropertySymbol()区别

    前不久,一朋友求助,让我给解释一波Object.keys(), Object.getOwnPropertyNames(), for in的区别,面试中好几次呗问了.所以,抽了点时间看了看,大概把我看的 ...

  7. spark streaming将处理结果存入mysql中(使用c3p0连接池)

    1.c3p0相应的架包导入工程中 将以下四个架包导入工程, 主要有三个架包:c3p0-0.9.5.2.jar c3p0-oracle-thin-extras-0.9.5.2.jar mchange-c ...

  8. nrf52832-定时器例程

    SDK版本:15.20 代码 #include <stdbool.h> #include <stdint.h> #include "nrf_delay.h" ...

  9. Spring boot actuator端点启用和暴露

    1.启用端点 默认情况下,除了shutdown端点是关闭的,其它的都是启用的.配置一个端点的启用,使用management.endpoint..enabled属性,下面的例子是启用shutdown端点 ...

  10. z2-xcode使用

    @xcode区块命名 左边导航栏,右边工具栏,下边调试栏 @快捷键 最常用的#显示/隐藏导航栏:Command+ (反选一样Command+) #显示/隐藏工具栏:Command+Option+ (反 ...