quapona technologies
The Go Gopher

In the second part of our Go series, we’ve learned how to install Go, setup the environment and compile our first Go program. In this part we will get to know Go's build-in tools. A full overview of all available Go commands can be found here. While installing Go not only build tools will be installed, but also several other tools, which ease the process of development, deployment and code management. You’ve already used three of the Go  tools while following the last article  (go env, go build and go install).

This article is split in three chapters, which will be released one by one in the coming days. The fi rst one will give you an overview of the standard commands for everyday use. The main tools for programming is discussed in the second section. In the third chapter, we present the more advanced tools and their use cases.

Please note, that we won’t talk about all the available arguments for every single tool. Instead, we will show the most useful ones in later examples of this series. As always, if you feel there is something missing or you have a question to a specific command, feel free to leave us a message.

Have Good Friends

The everyday tool set of a beginning Go programmer consists out of the already known tools env, build and install. We already know that the go env tool is printing the environment variables used by Go. The latter ones are those you will use the most. Let’s see what they do and how they work.

go build

From the official documentation one can read, that the build tool is compiling the source code in your packages and all their imports. Remembering the example from part 2, we created a file under $GOPATH/src/my.domain.com/awesomeuser/firstprog/main.go with the source code

package main
import “fmt”
func main() {
    fmt.Println(“You are an awesome programmer!”)
}
 

We used the build command to compile the main.go file with

:$ go build main.go 

which creates a file named main in the same directory. Another option is to use the command without providing a file name.

:$ go build 

This compiles a file named firstprog. The compiled binary name is assigned whether you’ve provided a file for compilation or not. If you specify a file to build, the resulting binary is named after the .go-file used. If you just use the go build command with no arguments the resulting binary will be named after the directory it resides.
Lets try another experiment by adding a second .go-file to the folder and building this one. Naively, we're copying the main.go file initially.

:$ cp main.go anothermain.go
:$ go build anothermain.go 

Now the build command creates a file called anothermain. Try to use the go build command without any arguments again and you will get an error like

:$ go build
./main.go:5: main redeclared in this block
previous declaration at ./anothermain.go:5 

This message tells you that the main function was found twice, because the go build call without arguments tries to compile  every .go-file in the current directory. The reason for the message above is clear, because you have two .go-files belonging to the same package, which are both declaring a function called main  .
Now we can open the anothermain.go file and change the first line

package main 

to

package anotherpackage 

and build it again with go build. You should get the output

:$ go build
can’t load package: package .: found packages anotherpackage (anothermain.go) and main (main.go) in /home/awesomeuser/golang/src/my.domain.com/awesomeuser/firstprog 

This time the error above shows a very important convention of Go.

Note: In one directory, it is only allowed to define one package in one or more .go-files.

As a C/C++ developer, this is quite a change-over. Later, while designing the system architecture, we have to define the workspace structure in more depth, too.
Another interesting feature of some Go tools is the -x flag that is available for the build tool, too. If you try it, the build tool will print the commands executed during the build steps

:$ go build -x main.go 
WORK=/tmp/go-build524517212
mkdir -p $WORK/command-line-arguments/_obj/
mkdir -p $WORK/command-line-arguments/_obj/exe/ 
cd /home/user/golang/src/my.domain.com/awesomeuser/firstprog
/usr/lib/go/pkg/tool/linux_amd64/compile -o $WORK/command-line-arguments.a -trimpath $WORK -p main -complete -buildid 337c5a1b5cd97ec880fbf88be06a678724f5e652 -D _/home/user/golang/src/my.domain.com/awesomeuser/firstprog -I $WORK -pack ./main.go 
cd .
/usr/lib/go/pkg/tool/linux_amd64/link -o $WORK/command-line-arguments/_obj/exe/a.out -L $WORK -extld=gcc -buildmode=exe -buildid=337c5a1b5cd97ec880fbf88be06a678724f5e652 $WORK/command-line-arguments.a 
mv $WORK/command-line-arguments/_obj/exe/a.out main 

