Golang 的 构建

1 构建命令

go build
go build .  // 生成出来的可执行文件名为 包名
go build main.go  // 生成出来的可执行文件名为 main.exe 或 main 文件名
go build . -o app.exe // 生成出来的可执行文件为指定的 app.exe

2 Windows上构建时加上可执行文件的图标

2.1使用 winres​

参考文章 Golang生成exe时如何添加一个图标_go build 自定义图标-CSDN博客

在项目位置创建一个 build.rc​ 文件并准备一个 main.ico​

写入文本IDI_ICON1 ICON "main.ico"​

执行 windres -o main.syso main.rc​

编译时执行 go build -ldflags "-H windowsgui"​

2.2 使用 GoVersionInfo​

3 交叉编译

Go 语言支持交叉编译 意味着你可以在 Windows 编译出其他系统、其他架构的可执行文件

编译时由 Go的环境变量 GOOS、GOARCH 控制目标系统和架构

GOOS:

  • ​windows​
  • ​darwin​ MacOS
  • ​linux​
  • ​freebsd​
  • 其他

GOARCH:

  • ​amd64​ 最常用 也叫 x64 、x86-64、64-bit
  • ​386​ 过时的 也叫 x32、x86、32-bit
  • ​arm​ 一般手机的架构 或者某些国产CPU的架构
  • ​arm64​ 也叫 aarch64
  • 其他

3.1 Windows下 编译常用平台的可执行文件脚本

​build.bat​

脚本会生成一个 bin 目录 存放交叉编译的结果

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION

if not exist bin (
    mkdir bin
)

REM 设置程序名称和源文件
SET APP_NAME=clash
SET SOURCE_FILE=main.go

REM 设置目标系统和架构
SET PLATFORMS=windows linux darwin
SET ARCHS=amd64 386 arm64

REM 开始编译
FOR %%P IN (%PLATFORMS%) DO (
    FOR %%A IN (%ARCHS%) DO (
        SET GOOS=%%P
        SET GOARCH=%%A
        SET OUTPUT_NAME=!APP_NAME!-!GOOS!-!GOARCH!
        IF "%%P"=="windows" (
            SET OUTPUT_NAME=!OUTPUT_NAME!.exe
        )
        echo building: !OUTPUT_NAME!
        REM 删除旧的二进制文件
        IF EXIST bin\!OUTPUT_NAME! (
            del bin\!OUTPUT_NAME!
        )
        go build -o bin/!OUTPUT_NAME! -ldflags "-s -w -extldflags '-static'" %SOURCE_FILE%
        IF NOT !ERRORLEVEL! == 0 (
            echo build failed !OUTPUT_NAME!
        ) ELSE (
            echo build success !OUTPUT_NAME!
        )
    )
)

ECHO build finished
ENDLOCAL

3.2 Linux 下 编译常用平台的可执行文件脚本

​build.sh​

#!/bin/bash

# 创建二进制文件存放目录
mkdir -p bin

# 设置程序名称和源文件
APP_NAME="clash"
SOURCE_FILE="main.go"

# 设置目标系统和架构
PLATFORMS="windows linux darwin"
ARCHS="amd64 386 arm64"

# 开始编译
for GOOS in $PLATFORMS; do
    for GOARCH in $ARCHS; do
        OUTPUT_NAME="${APP_NAME}-${GOOS}-${GOARCH}"
        if [ "$GOOS" == "windows" ]; then
            OUTPUT_NAME="${OUTPUT_NAME}.exe"
        fi
        echo "building: $OUTPUT_NAME"
        # 删除旧的二进制文件
        if [ -f "bin/$OUTPUT_NAME" ]; then
            rm "bin/$OUTPUT_NAME"
        fi
        # 设置环境变量并编译
        GOOS=$GOOS GOARCH=$GOARCH go build -o "bin/$OUTPUT_NAME" $SOURCE_FILE
        if [ $? -eq 0 ]; then
            echo "build success: $OUTPUT_NAME"
        else
            echo "build failed: $OUTPUT_NAME"
        fi
    done
done

echo "build finished"

安装 goversioninfo​ 并准备一个 main.ico​

