Go Install Binary name - go

go build allow to precise binary name with the -o command line option.
go install doesn't, but it deploy the binary and cache package compilation.
How to either change the binary name with go install? or cache compilation with go build?
A simple answer would be "use go install with correct package name", but please, where is the option I am missing?

You can use the -i flag to go build:
The -i flag installs the packages that are dependencies of the target.
go build -i -o binary packagename

When you type go help install you get
usage: go 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.
The only build flags allowed are
-a
force rebuilding of packages that are already up-to-date.
-n
print the commands but do not run them.
-p n
the number of programs, such as build commands or
test binaries, that can be run in parallel.
The default is the number of CPUs available, except
on darwin/arm which defaults to 1.
-race
enable data race detection.
Supported only on linux/amd64, freebsd/amd64, darwin/amd64 and windows/amd64.
-msan
enable interoperation with memory sanitizer.
Supported only on linux/amd64,
and only with Clang/LLVM as the host C compiler.
-v
print the names of packages as they are compiled.
-work
print the name of the temporary work directory and
do not delete it when exiting.
-x
print the commands.
-asmflags 'flag list'
arguments to pass on each go tool asm invocation.
-buildmode mode
build mode to use. See 'go help buildmode' for more.
-compiler name
name of compiler to use, as in runtime.Compiler (gccgo or gc).
-gccgoflags 'arg list'
arguments to pass on each gccgo compiler/linker invocation.
-gcflags 'arg list'
arguments to pass on each go tool compile invocation.
-installsuffix suffix
a suffix to use in the name of the package installation directory,
in order to keep output separate from default builds.
If using the -race flag, the install suffix is automatically set to race
or, if set explicitly, has _race appended to it. Likewise for the -msan
flag. Using a -buildmode option that requires non-default compile flags
has a similar effect.
-ldflags 'flag list'
arguments to pass on each go tool link invocation.
-linkshared
link against shared libraries previously created with
-buildmode=shared.
-pkgdir dir
install and load all packages from dir instead of the usual locations.
For example, when building with a non-standard configuration,
use -pkgdir to keep generated packages in a separate location.
-tags 'tag list'
a list of build tags to consider satisfied during the build.
For more information about build tags, see the description of
build constraints in the documentation for the go/build package.
-toolexec 'cmd args'
a program to use to invoke toolchain programs like vet and asm.
For example, instead of running asm, the go command will run
'cmd args /path/to/asm <arguments for asm>'.
Where -i and -o flags are no possible to install command and are available to build command only.
Now, The only option that I see to change the name of the Go install binary name is manually mv oldnamebinary newnamebinary. At least, this behaviour is in GO 1.6, maybe on coming releases can change.

we can run below commands to generate binary executable with the desired name and path:
optional if you want dep to be downloaded and installed
go install
to build the binary at path and name desired:
go build -o path/binary_name
example: go build -o ~/go/bin/mybinaryname

In GO 1.6+ you can rename your main file to whatever you want.
Example :
mv main.go myApp.go
Then just run go install myApp.go
Your myApp is ready to exec, and the location is in $GOROOT/bin

Related

GoConvey: command not found : goconvey [duplicate]