The listing above contains the build command and the formatted output for a better overview. In the first block of the output the build command creates some temporary directories. The second block compiles the main.go file with the Go tool compile. The output is written to the file command-line-arguments.a. With the tool link, this archive is linked as an executable called a.out. At the end the newly created executable is moved to the original directory the command was called from.
If you already experienced with the toolchain of C and C++, you will notice, that the build steps of the Go tool build chain is similar to the one you probably already know. So our team is some more familiar with the magic happening in the background.

go install

The second tool you already know and used is the go install command. This command is a good example of the not-so-complete documentation of the Go tools. Using the --help argument you  get the following output

:$ go install --help
usage: install [build flags] [packages]

Install compiles and installs the packages named by the import paths,

along with their dependencies.

For more about the build flags, see 'go help build'. For more about specifying packages, see 'go help packages'.

See also: go build, go get, go clean.

which isn't quite satisfying at all. But if you try to pass the same arguments to the build flag field of the go install command as to the go build command, you get a first idea what it is doing.

:$ go install -x main.go 
WORK=/tmp/go-build518529880
mkdir -p $WORK/command-line-arguments/_obj/
mkdir -p $WORK/command-line-arguments/_obj/exe/ 
cd /home/user/golang/src/my.domain.com/awesomeuser/firstprog
/usr/lib/go/pkg/tool/linux_amd64/compile -o $WORK/command-line-arguments.a -trimpath $WORK -p main -complete -buildid 337c5a1b5cd97ec880fbf88be06a678724f5e652 -D _/home/user/golang/src/my.domain.com/awesomeuser/firstprog -I $WORK -pack ./main.go 
cd .
/usr/lib/go/pkg/tool/linux_amd64/link -o $WORK/command-line-arguments/_obj/exe/a.out -L $WORK -extld=gcc -buildmode=exe -buildid=337c5a1b5cd97ec880fbf88be06a678724f5e652 $WORK/command-line-arguments.a 
mkdir -p /home/user/golang/bin/
mv $WORK/command-line-arguments/_obj/exe/a.out /home/user/golang/bin/main 

Again, the output is formatted for a better overview. You should notice that the output is the same as from the go build tool, despite the last two lines. This is the so called installation the help message is talking about. The installation is composed of a mkdir command, which creates the bin folder in the GOPATH, and the mv command, which moves the output to the GOBIN path instead of the directory the go install command was executed in.

go run

Last but not least, you'll want to use the go run command in your everyday programmer business. This tool is, as the go install tool, composed of a build step (as done by go build) and direct execution of the build output.

:$ go run -x main.go 
WORK=/tmp/go-build351040585
mkdir -p $WORK/command-line-arguments/_obj/
mkdir -p $WORK/command-line-arguments/_obj/exe/ 
cd /home/user/golang/src/my.domain.com/awesomeuser/firstprog
/usr/lib/go/pkg/tool/linux_amd64/compile -o $WORK/command-line-arguments.a -trimpath $WORK -p main -complete -buildid 337c5a1b5cd97ec880fbf88be06a678724f5e652 -D _/home/user/golang/src/my.domain.com/awesomeuser/firstprog -I $WORK -pack ./main.go
 
cd .
/usr/lib/go/pkg/tool/linux_amd64/link -o $WORK/command-line-arguments/_obj/exe/main -L $WORK -w -extld=gcc -buildmode=exe -buildid=337c5a1b5cd97ec880fbf88be06a678724f5e652 $WORK/command-line-arguments.a
$WORK/command-line-arguments/_obj/exe/main
You are an awesome programmer! 

As you can see in the last line, the build program is executed right from the temporary directory and we get our praise from the terminal. Running the program in a temporary directory might give us some flexibility to avoid spamming data in our workspace in the future.

This was the first section of the built-in Go tools.
The next section will be about the tools you can use while programming Go programs.
If you like our articles, feel free to share them. Please post any questions and commentaries in the comments area below.

The quapona® technologies Developer Team

Kommentare powered by CComment

Beitrag teilen