本人近十来年来本地用 Mac OS 开发, 服务器为 Linux, 为什么又要涉及到 Windows 的 GCC 呢?因为有个跨平台的东西用的是 C++, 需要分别编译出目标平台为 Linux 和 Windows 的二进制文件. 然而 C++ 并没有像 Rust 那样一出生就含着 Cargo 那样的工具链,完美的支持跨平台开发,构建。对于 C++ 代码不得不在 Linux 下用 GCC 编译器(Makefile), 而 Windows 下使用的 Visual Studio 的 MSBuild, 为了能统一用 Makefile 文件 + GCC 的方式编译 C++ 项目, 可选择 Windows 平台下也安装 GCC。
GCC 又是什么呢?它是 GNU 的编译工具集,包括对 C, C++, Objective-C, Foratran, Ada, Go 和 D 等一众语言的支持, 和它类似的工具集有 LLVM。GCC 支持多操作系统平台,怎么找到它的各种二进制安装包呢?我们循着官网去找, 打开 GCC 首页 https://gcc.gnu.org/,从页面的右边栏可找到
我们想要下载二进制包,点击 Download 下的 Binaries 链接,进而来到页面
有常用平台的二进制包,Windows 下有 Cygwin(原 Cygnus 出品, 已被 RedHat 收购) 和 MinGW(Minimalist GNU for Windows)/mingw-w64(64 位) 两种应用方案,Cygwin 几乎提供了一个在 Windows 平台完整的 Linux 模拟环境,X Windows 都可以有, 大过庞大, 对于只用到 GCC 的我们完全没有必要, mingw-w64 自然地就成为了较合适的选择. 所以进一步来到 mingw-w64 的下载页面 https://www.mingw-w64.org/downloads/, 关于 Windows 的又有以下几种方案
一:含有 GCC 及许多 GNU 命令的压缩包,下载解压后,需配置 PATH 环境变量指向到相应的 bin 目录,然后使用。此类点多数, 如 LLVM-MinGW, w64devkit, MingW-W64-builds, 和 WinLibs.com
二:安装后启动后就是一个终端窗口,所以无需手动配置 PATH 环境变量即可使用。这类有 MYSS2 和 Cygwin, 对于本地操作较为友好, 但安装过程可能会有些麻烦, 如远程安装。
不管是哪里种式,它们都提供了 GCC 及许多的 GNU 命令,它们只是在 Windows 上的模拟,本质上还是 Win32 程序,所以它们都以 *.exe 文件存在,与 WSL Linux 子系统(虚拟机) 不同。
接下来我们拣最具代表性的 w64devkit 和 MSYS2 两种方式来体验一下,为写成这篇日志,还特地在家中的 Windows 11 Pro 上测试了一番, 并且也在 Windows 输入了大部分的文字, 十分的不习惯。
Windows 下安装使用 w64devkit
点击前面表格中的链接 w64devkit,可见它的安装指南 Installation: GitHub。然后在该 GitHub 链接的 Assets 部分找到 w64devkit-1.21.0.zip(当前最新版本), 下载后解压到如 C:\w64devkit, 其中 bin 目录包含了许多的 gnu 命令, 例如 ls, rm 等, 还有 sed, awk, grep 等, 连 vi/vim, gvim 都有, 当然少了不 gcc, make.
在开始使用它带的 GCC 之前需把它的 bin 目录配置到 PATH 环境变量中, 可通过电脑属性永久性设置,或在 CMD 命令窗口中临时设置,用
set PATH=%PATH%;c:\w64devkit\bin
至此我们就可以开始尝试用 GCC 来编译一段 C++ 的 Hello World, 正好可以直接用 vi 来书写代码,启动
vi test.cpp
并键入代码
1 2 3 4 5 6 |
#include <stdio.h> int main() { printf("Hello World!\n"); return 0; } |
这个 vim 还支持语法高度显示
保存后, 使用如下命令
gcc -o test test.cpp
编译后生成 test.exe 文件, 大小为 70531 字节, 执行正常, 输出 Hello World!
注意, 如果没有把 w64devkit\bin 加上 PATH 环境变量中,而是直接用全路径来使用 gcc 命令会出错
C:\w64devkit\bin\gcc -o test test.cpp
gcc.exe: fatal error: cannot execute 'as': CreateProcess: No such file or directory
compilation terminated.
因为除了用到 gcc 命令本身外还调用该 bin 目录中的其他命令.
gcc 会自动根据源文件的类型选择合适的编译器,如 cpp 文件会选择 g++ 进行编译. 查看 gcc 的版本为
gcc --version
gcc (GCC) 13.2.0
它支持当前正在使用中的 c++ 标准有 c++03, c++11, c++14, c++17, c++20, c++23, c++2a, c++2b, c++98, gnu++03, gnu++11, gnu++14, gnu++17, gnu++20, gnu++23, gnu++2a, gnu++2b, gnu++98 等. 所以在用 gcc 编译时可指定参数 -std=c++11
LLVM-MinGW, MinW-W64-builds, 以及 WinLibs.com 都和 w64devkit 的安装使用方式一样, 下载的也是压缩包, 解压后其中的 bin 目录加到 PATH 环境变量中, 再使用其中的命令.
当然在 PowerShell 命令窗口中配置了 PATH 环境变量的话也是同样的使用方法
Windows 下安装使用 MSYS2
选择使用 MSYS2 的话, 安的安装链接会导向到 msys2.org, 当前的安装文件是 msys2-x86_64-20240113.exe. 安装完后, 启动 MSYS2 USRT64
程序后它就是一个终端窗口,所以 PATH 环境变量配置也就免了. 不过 GCC 却不是现成的, 需要在该终端中用如下命令单独安装
pacman -S mingw-w64-ucrt-x86_64-gcc
想要 vim 也得用 pacman -S vim 命令安装, 其他 Linux 类似的命令也用同样的方式安装
MSYS2 看起来像个 Linux 终端, 它也有自己的根文件系统, 以及类似于 Linux 的目录结构. 例如我们在安装 MSYS2 的过程中选择了安装目录为 c:\msys64, 这就是 MSYS2 的根文件系统. ls /
将能看到有 /var
, /tmp
, /proc
, /dev
, /etc
等目录结构。
MSYS2 所带的命令在在 c:\msys64\usr\bin, 在它终端端口中就是 /usr/bin
要访问 Windows 的 C, D 盘的话用 cd /c
, cd /d/
切换
在 MSYS2 终端窗口中可用下面两个命令列出未 Deprecated 的 C++, C 的标准
# 当前未 Deprecated 的 C++ 标准
gcc -v --help 2> /dev/null | grep -iv deprecated | grep "C++" | sed -n '/^ *-std=\([^<][^ ]\+\).*/ {s//\1/p}'
# 当前未 Deprecated 的 C 标准
gcc -v --help 2> /dev/null | grep -iv deprecated | grep "C " | sed -n '/^ *-std=\([^<][^ ]\+\).*/ {s//\1/p}'
得到的就是前面列出的像 c++17, c++20, c++23, c++98, gnu++03, gnu++11 那样的结果.
至于 GCC 编译 C++ 代码就无需再演示了, 同样是生成 exe 文件, 因为是给 Windows 执行吗.
MSYS2 相对于 Cygwin 非常的小巧
链接:
本文链接 https://yanbin.blog/windows-install-use-gcc/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
我记得G++/GCC都是支持交叉编译的,你可以在linux/macos下面编译出windows平台的二进制PE文件……
是的,像 Rust 和 dotnet core 一样,都可以支持 Cross compile.
Rust 和 g++ 在 Linux 下编译出 Windows 二进制文件都需要先安装 mingw-w64
$ apt install mingw-w64
然后 g++ 可以指向命令 x86_64-w64-mingw32-g++ 进行跨平台编译