I want to install packages from github to my $GOPATH, I have tried this:
go get github.com:capotej/groupcache-db-experiment.git
the repository is here.
Command go
Download and install packages and dependencies
Usage:
go get [-d] [-f] [-t] [-u] [-v] [-fix] [-insecure] [build flags] [packages]
Get downloads the packages named by the import paths, along with their
dependencies. It then installs the named packages, like 'go install'.
The -d flag instructs get to stop after downloading the packages; that
is, it instructs get not to install the packages.
The -f flag, valid only when -u is set, forces get -u not to verify
that each package has been checked out from the source control
repository implied by its import path. This can be useful if the
source is a local fork of the original.
The -fix flag instructs get to run the fix tool on the downloaded
packages before resolving dependencies or building the code.
The -insecure flag permits fetching from repositories and resolving
custom domains using insecure schemes such as HTTP. Use with caution.
The -t flag instructs get to also download the packages required to
build the tests for the specified packages.
The -u flag instructs get to use the network to update the named
packages and their dependencies. By default, get uses the network to
check out missing packages but does not use it to look for updates to
existing packages.
The -v flag enables verbose progress and debug output.
Get also accepts build flags to control the installation. See 'go help
build'.
When checking out a new package, get creates the target directory
GOPATH/src/. If the GOPATH contains multiple entries, get
uses the first one. For more details see: 'go help gopath'.
When checking out or updating a package, get looks for a branch or tag
that matches the locally installed version of Go. The most important
rule is that if the local installation is running version "go1", get
searches for a branch or tag named "go1". If no such version exists it
retrieves the default branch of the package.
When go get checks out or updates a Git repository, it also updates
any git submodules referenced by the repository.
Get never checks out or updates code stored in vendor directories.
For more about specifying packages, see 'go help packages'.
For more about how 'go get' finds source code to download, see 'go
help importpath'.
This text describes the behavior of get when using GOPATH to manage
source code and dependencies. If instead the go command is running in
module-aware mode, the details of get's flags and effects change, as
does 'go help get'. See 'go help modules' and 'go help module-get'.
See also: go build, go install, go clean.
For example, showing verbose output,
$ go get -v github.com/capotej/groupcache-db-experiment/...
github.com/capotej/groupcache-db-experiment (download)
github.com/golang/groupcache (download)
github.com/golang/protobuf (download)
github.com/capotej/groupcache-db-experiment/api
github.com/capotej/groupcache-db-experiment/client
github.com/capotej/groupcache-db-experiment/slowdb
github.com/golang/groupcache/consistenthash
github.com/golang/protobuf/proto
github.com/golang/groupcache/lru
github.com/capotej/groupcache-db-experiment/dbserver
github.com/capotej/groupcache-db-experiment/cli
github.com/golang/groupcache/singleflight
github.com/golang/groupcache/groupcachepb
github.com/golang/groupcache
github.com/capotej/groupcache-db-experiment/frontend
$
First, we need GOPATH
The $GOPATH is a folder (or set of folders) specified by its environment variable. We must notice that this is not the $GOROOT directory where Go is installed.
export GOPATH=$HOME/gocode
export PATH=$PATH:$GOPATH/bin
We used ~/gocode path in our computer to store the source of our application and its dependencies. The GOPATH directory will also store the binaries of their packages.
Then check Go env
You system must have $GOPATH and $GOROOT, below is my Env:
GOARCH="amd64"
GOBIN=""
GOCHAR="6"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/elpsstu/gocode"
GORACE=""
GOROOT="/home/pravin/go"
GOTOOLDIR="/home/pravin/go/pkg/tool/linux_amd64"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
Now, you run download go package:
go get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]
Get downloads and installs the packages named by the import paths, along with their dependencies. For more details you can look here.
Note that since Go 1.17 installing packages with go get is deprecated:
Building and installing packages with get is deprecated. In a future release, the -d flag will be enabled by default, and go get will be only be used to adjust dependencies of the current module. To install a package using dependencies from the current module, use go install.
This "future release" is Go 1.18, as mentioned in the release notes:
go get no longer builds or installs packages in module-aware mode. go get is now dedicated to adjusting dependencies in go.mod. Effectively, the -d flag is always enabled.
(The -d flag instructs go get to only download packages and not install them.)
Use go install instead:
# Install the latest version of a program,
# ignoring go.mod in the current directory (if any).
$ go install golang.org/x/tools/gopls#latest
# Install a specific version of a program.
$ go install golang.org/x/tools/gopls#v0.6.4
# Install a program at the version selected by the module in the current directory.
$ go install golang.org/x/tools/gopls
# Install all programs in a directory.
$ go install ./cmd/...
The Go 1.18 release notes also mention that go get will work as before with GO111MODULE=off. However in 2022 you should definitely migrate to modules and use go install instead.
Run it from console
go mod download

How to `go install` to bin inside module dir?

