我需要能够构建不同版本的go应用程序; 'debug'版本和普通版本。
这很容易做到;我只是有一个const DEBUG,它控制着应用程序的行为,但每次我需要在构建类型之间进行交换时,必须编辑配置文件很烦人。
我正在阅读有关go build(http://golang.org/pkg/go/build/)和标签的内容,我想也许我可以这样做:
config.go:
// +build !debug
package build
const DEBUG = false
config.debug.go:
// +build debug
package build
const DEBUG = true
然后我应该能够使用“go build”或“go build -tags debug”进行构建,标签应该排除config.go并包含config.debug.go。
......但这不起作用。我明白了:
src / build / config.go:3:在此块(< 0>)之前重新声明的DEBUG 声明在src / build / config.debug.go:3
我做错了什么?
我应该使用另一种更合适的#ifdef样式吗?
答案 0 :(得分:29)
见my answer to another question。在“// + build”行之后需要一个空行。
另外,你可能想要“!”在config.go中,而不是在config.debug.go中;并且大概你想要一个人“DEBUG = false”。
答案 1 :(得分:21)
您可以使用编译时常量:如果使用
编译程序go build -ldflags '-X main.DEBUG=YES' test.go
来自包main的变量DEBUG
将被设置为字符串“YES”。否则它会保留其声明的内容。
package main
import (
"fmt"
)
var DEBUG = "NO"
func main() {
fmt.Printf("DEBUG is %q\n", DEBUG)
}
编辑:由于Go 1.6(?),开关为-X main.DEBUG=YES
,之前是-X main.DEBUG YES
(没有=
)。感谢@poorva的评论。
答案 2 :(得分:0)
从 Go 1.17 开始,可以使用新的 //go:build
语法指定构建标记。
至于 //go:build
指令的位置,新设计指出:
约束可以出现在任何类型的源文件中(不仅仅是 Go),但它们必须出现在文件顶部附近,前面只能有空行和其他 //
和 /* */
注释。这些规则意味着在 Go 文件中,构建约束必须出现在 package 子句之前。
所以你仍然需要在 //go:build
指令和包语句之间留一个空行,否则它可以被解析为包文档,但是现在:
go fmt
将自动修复错位的指令例如在(无空行)上运行 go fmt
:
//go:build foo
package main
import "fmt"
func main() {
fmt.Println("Hello world")
}
给出(带空行):
//go:build foo
package main
import "fmt"
func main() {
fmt.Println("Hello world")
}
另请参阅 this answer 以了解有关新语法的更改的更多详细信息。