兼容不同平台的跨平台编译

说明:因为go的log/sys_log库只能在unix系统编译通过,所以用这个日志库作为跨平台编译对象

标签tags编译

主文件main.go,linux标签文件log_tag_lx.go, windows标签文件log_tag_wx.go
说明: 由于标签放在同一个文件编译不通过,所以分开成不同文件
内容如下:

  • main.go
package main

func main() {
       TagLog()
}
  • log_tag_lx.go
// +build linux

package main

import (
    "log/syslog"
)

func TagLog() {
    sysLog, err := syslog.Dial("", "", syslog.LOG_ERR, "Saturday")
    if err != nil {
        log.Fatal(err)
    }

    sysLog.Emerg("it is tag linux")
}
  • log_tag_wx.go
// +build windows

package main

import "log"

func TagLog() {
    log.Print("it is tag windows")
}

尝试在win10下build,结果如下:

D:\project\gotests>go build -tags windows

D:\project\gotests>go build -tags linux
# runtime/internal/sys
C:\Go\src\runtime\internal\sys\zgoos_windows.go:7:7: GOOS redeclared in this block

windows build并运行成功,使用-tags linux build失败,同理在linux环境下正相反

文件后缀编译

不使用tags编译,可以使用适应平台的后缀文件编译,不同平台用不同后缀,编译的时候编译器自动根据平台选择不同的编译文件编译

主文件main.go, linux后缀文件log_linux.go, windows后缀文件log_windows.go

  • main.go
package main

func main() {
       SuffixLog()
}
  • log_linux.go
package main

import (
    "log/syslog"
)

func SuffixLog() {
    sysLog, err := syslog.Dial("", "", syslog.LOG_ERR, "Saturday")
    if err != nil {
        log.Fatal(err)
    }

    sysLog.Emerg("it is suffix linux")
}
  • log_windows.go
package main

import "log"

func SuffixLog() {
    log.Print("it is suffix windows")
}

win10环境下编译并输出如下

D:\project\gotests>go build

D:\project\gotests>gotests.exe
2020/11/01 21:47:13 it is suffix windows

说明编译器能正确能识别不同平台文件并编译成功,同理linux环境也能成功

二进制文件混淆保护

默认情况下go编译出的程序在运行出错时会输出自己在哪个线程哪个文件哪个函数哪行出的错,就像这样


DWARF信息对于小黑客们可是如获至宝,这些关键信息不能留下。而且去掉这些东西也非常简单:

go build -ldflags "-s -w” [<your/package]

(需要Go版本大于1.7)
这里的 -ldflags 参数最终会在 go tool link 的时候传给它, go tool link -h解释如下

  -s    disable symbol table
  -w    disable DWARF generation

删除掉调试符号的另一个好处就是,显著减小了文件大小(平均20%)