>  기사  >  백엔드 개발  >  go install 명령의 용도는 무엇입니까?

go install 명령의 용도는 무엇입니까?

青灯夜游
青灯夜游원래의
2023-01-29 11:20:293908검색

"go install" 명령은 지정된 코드 패키지와 해당 종속 패키지를 컴파일하고 설치하는 데 사용됩니다. 지정된 코드 패키지의 종속 패키지가 컴파일 및 설치되지 않은 경우 이 명령은 먼저 종속 패키지를 처리합니다. "go install" 명령은 컴파일된 중간 파일을 GOPATH의 pkg 디렉토리에 배치하고 컴파일 결과를 GOPATH의 bin 디렉토리에 영구적으로 배치합니다.

go install 명령의 용도는 무엇입니까?

이 튜토리얼의 운영 환경: Windows 7 시스템, GO 버전 1.18, Dell G3 컴퓨터.

go 설치 명령 - 컴파일 및 설치

go install 명령은 지정된 코드 패키지와 해당 종속 패키지를 컴파일하고 설치하는 데 사용됩니다. 지정된 코드 패키지의 종속 패키지가 컴파일 및 설치되지 않은 경우 이 명령은 먼저 종속 패키지를 처리합니다. go build 명령과 마찬가지로 go install 명령에 전달된 코드 패키지 인수는 가져오기 경로 형식으로 제공되어야 합니다. 또한 go build 명령의 태그 대부분은 go install 명령에서도 사용할 수 있습니다. 실제로 go install 명령은 go build 명령보다 한 가지 작업만 더 수행합니다. 즉, 컴파일된 결과 파일을 지정된 디렉터리에 설치합니다. go install命令用于编译并安装指定的代码包及它们的依赖包。当指定的代码包的依赖包还没有被编译和安装时,该命令会先去处理依赖包。与go build命令一样,传给go install命令的代码包参数应该以导入路径的形式提供。并且,go build命令的绝大多数标记也都可以用于go install命令。实际上,go install命令只比go build命令多做了一件事,即:安装编译后的结果文件到指定目录。

在对go install命令进行详细说明之前,让我们先回顾一下goc2p的目录结构。为了节省篇幅,我在这里隐藏了代码包中的源码文件。如下:

$HOME/golang/goc2p:
    bin/
    pkg/
    src/
        cnet/
        logging/
        helper/
            ds/
        pkgtool/

我们看到,goc2p项目中有三个子目录,分别是bin目录、pkg目录和src目录。现在只有src目录中包含了一些目录,而其他两个目录都是空的。

现在,我们来看看安装代码包的规则。

安装代码包

如果go install命令后跟的代码包中仅包含库源码文件,那么go install命令会把编译后的结果文件保存在源码文件所在工作区的pkg目录下。对于仅包含库源码文件的代码包来说,这个结果文件就是对应的代码包归档文件(也叫静态链接库文件,名称以.a结尾)。相比之下,我们在使用go build命令对仅包含库源码文件的代码包进行编译时,是不会在当前工作区的src目录以及pkg目录下产生任何结果文件的。结果文件会出于编译的目的被生成在临时目录中,但并不会使当前工作区目录产生任何变化。

如果我们在执行go install命令时不后跟任何代码包参数,那么命令将试图编译当前目录所对应的代码包。比如,我们现在要安装代码包pkgtool

hc@ubt:~/golang/goc2p/src/pkgtool$ go install -v -work
WORK=D:\cygwin\tmp\go-build758586887
pkgtool

我们在前面说过,执行go install命令后会对指定代码包先编译再安装。其中,编译代码包使用了与go build命令相同的程序。所以,执行go install命令后也会首先建立一个名称以go-build为前缀的临时目录。如果我们想强行重新安装指定代码包及其依赖包,那么就需要加入标记-a:

hc@ubt:~/golang/goc2p/src/pkgtool$ go install -a -v -work
WORK=/tmp/go-build014992994
runtime
errors
sync/atomic
unicode
unicode/utf8
sort
sync
io
syscall
strings
bytes
bufio
time
os
path/filepath
pkgtool

