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
参考文章 https://blog.csdn.net/Java_oujinjie/article/details/114175205
在项目位置创建一个 build.rc
文件并准备一个 main.ico
写入文本IDI_ICON1 ICON "main.ico"
执行 windres -o main.syso build.rc
编译时执行 go build -ldflags "-H windowsgui"
2.2 使用 GoVersionInfo
go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@latest
添加文件头信息
//go:generate goversioninfo
package main
func main() {
...
}
定义版本信息 创建一个 versioninfo.json
如果要复制这份Json模板 请删除注释 否则会编译失败
{
"FixedFileInfo": {
"FileVersion": {
"Major": 1,
"Minor": 0,
"Patch": 0,
"Build": 0
},
"ProductVersion": {
"Major": 1, // 主版本号
"Minor": 0, // 次版本号
"Patch": 0, // 补丁版本号
"Build": 0 // 编译版本号
},
"FileFlagsMask": "3f", // 文件标志掩码
"FileFlags ": "00", // 文件标志
"FileOS": "040004", // 文件操作系统 代表Windows NT
"FileType": "01", // 文件类型 代表应用程序
"FileSubType": "00"
},
"StringFileInfo": {
"Comments": "应用描述",
"CompanyName": "应用公司名称",
"FileDescription": "应用说明",
"FileVersion": "v1.0.0.0",
"InternalName": "应用内部信息",
"LegalCopyright": "Copyright (c) 2024 by 作者",
"LegalTrademarks": "法律商标",
"OriginalFilename": "原始文件名",
"PrivateBuild": "程序内部版本",
"ProductName": "程序名称",
"ProductVersion": "v1.0.0.0",
"SpecialBuild": "特殊版本"
},
"VarFileInfo": {
"Translation": {
"LangID": "0804", // 代表中文
"CharsetID": "04B0" // 代表Unicode
}
},
"IconPath": "main.ico", // 图标路径
"ManifestPath": ""
}
生成syso文件 并编译
go generate
go build -o app.exe -ldflags "-s -w -extldflags '-static'"
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}}' 为正在构建的包提供的导入路径。
评论