Go 编译构建的一些细节

Go 编译构建的一些细节

发现自己竟然没有怎么认真研究过 go 的编译构建命令。

结论前置

  • go run 专门用来运行命令源码文件的命令,一般用来运行单个文件
  • go build 主要是用于测试编译。编译某个包或者项目,在当前目录下生成可执行文件
  • go install 编译并安装代码包或者源码文件的。
  • go get 用于从远程代码仓库(比如 Github )上下载代码包并更新 mod
  • go 1.17 之后 go get 只下载源码,并将依赖添加到 go.mod。get install 用来下载和安装三方库

go 命令常用选项

在这里插入图片描述

下面是细节。

go run

专门用来运行命令源码文件的命令,不是用来运行所有 go 源码文件的

go run 命令只能接受一个命令源码文件以及若干个库源码文件(必须同属于 main 包)作为文件参数,且不能接受测试源码文件。它在执行时会检查源码文件的类型。如果参数中有多个或者没有命令源码文件,那么 go run 命令就只会打印错误提示信息并退出,而不会继续执行。

go run -ngo run 命令的一个选项,用于执行编译和运行 Go 源文件,但不实际运行。它会打印出编译时将要执行的命令,而不会真正运行该命令。这对于调试构建脚本或查看编译命令是否正确非常有用。

  1. 临时文件生成: 在使用 go run 命令时,会生成临时工作目录(通常在系统的临时目录下),其中包含编译过程中产生的临时文件和中间文件。
  2. 导入文件(importcfg 文件): importcfg 文件用于指定程序在编译时所需的导入包。这个文件在编译过程中被使用,而不是在运行时。
  3. compile 命令和生成 link 文件: 在编译过程中,compile 命令用于将源码文件编译成归档文件(archive)。生成的 link 文件记录了编译过程中用到的依赖信息。
  4. 生成可执行文件: 最后,exe 文件是通过连接编译生成的归档文件和 link 文件,并将其与源码文件一起打包成可执行文件。
  5. go run 命令生成的文件: go run 命令会在执行过程中生成两个文件,一个是编译生成的归档文件(通常具有 .a 扩展名),另一个是最终的可执行文件。

举例:

