目录
一、常用编程语言的编译器(compiler)概述
二、GCC、MinGW、MinGW-w64 、TDM-GCC、Cygwin、MSYS、MSYS2的区别
三、MinGW-w64编译器套件下载及安装
四、MinGW-w64安装后,windows环境变量配置(设置)
五、编译器的运行及其与开发环境的关系、编译器的来源
机器语言是二进制在计算机中的表达,通过高低电平(高电压叫高电平,低电压叫低电平)来表示1和0的二进制。1和0的二进制构成机器指令(instruction),也称为机器码或计算机指令,计算机按照二进制的机器码执行。
一条机器指令(机器码)必须包括操作码和地址码(或操作数)两部分。操作码指出该指令完成操作的类型,比如:加、减、乘、除、传送等。地址码指出参与操作的数据和操作结果存放的位置。机器指令在CPU中会进一步翻译为具体的操作,以便计算机按具体的操作执行。
C和C++通过编译器(Compiler)即可把代码编译成机器码,计算机根据机器码即可执行,而Java、Python是把代码先编译成字节码,然后再把字节码编译成机器码并执行,前者从整体上讲只需要一次编译,编译完成后再执行,后者相对独立地进行了两次编译(第二次是编译和执行)。可见,安装C语言或安装C++不像安装Java或Python,前者只需要安装一个编译器,就可以运行程序,而后者需要安装编译器+虚拟机,比如:python的解释器就是由编译器+虚拟机构成。因此,C语言安装或C++安装与Java或Python安装是存在很大差异的,这主要由两者处理过程的特点决定了。
但从广义上讲,Java或Python安装的也是一种编译器,只是这种编译器比较特殊,它经历两次相对独立的翻译,而且第二次实现一边翻译一边执行,正因为这个特点,第二次的翻译执行称为虚拟机,而C或C++的编译器从整体上讲只有一次翻译,翻译完成后生成机器码特点的文件,生成的这种文件与所在计算机系统密切相关(一个能在计算机上执行的文件与这台计算机的操作系统和硬件系统是密切相关的,与之相适应才能执行),因此,C或C++缺乏跨平台性、可移植性,而Java或Python第一次编译生成的字节码,与所在计算机的系统不相关,它只是对代码的一次梳理,并不与计算机系统关联,在第二次翻译执行的时候才与计算机系统密切相关,因此,Java或Python第一次编译的字节码形式确保了它们的跨平台性(cross platform)、可移植性(portability),这也是它们的一种优势。
任何编程语言的安装,实际主要就是安装一种对这种代码语言具有翻译能力的文件(简称编译器),这种翻译功能就是把代码转换为最终的机器码,CPU然后根据机器码执行。其它附加的安装更多的是为了给用户提供便利,完全可以去掉这些附加的功能,仅用翻译功能我们也能实现这些附加功能,只是这会考验我们的能力和占用我们更多的开发时间,因此,有的编程语言安装会占用存储空间很大,其实是增加了很多附加功能,比如:matlab,它提供了大量的计算工具,因为这种语言侧重数学计算。
只要我们写的代码符合c或c++规范,编译器能把这些代码翻译成计算机能直接执行的机器码(机器指令),然后CPU依据这些指令执行,从而实现程序的运行。下面我们先了解几款与c/c++编译器有关的、可以在Windows平台上支持GCC的软件,再介绍C/C++编译器的安装。
GCC(GNU Compiler Collection) ,GNU编译器套件。GCC原名为GNU C语言编译器(GNU C Compiler),只能处理C语言,经过扩展能够支持C、C++、 Objective-C、 Objective-C++、Fortran、Ada、Modula-2和Go多种编程语言,所以改名GNU编译器套件(GNU Compiler Collection)。GCC不完全支持Java、Python的编译,但Java、Python底层的C实现会用到C编译器。
GCC的初衷是为GNU操作系统专门编写一款编译器,现已被大多数类Unix操作系统(比如:Linux、BSD、MacOS X等)采纳为标准的编译器。
GCC在Windows平台上的支持并不完善,缺乏兼容性,用GCC在Windows上开发应用程序存在很多问题。下面几款编译软件具有各自特点,含有GCC且适合Windows平台。
MinGW、MinGW-w64 与TDM-GCC是基于GCC而适合Windows操作系统的编译器套件(编译器集成包)。
MinGW将GCC移植到Windows上,但仅支持32位应用程序,MinGW-w64衍生于MinGW,不仅可以支持32位应用程序,还可以支持64位。TDM-GCC是非官方组织提供及维护的编译器套件,支持32位和64位应用程序。
Cygwin、MSYS、MSYS2都是代表可以在Windows上运行的环境,不是单纯的编译器套件,它们都支持Windows,因而,其内置的GCC也可以在Windows平台上使用。
Cygwin是一个可以在Windows上运行的UNiX模拟环境(虚拟环境),它提供UNIX 模拟 DLL 以及在其上层构建的多种可以在 Linux 系统中找到的软件包(其中含有GCC),这使得GCC可以在Windows平台上使用。
MSYS(Minimal GNU(POSIX) system on Windows )是一个小型的可以在Windows上运行的GNU环境。GNU的设计类似Unix,但它不包含具著作权的Unix代码。POSIX为可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX)。接口可以理解为不同组成部分衔接的约定。
MSYS2是一个MSYS的独立改写版本,也是一个在Cygwin(POSIX)和 MinGW-w64基础上产生的Windows 软件。
因此,MSYS、MSYS2也使得GCC可以在Windows平台上使用。
上面介绍了几款可以在Windows平台上支持GCC的软件。我们可以根据自己的需求下载相应的编译软件,下面表3-1提供了可在Windows平台上运行的常用的编译软件的下载地址。
表3-1在Windows平台上支持GCC的常用软件
GCC官网地址 |
GCC, the GNU Compiler Collection- GNU Project |
MinGW-w64官网地址 |
MinGW-w64 |
TDM-GCC官网地址 |
tdm-gcc |
Cygwin官网地址 |
Cygwin |
MSYS2官网地址 |
MSYS2 |
MinGW-w64开源,且有活跃的开源社区维护,这里,我们选择安装MinGW-w64编译器套件。打开表3-1中MinGW-w64官网地址,如图3-1所示。
图3-1 MinGW-w64官网地址
点击图3-1中红箭头位置,在弹出的菜单中点击Downloads选项,进入下载页面(也即Downloads - MinGW-w64),该页面的Pre-built toolchains and packages标题下面是预构建的工具链和软件包,也即含有GCC/Mingw-w64的特定工具的整合包,而我们只需要下载MinGW-w64,可以下拉页面到如图3-2红框的Sources位置。
图3-2 MinGW-w64下载链接
点击图3-2红箭头所指的SourceForge内链,进入MinGW-w64下载页面(也即MinGW-w64 - for 32 and 64 bit Windows - Browse /mingw-w64/mingw-w64-release at SourceForge.net),如图3-3所示。
图3-3 MinGW-w64下载页
图3-3红框中是不同时间、类型的MinGW-w64的源代码(源码)下载,红色箭头处为最近更新的MinGW-w64的源代码(源码),这些源码不是安装程序,因而是没有bin文件夹的(bin文件夹有安装后的可执行文件,我们在配置环境变量时需要用到这个文件夹)。
我们需要使用MinGW-w64的可执行文件用来产生编译功能,因而我们需要下载MinGW-w64的安装程序,安装后即可获得可执行文件,下拉页面到如图3-4所示位置。注意,这里讲的可执行文件是指已经被编译处理过且能执行的文件(也称为机器码文件或机器码构成的二进制文件),上面提到的源码是没被编译过的。
图3-4 MinGW-w64安装程序
图3-4中①、②为最新版本的MinGW-w64,第①个红框是在线安装MinGW-w64,若访问外网速度比较慢,可以选下载择第②个红框的压缩包,这个压缩包是MinGW-w64已生成的可执行文件,解压后即可用,当然,不论哪种方式,都需要配置环境变量后MinGW-w64的可执行文件才能在windows中运行。
这里我们选择下载第二个红框的压缩包。在下载压缩包之前我们需要了解图3-4中第②个红框压缩包名称中参数的含义,下面表3-2列出了其参数的代表的含义。
表3-2 MinGW-w64版本类型
参数类型 |
参数 |
说明 |
CPU架构 |
x86_64 |
64位 |
i686 |
32位 |
|
操作系统接口协议 |
win32 |
开发windows的应用程序 |
posix |
开发Linux、Mac的应用程序 |
|
异常处理模型 |
sjlj |
版本低,可支持32位和64位 |
seh |
版本新,性能较好,只支持64位 |
|
dwarf |
版本新,性能较好,只支持32位 |
根据表3-2,我们可以下载x86_64-win33-seh这个版本,解压后就是已经安装生成的可执行文件,相当于图3-4中第①个红框(MinGW-W64-install.exe)下载后在线安装的结果。
另外,上述表3-2中的参数实际也是图3-4中第①个红框(MinGW-W64-install.exe)下载后的在线安装时的安装选项设置,这里不再列举第①个红框下载后的安装过程,其选项配置可参考表3-2中参数的含义。
环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还会到环境变量path中指定的路径去找可运行的变量。
环境变量中的系统变量是对所有用户有效,用户变量是对当前登录的windows账号有效,当系统变量查找不到时,会到当前用户变量中查找。另外,环境变量名称是不区分大小写的,比如:PATH和path,两个名称是一样的。
因此,为方便调用MinGW-w64编译器软件,我们需要配置环境变量(environment variable),把MinGW-w64安装后的bin文件夹所在的路径设置为环境变量的值,以方便调用可执行文件。
上面我们是下载压缩文件直接解压MinGW-w64的安装,若我们是下载的安装程序(即图3-4中第①个红框)安装,也需要设置环境变量(environment variable),但很多安装程序在安装时会提示设置环境变量。
下面我们介绍环境变量的配置(Configuration)。鼠标右键电脑图标如图4-1所示。
图4-1 电脑属性
在图4-1菜单中单击属性,进入图4-2中的电脑设置界面。
图4-2 电脑设置
在图4-2中单击红色箭头处的高级系统设置,进入图4-3系统设置界面。
图4-3 系统属性
在图4-3中单击红色箭头处的环境变量,进入图4-4环境变量界面。
图4-4 环境变量
根据上面提到的环境变量的特点,我们可以选择图4-4中红框的系统变量Path变量,然后单击红色箭头处的编辑,或双击Path变量,进入图4-5编辑环境变量界面。
图4-5 编辑环境变量
在图4-5中单击红色箭头处的新建,进入图4-6环境变量界面。
图4-6 新建环境变量
如图4-6所示输入MinGW-W64的安装路径,路径应该含有bin目录,即一般为…\mingw64\bin。
bin目录有cpp.exe、gcc.exe、g++.exe、gdb.exe等可执行文件,其中,cpp.exe是预处理器,g++/gcc.exe是编译器,gdb.exe是调试器,as.exe 是汇编器,ld.exe是链接器。
新建环境变量输入完成后单击确定,单击所有的确定后,环境变量配置成功。在调用时,当未指明路径时系统会自动进入该配置的位置匹配调用。
上面配置完后,我们使用win+r快捷键(也即Windows+R)打开运行窗口,输入cmd并确定,打开cmd命令行窗口,在命令行窗口中输入gcc -v,查看gcc的版本信息,从而可以确定gcc是否安装并且环境变量配置成功,v可以理解为version的简写,如图4-7所示为安装成功且配置成功。
图4-7 gcc版本信息
至此,MinGW-W64 install及环境变量配置完成,也相当于c install(或c++ install)完成,在windows中可以使用编译器进行C/C++程序开发了。
编译器是由文件构成,我们还需要工具运行这些可执行文件,也即调用编译器(Compiler)进行编译,来实现程序开发的作用。cmd.exe是 Windows 系统的一种命令行操作工具,用户可以通过输入命令来完成各种各样的系统或程序操作。
对于任何一门编程语言,只要安装了这个编程语言的编译器,我们可以用文本编辑器(txt文件)写好代码,然后保存为编程语言的格式(即把.txt后缀改为编程语言的后缀),可以通过cmd命令提示窗调用这个编程语言的编译器运行这个编写好的代码文件。上面我们安装的MinGW-W64编译器套件是适合windows平台的,我们可以使用windows的命令提示符cmd.exe来运行编译器,进行C/C++程序开发。
cmd运行C/C++程序代码参见Windows的cmd运行编译器(cmd运行c/c++、python等)。
在windows中,除了上述CMD命令调用编译器的方法,我们还可以用集成开发环境(Integrated Development Environment,简写IDE)工具来运行编译器,进行程序代码开发。
集成开发环境工具是带有一整套可以帮助我们提高语言开发效率的工具(比如:代码编辑、调试、语法高亮、智能提示(intellisense)等),可以提高项目开发、管理效率。在集成开发环境工具中设置好编译器(也即调用编译器)就可以实现基于该编译器的程序代码开发,编译器提供了编程语言的翻译功能,集成开发环境工具仅是提供了开发程序的便利性的辅助作用,简单地讲,集成开发环境就是我们编程的辅助工具,方便我们编写代码,但真正实现编程语言的程序运行的还是编译器,集成开发环境会调用编译器运行程序。
编程语言(C/C++、Java、Python、Matlab等)一般都是借助集成开发环境(IDE)来开发,这样可以提高编写代码的效率,有的编程语言有自带的IDE,比如:python有自带的IDLE工具,但是一个简单的IDE,其操作有局限性,因而,一般使用其它IDE(比如:pycharm)进行编写代码,matlab.exe启动的界面就是一个自带的IDE(默认调用matlab的编译器),这个IDE功能比较全面,因而使用matab语言一般也是使用其自带的IDE。
VS Code代码编辑器虽然定位为编辑器,实际也具有集成开发环境工具的基本功能,由于是免费的,因而很受用户青睐,可以用在C/C++、Java、Python等程序开发。我们也可以用VS Code工具进行C/C++开发,参见2023年最新VS Code安装详细教程及vs code配置。
编译器(Compiler)需要cmd.exe或IDE(集成开发环境)调用运行,实际也是让操作系统参与进来,发挥操作系统的作用(计算机资源分配),从而顺利实现程序的运行。
上面我们提到源代码(源码),也就是我们根据语言的规范写的代码,也是没有编译过的代码,只有通过编译器翻译成机器码后才能执行。那么一种编程语言诞生后,它并没有诞生编译器,它是如何运行的呢?最开始是借助其它编译器来运行,然后再根据这个语言写一个编译器源码文件,让其它语言的编译器把这个语言写的编译器源码文件编译成可执行文件,通过不断完善,从而最终诞生这个语言的可执行的编译器(可执行文件,也即一个由机器码构成的文件,计算机根据机器码就可以执行)。
计算机诞生时,最初的计算机功能很简单,因而,最初的编译器用人来担任,把人写的语句翻译成机器语言,让机器执行。但随着计算机功能的增强,机器指令不断增加,由人来实现翻译工作,很容易出错,而且工作繁琐,人很难胜任,尤其当出现标准的编程语言规范时,就更需要一个能把编程语言翻译成机器码的自动化操作。
针对这种现状,伴随着由机器语言发展出汇编语言,计算机工作者开始用机器码来实现一个编译器,用来把汇编语言的源码编译(翻译)成机器码,让机器执行。通过这种方式让汇编程序代码能够在机器上运行,然后就可以用汇编语言编写一个有关自身的编译器源码文件,并让由机器码实现的编译器把这个汇编语言写的编译器源码文件编译成可执行文件,再通过不断完善,从而最终诞生这个汇编语言的可执行的编译器文件,这也就实现了用一种编程语言实现该语言自身的编译器,这也称为这种编程语言的自举(Bootstrapping)。
同理,当其它语言诞生时,可以借助汇编语言的编译器生成一个该语言的可执行的编译器。比如:汇编语言→B语言→C语言,c语言可以通过汇编语言的编译器实现自举,生成c语言本身的编译器,然后,c语言代码可以利用自身的这个c编译器实现编译,翻译成cpu可以执行的机器码,从而实现c语言代码的运行。
C语言是比较接近机器底层,而又比较适合人阅读的语言,由于接近机器底层,对硬件操作有优势,运行速度快,因而,c语言自然得到用户的肯定,c编译器也是被其它语言引用比较广泛的编译器。
因此,编译器是由人、机器码、汇编、c等一步步发展出来的,诞生的编程语言都是依靠已经诞生的语言的编译器来实现自举(Bootstrapping),产生自身的编译器。