可以看到,代码包pkgtool

go install 명령에 대해 자세히 설명하기 전에 먼저 goc2p의 디렉터리 구조를 살펴보겠습니다. 공간을 절약하기 위해 여기 코드 패키지의 소스 코드 파일을 숨겼습니다. 다음과 같습니다:

$HOME/golang/goc2p:
    bin/
    pkg/
        linux_386/
            pkgtool.a
    src/

goc2p 프로젝트에는 bin 디렉토리, pkg 디렉토리 및 src 디렉토리의 세 가지 하위 디렉토리가 있음을 알 수 있습니다. 이제 src 디렉토리에만 일부 디렉토리가 포함되어 있고 다른 두 디렉토리는 비어 있습니다.

이제 코드 패키지 설치 규칙을 살펴보겠습니다.

코드 패키지 설치

go install 명령 뒤에 오는 코드 패키지에 라이브러리 소스 코드 파일만 포함되어 있는 경우 go install 명령은 컴파일된 파일을 저장합니다. 결과 파일 소스 코드 파일이 위치한 작업 공간의 pkg 디렉터리에 있습니다. 라이브러리 소스 파일만 포함된 코드 패키지의 경우 이 결과 파일은 해당 코드 패키지 아카이브 파일입니다(정적 링크 라이브러리 파일이라고도 하며 이름은 .a로 끝남). 반면, go build 명령을 사용하여 라이브러리 소스 파일만 포함된 코드 패키지를 컴파일하면 현재 작업공간의 src 디렉터리와 pkg 디렉터리에 결과 파일이 생성되지 않습니다. 결과 파일은 컴파일 목적으로 임시 디렉토리에 생성되지만 현재 작업공간 디렉토리는 변경되지 않습니다.

코드 패키지 매개변수 없이 go install 명령을 실행하면 이 명령은 현재 디렉터리에 해당하는 코드 패키지를 컴파일하려고 시도합니다. 예를 들어, 이제 코드 패키지 pkgtool을 설치하려고 합니다. 🎜
hc@ubt:~/golang/goc2p/src/pkgtool$ go install -a -v -work ../cnet/ctcp
WORK=/tmp/go-build083178213
runtime
errors
sync/atomic
unicode
unicode/utf8
math
sync
sort
io
syscall
internal/singleflight
bytes
strings
strconv
bufio
math/rand
time
reflect
os
fmt
log
runtime/cgo
logging
net
cnet/ctcp
🎜앞서 말했듯이 go install 명령을 실행한 후 지정된 코드 패키지가 컴파일되고 그런 다음 설치되었습니다. 그 중 컴파일된 코드 패키지는 go build 명령과 동일한 프로그램을 사용합니다. 따라서 go install 명령을 실행한 후 이름 앞에 go-build가 붙은 임시 디렉터리가 먼저 생성됩니다. 지정된 코드 패키지와 해당 종속 패키지를 강제로 다시 설치하려면 -a 표시를 추가해야 합니다.🎜
hc@ubt:~/golang/goc2p/src/cnet/ctcp$ go install -v -work ~/golang/goc2p/src/cnet/ctcp
can't load package: package /home/hc/golang/goc2p/src/cnet/ctcp: import "/home/hc/golang/goc2p/src/cnet/ctcp": cannot import absolute path
🎜보시다시피 코드 패키지 pkgtool 언어 표준 라이브러리의 Go Code 패키지에만 의존합니다. 🎜🎜이제 goc2p 프로젝트 디렉터리를 살펴보겠습니다. 🎜
$HOME/golang/goc2p:
    bin/
    pkg/
        linux_386/
            /cnet
                ctcp.a
            logging.a
            pkgtool.a
    src/
