今天继续关于
go
go
交叉编译是用来在一个平台上生成另一个平台的可执行程序。比如我工作开发时用的Mac,系统内核是
darwin
windows
那么假如我编写的代码依赖了系统底层平台或处理器架构特性的
go
go
panic
syscall.Dup2
syscall.Dup2
go
Unix
X86_64
windows
所以在上篇文章说的那个为了追踪在
Kubernetes
syscall.Dup2
<pre class="brush:php;toolbar:false;">func RewriteStderrFile() error {   if runtime.GOOS == "windows" {      return nil   }   ......    file, err := os.OpenFile(stdErrFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)    if err != nil {      fmt.Println(err)        return err    }        if err = syscall.Dup2(int(file.Fd()), int(os.Stderr.Fd())); err != nil {        fmt.Println(err)        return err    }    ......    return nil}天真的用了一个runtime.GOOS == "windows"的判断,我还想着能在代码里根据内核的不同执行不同的代码,但是
go
windows
syscall.Dup2
我这不就是典型的动态语言的思维吗,之前还写文章跟别人讲《如何避免用动态语言的思维写Go代码》......这次打自己脸打的实在有点疼。
虽然项目这个更新已经上线了,但是土壕小张和运维我都惹不起,迫于无奈我就看了看
go
我发现在go的每个内置库里都有很多以不停系统名结尾的文件。下面是
go

在有些文件里还有类似下面这样的注释:
代码语言:javascript代码运行次数:0运行复制<pre class="brush:php;toolbar:false;">// +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solarispackage os...
看了些资料后才知道,他们是用于
go
go
#define
go
build tags
go
构建标签就是上面我说的源代码里的注释:
代码语言:javascript代码运行次数:0运行复制<pre class="brush:php;toolbar:false;">// +build aix darwin dragonfly freebsd js,wasm linux netbsd openbsd solarispackage os...
需要注意的是,构建标签必须在代码文件里位于
package
当
go
构建标签遵循以下三个原则:
空格隔开的选项是或(OR)的关系逗号隔开的选项是与(AND)的关系每个选项由字母和数字组成。如果前面加上!
<pre class="brush:php;toolbar:false;">// +build darwin freebsd netbsd openbsd
上面的例子,表示这个源码文件只会在支持
kqueue
BSD
一个源码文件可以包含多个构建标签。构建规则是每个独立规则的逻辑与关系。如下例子表示该文件将在
linux/386
darwin/386
<pre class="brush:php;toolbar:false;">// +build linux darwin// +build 386
用逻辑表达式表示就是:(linux OR darwin) AND 386。
文件名后缀第二种条件编译的方法是通过源码文件的文件名实现的。这种方案比构造标签方案更简单。
go/build包的文档有关于命名约定的描述。简单来说,如果文件名包含_GOOS.go后缀,那么这个源码文件只会在对应的平台被编译。其他平台会忽略这个文件。另一种约定是_GOARCH.go。这两种后缀可以组合起来,但要保证顺序,正确的格式是_GOOS_GOARCH.go,错误的格式是_GOARCH_GOOS.go。
以下是文件名后缀的一些例子:
代码语言:javascript代码运行次数:0运行复制<pre class="brush:php;toolbar:false;">mypkg_freebsd_arm.go // 只在 freebsd/arm 系统编译mypkg_plan9.go // 只在 plan9 编译mypkg_darwin.go // 只在macos 系统编译
源码文件光有后缀是不行的,比如如下文件名:
代码语言:javascript代码运行次数:0运行复制<pre class="brush:php;toolbar:false;">_linux.go_freebsd_386.go
即使是在Linux或FreeBSD系统,这两个文件也会被忽略,原因是
go/build
.
_
构建标签和文件名后缀在功能上是重叠的。比如,一个名为
mypkg_linux.go
// +build linux
通常来说,当只有一个特定平台或体系需要指定时,我们选择文件名后缀的方式。比如:
代码语言:javascript代码运行次数:0运行复制<pre class="brush:php;toolbar:false;">mypkg_linux.go // 只在 linux 系统编译mypkg_windows_amd64.go // 只在 windows amd 64位 平台编译
相反,如果你的文件需要指定给多个平台或体系架构使用,或者你需要排除某个特定平台时,我们选择构建标签的方式。比如:
代码语言:javascript代码运行次数:0运行复制<pre class="brush:php;toolbar:false;">// 在所有类unix平台编译// +build darwin dragonfly freebsd linux netbsd openbsd// 在非Windows平台编译// +build !windows
应用环境,我就说下是怎么解决文章开头说的问题让小张大佬平复心情的吧......。
设置条件编译首先我像下面这样,在包里建了两个源码文件,用来分别存放在
windows
windows
RewriteStderrFile
<pre class="brush:php;toolbar:false;">project|└───pkg1│ │----rewrite_err_unix.go│ │----rewrite_err_windows.go
因为我们的项目在那几个大佬电脑的
windows
Linux
<pre class="brush:php;toolbar:false;">//rewrite_err_windows.gopackage pkg1func RewriteStdErrLog(topic string) error { return nil}对于要在服务器上和Mac电脑上编译的源码,跟之前的差不多,只是增加了构建标签:
代码语言:javascript代码运行次数:0运行复制<pre class="brush:php;toolbar:false;">//+build darwin linuxpackage pkg1......func RewritePanicsToFile(topic string) error {    ......    file, err := os.OpenFile(stdErrFile, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)    if err != nil {      fmt.Println(err)        return err    }   if err = syscall.Dup2(int(errFileHandler.Fd()), int(os.Stderr.Fd())); err != nil {      return err   }    ......     return nil}交叉编译的执行就非常简单了,在编译时给go build命令设置
OS
ARCH
比如在Mac 下编译
windows
<pre class="brush:php;toolbar:false;">CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go
在Mac系统执行完上面的命令就会编译生成软件包在Windows系统上的可执行文件(.exe文件)
如果是
windows
<pre class="brush:php;toolbar:false;">SET CGO_ENABLED=0SET GOOS=darwinSET GOARCH=amd64go build main.go
事实上,除了用于
.go
.c
.s
go
runtime
syscall
OS
net
[1]
os: https://github.com/golang/go/tree/master/src/os
以上就是我在暴躁同事小张的胁迫下学会了Go的交叉编译和条件编译的详细内容,更多请关注php中文网其它相关文章!
 
                        
                        每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
 
                 
                                
                                 收藏
收藏
                                                                             
                                
                                 收藏
收藏
                                                                             
                                
                                 收藏
收藏
                                                                            Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号