前言

在真实环境中,我们可能需要为不同的编译环境编写不同的 Go 代码,所以需要做构建约束。

比如:syscall.NewLazyDLL("test.dll")

加载 dll 的程序在 Linux 平台中就没有,所以当你写程序时就需要指定包含这个 API 的文件只能在 Windows 下面编译,在其他平台自动忽略,这样就不会代码移植到别的平台出现编译时错误了。

Go 语言对这一问题的解决方案是在文件层面进行有条件的编译:每个文件要么在编译中,要么不在。

也就是,假设不符合构建约束的场景。那么会直接不编译这个文件,因为它不在编译范围内。

那程序再想运行时,就会报错,表示找不到文件。

构建约束的背景

最早的构建约束是在 2011 年 9 月引入的,我们平时常见的构建约束(build constraint),也叫做构建标记(build tag),构建约束必须出现在 package 之前。

通过代码文件中添加注释进行约束

平时会在 Go 工程的文件中的最开始会看到如下行注解:

// +build

为了将构建约束与包文档区分开来,构建约束后必须跟一个空行。

// +build linux,386 darwin,!cgo

又或是:

// +build linux darwin
// +build amd64

还可以根据 Go 版本来约束:

// +build go1.9

其主要支持如下几种:

  • 指定编译的操作系统,例如:windows、linux 等,对应 runtime.GOOS 的值。
  • 指定编译的计算机架构,例如:amd64、386,对应 runtime.GOARCH 的值。
  • 指定使用的编译器,例如:gccgo、gc,是否开启CGO,cgo。
  • 指定 Go 版本,例如:go1.19、go1.20 等。
  • 指定自定义的标签,例如:编译时通过指定 -tags 传入的值。
  • // +build ignore,编译时自动忽略该文件
  • ……

标签之间有如下几种运算关系:

空格表示:AND
逗号表示:OR
!表示:NOT
换行表示:AND

比如:

// +build linux,386 darwin,!cgo
运算表达式为:(linux && 386) || (darwin && !cgo)

使用文件后缀进行约束

这种方式就是通过文件的后缀名来对要指定平台的编译的文件进行约束,文件格式如下:

sourcefilename_GOOS_GOARCH

上面的格式就是文件名_系统名_架构名.go,GOOS和GOARCH可以通过go env看到,也可以在环境变量中指定;下面举个例子:

user_windows_amd64.go  //在 windows 中 amd64 架构下才会编译,其他的环境中会自动忽略
user_linux_arm.go // 在 linux 中的 arm 架构下才会编译,其他环境中会自动忽略

