今天在vscode上写代码,运行了一个c代码直接提示我没有gcc这个命令。一直用VS的我从来都没有遇到过这个问题啊!!!不过完全没有问题,遇事不决首选cc,秉持着这个原则,我也是毫不犹豫的把问题扔给了AI,果不其然它5分钟不到就搞定了。这个时候该死的好奇心突然间我尽然萌生了一个想看看AI怎么安装的理解一下原理的可怕念头,果不其然一个下午就这样浪费掉了呜呜呜呜呜呜~~
反正已经浪费了这么长的时间了,就把今天我所能理解的部分记录下来,大家就看个乐呵就行了,最后再说一句,cc牛逼!!!!
一、原理
VSCode上本身是不带gcc(c编译器,把程序编译成exe的)和gdb(调试器)的。所以我们要先下载这两个东西。winlibs这里面是直接包含处理c,c++这一整套的工具的。所以直接去下载这个安装包。解压这个安装包,然后把gcc,gdb添加到环境变量里面就行了~~
二、
1、添加环境变量的一般方法:
先找到要添加的文件所对应的bin路径
接着去环境变量里面查看是不是已经包含了这个内容
不包含把它包含进去就行
不添加进环境变量每次就要输入完整路径,会很麻烦。
不是!PATH 环境变量里放的是文件夹路径,不是 exe 文件本身
重点:往 PATH 添加的是目录(文件夹) ,不是
xxx.exe这个文件。
系统在 PATH 目录里,能找哪些类型的可执行文件
Windows 下,系统会在 PATH 的文件夹中,依次查找后缀在 PATHEXT 里的文件,默认包含: .EXE、.COM、.BAT、.CMD、.VBS、.PS1 等 只要是这些后缀,都可以直接敲文件名运行,不局限 exe:
.bat/.cmd:批处理脚本.vbs:vb 脚本.ps1:powershell 脚本
Linux/macOS 的 PATH 同样是文件夹,里面可以是: 二进制程序(类似 exe)、shell 脚本(.sh)、Python 脚本等,只要有执行权限就行。
举个例子
把 D:\tools\mytool 这个文件夹加到 PATH,文件夹里面有:
test.exe→ 可以直接敲testrun.bat→ 可以直接敲run两个都能直接调用。
容易混淆的误区
❌ 错误理解:把python.exe这个文件添加到 PATH ✅ 正确操作:把D:\software\Python310(python.exe 所在的文件夹)添加进 PATH
(就像这样,有了AI就是方便哈哈哈哈哈哈~~)
2、安装软件
像今天安装winlibs就超时了。winget是Windows的应用市场,它里面存的都是下载安装软件的重要信息(像下载网址,重要参数)执行winget install 软件名,就开始下载了。
但是在执行前可以先看一下这个软件的下载地址。winget show 包ID。翻到最下面的安装地址。