For example, when I run this
GOOS="windows" GOARCH="386" go install ./something
The executable would be created at
$GOROOT/bin/$GOOS_$GOARCH/something.exe
I want the executable to be created at
path/to/my/module/bin/$GOOS_$GOARCH/something.exe
EDIT
To clarify, I ask the question in the context of cross compiled builds inside a module.
I get the desired result using this command inside my module. I'd like to avoid specifying the path.
GOOS="windows" GOARCH="386" go build -o ./bin/$GOOS_$GOARCH/something.exe ./something
So, is it possible to get the same with go install?
Setting GOBIN results in an error
GOBIN=$(pwd)/bin GOOS="windows" GOARCH="386" go install ./something
# go install: cannot install cross-compiled binaries when GOBIN is set
Don't use go install for cross compiling. Use go build with -o flag.
Here is some history regarding GOBIN, robpike posted an issue stating "I have $GOBIN set but the go tool is ignoring it when installing..."
This article mentions
"When cross compiling, you should use go build, not go install. This is the one of the few cases where go build is preferable to go install...
The reason for this is go install always caches compiled packages, .a files, into the pkg/ directory that matches the root of the source code...
This logic also holds true for the standard library, which lives in /usr/local/go/src, so will be compiled to /usr/local/go/pkg/$GOOS_$GOARCH. This is a problem, because when cross compiling the go tool needs to rebuild the standard library for your target, but the binary distribution expects that /usr/local/go is not writeable.
Using go build rather that go install is the solution here, because go build builds, then throws away most of the result (rather than caching it for later), leaving you with the final binary in the current directory, which is most likely writeable by you"

Error: "build flag -mod=vendor only valid when using modules" when building Go project

According to this document I need to add -mod=vendor to my build command to make use of my local vendor folder:
By default, go commands like go build ignore the vendor directory when in module mode. The -mod=vendor flag (e.g., go build -mod=vendor) instructs the go commands to use the main module's top-level vendor directory to satisfy dependencies.
When I run this command:
go build -mod=vendor -a -ldflags "-s -w -X github.com/my-api/pkg/config.Version=169.3988801" -o bin/my-api
I get this error:
build flag -mod=vendor only valid when using modules
Locally the command works as expected, the error only occurs on the build server.
I think the key part of the help you are showing is when in module mode. This will only happen when you are working on code outside of GOPATH or if you have set the GO111MODULE=on environment variable so I think you have this set in your local environment but not the build server.
More information about enabling module support is here:
https://golang.org/cmd/go/#hdr-Preliminary_module_support

how can I debug go tests with gdb

I have some go tests. I would like to debug with gdb.
But the binaries built by go test are thrown away after running.
So how do I do it?
go 1.6 on windows/64
You use go test -c which will produce the executable file xyz.test. Afterwards you use gdb xyz.test to debug.
Just check go test --help for an explanation of the -c flag:
Compile the test binary to pkg.test but do not run it
(where pkg is the last element of the package's import path).
The file name can be changed with the -o flag.

How to compile go program in 1.1.2 with dependencies compiled in 1.1.1?

Every time I try to compile my program after (this morning) upgrading go from 1.1.1 to 1.1.2 (on Windows 7 64 bits), I get error message like:
C:\Users\VonC\prog\go\src\github.com\spf13\hugo>go build -o hugo.exe main.go
# github.com/spf13/hugo/hugolib
hugolib\page.go:23: import C:\Users\VonC\prog\go\pkg\windows_amd64/github.com/emicklei/hopwatch.a:
object is [windows amd64 go1.1.1 X:none]
expected [windows amd64 go1.1.2 X:none]
I tried a go clean -r, but the error message persists?
What is the right clean command to use?
Actual solution:
I reproduced the issue with:
calling the 1.1.2 go.exe directly (I didn't have %GOROOT%\bin in my path)
with GOROOT pointing to the previous 1.1.1 installation folder (I kept go 1.1.1 and 1.1.2 installed in separated folders).
If you are sticking with the default go setup (ie: one C:\go installation directory, and %GOROOT%\bin in your PATH), you won't see this error.
But if you do see this error:
make sure %GOROOT% is consistent with the go.exe you are calling
go install -a as explained below. The go clean mentioned below won't be necessary.
As jnml comments:
the Go build system is supposed to figure out any obsolete stuff in $GOPATH/pkg and (transitively) rebuild it on demand.
Original solution:
In the "Remove object files" section of "Command go" page, I missed the go clean -i option:
-i
The -i flag causes clean to remove the corresponding installed archive or binary (what 'go install' would create).
And those .a file (like hopwatch.a) are precisely what go install generates for libraries (in Windows).
So the full clean command, to make sure go rebuild everything, would be:
cd C:\Users\VonC\prog\go\src\github.com\spf13\hugo
go clean -r -i
go install -a
That will rebuild and install everything, including all dependent packages.
The -a is actually a build option, which forces rebuilding of packages that are already up-to-date.
As usual, go clean -r -n would show you what would be cleaned (-n: preview option).
It doesn't hurt to be sure of what will be deleted... before actually deleting anything.

Resources