4 go build 的详细参数

	-o Name
			编译出的文件名,默认为包名或者文件名

	-i
			缓存已编译包,提升后续编译速度,Go 1.12	以后会自动缓存 无需显式添加

    -C dir
            在运行命令前更改到 dir 目录。
            命令行上指定的任何文件都在更改目录后解释。
            如果使用,此标志必须是命令行中的第一个。

    -a
            强制重建已是最新的包。

    -n
            打印编译命令但不运行它们。

    -p n
            编译时使用的核心数量,默认为CPU核心数。

    -race
            启用数据竞争检测。
            仅支持在 linux/amd64, freebsd/amd64, darwin/amd64, darwin/arm64, windows/amd64,
            linux/ppc64le 和 linux/arm64(仅限48位 VMA)。

    -msan
            启用与内存消毒器的互操作。
            仅支持在 linux/amd64, linux/arm64, linux/loong64, freebsd/amd64
            且仅当宿主 C 编译器为 Clang/LLVM 时。
            在 linux/amd64 之外的所有平台上将使用 PIE 构建模式。

    -asan
            启用与地址消毒器的互操作。
            仅支持在 linux/arm64, linux/amd64, linux/loong64。
            在 linux/amd64 或 linux/arm64 上支持,仅适用于 GCC 7 及以上
            或 Clang/LLVM 9 及以上。
            并且在 linux/loong64 上仅支持 Clang/LLVM 16 及以上。

    -cover
            启用代码覆盖率工具。

    -covermode set,count,atomic
            设置覆盖分析模式。
            默认为 "set",除非启用了 -race,
            在这种情况下为 "atomic"。
            值:
            set: bool: 这个语句运行了吗?
            count: int: 这个语句运行了几次?
            atomic: int: count, 但在多线程测试中正确;
                    成本显著更高。
            设置 -cover。

    -coverpkg pattern1,pattern2,pattern3
            针对目标为 'main' 包的构建(例如构建 Go 可执行文件),对每个匹配模式的包应用覆盖

    -tags tag1,tag2,tag3
			指定编译时额外参加编译的标签,例如debug 文件头添加 // +build debug 来定义标签

	-v
			打印正在编译的包的名称。

	-work
			打印临时工作目录的名称,并在退出时不删除它。

	-x
			打印编译时命令。

	-asmflags '[pattern=]arg list'
			传递给每次调用 go tool asm 的参数。

	-buildmode mode
			-buildmode=archive
				构建列出的非主包为 .a 文件。名为 main 的包将被忽略。
			-buildmode=c-archive
				将列出的主包及其导入的所有包构建成一个 C 归档文件。唯一可调用的符号将是使用 cgo //export 注释导出的函数。这要求准确地列出一个主包。
			-buildmode=c-shared
				将列出的主包及其导入的所有包构建成一个 C 共享库。唯一可调用的符号将是使用 cgo //export 注释导出的函数。这要求准确地列出一个主包。
			-buildmode=default
				列出的主包被构建成可执行文件,列出的非主包被构建成 .a 文件(默认行为)。
			-buildmode=shared
				将所有列出的非主包合并成一个单一的共享库,该库将在使用 -linkshared 选项构建时使用。名为 main 的包将被忽略。
			-buildmode=exe
				将列出的主包及其导入的所有内容构建成可执行文件。未命名为 main 的包将被忽略。
			-buildmode=pie
				将列出的主包及其导入的所有内容构建成位置独立的可执行文件(PIE)。未命名为 main 的包将被忽略。
			-buildmode=plugin
				将列出的主包及其导入的所有包构建成一个 Go 插件。未命名为 main 的包将被忽略。
			在 AIX 上,当链接使用 -buildmode=c-archive 构建的 Go 归档文件的 C 程序时,必须向 C 编译器传递 -Wl,-bnoobjreorder 参数。

	-buildvcs
			是否将版本控制信息标记到二进制文件中("true","false" 或 "auto")。默认情况下("auto"),
			如果主包、包含它的主模块和当前目录都在同一仓库中,则会将版本控制信息标记到二进制文件中。
			使用 -buildvcs=false 始终省略版本控制信息,
			或使用 -buildvcs=true 在版本控制信息可用但由于缺少工具或目录结构不明确无法包含时报错。

	-compiler name
			使用的编译器名称,如 runtime.Compiler 中的 gccgo 或 gc

	-gccgoflags '[pattern=]arg list'
			传递给每次调用 gccgo 编译器/链接器的参数。

	-gcflags '[pattern=]arg list'
			垃圾回收机制参数

	-installsuffix suffix
			用于包安装目录名称的后缀,以使输出与默认构建分开。如果使用 -race 标志,安装后缀自动设置为 race,
			或者如果明确设置,则追加 _race。对于 -msan 和 -asan 标志也是如此。使用需要非默认编译标志的 -buildmode 选项具有类似效果。

	-ldflags '[pattern=]arg list'
			-s
				移除二进制文件中的符号表,报错时的调试信息,能减少可执行文件大小。
			-w
				省略二进制文件中的调试信息(DWARF 调试信息),能减少可执行文件大小。
			-X 
				设置内部变量值,常用于构建时快捷设置版本号 "-X 'main.Version=1.0.0' -X 'main.BuildTime=$(date)'"
			-H
				设置二进制的类型,比如使得生成的二进制为静态链接 
				例如 构建不带控制台窗口的 GUI 应用程序: "-H windowsgui" 
			-memprofile
				在运行时进行内存分析,生成内存使用的概况文件。
			-cpuprofile
				创建 CPU 使用概况文件,帮助分析 CPU 使用情况。
			-extldflags "-static"
				静态编译 提高兼容性

	-linkshared
			构建将与先前使用 -buildmode=shared 创建的共享库链接的代码。

	-mod mode
			使用的模块下载模式:readonly,vendor 或 mod。默认情况下,
			如果存在 vendor 目录且 go.mod 中的 go 版本为 1.14 或更高,则 go 命令行为就像设置了 -mod=vendor。否则,行为就像设置了 -mod=readonly。

	-modcacherw
			让新创建的模块缓存目录保持可写状态,而不是将其设置为只读。

	-modfile file
			在模块感知模式下,读取(可能写入)一个备用的 go.mod 文件,
			而不是模块根目录中的文件。必须仍然存在名为 "go.mod" 的文件,以确定模块根目录,但不访问此文件。
			指定 -modfile 时,还会使用一个备用的 go.sum 文件,其路径是根据 -modfile 标志修剪 ".mod" 扩展名并追加 ".sum" 获得的。

	-overlay file
			读取一个为构建操作提供覆盖的 JSON 配置文件。该文件是一个 JSON 结构,有一个名为 'Replace' 的字段,
			该字段将每个磁盘文件路径(一个字符串)映射到其后备文件路径,以便构建运行时就像磁盘文件路径具有由后备文件路径给出的内容一样,
			或者如果后备文件路径为空则磁盘文件路径不存在。支持 -overlay 标志有一些限制:重要的是,
			从包含路径外部包含的 cgo 文件必须与包含它们的 Go 包在同一目录中,且在通过 go run 和 go test 运行二进制文件和测试时,覆盖将不会出现。

	-pgo file
			指定用于配置文件引导优化(PGO)的配置文件路径。当指定特殊名称 "auto" 时,对于构建中的每个主包,
			如果该目录中存在名为 "default.pgo" 的文件,go 命令会选择该文件,并将其应用于主包的(传递的)依赖项(其他包不受影响)。
			特殊名称 "off" 用于关闭 PGO。默认值为 "auto"。

	-pkgdir dir
			将所有包从常规位置安装和加载到指定的 dir 目录中。例如,在使用非标准配置构建时,使用 -pkgdir 将生成的包保持在一个单独的位置。

	-trimpath
			从结果可执行文件中删除所有文件系统路径。而不是绝对文件系统路径,记录的文件名将从模块路径@版本开始(使用模块时),或者从普通的导入路径开始(使用标准库或 GOPATH 时)。

	-toolexec 'cmd args'
			用于调用像 vet 和 asm 这样的工具链程序的程序。例如,代替运行 asm,
			go 命令将运行 'cmd args /path/to/asm <arguments for asm>'。
			将设置 TOOLEXEC_IMPORTPATH 环境变量,匹配 'go list -f {{.ImportPath}}' 为正在构建的包提供的导入路径。

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

deadmau5v

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值