“go build” and “go install”


Let’s tidy up the $GOPATH directory and only keep Go source code files left over:

  1. # tree
  2. .
  3. ├── bin
  4. ├── pkg
  5. └── src
  6. ├── greet
  7. └── greet.go
  8. └── hello
  9. └── hello.go
  10. 5 directories, 2 files

The greet.go is greet package which just provides one function:

  1. # cat src/greet/greet.go
  2. package greet
  3. import "fmt"
  4. func Greet() {
  5. fmt.Println("Hello 中国!")
  6. }

While hello.go is a main package which takes advantage of greet and can be built into an executable binary:

  1. # cat src/hello/hello.go
  2. package main
  3. import "greet"
  4. func main() {
  5. greet.Greet()
  6. }

(1) Enter the src/hello directory, and execute go build command:

  1. # pwd
  2. /root/gowork/src/hello
  3. # go build
  4. # ls
  5. hello hello.go
  6. # ./hello
  7. Hello 中国!

We can see a fresh hello command is created in the current directory.

Check the $GOPATH directory:

  1. # tree
  2. .
  3. ├── bin
  4. ├── pkg
  5. └── src
  6. ├── greet
  7. └── greet.go
  8. └── hello
  9. ├── hello
  10. └── hello.go
  11. 5 directories, 3 files

Compared before executing go build, there is only a final executable command more.

(2) Clear the $GOPATH directory again:

  1. # tree
  2. .
  3. ├── bin
  4. ├── pkg
  5. └── src
  6. ├── greet
  7. └── greet.go
  8. └── hello
  9. └── hello.go
  10. 5 directories, 2 files

Running go install in hello directory:

  1. # pwd
  2. /root/gowork/src/hello
  3. # go install
  4. #

Check the $GOPATH directory now:

  1. # tree
  2. .
  3. ├── bin
  4. └── hello
  5. ├── pkg
  6. └── linux_amd64
  7. └── greet.a
  8. └── src
  9. ├── greet
  10. └── greet.go
  11. └── hello
  12. └── hello.go
  13. 6 directories, 4 files

Not only the hello command is generated and put into bin directory, but also the greet.a is in the pkg/linux_amd64. While the src folder keeps clean with only source code files in it and unchanged.

(3) There is -i flag in go build command which will install the packages that are dependencies of the target, but won’t install the target. Let’s check it:

  1. # tree
  2. .
  3. ├── bin
  4. ├── pkg
  5. └── src
  6. ├── greet
  7. └── greet.go
  8. └── hello
  9. └── hello.go
  10. 5 directories, 2 files

Run go build -i under hello directory:

  1. # pwd
  2. #/root/gowork/src/hello
  3. # go build -i

Check $GOPATH now:

  1. # tree
  2. .
  3. ├── bin
  4. ├── pkg
  5. └── linux_amd64
  6. └── greet.a
  7. └── src
  8. ├── greet
  9. └── greet.go
  10. └── hello
  11. ├── hello
  12. └── hello.go

Except a hello command in src/hello directory, a greet.a library is also generated in pkg/linux_amd64 too.

(4) By default, the go build uses the directory’s name as the compiled binary’s name, to modify it, you can use -o flag:

  1. # pwd
  2. /root/gowork/src/hello
  3. # go build -o he
  4. # ls
  5. he hello.go

Now, the command is he, not hello.