Go 编译构建的一些细节

news2025/2/6 19:54:02

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

(4)步态识别论文研读——用于步态识别的分层时空表示学习

论文题目Hierarchical Spatio-Temporal Representation Learning for Gait Recognition 论文地址 https://arxiv.org/abs/2307.09856 1.摘要 步态识别是一种生物特征技术,通过其独特的行走方式识别个体,适用于无约束环境,具有广泛的应用。…

链表OJ1——删除链表中等于给定值 val 的所有节点

题目 力扣OJ链接:. - 力扣(LeetCode) 解法 我们来看看这个题目啊,怎么做呢? 有两种解法 三指针法 我们完全可以定义三个指针来进行这个删除操作 假设我们要移除的是2 这样子就完成了 特殊情况 开头——假设我们…

一文速览铁威马TOS 6全新“文件管理”

TOS 6 Beta已经上线一段时间了,各位铁粉用着怎么样呢?今天就和大家分享,TOS 6全新文件管理。 为了向用户提供更流畅、更便捷的文件管理体验,铁威马的研发团队积极借鉴了Windows OS和Mac OS在文件管理方面的优点,投入巨…

系统学c#:2、基础语法(关键字、标识符、数据类型、变量、常量、字面量、运算符、类型转换)

关键字: 关键字是编程语言中具有特殊含义的单词或符号,它们通常被编程语言用于表示特定的语法结构、操作或约定。在C#中,关键字具有特定的语法和功能,用于定义语言的基本结构和规则。 以下是一些C#中常用的关键字及其功能&#xf…

使用colab进行yolov5小demo练习

输入一张动物的图片进行目标检测和分类 !pip install yolov5 import torch from PIL import Image from torchvision import transforms from yolov5.models.experimental import attempt_load from yolov5.utils.general import non_max_suppression# 加载YOLOv5模型 device …

Gradle 构建自动化工具入门

🏷️个人主页:牵着猫散步的鼠鼠 🏷️系列专栏:Java全栈-专栏 🏷️个人学习笔记,若有缺误,欢迎评论区指正 目录 1. 前言 2. 简介 3. 常见的项目构建工具 4. 安装 4.1. 安装说明 4.2. 下载…

【小风扇/移动电源升压芯片方案】FP6291是一款异步内置MOS管升压恒压芯片 小封装(SOT23-6)设计简单外围器件少

芯片概述 FP6291是一款异步内置MOS管升压恒压芯片,与肖特基和电感形成回路组成升压架构; 工作电压2.6-5.5V,可适用已单节电池和5V供电升压; 恒压基准(VFB)为0.6V2%,误差小提高输出的准确度&…

前端开发攻略---用JavaScript将数字转换为中文。支持万亿以下的正整数;深入解析:JavaScript 函数详解数字转换为中文的实现原理与流程

1、演示 2、实现思路 函数名为 toChineseNumber,它的作用是将一个数字转换成对应的中文表示形式。这个函数是一个自定义的实现,通过一系列步骤将数字转换成中文。我会逐步解释每一部分,以确保您对代码的理解清晰明了。 首先,让我们…

2024第十五届蓝桥杯 C/C++ B组 参赛经历分享(以及部分题解)

前言 emmmmmm,dp杯居然不考dp了,蓝桥一直没怎么出过的高精度居然也考了(当时居然因为没太复习那块知识直接模拟混分了),题量也改了,总的来说反而简单了?。。。还好天津竞赛弱省,但愿…

STM32学习和实践笔记(12):蜂鸣器实验

蜂鸣器主要分为两种,一种是压电式的无源蜂鸣器,一种是电磁式的有源蜂鸣器。 有源和无源是指其内部有没有振荡器。 无源的没有内部振荡器,需要输入1.5-5KHZ的音频信号来驱动压电蜂鸣片发声。 有源的内部有振荡器,因此只需要供给…

Jackson 2.x 系列【24】Spring Web 集成

有道无术,术尚可求,有术无道,止于术。 本系列Jackson 版本 2.17.0 源码地址:https://gitee.com/pearl-organization/study-jaskson-demo 文章目录 1. 前言2. Spring Web3. Jackson2ObjectMapperBuilder4. Jackson2ObjectMapperFa…

STL —— priority_queue

博主首页: 有趣的中国人 专栏首页: C专栏 本篇文章主要讲解 priority_queue 的相关内容 目录 1. 优先级队列简介 基本操作 2. 模拟实现 2.1 入队操作 2.2 出队操作 2.3 访问队列顶部元素 2.4 判断优先队列是否为空 2.5 获取优先队列的大小 …

分布式向量数据库-安装部署

下载 GitHub - pgvector/pgvector: Open-source vector similarity search for Postgres 源码编译 ##文件解压缩 unzip pgvector-0.6.2.zip ##编译 make && make install 功能验证 #安装扩展CREATE EXTENSION vector;#创建测试表CREATE TABLE items (id bigseri…

mysql题目1

tj11: ​ select * from t_student where grade 大一 and major 软件工程 ​ tj12: SELECTt_student.name, count(t_choice.cid)FROMt_choiceINNER JOINt_courseON t_choice.cid t_course.idINNER JOINt_studentON t_choice.sid t_student.id GROUP BYt_choice.sid HAVIN…

【Unity 实用工具篇】 | UIEffect 实现一系列UGUI特效,灰度、负片、像素化特效

前言 【Unity 实用工具篇】 | UIEffect 实现一系列UGUI特效,灰度、负片、像素化特效一、UGUI特效插件:UIEffect1.1 介绍1.2 效果展示1.3 使用说明及下载 二、组件属性面板三、代码操作组件四、组件常用方法示例4.1 使用灰度特效做头像(关卡)选择 总结 前…

win11电脑驱动怎么更新,windows11更新驱动

驱动是指计算机里软件的程序,硬件的运作离不开驱动的支持,因为驱动就是使得硬件和电脑系统沟通的桥梁。既然驱动如此重要,那么不装肯定不行,如果有问题,也要及时地修复和更新。最近,有位win11用户,想要了解win11电脑驱动怎么更新?接下来,教程会带来两种更新win11驱动的…

CodeForce[1500-2000]——1948D Tandem Repeats?

大概题目意思就是:给你一个只有小写字母和问号的字符串,可以在头或尾删除任意长度,得到一个字串,并且该字串要满足长度为偶数,前一半和后一半(问号可以匹配任意字符)相等,求这样的字…

专治Java底子差,线程操作篇(2)

💗推荐阅读文章💗 🌸JavaSE系列🌸👉1️⃣《JavaSE系列教程》🌺MySQL系列🌺👉2️⃣《MySQL系列教程》🍀JavaWeb系列🍀👉3️⃣《JavaWeb系列教程》…

2024五一杯数学建模A题B题C题思路汇总分析

文章目录 1 赛题思路2 比赛日期和时间3 组织机构4 建模常见问题类型4.1 分类问题4.2 优化问题4.3 预测问题4.4 评价问题 5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 比赛日期和时间 报名截止时间:2024…

设计模式——2_9 模版方法(Template Method)

人们往往把任性也叫做自由,但是任性只是非理性的自由,人性的选择和自决都不是出于意志的理性,而是出于偶然的动机以及这种动机对感性外在世界的依赖 ——黑格尔 文章目录 定义图纸一个例子:从文件中获取信息分几步?Rea…