I'm running golang in a docker container. And 'go tool' is unable to find 'vet'. Could you give me ideas on how to debug this?
I've used the Dockerfile for 1.5 as a template. https://github.com/docker-library/golang/blob/51d6eacd41fe80d41105142b9ad32f575082970f/1.5/Dockerfile
ENV GOLANG_VERSION 1.5.1
ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux- amd64.tar.gz
ENV GOLANG_DOWNLOAD_SHA1 46eecd290d8803887dec718c691cc243f2175fe0
RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \
&& echo "$GOLANG_DOWNLOAD_SHA1 golang.tar.gz" | sha1sum -c - \
&& tar -C /usr/local -xzf golang.tar.gz \
&& rm golang.tar.gz
ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
However, when I install govet with
go get golang.org/x/tools/cmd/vet
and try
bash-4.3# go tool vet
go tool: no such tool "vet"
I have the following go environment set up:
$PATH includes $GOPATH/bin /usr/lib/go/bin:/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
bash# go env
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/go"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT=""
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
bash# ls $GOPATH/bin
fgt go-junit-report godep golint mt-content-blogs vet
bash# ls $GOROOT/bin/
go gofmt
The crux of the issue is that go tools does not list vet, even after installing it with go get golang.org/x/tools/cmd/vet
bash# go tool
addr2line
api
asm
cgo
compile
dist
doc
fix
link
nm
objdump
pack
pprof
trace
yacc
Warning: starting Go 1.12 (February 2019, 3.5 years later), go tool vet won't be available at all. Only go vet.
See go 1.12 release notes:
The go vet command has been rewritten to serve as the base for a range of different source code analysis tools. See the golang.org/x/tools/go/analysis package for details.
A side-effect is that go tool vet is no longer supported.
External tools that use go tool vet must be changed to use go vet.
Using go vet instead of go tool vet should work with all supported versions of Go.
As part of this change, the experimental -shadow option is no longer available with go vet.
Checking for variable shadowing may now be done using:
go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow
go vet -vettool=$(which shadow)
Figured out the issue. It appears that I had missed installing go tools on the base docker image that I was using.
RUN apk --update-cache --allow-untrusted \
--repository http://dl-3.alpinelinux.org/alpine/edge/community/ \
--arch=x86_64 add \
go=${GOLANG_VERSION}-r3 \
go-tools=${GOLANG_VERSION}-r3 \
git \
&& rm -rf /var/cache/apk/* \
&& mkdir -p /go/src /go/bin \
&& chmod -R 777 /go
Related
There are two folds to this problem:
1) Go install not able to generate binary
go version go1.7.3 linux/amd64
go env:
GOARCH="amd64" GOBIN="" GOEXE="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/opt/gopath" GORACE="" GOROOT="/opt/go" GOTOOLDIR="/opt/go/pkg/tool/linux_amd64" CC="gcc" GOGCCFLAGS="-fPIC
-m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build831334660=/tmp/go-build -gno-record-gcc-switches" CXX="g++" CGO_ENABLED="1"
Source of the program: https://github.com/hyperledger/fabric
Working dir: /opt/gopath/src/github.com/hyperledger/fabric
Main program to build: /opt/gopath/src/github.com/hyperledger/fabric/peer/main.go
Build command:
CGO_ENABLED=0 GOBIN=/opt/gopath/bin go install -x -ldflags " -X github.com/hyperledger/fabric/common/metadata.Version=1.0.0-snapshot-d6fbfcf -X github.com/hyperledger/fabric/common/metadata.BaseVersion=0.3.0 -X github.com/hyperledger/fabric/common/metadata.BaseDockerLabel=org.hyperledger.fabric -X github.com/hyperledger/fabric/common/metadata.DockerNamespace=hyperledger -X github.com/hyperledger/fabric/common/metadata.BaseDockerNamespace=hyperledger -linkmode external -extldflags -static -lpthread" github.com/hyperledger/fabric/peer
I expect the binary built in /opt/gopath/bin but there was nothing there.
It shows on the console that series of .a files were built and moved to /opt/gopath/pkg/linux_amd64/
Eventually program stopped and no binary was built.
This is true regardless CGO_ENABLED was set to 0 or 1.
Somehow the program thoughts it was done, without linking the object files and building the binary? Any other debugging measures that I can use to look further into it?
2) The 'Go install' command was taken from Makefile
#$(DRUN) \
-v $(abspath build/docker/bin):/opt/gopath/bin \
-v $(abspath build/docker/$(TARGET)/pkg):/opt/gopath/pkg \
hyperledger/fabric-baseimage:$(BASE_DOCKER_TAG) \
go install -compiler gccgo -ldflags "$(DOCKER_GO_LDFLAGS)" $(pkgmap.$(#F))
where
DRUN = docker run -i --rm $(DOCKER_RUN_FLAGS) \
-v $(abspath .):/opt/gopath/src/$(PKGNAME) \
-w /opt/gopath/src/$(PKGNAME)
The 'Go install' command was run inside a docker container, which was started the same way the Makefile specified. The only difference was that I was doing it manually, in two shots, i.e. start docker container + go install. If I were to build it with Makefile in one shot, it would work just fine.
Is there any catch/caveat on using this 'docker run <image> go install <args>' style command?
I use command go get github.com/gorilla/mux. I made http server using Golang, and I run this program :
package main
import (
"fmt"
"html"
"log"
"net/http"
"github.com/gorilla/mux"
)
func main() {
router := mux.NewRouter().StrictSlash(true)
router.HandleFunc("/", Index)
log.Fatal(http.ListenAndServe(":8080", router))
}
func Index(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
But I conflict this error :
/usr/local/go/bin/go build -i [/Users/imac/go/src]
http.go:9:5: cannot find package "github.com/gorilla/mux" in any of:
/usr/local/go/src/github.com/gorilla/mux (from $GOROOT)
($GOPATH not set)
Error: process exited with code 1.
My Go environment is here :
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/imac/go"
GORACE=""
GOROOT="/usr/local/go"
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
CC="clang"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/v9/fkc_t97s5v1g9sr938zzvxvh0000gn/T/go-build096571864=/tmp/go-build -gno-record-gcc-switches -fno-common"
CXX="clang++"
CGO_ENABLED="1"
I fight with this error for a week, But I can't find out solution. Please help me.
Could you try this steps to debug it:
ls -l /usr/local/go/src/github.com | grep gorilla
cd $GOPATH
go list ... | grep gorilla
if you din't see gorilla in the above two command, then you need to install it:
go get -v -u github.com/gorilla/mux
Please run this: export PATH=$PATH:$GOPATH/bin
How about running go run main.go ? is that working, if yes you should be able to do go build from your project path.
I wish this helpful.
You may off the 'mod'.
$ export GO111MODULE=off
This works for me...
fire command
> go mod init <your-directoryNane-where-main.go-exits>
fire command > go get github.com/gorilla/mux
after firing this both commands you will be able see 2 files :
go.mod
go.sum
finally, Close VS code and open again, the error will be resolved
Just remove quotes like this:
go get github.com/gorilla/mux
If you are using VS Code as your IDE and facing this problem:
VS Code uses $HOME/go as your default GOPATH - if you export another GOPATH you running into this trouble.
How to solve:
Use the VS Code internal terminal and navigate to your project folder: cd prjectFolder. Type go env and check if the GOPATH entry is the same as you get when you use cmd+t and then >Go: Current GOPATH
If it doesn't fit, add in your user settings:
"go.gopath": "/some/path"
where /some/path is the same path you export in you shell, zsh and so on.
Hope this helps.
I try to remove github.com/gorilla and github.com/peterbourgon directory, then, retry: make, it works.
<pre>
fail log:
mac#user:~/TempPlace/temp/ngrok% make
go fmt ngrok/...
go get github.com/jteeuwen/go-bindata
GOOS="" GOARCH="" go install github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=debug \
-debug=true \
-o=src/ngrok/client/assets/assets_debug.go \
assets/client/...
go get github.com/jteeuwen/go-bindata
GOOS="" GOARCH="" go install github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=debug \
-debug=true \
-o=src/ngrok/server/assets/assets_debug.go \
assets/server/...
go get -tags 'debug' -d -v ngrok/...
src/ngrok/server/config.go:16:2: no Go files in /Users/apple/TempPlace/temp/ngrok/src/github.com/gorilla/mux
src/ngrok/server/config.go:17:2: no Go files in /Users/apple/TempPlace/temp/ngrok/src/github.com/peterbourgon/diskv
make: *** [deps] Error 1
success log:
mac#user:~/TempPlace/temp/ngrok% make
go fmt ngrok/...
go get github.com/jteeuwen/go-bindata
GOOS="" GOARCH="" go install github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=debug \
-debug=true \
-o=src/ngrok/client/assets/assets_debug.go \
assets/client/...
go get github.com/jteeuwen/go-bindata
GOOS="" GOARCH="" go install github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=debug \
-debug=true \
-o=src/ngrok/server/assets/assets_debug.go \
assets/server/...
go get -tags 'debug' -d -v ngrok/...
github.com/gorilla/websocket (download)
github.com/gorilla/mux (download)
src/ngrok/server/config.go:17:2: no Go files in /Users/apple/TempPlace/temp/ngrok/src/github.com/peterbourgon/diskv
make: *** [deps] Error 1
mac#user:~/TempPlace/temp/ngrok% make
go fmt ngrok/...
go get github.com/jteeuwen/go-bindata
GOOS="" GOARCH="" go install github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=debug \
-debug=true \
-o=src/ngrok/client/assets/assets_debug.go \
assets/client/...
go get github.com/jteeuwen/go-bindata
GOOS="" GOARCH="" go install github.com/jteeuwen/go-bindata/go-bindata
bin/go-bindata -nomemcopy -pkg=assets -tags=debug \
-debug=true \
-o=src/ngrok/server/assets/assets_debug.go \
assets/server/...
go get -tags 'debug' -d -v ngrok/...
github.com/peterbourgon/diskv (download)
github.com/google/btree (download)
go install -tags 'debug' ngrok/main/ngrok
go install -ldflags "-s" -tags 'debug' ngrok/main/ngrokd
</pre>
Try go build /Users/imac/go/src/project
because I see you try to use go build under /Users/imac/go/src
Maybe this can help other users running in Windows.
In my case I had to create two symlinks:
1. run cmd as administrator
2. cd %gopath%
3. mklink /D src pkg\mod
this creates a symlink between src and pkg\mod
4. cd src\github.com\gorilla
Here you'll notice that the mux package might be listed as mux#v1.8.0
5. mklink /D mux mux#v1.8.0
With this, go will be able to find github.com/gorilla/mux
under %gopath%\src\github.com\gorilla\mux
Finally, you have to set GO111Module to off
set GO111Module=off
and now you can build your app:
go build app.go
On go version : It prints
go version xgcc (Ubuntu 4.9.1-0ubuntu1) 4.9.1 linux/amd64
My installed version is the latest one and i.e 1.4.2
which got installed from the tar version : go1.4.2.linux-amd64.tar.gz
GO Environmental variables looks exactly like this:
GOARCH="amd64"
GOBIN="/home/user/coding/golang/gocnew/goc/bin"
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user/coding/golang/gocnew/goc"
GORACE=""
GOROOT="/home/user/go"
GOTOOLDIR="/home/user/go/pkg/tool/linux_amd64"
TERM="dumb"
CC="gcc"
GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread"
CXX="g++"
CGO_ENABLED="1"
I expect go version to be printed as 1.4.2, so how that can be achieved?
Looks like you have two versions of Go installed. One from ubuntu package manager and one you installed from source tar.
To confirm kindly try to remove gccgo :
sudo apt-get remove gccgo
I got the same issue and i fixed it by this way:
Access to go folder: /usr/local/go (The installation folder of go)
Execute these commands:
Added by Go Path
echo 'export GOROOT=/usr/local/go' >> ~/.bashrc
echo 'export GOPATH=$HOME/go' >> ~/.bashrc
echo 'export PATH=$PATH:$GOROOT/bin:$GOPATH/bin' >> ~/.bashrc
And then go to the source folder and check go version:
go version go1.12.2 linux/amd64 it will be displayed the same version in go folder and you can work with go commands.
I have tried to search and found a lot of topics which are related to my problem, but none of them I could follow to success.
I can go run and go get with no issues, but I need to compile into windows and there I have problems please see bellow
mikhail#mikhail-desktop:/usr/lib/go/src$ sudo ./make.bash
# Building C bootstrap tool.
cmd/dist
go tool dist: $GOROOT is not set correctly or not exported
GOROOT=/usr/share/go
/usr/share/go/include/u.h does not exist
mikhail#mikhail-desktop:/usr/lib/go/src$ go env
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/mikhail/Documents/FL/0go"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
TERM="dumb"
CC="gcc"
GOGCCFLAGS="-g -O2 -fPIC -m64 -pthread"
CXX="g++"
CGO_ENABLED="1"
mikhail#mikhail-desktop:/usr/lib/go/src$
By some reasons it thinks the GOROOT is /usr/share/go while it actually /usr/lib/go
sudo can clean environment variables, to check if that is the case here, run sudo $(which go) env and check if the output is what you expect. If not, you can keep the enviroment of your user by using the -E flag: sudo -E ./make.bash.
I think it somehow connected to Debian/Ubuntu thing. I seen such issues but related to 0.9. version.
I have installed go from source into ~/go and then everything went quite OK, now I can compile to windows from ubuntu with help Introduction to cross compilation with go and LiteIDE.
I am trying to cross-compile a go app on OSX to build binaries for windows and linux. I have read everything what I could find on the net. Closest example that I have found has been published on (apart from many unfinished discussions on go-nuts mailing list):
http://solovyov.net/en/2012/03/09/cross-compiling-go/
yet it does not work on my installation. I have go 1.0.2. As 1.0.2 is quite recent it looks to me that all above examples do not apply to this version.
Tried to do ./make.bash --no-clean with ENV vars set to 386/windows, it does build go, however it builds go for my installation which is darwin/amd64 and completely ignores what is set in ENV that suppose to build different compiler.
Any advises how it can be done (if it can be done at all)?
With Go 1.5 they seem to have improved the cross compilation process, meaning it is built in now. No ./make.bash-ing or brew-ing required. The process is described here but for the TLDR-ers (like me) out there: you just set the GOOS and the GOARCH environment variables and run the go build.
For the even lazier copy-pasters (like me) out there, do something like this if you're on a *nix system:
env GOOS=linux GOARCH=arm go build -v github.com/path/to/your/app
You even learned the env trick, which let you set environment variables for that command only, completely free of charge.
Thanks to kind and patient help from golang-nuts, recipe is the following:
1) One needs to compile Go compiler for different target platforms and architectures. This is done from src folder in go installation. In my case Go installation is located in /usr/local/go thus to compile a compiler you need to issue make utility. Before doing this you need to know some caveats.
There is an issue about CGO library when cross compiling so it is needed to disable CGO library.
Compiling is done by changing location to source dir, since compiling has to be done in that folder
cd /usr/local/go/src
then compile the Go compiler:
sudo GOOS=windows GOARCH=386 CGO_ENABLED=0 ./make.bash --no-clean
You need to repeat this step for each OS and Architecture you wish to cross compile by changing the GOOS and GOARCH parameters.
If you are working in user mode as I do, sudo is needed because Go compiler is in the system dir. Otherwise you need to be logged in as super user. On Mac you may need to enable/configure SU access (it is not available by default), but if you have managed to install Go you possibly already have root access.
2) Once you have all cross compilers built, you can happily cross compile your application by using the following settings for example:
GOOS=windows GOARCH=386 go build -o appname.exe appname.go
GOOS=linux GOARCH=386 CGO_ENABLED=0 go build -o appname.linux appname.go
Change the GOOS and GOARCH to targets you wish to build.
If you encounter problems with CGO include CGO_ENABLED=0 in the command line. Also note that binaries for linux and mac have no extension so you may add extension for the sake of having different files. -o switch instructs Go to make output file similar to old compilers for c/c++ thus above used appname.linux can be any other extension.
If you use Homebrew on OS X, then you have a simpler solution:
$ brew install go --with-cc-common # Linux, Darwin, and Windows
or..
$ brew install go --with-cc-all # All the cross-compilers
Use reinstall if you already have go installed.
You can do this pretty easily using Docker, so no extra libs required. Just run this command:
docker run --rm -it -v "$GOPATH":/go -w /go/src/github.com/iron-io/ironcli golang:1.4.2-cross sh -c '
for GOOS in darwin linux windows; do
for GOARCH in 386 amd64; do
echo "Building $GOOS-$GOARCH"
export GOOS=$GOOS
export GOARCH=$GOARCH
go build -o bin/ironcli-$GOOS-$GOARCH
done
done
'
You can find more details in this post:
https://medium.com/iron-io-blog/how-to-cross-compile-go-programs-using-docker-beaa102a316d
The process of creating executables for many platforms can be a little tedious, so I suggest to use a script:
#!/usr/bin/env bash
package=$1
if [[ -z "$package" ]]; then
echo "usage: $0 <package-name>"
exit 1
fi
package_name=$package
#the full list of the platforms: https://golang.org/doc/install/source#environment
platforms=(
"darwin/386"
"dragonfly/amd64"
"freebsd/386"
"freebsd/amd64"
"freebsd/arm"
"linux/386"
"linux/amd64"
"linux/arm"
"linux/arm64"
"netbsd/386"
"netbsd/amd64"
"netbsd/arm"
"openbsd/386"
"openbsd/amd64"
"openbsd/arm"
"plan9/386"
"plan9/amd64"
"solaris/amd64"
"windows/amd64"
"windows/386" )
for platform in "${platforms[#]}"
do
platform_split=(${platform//\// })
GOOS=${platform_split[0]}
GOARCH=${platform_split[1]}
output_name=$package_name'-'$GOOS'-'$GOARCH
if [ $GOOS = "windows" ]; then
output_name+='.exe'
fi
env GOOS=$GOOS GOARCH=$GOARCH go build -o $output_name $package
if [ $? -ne 0 ]; then
echo 'An error has occurred! Aborting the script execution...'
exit 1
fi
done
I checked this script on OSX only
gist - go-executable-build.sh
for people who need CGO enabled and cross compile from OSX targeting
windows
I needed CGO enabled while compiling for windows from my mac since I had imported the https://github.com/mattn/go-sqlite3 and it needed it.
Compiling according to other answers gave me and error:
/usr/local/go/src/runtime/cgo/gcc_windows_amd64.c:8:10: fatal error: 'windows.h' file not found
If you're like me and you have to compile with CGO. This is what I did:
1.We're going to cross compile for windows with a CGO dependent library. First we need a cross compiler installed like mingw-w64
brew install mingw-w64
This will probably install it here /usr/local/opt/mingw-w64/bin/.
2.Just like other answers we first need to add our windows arch to our go compiler toolchain now. Compiling a compiler needs a compiler (weird sentence) compiling go compiler needs a separate pre-built compiler. We can download a prebuilt binary or build from source in a folder eg: ~/Documents/go
now we can improve our Go compiler, according to top answer but this time with CGO_ENABLED=1 and our separate prebuilt compiler GOROOT_BOOTSTRAP(Pooya is my username):
cd /usr/local/go/src
sudo GOOS=windows GOARCH=amd64 CGO_ENABLED=1 GOROOT_BOOTSTRAP=/Users/Pooya/Documents/go ./make.bash --no-clean
sudo GOOS=windows GOARCH=386 CGO_ENABLED=1 GOROOT_BOOTSTRAP=/Users/Pooya/Documents/go ./make.bash --no-clean
3.Now while compiling our Go code use mingw to compile our go file targeting windows with CGO enabled:
GOOS="windows" GOARCH="386" CGO_ENABLED="1" CC="/usr/local/opt/mingw-w64/bin/i686-w64-mingw32-gcc" go build hello.go
GOOS="windows" GOARCH="amd64" CGO_ENABLED="1" CC="/usr/local/opt/mingw-w64/bin/x86_64-w64-mingw32-gcc" go build hello.go
Since go 1.17.1 you must explicitly set go env variables.
I've done it in a shell script
#!/bin/bash
GOOS=linux
GOARCH=amd64
go.exe get -d -v ./...
go.exe env -w GOOS=$GOOS
go.exe env -w GOARCH=$GOARCH
go.exe build -v ./cmd/tecnoalarm/main.go
for people who need CGO enabled and cross-compile from another system
There is one docker solution golang-crossbuild
Here is one example to build linux/armv7 on Windows/MacOS
docker run -it --rm \
-v $GOPATH/src/github.com/user/go-project:/go/src/github.com/user/go-project \
-w /go/src/github.com/user/go-project \
-e CGO_ENABLED=1 \
docker.elastic.co/beats-dev/golang-crossbuild:1.16.4-armhf \
--build-cmd "make build" \
-p "linux/armv7"