🎜이제 pkg 디렉터리에 추가 하위 디렉터리가 있습니다. 섹션 0.0을 읽은 독자라면 linux_386이 플랫폼 관련 디렉터리라고 불리는 것을 이미 알고 있을 것입니다. 이름은 ${GOOS}_${GOARCH}에서 확인할 수 있습니다. 그 중 ${GOOS}, ${GOARCH}는 각각 현재 운영체제의 환경변수 GOOS, GOARCH의 값이다. 존재하지 않는 경우 Go 언어는 내부적으로 미리 결정된 값을 사용합니다. 위의 예는 컴퓨팅 아키텍처 386과 Linux 운영 체제를 갖춘 컴퓨터에서 실행됩니다. 따라서 여기서 플랫폼 관련 디렉터리는 linux_386입니다. 또한 goc2p 프로젝트의 플랫폼 관련 디렉터리에 pkgtool.a라는 파일이 있다는 것을 알 수 있습니다. 이는 코드 패키지 pkgtool의 아카이브 파일입니다. 파일 이름은 코드 패키지 이름과 ".a" 접미사의 조합입니다. 🎜🎜실제로 코드 패키지의 아카이브 파일은 항상 pkg 디렉터리의 플랫폼 관련 디렉터리에 직접 저장되는 것이 아니라, 이 플랫폼 관련 디렉터리의 하위 디렉터리에 저장될 수도 있습니다. 다음으로 cnet/ctcp 패키지를 설치합니다: 🎜
hc@ubt:~/golang/goc2p/src$ go install helper/ds/showds.go
go install: no install location for .go files listed on command line (GOBIN not set)
🎜 코드 패키지 pkgtool에 해당하는 디렉터리에 cnet/ctcp 패키지를 설치했습니다. 우리는 디렉터리 상대 경로를 사용했습니다. 🎜🎜실제로 이 코드 패키지의 위치를 ​​제공하는 방법을 로컬 코드 패키지 경로 방법이라고 하며, 앞서 소개한 go build 명령을 포함하여 모든 Go 명령에서 허용되는 방법이기도 합니다. 다만, 로컬 코드 패키지 경로는 디렉터리 상대 경로 형태로만 표현될 수 있으며, 디렉터리 절대 경로는 사용할 수 없다는 점에 유의해야 한다. 다음 예를 살펴보십시오. 🎜
hc@ubt:~/golang/goc2p/src$ echo $GOPATH
/home/hc/golang/lib:/home/hc/golang/goc2p
🎜 위 예의 명령 프롬프트 정보를 통해 디렉터리에 대한 절대 경로 형식으로 코드 패키지 위치를 제공하면 Go 명령이 인식되지 않는다는 것을 알 수 있습니다. 🎜

这是由于Go认为本地代码包路径的表示只能以“./”或“../”开始,再或者直接为“.”或“..”,而代码包的代码导入路径又不允许以“/”开始。所以,这种用绝对路径表示代码包位置的方式也就不能被支持了。

上述规则适用于所有Go命令。读者可以自己尝试一下,比如在执行go build命令时分别以代码包导入路径、目录相对路径和目录绝对路径的形式提供代码包位置,并查看执行结果。

我们已经通过上面的示例强行的重新安装了cnet/ctcp包及其依赖包。现在我们再来看一下goc2p的项目目录:

$HOME/golang/goc2p:
    bin/
    pkg/
        linux_386/
            /cnet
                ctcp.a
            logging.a
            pkgtool.a
    src/

我们发现在pkg目录的平台相关目录下多了一个名为cnet的目录,而在这个目录下的就是名为ctcp.a的代码包归档文件。由此我们可知,代码包归档文件的存放目录的相对路径(相对于当前工作区的pkg目录的平台相关目录)即为代码包导入路径除去最后一个元素后的路径。而代码包归档文件的名称即为代码包导入路径中的最后一个元素再加“.a”后缀。再举一个例子,如果代码包导入路径为x/y/z,则它的归档文件存放路径的相对路径即为x/y/,而这个归档文件的名称即为z.a。

回顾代码包pkgtool的归档文件的存放路径。因为它的导入路径中只有一个元素,所以其归档文件就被直接存放到了goc2p项目的pkg目录的平台相关目录下了。

此外,我们还发现pkg目录的平台相关目录下还有一个名为logging.a的文件。很显然,我们并没有显式的安装代码包logging。这是因为go install命令在安装指定的代码包之前,会先去安装指定代码包的依赖包。当依赖包被正确安装后,指定的代码包的安装才会开始。由于代码包cnet/ctcp依赖于goc2p项目(即当前工作区)中的代码包logging,所以当代码包logging被成功安装之后,代码包cnet/ctcp才会被安装。