go run app/user/*.go

等价于什么呢?

go run app/user/*.go 命令用于直接运行指定目录下的所有 Go 源代码文件。它的等价操作包括:

  1. 编译并运行每个 .go 文件中的代码。
  2. 如果代码中有 main 函数,则执行该函数;如果没有,则不执行。
  3. 该命令只在开发阶段使用,不会生成可执行文件,而是临时编译和执行代码。

因此,go run app/user/*.go 与手动编译并执行每个文件的操作等价。

问题:会递归查找所有目录吗?

不会。go run app/user/*.go 只会在 app/user/ 目录下查找直接位于该目录下的 .go 文件,而不会递归查找其子目录中的文件。如果需要递归查找所有子目录中的 .go 文件,可以使用 ./... 来代替 *,例如 go run ./...go run ./... 是一个 Go 语言的命令,用于编译并运行当前目录(以及子目录)中的所有 Go 源码文件。这个命令会查找当前目录下的所有 .go 文件,并且假定它们属于同一个包,然后尝试编译它们。

这里的 ./... 是一个模式匹配表达式,用于匹配当前目录及其所有子目录中的所有文件和目录。在 Go 命令中,这种模式匹配通常用于指定源码文件的路径。

具体来说:

  • . 表示当前目录。
  • ...(三个点)是一个通配符,表示递归地匹配当前目录下的所有子目录。

因此,go run ./... 命令会执行以下操作:

  1. 编译当前目录及其所有子目录中的所有 .go 文件。
  2. 将编译后的代码链接成一个可执行文件。
  3. 运行这个可执行文件。

这个命令在处理包含多个源码文件的包时非常有用,尤其是当你想要快速运行和测试整个包中的代码时。然而,需要注意的是,这个命令不会递归地编译子目录中的子目录,它只编译当前目录及其直接文件和子目录中的 .go 文件。

如果你的 Go 项目结构中,每个功能或模块位于不同的包中,那么使用 go run ./... 可能不会按预期工作,因为它会尝试编译所有匹配到的源码文件,而不管它们是否属于同一个包。在这种情况下,你可能需要更精细地指定要编译的文件或目录。

再看 go build

另外,使用 dlv 进行远程调试的话,必须 build 出可执行文件 main 之后,才可以。

所以这个时候需要执行

go build -o main

然后运行就可以开始监听了。

在这里插入图片描述

区别于 go build main.go

区分 Go 编译单个文件和目录下所有文件

go build main.gogo build -o main 都是用于构建 Go 应用程序的命令,但它们之间有一些区别:

  1. go build main.go:这个命令告诉 Go 编译器要编译名为 main.go 的文件,并生成一个默认的可执行文件,文件名与包名相同(如果 main.go 中的包名是 main,则生成的可执行文件为 main)。
  2. go build -o main:这个命令告诉 Go 编译器要编译当前目录下的所有文件,并将生成的可执行文件命名为 main。使用 -o 标志可以指定生成的可执行文件的名称,而不是使用默认的包名。

总的来说,go build main.go 适用于单个文件的构建,而 go build -o main 适用于多个文件的构建,并且可以指定生成的可执行文件的名称。

  1. 用途: go build 命令主要用于编译测试。它会编译指定的源码文件或代码包及其依赖。

  2. 普通包 vs. main 包:

    • 对于普通包:执行 go build 后不会生成任何文件。
      举例:
      在这里插入图片描述
    • 对于 main 包:只执行 go build 会在当前目录下生成一个可执行文件。要在 $GOPATH/bin 目录下生成相应的可执行文件,需要执行 go install 或者使用 go build -o 路径/可执行文件
  3. 单文件 vs. 多文件:

    • 如果某个文件夹下有多个文件,而只想编译其中的某一个文件,可以在 go build 之后加上文件名,例如 go build a.go
    • 默认情况下,go build 会编译当前目录下的所有 go 文件。
  4. 指定输出文件名: 可以使用 -o 标志指定编译输出的文件名。默认情况下,输出文件名为包名(对于非 main 包)或第一个源文件的文件名(对于 main 包)。

  5. 忽略文件: go build 会忽略目录下以"_“或”."开头的 go 文件。

  6. 跨平台编译: 如果源代码需要针对不同的操作系统进行处理,可以根据不同的操作系统后缀来命名文件。

  7. 库源码文件编译: 对于库源码文件,go build 只会进行检查性的编译,而不会生成任何结果文件。

  8. 示例: 执行 go build 编译命令源码文件时,会在该命令的执行目录中生成一个可执行文件。如果跟了代码包导入路径作为参数,则该代码包及其依赖都会被编译。

  9. 执行过程: 类似于 go rungo build 在编译后会将生成的可执行文件重命名并移动到当前目录下。

参考:

https://zhuanlan.zhihu.com/p/619500945

go install 和 go get

go getgo install 是 Go 语言中两个常用的命令,它们虽然有一些相似之处,但在功能上有一些不同。

  1. go get:

    • go get 命令用于从远程仓库中获取并安装指定的包或模块。它通常用于获取项目的依赖项。
    • 如果执行 go get 命令时指定了包或模块的路径,它将尝试从远程仓库中下载该包或模块,并将其放置在 $GOPATH/src 目录下的相应位置。
    • go get 还会安装该包或模块所依赖的其他包或模块。
  2. go install:

    • go install 命令用于编译并安装指定的包或可执行文件。
    • 如果执行 go install 命令时指定了包的路径,它将编译该包并将生成的二进制文件安装到 $GOPATH/bin 目录(或 $GOBIN 目录)下。
    • 如果执行 go install 命令时指定了可执行文件的路径,它将编译该可执行文件并将生成的二进制文件安装到 $GOPATH/bin 目录(或 $GOBIN 目录)下。

在实践中,通常情况下,我们使用 go get 来获取项目的依赖项,而使用 go install 来构建并安装我们自己的代码或可执行文件。

go install 命令

  • 用途: 编译并安装代码包或者源码文件。

  • 流程: 分为两步:

    1. 第一步是生成结果文件(可执行文件或者.a 包)。
    2. 第二步是将编译好的结果移到 $GOPATH/pkg 或者 $GOPATH/bin
  • 可执行文件: 一般由带有 main 函数的 Go 文件产生,具有函数入口,可以直接运行。

  • .a 应用包: 一般由不包含 main 函数的 Go 文件产生,没有函数入口,只能被调用。

go get 命令

  • 用途: 从远程代码仓库(如 GitHub)下载并安装代码包。

  • 注意:

    • go get 命令将当前代码包下载到 $GOPATH 中的第一个工作区的 src 目录,并进行安装。
    • 从 Go 1.17 版本开始,go get 仅用于下载库和更新 mod 文件,并不会执行安装操作。

其他命令

go clean 命令是用来移除当前源码包里面编译生成的文件,这些文件包括

_obj/ 旧的 object 目录,由 Makefiles 遗留

_test/ 旧的 test 目录,由 Makefiles 遗留

_testmain.go 旧的 gotest 文件,由 Makefiles 遗留

test.out 旧的 test 记录,由 Makefiles 遗留

build.out 旧的 test 记录,由 Makefiles 遗留

*.[568ao] object 文件,由 Makefiles 遗留

DIR(.exe) 由 go build 产生

DIR.test(.exe) 由 go test -c 产生

MAINFILE(.exe) 由 go build MAINFILE.go 产生

go fmt 命令主要是用来帮你格式化所写好的代码文件。

go test 命令,会自动读取源码目录下面名为*_test.go 的文件,生成并运行测试用的可执行文件。默认的情况下,不需要任何的参数,它会自动把你源码包下面所有 test 文件测试完毕,当然你也可以带上参数,详情请参考 go help testflag

go doc 命令其实就是一个很强大的文档工具。

go fix 用来修复以前老版本的代码到新版本,例如 go1 之前老版本的代码转化到 go1

go version 查看 go 当前的版本

go env 查看当前 go 的环境变量

go list 列出当前全部安装的 package

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/548013.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

图形化编程要怎么做

0. 简介 Scratch其实应该算得上最早做图形化编程的工程了。Scratch 是麻省理工学院的“终身幼儿园团队”在 2007 年 [5]发布的一种图形化编程工具,主要面对全球青少年开放,是图形化编程工具当中最广为人知的一种,所有人都可以在软件中创作自…

大模型赋能:爬虫技术的全新革命

大模型加持下的爬虫技术革新:从BS4到提示工程的飞跃 在爬虫技术的演进历程中,内容解析一直是一个核心环节。传统的爬虫技术,如使用BeautifulSoup(BS4)等工具,需要逐个解析网页内容,通过XPath或C…

【NPS】内网穿透工具之 NPS

一、linux 安装 nps nps-releases:https://github.com/ehang-io/nps/releases 1.1、在 ubuntu下安装对应版本(非docker) 可以看到如下指令 wget https://ghproxy.com/https://github.com/ehang-io/nps/releases/download/v0.26.10/linux…

网络安全-自学笔记

一、自学网络安全学习的误区和陷阱 1.不要试图先成为一名程序员(以编程为基础的学习)再开始学习 我在之前的回答中,我都一再强调不要以编程为基础再开始学习网络安全,一般来说,学习编程不但学习周期长,而…

weblogic JSP action的配置

action(如xxx.do)可以在Java文件中通过注解的方式配置,也可以在web.xml中进行配置 在java文件中配置的场合 @WebServlet(xxxx.do) 并实现支持的方法:doGet或doPost等 或者 @WebServlet(xxxx.do) 并实现service方法 所有method的处理方法都会先经过service方法 在web.x…

【24年物联网华为杯】赛题分析与初步计划

赛事介绍 官网链接:2024 年全国大学生物联网设计竞赛 (sjtu.edu.cn) 含金量:属于A类赛事 (注意:很多搜索结果的序号是按照选入时间排列的,与含金量无关,华为杯是23年选入的) Kimi Chat: 全国…

经历分享:我是如何出版了人生的第一本书的,成体系化的神级Golang进阶笔记,

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞…

轻松上手MYSQL:MYSQL初识(下)

​🌈 个人主页:danci_ 🔥 系列专栏:《MYSQL入门》 💪🏻 制定明确可量化的目标,坚持默默的做事。 轻松上手MYSQL:从零开始构建你的数据库世界 🚀 🚀欢迎来到My…

Qt nodeeditor ROI 组态软件

节点显示节点连接属性设置插件导入导出 展示:

【小贴士|Unity】华佗热更版本控制配置

现在越来越多的新项目选择使用HybridCLR,而不是以前的Lua。也不妨有的项目会配置打包机器人以及版本控制,但是这个版本控制的配置还真需要注意一些。(因为我就踩坑了) 如图所示,当你第一次执行HybridCLR/Generate/All后…

监控平台zabbix的认识与搭建

一. 监控系统的相关知识 1. 监控系统运用的原因 当我们需要实时关注与其相关的各项指标是否正常,往往存在着很多的服务器、网络设备等硬件资源,如果我们想要能够更加方便的、集中的监控他们,zabbix 可以实现集中监控管理的应用程序。 监控的…

基于51单片机的秒表设计—0.01精度、有提示音

基于51单片机的秒表设计 (仿真+程序+原理图+设计报告) 功能介绍 具体功能: 1.数码管显示,精度为0.01; 2.按键控制启动/停止,暂停/开始; 3.有一秒钟一次提示…

金三银四面试题(二十):单例模式知多少?

设计模式也是面试中的热门考题,基本这个部分都是问问你知不知道XXX设计模式,有什么用,优缺点,然后再现场手写一个demo。很多时候是和spring一起考的,问问你知不知道spring框架用了哪些设计模式。今天我们来先看看单例模…

信息系统项目管理师——成本管理计算专题(一)

常见考点如下: ①问项目预算、BAC、成本基准、应急储备、管理储备的含义及它们之间的区别 ②给出成本基准和管理储备求项目预算,或者给出预算求成本基准等等 ③看图找 PV、AC、EV、SV、CV、BAC、EAC、ETC等 ④根据题干求项目的PV、AC、EV、SV、CV、BAC、EAC、ETC等 …

骑行听音乐用什么运动耳机?五款宝藏机型汇总推荐

热爱骑行的你们,是否曾为选购一款合适的运动蓝牙耳机而纠结?市面上品牌众多、功能各异的运动耳机,究竟哪款才是你的运动良伴?今天,我就来聊聊运动蓝牙耳机的选购要点,并为你推荐几款高性价比的运动蓝牙耳机…

OMS系统集成案例分享:数环通轻松实现OMS系统对接

在数字化浪潮席卷全球的今天,订单管理系统(OMS)作为连接企业与客户的桥梁,正逐渐成为企业提升订单处理效率、优化客户体验的关键。然而,由于企业内部系统的复杂性和多样性,OMS系统与其他业务系统的集成往往…

OCR技术可以通过识别身份证区分性别么?

可以,只需将它识别成结构化的数据,然后根据性别进行筛选即可。具体操作方法如下: 1、到金鸣识别官网下载安装金鸣表格文字识别电脑客户端。 2、打开安装好的金鸣表格文字识别电脑客户端。 3、点击“添加文件”,在弹出的对话框中选…

【C语言回顾】数组

前言1. 数组2. 一维数组2.1 一维数组的创建2.2 一维数组的初始化2.3 一维数组的使用2.3.1 一维数组的下标2.3.2 一维数组的输入和输出 2.4 一维数组在内存中的存储 3. 二维数组3.1 二维数组的创建3.2 二维数组的初始化3.3 二维数组的使用3.3.1 二维数组的下标3.3.2 二维数组的输…

Lesson2: 算法的时间复杂度和空间复杂度

【本节目标】 1. 算法效率 2. 时间复杂度 3. 空间复杂度 4. 常见时间复杂度以及复杂度 oj 练习 1.算法效率 1.1 如何衡量一个算法的好坏 如何衡量一个算法的好坏呢&#xff1f;比如对于以下斐波那契数列&#xff1a; long long Fib(int N) {if(N < 3)return 1;retu…

【模板】差分

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 3 2 1 2 3 1 2 4 3 3 -2 输出 5 6 1 思路&#xff1a; 一直以来&#xff0c;我总是不太理解差分和树状数组操作区别。 现在摸了一下开始有所理解了。 差分和树状数组的区别…