英文:
using ldflags for giving binary file a version not working in golang
问题
以下是翻译好的内容:
main.go的代码如下:
package main
func main() {
println("hello world")
}
Makefile的代码如下:
flags=-X main.version=1.5.0
build:
go build -ldflags "$(flags)" -o main main.go
然后我运行make
,得到了main文件。
当我运行./main -v
时,我只得到了:
hello world
为什么它没有显示1.5.0
?
go版本是go version go1.18 darwin/arm64
,当我运行go version -m main
时,我得到了:
main: go1.18
path command-line-arguments
build -compiler=gc
build -ldflags="-X main.version=1.5.0"
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=arm64
build GOOS=darwin
我对ldflags
有误解。它的工作原理如下:
package main
import (
"fmt"
"os"
)
var (
version string
)
func main() {
args := os.Args
if len(args) == 2 && (args[1] == "--version" || args[1] == "-v") {
fmt.Printf("project version: %s \n", version)
return
}
}
$ ./main -v
project version: 1.5.0
英文:
The main.go as follows:
package main
func main() {
println("hello world")
}
The Makefile as follows:
flags=-X main.version=1.5.0
build:
go build -ldflags "$(flags)" -o main main.go
Then I run make
, and got main file.
After I runing ./main -v
, I just got:
hello world
Why it does not display 1.5.0
?
go version is go version go1.18 darwin/arm64
, when I run go version -m main
, I got:
main: go1.18
path command-line-arguments
build -compiler=gc
build -ldflags="-X main.version=1.5.0"
build CGO_ENABLED=1
build CGO_CFLAGS=
build CGO_CPPFLAGS=
build CGO_CXXFLAGS=
build CGO_LDFLAGS=
build GOARCH=arm64
build GOOS=darwin
I had a misunderstanding of ldflags
. It works as follows:
package main
import (
"fmt"
"os"
)
var (
version string
)
func main() {
args := os.Args
if len(args) == 2 && (args[1] == "--version" || args[1] == "-v") {
fmt.Printf("project version: %s \n", version)
return
}
}
$ ./main -v
project version: 1.5.0
答案1
得分: 3
你正在设置的ldflags
变量(version
)必须在包级别的包中声明。处理-v
选项的部分需要你自己实现。
package main
import "flag"
var version string
func main() {
var vFlag bool
flag.BoolVar(&vFlag, "v", false, "显示版本号")
flag.Parse()
if vFlag {
println(version)
} else {
println("你好,世界")
}
}
go build -ldflags "-X main.version=1.5.0" -o main main.go
./main -v
# 1.5.0
./main
# 你好,世界
英文:
The variable you're setting with ldflags (version
) must be declared in the package at the package level. The handling of -v
you yourself must implement.
package main
import "flag"
var version string
func main() {
var vFlag bool
flag.BoolVar(&vFlag, "v", false, "show version")
flag.Parse()
if vFlag {
println(version)
} else {
println("hello world")
}
}
go build -ldflags "-X main.version=1.5.0" -o main main.go
./main -v
# 1.5.0
./main
# hello world
答案2
得分: 2
如果要构建一个包(如 go build github.com/xxx/yyy/zzz
),那么符号必须相应地加上前缀。例如:
go build \
-ldflags "-X github.com/xxx/yyy/zzz/main.version=1.5.0" \
-o my-awesome-app \
github.com/xxx/yyy/zzz
顺便说一下,找出要使用的符号 ID 的另一种方法是运行 nm
命令,并使用 grep 查找你要查找的变量。
英文:
If one builds a package (as in go build github.com/xxx/yyy/zzz
then the symbol must be prefixed accordingly. For example:
go build \
-ldflags "-X github.com/xxx/yyy/zzz/main.version=1.5.0" \
-o my-awesome-app \
github.com/xxx/yyy/zzz
B.T.W. Another way to figure out which symbol ID to use is to run nm
and grep for the variable you are looking for.
答案3
得分: 0
这条评论并不是对实际问题的回答,而是与标题相关的。因此,我认为在这里值得分享。
ldflags可能看起来不起作用的一个原因是它只对字符串类型的变量起作用。
例如:
package main
import "fmt"
var sss = "FOO"
var ccc = 2
func main() {
fmt.Println("variables:", sss, ccc)
}
- 使用
go run main.go
执行此代码会显示variables: FOO 2
- 使用
go run -ldflags="-X main.sss=BAR" main.go
执行它会显示variables: BAR 2
- 使用
go run -ldflags="-X main.ccc=5" main.go
执行它会显示main.ccc: cannot set with -X: not a var of type string (type.int)
另一个需要注意的地方是,如果缺少-X
,你将不会收到错误消息。它只是不会按你的期望执行:
- 使用
go run -ldflags="main.sss=BAR" main.go
执行它会显示variables: FOO 2
英文:
This comment is not an answer for the actual question but is related to the title. Therefore, I think it is worth sharing here.
One reason why ldflags may seem not to be working is that it works only for string type variables.
Example:
package main
import "fmt"
var sss = "FOO"
var ccc = 2
func main() {
fmt.Println("variables:", sss, ccc)
}
- Executing this code with
go run main.go
displaysvariables: FOO 2
- Executing it with
go run -ldflags="-X main.sss=BAR" main.go
displaysvariables: BAR 2
- Executing it with
go run -ldflags="-X main.ccc=5" main.go
displaysmain.ccc: cannot set with -X: not a var of type string (type.int)
Another gotcha is you get no error message if -X
is missing. It just doesn't do what you expect:
- Executing it with
go run -ldflags="main.sss=BAR" main.go
displaysvariables: FOO 2
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论