还有一个问题:上述的安装过程涉及到了那么多代码包,那为什么goc2p项目的pkg目录中只包含该项目中代码包的归档文件呢?实际上,go install命令会把标准库中的代码包的归档文件存放到Go语言安装目录的pkg子目录中,而把指定代码包依赖的第三方项目的代码包的归档文件存放到当前工作区的pkg目录下。这样就实现了Go语言标准库代码包的归档文件与用户代码包的归档文件,以及处在不同工作区的用户代码包的归档文件之间的分离。

安装命令源码文件

除了安装代码包之外,go install命令还可以安装命令源码文件。为了看到安装命令源码文件是goc2p项目目录的变化,我们先把该目录还原到原始状态,即清除bin子目录和pkg子目录下的所有目录和文件。然后,我们来安装代码包helper/ds下的命令源码文件showds.go,如下:

hc@ubt:~/golang/goc2p/src$ go install helper/ds/showds.go
go install: no install location for .go files listed on command line (GOBIN not set)

这次我们没能成功安装。该Go命令认为目录/home/hc/golang/goc2p/src/helper/ds不在环境GOPATH中。我们可以通过Linux的echo命令来查看一下环境变量GOPATH的值:

hc@ubt:~/golang/goc2p/src$ echo $GOPATH
/home/hc/golang/lib:/home/hc/golang/goc2p

环境变量GOPATH的值中确实包含了goc2p项目的根目录。这到底是怎么回事呢?

我通过查看Go命令的源码文件找到了其根本原因。在上一小节我们提到过,在环境变量GOPATH中包含多个工作区目录路径时,我们需要在编译命令源码文件前先对环境变量GOBIN进行设置。实际上,这个环境变量所指的目录路径就是命令程序生成的结果文件的存放目录。go install命令会把相应的可执行文件放置到这个目录中。

由于命令go build在编译库源码文件后不会产生任何结果文件,所以自然也不用会在意结果文件的存放目录。在该命令编译单一的命令源码文件或者包含一个命令源码文件和多个库源码文件时,在结果文件存放目录无效的情况下会将结果文件(也就是可执行文件)存放到执行该命令时所在的目录下。因此,即使环境变量GOBIN的值无效,我们在执行go build命令时也不会见到这个错误提示信息。

然而,go install命令中一个很重要的步骤就是将结果文件(归档文件或者可执行文件)存放到相应的目录中。所以,go install命令在安装命令源码文件时,如果环境变量GOBIN的值无效,则它会在最后检查结果文件存放目录的时候发现这一问题,并打印与上述示例所示内容类似的错误提示信息,最后直接退出。

这个错误提示信息在我们安装多个库源码文件时也有可能遇到。示例如下:

hc@ubt:~/golang/goc2p/src/pkgtool$ go install envir.go fpath.go ipath.go pnode.go util.go
go install: no install location for .go files listed on command line (GOBIN not set)

而且,在我们为环境变量GOBIN设置了正确的值之后,这个错误提示信息仍然会出现。这是因为,只有在安装命令源码文件的时候,命令程序才会将环境变量GOBIN的值作为结果文件的存放目录。而在安装库源码文件时,在命令程序内部的代表结果文件存放目录路径的那个变量不会被赋值。最后,命令程序会发现它依然是个无效的空值。所以,命令程序会同样返回一个关于“无安装位置”的错误。这就引出一个结论,我们只能使用安装代码包的方式来安装库源码文件,而不能在go install命令罗列并安装它们。另外,go install命令目前无法接受标记-o以自定义结果文件的存放位置。这也从侧面说明了go install命令不支持针对库源码文件的安装操作。

至此,我们对怎样用go install命令来安装代码包以及命令源码文件进行了说明。如果你已经熟知了go build命令,那么理解这些内容应该不在话下。

【相关推荐:Go视频教程编程教学

위 내용은 go install 명령의 용도는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.