Go cli: Difference between revisions
(12 intermediate revisions by the same user not shown) | |||
Line 89: | Line 89: | ||
/home/iwiseman/dev/courses/go-cli/03/demos/demos/03-race/main.go:11 +0xe4 | /home/iwiseman/dev/courses/go-cli/03/demos/demos/03-race/main.go:11 +0xe4 | ||
================== | ================== | ||
</syntaxhighlight> | |||
==Shared Libraries== | |||
This did not impress. We have to build the standard library doing | |||
<syntaxhighlight lang="bash"> | |||
sudo /usr/local/go/bin/go build -buildmode=shared std | |||
</syntaxhighlight> | |||
Just do not like the sudo, guess in a container not a problem. Anyway we just need to build the program | |||
<syntaxhighlight lang="bash"> | |||
go build -linkshared cmds/hello | |||
</syntaxhighlight> | |||
==C/C++ Integration== | |||
===Static Linking=== | |||
We can link go archives to C by | |||
*Include "C" package | |||
*Creating an empty main (no idea why) | |||
*Add comment with export name - note no space | |||
<syntaxhighlight lang="go"> | |||
package main | |||
import "fmt" | |||
import "C" | |||
func main() {} | |||
//export Hello | |||
func Hello() { | |||
fmt.Println("Hello") | |||
} | |||
</syntaxhighlight> | |||
Next issue the build mode command which will produce an include hello.h | |||
<syntaxhighlight lang="bash"> | |||
go build -buildmode=c-archive hello.go | |||
</syntaxhighlight> | |||
From there we are good to go - no pun intended | |||
<syntaxhighlight lang="bash"> | |||
cc test.c ./hello.a -;pthread | |||
</syntaxhighlight> | |||
===Dynamic Linking=== | |||
No surprises except of course the crappyness to the approach with export comments. I really think they are just trying to keep the precious keyword count down | |||
<syntaxhighlight lang="bash"> | |||
go build -buildmode=c-shared hello.go | |||
</syntaxhighlight> | |||
==Plugins== | |||
Go lets you write plugins which, simply to dlopen, can be used at runtime. To create one you used the buildmode plugin giving the output and the source. | |||
<syntaxhighlight lang="bash"> | |||
go build -buildmode=plugin -oplugin.so src/plugin/plugin.so | |||
</syntaxhighlight> | |||
Here is the example of usage without error checking | |||
<syntaxhighlight lang="go"> | |||
p, err := plugin.Open(*path) | |||
f, err := p.Lookup("Foo") | |||
foo, ok := f.(func()) | |||
foo() | |||
</syntaxhighlight> | |||
=Testing= | |||
==Introduction== | |||
Given the directory structure | |||
<br> | |||
[[File:Go Cli tree4.png|200px]] | |||
We can run a test with | |||
<syntaxhighlight lang="bash"> | |||
go test mylib | |||
</syntaxhighlight> | |||
Or run all tests with the triple dot wildcard | |||
<syntaxhighlight lang="bash"> | |||
go test mylib/... | |||
</syntaxhighlight> | |||
==Flags== | |||
Brief and not complete list of flags | |||
-cpu specify number of cpus | |||
-parallel amount of parallelism | |||
-list list out tests with regex e.g. --list mytestid mylib/... | |||
-run runs tests with regex e.g. --run mytestid mylib/... | |||
-timeout d timeout stop after d duration | |||
<br> | |||
For code coverage we can use | |||
go test -cover mylib | |||
More example with reports are | |||
go test -cover -html=cover.out | |||
For bench marking we can run | |||
go test -benchtime 5s -bench . mylib | |||
For bench marking with memory we can run | |||
go test -bench . -benchmem . mylib | |||
Lots of options, read the docs | |||
==Profiling== | |||
We can generate profiles with a two step approach. Note the memprofilerate sets the granularity of the testing and 1 is the most fine | |||
<syntaxhighlight lang="bash"> | |||
go test -memprofile mem.out -memprofilerate 1 mylib | |||
go tool pprof -web mylib.test mem.out | |||
</syntaxhighlight> | |||
Again lots of options for this and cpu and trace. | |||
=Workspaces= | |||
So some options were | |||
<syntaxhighlight lang="bash"> | |||
// Clean | |||
go clean | |||
// Format | |||
go fmt | |||
// Vet (linting) | |||
go vet | |||
</syntaxhighlight> | </syntaxhighlight> |
Latest revision as of 11:38, 30 January 2021
Introduction
This is just a page on go command options
go help <command>
// e.g.
go help test
We can go to https://golang.org/cmd/go/ for online
Building and Running
Environment
For me I have set up my PATH to include go and my GOROOT to be the parent directory of the src folder.
export PATH=/usr/local/go/bin:$PATH
cd blah1/blah2/src/..
export GOPATH=`pwd`
Run
Compiles and run a program without leaving artefacts.
go run src/cmds/hello/hello.go
Build
Compiles but does not run a program. Given the tree
This command will build the library but not produce anything.
go build hello
This command will build the binary and produce a binary
go build cmds/hello
Adding the -i forces the intermediate files to be created on disk in the pkg directory
go build -i cmds/hello
Install
Go install will do all of what build will do but will also create the bin and the library in the workspace. e.g.
go install cmds/hello
Other Commands
So here are some other flags
-a force rebuild -n dry run with verbose -n no dry run with verbose -p for processors -v verbose
Race Flag
This is a flag to detect issues with concurrency adding this to the run can help find issues. Just run the code with -race. Without the shadowing to local scope this code would fail.
package main
import "fmt"
import "sync"
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
// ===>>> i := i
go func() {
fmt.Println(i)
wg.Done()
}()
}
wg.Wait()
}
Running with -race will help
==================
WARNING: DATA RACE
Read at 0x00c0000160b0 by goroutine 7:
main.main.func1()
/home/iwiseman/dev/courses/go-cli/03/demos/demos/03-race/main.go:12 +0x3c
Previous write at 0x00c0000160b0 by main goroutine:
main.main()
/home/iwiseman/dev/courses/go-cli/03/demos/demos/03-race/main.go:8 +0x108
Goroutine 7 (running) created at:
main.main()
/home/iwiseman/dev/courses/go-cli/03/demos/demos/03-race/main.go:11 +0xe4
==================
This did not impress. We have to build the standard library doing
sudo /usr/local/go/bin/go build -buildmode=shared std
Just do not like the sudo, guess in a container not a problem. Anyway we just need to build the program
go build -linkshared cmds/hello
C/C++ Integration
Static Linking
We can link go archives to C by
- Include "C" package
- Creating an empty main (no idea why)
- Add comment with export name - note no space
package main
import "fmt"
import "C"
func main() {}
//export Hello
func Hello() {
fmt.Println("Hello")
}
Next issue the build mode command which will produce an include hello.h
go build -buildmode=c-archive hello.go
From there we are good to go - no pun intended
cc test.c ./hello.a -;pthread
Dynamic Linking
No surprises except of course the crappyness to the approach with export comments. I really think they are just trying to keep the precious keyword count down
go build -buildmode=c-shared hello.go
Plugins
Go lets you write plugins which, simply to dlopen, can be used at runtime. To create one you used the buildmode plugin giving the output and the source.
go build -buildmode=plugin -oplugin.so src/plugin/plugin.so
Here is the example of usage without error checking
p, err := plugin.Open(*path)
f, err := p.Lookup("Foo")
foo, ok := f.(func())
foo()
Testing
Introduction
Given the directory structure
We can run a test with
go test mylib
Or run all tests with the triple dot wildcard
go test mylib/...
Flags
Brief and not complete list of flags
-cpu specify number of cpus -parallel amount of parallelism -list list out tests with regex e.g. --list mytestid mylib/... -run runs tests with regex e.g. --run mytestid mylib/... -timeout d timeout stop after d duration
For code coverage we can use
go test -cover mylib
More example with reports are
go test -cover -html=cover.out
For bench marking we can run
go test -benchtime 5s -bench . mylib
For bench marking with memory we can run
go test -bench . -benchmem . mylib
Lots of options, read the docs
Profiling
We can generate profiles with a two step approach. Note the memprofilerate sets the granularity of the testing and 1 is the most fine
go test -memprofile mem.out -memprofilerate 1 mylib
go tool pprof -web mylib.test mem.out
Again lots of options for this and cpu and trace.
Workspaces
So some options were
// Clean
go clean
// Format
go fmt
// Vet (linting)
go vet