I have a variable VERSION in a make file that sets the version for binary at compile time using -ldflags
VERSION = $(strip $(TIMESTAMP))
LDFLAGS = -ldflags "-X main.buildTime $(BUILD_TIME) -X main.buildNumber $(VERSION)"
Now I want to get the VERSION in a package which is not main and print it. I tried bunch of options, but not able to make it work.
My question is how can I get it in the package and then print it to client at run time, such as you are connected to app version 2.0..??
Directory structure:
- main.go
- test/
- test.go
test.go
package test
var Version = ""
main.go
package main
import (
"fmt"
"test"
)
func main() {
fmt.Println(test.Version)
}
Finally, run:
go run -ldflags="-X test.Version 2.0.0" main.go
Outputs:
> 2.0.0
Since we can specify import path, we can set the value of a string everywhere, not only in main.
From go 1.5 up, syntax is changed to importpath.name=string.
Related
Hi could someone help me run my main.go: go run main.go ?
There are two folders, which are next to each other:
proj1 folder has main.go, go.mod
package1 folder has package1.go, go.mod, utility.go
inside of main.go:
package main
import (
"package1"
"fmt"
)
func main() {
y := package1.Struct1{
v: "1",
}
z := package1.isTrue()
fmt.Println(z)
}
inside my package folder: package1.go
package package1
type Package1 struct {}
func (a *Package1) IsTrue() bool {
return true
}
My Go version: go1.15.2 linux/amd64
My Go env settings:
GO111MODULE="on"
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user1/.cache/go-build"
GOENV="/home/user1/.config/go/env"
GOMODCACHE="/mnt/sda5/gopath/pkg/mod"
GOOS="linux"
GOPATH="/mnt/sda5/gopath"
GOROOT="/usr/local/go"
...
I tried :
go install, go build ... results no error inside the package folder
go mod vendor, go run main.go, go get -u package1 ... result in the same message when run inside the proj1 folder:
package package1 is not in GOROOT (/usr/local/go/src/package1)
The VS Code Go Plugin Linter shows no problem.
Please help. Thank you!
To solve the error i was facing package package1 is not in GOROOT (/usr/local/go/src/package1)
I had to ensure the environment variables were correctly configured.
I added those lines in the bashrc file:
export GO111MODULE=on
#GOPATH MUST BE OUTSIDE OF GOROOT directory!!!
export GOPATH=/mnt/sda1/programming/gopath
export PATH=$PATH:$GOPATH/bin
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
I loaded the bashrc file in the terminal:
source ~/.bashrc
Now i can execute following procedure to program with the Go language.
Make a new main folder...
Inside this main folder:
make main.go file begin with package main
Run the command below:
go mod init main
make another folder with the new package name: e.g. package1
inside the package1 folder:
make all files with package package1 in its 1st line ... but DO NOT MAKE MOD FILE inside this package folder!!!
in your main.go, you can import that package and use it
import "main/package1"
y := package1.Struct1{a: 1, b: 2,...}
z := y.func1()
This page is the top search result for...
package xxxxx is not in GOROOT (/usr/lib/go/src/xxxxx)
In my case, I was trying:
go build mything
That gave me the error. The solution was simple, I needed to be more specific:
go build mything.go
I faced the same problem but in my case i forgot the .go so after running :
problem : go run main
solution: go run main.go
and now it works fine
I am struggling with my travis-ci build.
Here the arborescence of my project:
- github.com
- src
- MyLib
- MyLibImpl.go
- main.go
The main.go is referencing MyLib like this
package main
import "fmt"
import MyLib "github.com/hako910/GolangTest/src/MyLib"
func main() {
fmt.Printf("%v", MyLib.HelloWorld())
}
It works great on my machine but fails in travis-ci with this message:
$ go get -t -v ./...
github.com/hako910/GolangTest (download)
package github.com/hako910/GolangTest/src/MyLib: /home/travis/gopath/src/github.com/hako910/GolangTest exists but /home/travis/gopath/src/github.com/hako910/GolangTest/.git does not - stale checkout?
The command "eval go get -t -v ./... " failed. Retrying, 2 of 3.
Here is my source code https://github.com/hako910/GolangTest and here is my travis-ci build https://travis-ci.org/hako910/GolangTest/jobs/348845103
What is wrong with my configuration?
Inspired by this SO question I wanted to use the same mechanism to embed a version number in my golang application. However I'm using the Cobra command line parser and want to have a version sub-command. This leads to the following directory and package structure:
.
|-- cmd
`-- version.go
|-- main.go
Up to now I have tried the following:
go run -ldflags "-X cmd/version.versionString=0.1.0" main.go version
-
go run -ldflags "-X version.versionString=0.1.0" main.go version
-
go run -ldflags "-X version.VersionString=0.1.0" main.go version
With version.go containing a variable declaration like:
var versionString string
and
var VersionString string
respectively.
I've also tried to put the variable declarations in main.go but then I'm not clear how to reference the variables in version.go for this option I tried:
import "github.com/basbossink/psiw"
....
fmt.Println(psiw.VersionString)
-
import "github.com/basbossink/psiw/main"
...
fmt.Println(main.VersionString)
In both cases the compiler complains that psiw and main respectively are unknown.
Note that using the VersionString in main gives the expected result.
I would prefer a solution where the link flags point to the variable in the version package since they don't require a back-pointer. But any suggestions are welcome.
Looking at the Hugo source I've discovered the answer to my question. The trick is to use:
go run -ldflags "-X github.com/basbossink/psiw/cmd.versionString=0.1.0" main.go version
So I made two mistakes:
I mixed up the notion of package and source file, the version.go file had package cmd as it's package statement.
The way to reference the variable is to use the fully qualified name.
If I compile this program
package main
import (
"fmt"
"os"
)
var version = os.Getenv("VERSION")
func main() {
fmt.Println(version)
}
It prints the env var when I run it
VERSION="0.123" ./example
> 0.123
Is there a way to compile the env var into the binary, for example:
VERSION="0.123" go build example.go
Then get the same output when I run
./example
Go 1.5 and above edit:
As of now, the syntax has changed.
On Unix use:
go build -ldflags "-X main.Version=$VERSION"
On Windows use:
go build -ldflags "-X main.Version=%VERSION%"
This is what -X linker flag is for. In your case, you would do
go build -ldflags "-X main.Version $VERSION"
Edit: on Windows this would be
go build -ldflags "-X main.Version %VERSION%"
More info in the linker docs.
Ainer-G's answer led me to the right place, but it wasn't a full code sample answering the question. A couple of changes were required:
Declare the version as var version string
Compile with -X main.version=$VERSION
Here's the full code:
package main
import (
"fmt"
)
var version string
func main() {
fmt.Println(version)
}
Now compile with
go build -ldflags "-X main.version=$VERSION"
There is an os.Setenv() function which you can use to set environment variables.
So you can start your application by setting the environment variable like this:
func init() {
os.Setenv("VERSION", "0.123")
}
If you don't want to do this by "hand", you could create a tool for this which would read the current value of the VERSION environment variable and generate a .go source file in your package containing exactly like the code above (except using the current value of the VERSION environment variable). You can run such code generation by issuing the go generate command.
Read the Generating code blog post for more details about go generate.
compiler: http://code.google.com/p/go/downloads/detail?name=go1.0.3.windows-386.zip&can=2&q=
I've unpacked it to d:\, then made another directory d:\testgo, where I put two files:
The code:
package main
import "fmt"
func main() {
fmt.Println("Hello world!")
}
and the CMD file to run the compilation:
SET PATH=%PATH%;D:\go\bin
go build test.go
#pause>nul
And I got no exe but this:
test.go:3:8: import "fmt": cannot find package
package runtime: import "runtime": cannot find package
So what went wrong ?
The documentations says the following:
If you chose a directory other than c:\Go, you must set the GOROOT
environment variable to your chosen path.
SET GOROOT=d:\Go should do it.