go 编译约束//go:build dev //+build的更多相关文章

  1. 【转】Ubuntu10.04上编译Android源码(Build Android source in Ubuntu10.04 Platform)

    原文网址:http://blog.csdn.net/chenyafei617/article/details/6570928 一.Introduction 今天我们就来谈谈如何在Ubuntu平台上面编 ...

  2. npm run dev/build/serve

    1.ERR引发的思考 npm run dev npm ERR! missing script: dev npm ERR! A complete log of this run can be found ...

  3. 代码编译 Compile、Make、Build 的区别

    代码编译 Compile.Make.Build 的区别 https://blog.csdn.net/fanzheng220112583/article/details/7780250 VC++6.0中 ...

  4. (转)Maven的pom.xml文件结构之Build配置build

    在Maven的pom.xml文件中,Build相关配置包含两个部分,一个是<build>,另一个是<reporting>,这里我们只介绍<build>. 1. 在M ...

  5. npm WARN build `npm build` called with no arguments. Did you mean to `npm run-script build`?

    跑npm build结果如下: npm WARN build `npm build` called with no arguments. Did you mean to `npm run-script ...

  6. cmake编译成功之后VS2015可以build Solution但是不可以运行的解决办法

    1.在VS2015解决方案管理器中删除掉ALL_BUILD和ZERO_CHECK项,只保留Cmake生成的工程文件. 2.进行第一部之后还是有可能生成(build)失败,此时有可能是缺少文件.

  7. ionic2 在执行ionic serve后报 build dev failed: Cannot set property 'fileSystem' of null

    ionic2 真是烦人,因为环境依赖的问题还有网络的问题,不知砸的,项目放一段事件不运行就会出问题. 我一开始是 用 cnpm install安装的依赖,其中也报了错, 然后执行 ionic serv ...

  8. Angular6之ng build | ng build --aot | ng build --prod 差异

    由于写了大半年的项目终于要告一段落并且即将进行第二阶段优化开发,emmm 基础版本已经二十多个模块了,必不可少的优化是很重要的,尽管项目上使用多层嵌套懒加载,但是在首屏加载的时候,任然很慢啊,因为一直 ...

  9. Project 'king.commons' is missing required library: 'lib/plweb.jar' Build path Build Path Problem

    问题描述:之前在项目里引用一个jar 包,后来不用了删掉 ,但是没有删干净,然后报以下错误. 解决方案: 1.删除libraries 2.找到该项目下的 .classpath 文件,用记事本打开 ,删 ...

  10. npm 常用配置

    npm config list/ls 显示配置信息npm config list/ls -l 更详细npm -h 显示帮助信息,建议多查看npm -l display full usage info ...

随机推荐

  1. Qt/C++地图高级绘图/指定唯一标识添加删除修改/动态显示和隐藏/支持天地图高德地图百度地图

    一.前言说明 已经有了最基础的接口用来添加覆盖物,而且还有通过进入覆盖物模式动态添加覆盖物的功能,为什么还要来个高级绘图?因为又有新的需求,给钱就搞,一点底线都没有.无论哪个地图厂家,提供的接口都是没 ...

  2. 11.12javaweb学习

  3. 使用 NodeLocalDNS 提升集群 DNS 性能和可靠性

    本文主要分享如何使用 NodeLocal DNSCache 来提升集群中的 DNS 性能以及可靠性,包括部署.使用配置以及原理分析,最终通过压测表明使用后带来了高达 50% 的性能提升. 1.背景 什 ...

  4. Android SELinux 权限问题总结

    SELinux TE 添加权限不生效的解决方法==============================================selinux security level引起的denied ...

  5. Ubuntu 16.04 配置Windows 远程桌面(RDP & Unity Desktop)

    网上大多数方法安装完成后不是连不上就是花屏或者桌面环境变了,本方法可以解决以上问题. 一键配置脚本: 运行前chmod +x xrdp-installer-1.2.2.sh 添加权限,执行时不需要ro ...

  6. Solution Set -「LOCAL」冲刺省选 Round X

    \(\mathscr{Summary}\)   时间利用效率?   同学,你的效率呢?   我真不知道中途几个小时干了啥,我也不知道我实在划水.神游还是真的在自闭想题.   虽然真实考场肾上腺素不会允 ...

  7. .NET 开发的分流抢票软件,不做广告、不收集隐私

    前言 每年春节大家必备的抢票工具Bypass-分流抢票.分流抢票是一款免费无广适用于PC端的自动分流抢票软件. 分流抢票,是以用户为中心.人性化的抢票软件.不做广告.不做推广.不携带病毒.不收集隐私信 ...

  8. Mac安装brew的四种方法(指定能行)

    一,执行brew官网命令安装brew https://brew.sh/ 官网中复制下图中命令,在terminal中输入该命令,即: /bin/bash -c "$(curl -fsSL ht ...

  9. shell脚本中的循环(for循环,while循环)及break、continue的用法示例

    Shell脚本中也算是一门简易的编程语言了,当然循环是不能缺少的.常用到的循环有for循环和while循环.下面就分别介绍一下两种循环的结构. [for循环]: Shell脚本中的for循环示例: # ...

  10. 网络通信协议:TCP(三次握手四次挥手)和UDP

    通信要素2:网络协议  网络通信协议计算机网络中实现通信必须有一些约定,即通信协议,对速率.传输代码.代码结构.传输控制步骤.出错控制等制定标准. 问题:网络协议太复杂计算机网络通信涉及内容很多, ...