zl程序教程

您现在的位置是:首页 >  系统

当前栏目

Windows上的gcc

Windows gcc
2023-09-11 14:18:38 时间

在Windows上安装gcc,gcc官网上推荐我们了两种方式:

当然,除此之外还有其他的方式,我们先从mingw开始理解。

mingw-64

举个例子,c语言打开文件使用FILE *fopen( const char *filename, const char *mode );函数,而在c语言标准库中,这个函数的实现要与操作系统绑定,比如linux中最终会去调用int open(const char *path, int oflag, ...);而Windows中最终会去调用BOOL WINAPI GetOpenFileName(_Inout_ LPOPENFILENAME lpofn);这期间存在巨大的差异。gcc原生并不兼容Windows。

mingw:“GCC for Windows 64 & 32 bits”是把gcc的源代码移植到Windows平台,让gcc的代码直接去调用Windows API。
所以说,mingw的gcc编译出来的c/c++程序是可以原生在Windows上执行的。

注意mingw很多时候只做代码工作,发布编译好的gcc.exe会很懒,经常找不到合适的版本,除非自己下载源代码编译。
mingw-64是mingw的升级版,后边说道的mingw,都是指mingw-64。
mignw-64的官网 https://www.mingw-w64.org/

总结一下:mingw的工作是集成gcc源码与Windows API。用mingw的gcc.exe编译的程序可以在Windows上原生运行。他们命名方式一般如下:
winlibs-x86_64-posix-seh-gcc-12.1.0-llvm-14.0.4-mingw-w64ucrt-10.0.0-r2.zip
winlibs是编译发布的组织(实际上这也是个人做的)
x86_6464平台,可选i68632位
posix多线程方案,可选win32
seh异常处理方案,还有sjljdwarf
ucrtc运行时与c库,还有msvcrt,win10以前微软的c运行时是msvcrt,后来win10以后是ucrt替代,msvcrt对c99支持好像不太好。具体差别可以看这里 https://www.msys2.org/docs/environments/
c++的标准库也有好几个实现,有苹果的libc++还有gnu的libstdc++
这些库与gcc编译器的链接就有不同的组合,于是就有了这么多的gcc版本,举个例子mingw-w64-x86_64-gcc就是gcc msvcrt libstdc++的组合,面向的平台是x86_64

winlibs

https://winlibs.com/
前边说了,migw只提供源码,偶尔会给个二进制包。
而winlibs专注发布二进制包,他会拿到mingw的源码,编译并发布,发布形式是压缩包,解压即可用,而且提供了非常多的版本:

winlibs首页上提供的只有大版本的最新版,比如9.5之前的都没有。如果这些还不够用的话,可以去GitHub上下载所有的小版本发布:
https://github.com/brechtsanders/winlibs_mingw/releases?page=1

tdm-gcc

与mingw64类似的存在
https://jmeubank.github.io/tdm-gcc/
更新好像不是特别快,都2022年了,才到gcc10.3

cygwin

mingw的工作是让gcc适应Windows,而cygwin则换个角度,让Windows适应gcc。cygwin不改变gcc代码,而是在Windows上为gcc提供了一整套Linux api。
cygwin做了一个库,把Windows api封装起来伪装成linux api,这个库编译后得到的就cygwin1.dll,由于cygwin1.dll提供了完整的Linux api,所以原本在linux能跑的程序只要链接cygwin1.dll就可以正常运行,这其中就包括gcc。
于是cygwin把很多Linux上的软件借助cygwin1.dll编译成exe让我们在Windows上也可以用(当然包括gcc),这些软件的共同点就是:都依赖于cygwin1.dll。

总结一下:cygwin从linux上移植很多软件到Windows,这些软件都需要依赖cygwin的核心组件cygwin1.dll
cygwin与mingw不同,mingw只开发代码,gcc.exe这种二进制包,一般是其他组织编译并发布的,通常只发布一个压缩包(比如winlib)。而cygwin则做的更多,cygwin提供了一个仓库,仓库中是cygwin提前编译好的二进制。
更重点来了:cygwin的软件包里,还包含了mingw的gcc。也就是说cygwin软件包里不只有依赖cygwin1.dll的gcc还有mingw的gcc(编译原生Windows程序而不依赖cygwin1.dll)还有其他很多Linux平台的软件。如下图所示:

缺点:
1.安装略麻烦,如果需要安装某个软件,都需要执行cygwin的setup程序
2.软件版本并不全,比如gcc:

msys2

mingw-64只做gcc移植,cygwin的核心是提供了cygwin1.dll并提供了类似软件商店一样的东西,而msys2更像是cygwin的加强版,他的优点如下:

  • msys2做了一个msys-2.0.dll,我们完全可以把这玩意想象成cygwin1.dll
  • msys2用包管理pacman,这就比cygwin方便得多。
  • msys2还包含了mingw-64的gcc编译器。而且提供的组合非常多,比如mscrt、ucrt、clang等等这些都提供了,而cygwin相比就少的可怜
    可以说:cygwin提供了“商店”功能,但是msys2的“商店”更好用。

缺点:
比如gcc,使用pacman并不能安装所有版本的gcc。特定版本的msys2只能安装特定版本的gcc。cygwin这里做的就比msys2要好一点点。如下图,只有一个版本的gcc:

总结下

大概就是这个样子,省略部分细微差异

如何选择

  • 如果只用gcc,并且是Windows原生执行,那么只需要去winlibs下载,cygwin和msys2都用不到。
  • 如果想在Windows上用bash sed grep awk等等一系列强大的工具,那么cygwin和msys2还是非常有必要装一个的。
  • 想得到linux兼容性比较高的程序就使用依赖msys-2.0.dll或者cygwin1.dll的gcc。

msys2在清华源( https://mirrors.tuna.tsinghua.edu.cn/msys2/ )可以找到所有版本的安装包,也还比较方便。

one more thing

其实一开始mingw也是把自家的所有gcc打包发布的,但是这个setup包发布更新太慢这才出来了mingw-64。mingw-64同样因为类似的问题才出来了msys2。mingw-64已经很久没发布gcc的setup包了,都是cygwin或者msys2拿到mingw的代码编译一份出来。