Golang 编译约束/条件编译 ( // +build <tags> )

通常对程序进行编译的时候,可能带一些条件(如不同平台、架构有不同的代码实现),让编译器只对满足条件的代码进行编译,将不满足条件的代码舍弃,这就是条件编译。golang中,称之为编译约束,进行编译约束的方式有2种分别:

  • 编译标签(build tag)
  • 文件后缀

编译标签 (build tag)#

在源码文件顶部添加注释,来决定文件是否参与编译

// +build <tags>

说明:

  • 以空格分开表示AND
  • 以逗号分开表示OR
  • !表示NOT

标签可以指定为以下内容:

  • 操作系统,环境变量中GOOS的值,如:linuxdarwinwindows等等。可以通过 go env 查看 GOOS 环境变量的值。
  • 操作系统的架构,环境变量中GOARCH的值,如:arch64x86i386等等。可以通过 go env 查看 GOARCH 环境变量的值。
  • 使用的编译器,gc或者gccgo
  • 是否开启CGO,cgo
  • golang版本号: 比如Go Version 1.1为go1.1,Go Version 1.12版本为go1.12,以此类推。
  • 其它自定义标签,通过go build -tags指定的值。

例如,编译条件为(linux AND 386) OR (darwin AND (NOT cgo))

// +build linux,386 darwin,!cgo

另外一个文件可以有多个编译约束,比如条件为(linux OR darwin) AND amd64

// +build linux darwin
// +build amd64

也可以将一个文件从编译中排除,使用ignore标签。

// +build ignore

注意:// +build的下一行必须是空行。

// +build linux

// main package comment
package main

下面的写法不会识别为build tag,而会解析为包注释:

// +build linux
package main

文件后缀#

除了编译标签,编译器也会根据文件后缀来自动选择编译文件,格式如下:

$filename_$GOOS.go
$filename_$GOARCH.go
$filename_$GOOS_$GOARCH.go
  • $filename: 源文件名称。
  • $GOOS: 表示操作系统,从环境变量中获取。
  • $GOARCH: 表示系统架构,从环境变量中获取。

如在项目中有tcp.gotcp_linux_x86.go 两个文件,执行:

GOOS=linux GOARCH=x86 go build

将选择 tcp_linux_x86.go进行编译,而执行:

GOOS=linux GOARCH=x86 go build

选择tcp.go进行编译。

利用ldflags在编译过程中为变量赋值#

本节为附加说明,不属于条件编译的范畴。有时我们需要在编译过程中为变量赋值,此时可以利用ldflags参数完成。ldflagsgo build的一个参数,使用方式如下:

go build -ldflags "-w -s -X main.Version=${VERSION} -X github.com/demo/version.BuildNo=${BUILD_NO}"

参数说明:

-w 删除DWARF信息:编译出来的程序无法用gdb进行调试。

-s 删除符号表:panic的stack trace没有文件名/行号信息,等价于C/C++程序被strip。

-X 替换包中的变量的值。

加上-w -s可以有效减少编译出来地程序的大小,但不利于进行调试和日志追踪。

转载文章:Golang 编译约束/条件编译 ( // +build <tags> )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 `golang.org/x/net/websocket` 包中,并没有内置的路由功能。如果您想要使用该包处理不同的 WebSocket 路由,您可以结合使用 `net/http` 包的路由功能来实现。以下是一个示例代码: ```go package main import ( "log" "net/http" "golang.org/x/net/websocket" ) func main() { http.Handle("/ws/foo", websocket.Handler(handleFooWebSocket)) http.Handle("/ws/bar", websocket.Handler(handleBarWebSocket)) log.Println("WebSocket 服务器启动,监听端口 8080") err := http.ListenAndServe(":8080", nil) if err != nil { log.Fatal("WebSocket 服务器启动失败:", err) } } func handleFooWebSocket(conn *websocket.Conn) { // 处理 /ws/foo 路由的 WebSocket 连接逻辑 // ... } func handleBarWebSocket(conn *websocket.Conn) { // 处理 /ws/bar 路由的 WebSocket 连接逻辑 // ... } ``` 在上述示例中,我们使用 `net/http` 包的 `http.Handle` 函数来定义不同的路由,并使用 `websocket.Handler` 将每个路由的处理函数转换为 WebSocket 的处理器。 在这个示例中,我们定义了两个 WebSocket 路由,`/ws/foo` 和 `/ws/bar`。当有 WebSocket 连接请求到达时,路由器会将请求传递给相应的处理函数 `handleFooWebSocket` 或 `handleBarWebSocket` 进行处理。 您可以根据实际需求添加更多的路由和处理函数。 请注意,`golang.org/x/net/websocket` 包现在已经被废弃,推荐使用 `github.com/gorilla/websocket` 包来处理 WebSocket 连接。`github.com/gorilla/websocket` 包提供了更多的功能和灵活性。 希望以上信息对您有所帮助!如果您还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值