可以看到这里的URL是有github的,所以这就是为啥平时下载会卡,这个时候就要相信魔法的力量了~~~
软件是更大的概念,程序是软件的核心组成部分,二者不完全等同。
1. 程序(Program)
程序 = 一组可被计算机执行的指令代码
- 可以是单个文件:
gcc.exe、notepad.exe、winget.exe - 本质:二进制机器指令 / 脚本代码,CPU 能跑
- 特点:只有代码指令,单纯用来完成计算、逻辑任务
例:
gcc.exe就是一个程序。
2. 软件(Software)
软件 = 程序 + 配套资源 除了可执行程序外,还包含:
- 动态库(
.dll) - 配置文件、头文件、文档、说明、图片资源、许可证
- 甚至安装脚本、环境配置规则
👉 WinLibs 就是一套软件 :里面包含 gcc.exe、g++.exe、ld.exe(一堆程序)+ 头文件 .h + 库文件 .a + 文档。
所以:exe 是二进制文件的其中一种
3. 其他二进制文件举例(都不是 exe)
.dll:动态链接库(PE 二进制,不能直接双击运行).a/.lib:静态库(WinLibs 里面就有,二进制).png、.jpg:图片二进制.7z、.zip:压缩包二进制.obj:编译出来的目标文件(二进制,不能直接执行)
exe是Windows下的二进制文件,Linux下面是ELF
在这里我又好奇的查了一下软件,脚本,插件的区别(因为博主比较菜,只写过脚本,没写过插件,也没写过软件,请大家体谅一下)
1. 脚本(Script)
用解释器 一行一行读着执行,不需要提前编译成 exe 二进制 。 常见:
.bat、.cmd、.ps1、.py、.js、.sh
特点:
- 源码是文本文件,记事本直接打开查看修改
- 不能独立直接交给 CPU 跑,必须依赖解释器
- bat → cmd.exe
- python 脚本 → python.exe
- 用途:自动化、简单任务,比如批量改名、自动下载文件
- 体积很小,写起来快
例子:
- 写一个
clean.bat,一键清理临时文件 - Python 写的爬虫脚本
对比 exe:exe 是编译好的二进制,直接 Windows 加载运行;脚本是文本,靠解释器执行。
2. 插件(Plugin / Addon / Extension)
不能独立运行!必须挂靠在一个主软件上,给主软件增加额外功能。
特点:
- 宿主(主程序)提供接口,插件只能在宿主里面工作
- 形式不一定:可以是脚本,也可以是 dll 二进制模块
- 离开主软件,插件本身无法启动
例子:
- VS Code 的 C/C++ 扩展(插件,依附 VS Code)
- Chrome 浏览器广告拦截插件
- Photoshop 滤镜插件
- GCC 的插件(依附编译器)
重点:插件是附属品,没有宿主 = 无法使用。
3. 软件(Software)
完整独立产品,可以单独安装、独立运行。包含程序、库、配置、文档整套东西。 里面可以包含 exe、dll、脚本、资源文件。
特点:
- 拥有完整入口,可以独立启动
- 复杂软件内部往往同时包含:主程序 + 内置脚本引擎 + 支持插件系统
例子:
- WinLibs 工具链(整套开发软件,内含 gcc.exe 等多个程序)
- VS Code、Chrome、Notepad++
3、安装的命令
考虑到不同平台的兼容性(Linux,Mac上都是bash,就Windows是powershell)Windows搞了一个Git Bash来兼容这个bash环境,这样上面就可以跑Linux命令和shell脚本了。
where gcc clang cl tcc 2>&1; echo "---winget---"; where winget 2>&1; echo "---code---"; where code 2>&1
先检查有没有gcc。
winget search --id BrechtSanders.WinLibs --accept-source-agreements 2>&1 | head -30
把所有winlibs都列举出来,根据自己的需求安装。
这里就有一个Linux文件描述符的小知识点了:
我们平时电脑里面的所有进程,在创建以后都默认会开3个文件,对应的分别是stdin,stdout,stderr。对应的文件描述符分别是0,1,2.这3个文件并不是磁盘文件,是指向鼠标,显示器,键盘的。
>是重定向符号。前面如果是数字则默认是文件描述符。但如果后面是数字,却会被当成是一个文件名,这时候如果想转化成文件描述符,就一定要加&
管道只会接收stdout的内容,这条命令就是把把stderr里面的内容也放到stdout里面,最后选取总共的前30条,不然stderr根本就不会进管道。
这里接收所有条款是自动安装经常出现的。
winget install --id BrechtSanders.WinLibs.POSIX.UCRT --accept-package-agreements --accept-source-agreements --silent 2>&1 | tail -20
有了上面的例子,这里就很好理解了。这里就安装相应版本的winlibs了。
ls /c/Users/86133/AppData/Local/Microsoft/WinGet/Packages/BrechtSanders.WinLibs.POSIX.UCRT_Microsoft.Winget.Source_8wekyb3d8bbwe/ 2>&1; echo "=== links ==="; ls /c/Users/86133/AppData/Local/Microsoft/WinGet/Links/ 2>&1 | head -40
这里就做了两件事情。第一,检查winlibs是否安装成功。第二,检查links文件是否存在。
介绍一下Links文件
gcc.exe -> /c/Users/xxx/Packages/.../bin/gcc.exe
clang.exe -> /c/Users/xxx/Packages/.../bin/clang.exe
每个winlibs下的程序以及它所对应的地址这里都有,程序名和实际地址进行软连接。
C:\Users\86133\AppData\Local\Microsoft\WinGet\Links
把这个links放到path里面。这个links里面又都是软连接,这样顺着就能找到对应的地址。
ls /c/Users/86133/AppData/Local/Microsoft/WinGet/Packages/BrechtSanders.WinLibs.POSIX.UCRT_Microsoft.Winget.Source_8wekyb3d8bbwe/mingw64/bin/ 2>&1 | grep -iE "^(gcc|g\+\+|gdb|mingw32-make)" | head -20
查看gcc,gdb是否安装成功。
小知识点:软硬链接:
软链接(Symbolic Link / Symlink) vs 硬链接(Hard Link)
先记住一句话: 软链接 ≈ Windows 快捷方式(但更强,内核级);硬链接是同一个文件,多起了几个文件名。 你前面 winget Links 目录里用的,是 软链接。
注意:Windows 和 Linux/GitBash 都有软硬链接,但行为略有差别,下面优先讲通用原理,再结合 Windows。
基础概念铺垫
文件在磁盘上,分成两部分:
- 文件名(目录项):你在文件夹看到的名字
- inode(Linux)/ 文件记录(Windows NTFS):真正的文件本体,存文件内容、大小、权限
1. 硬链接 Hard Link
原理
多个不同文件名,全部指向同一个 inode(同一个文件本体)。 所有硬链接完全平等,没有 "原始文件" 和 "副本" 之分。
✅ 特点
- 修改任意一个链接里的内容,所有硬链接全部同步变化(本质就是同一个文件)
- 删除其中一个文件名,本体不会删掉 ;只有全部硬链接都删完,文件本体才会被真正删除
- 不能跨分区 / 跨磁盘
- 不能链接目录(文件夹),只能链接文件
- 硬链接看不到 "指向谁",没有箭头,它本身就是文件的名字
📌 Linux 创建:
ln 源文件.txt 硬链接.txt
Windows:NTFS 支持硬链接,用
mklink /H,只能文件,不能文件夹。
2. 软链接 Symbolic Link(Symlink,符号链接)
原理
软链接本身是一个独立小文件 ,这个文件里面只存:目标的路径字符串。 它记录 "我指向哪里",访问软链接时,系统自动跳转到目标文件 / 文件夹。
✅ 特点
- 可以链接 文件,也可以链接文件夹(winget 没有链接文件夹,但支持)
- 可以跨磁盘、跨分区
- 如果把原始本体删掉:软链接还存在,但变成「失效链接(悬空链接 dangling link)」,打不开,找不到目标
ls -l可以看到箭头gcc.exe -> /xxx/真实gcc.exe- 软链接是独立文件,有自己的 inode
📌 Linux/GitBash 创建:
ln -s 源文件 软链接名
Windows CMD 创建软链接:
mklink 链接名.exe "C:\真实路径\app.exe"