C++学习笔记(2):G++的基本使用

GCC(GNU编译器套件)

GCC

即GNU Compiler Collection(GUN 编译器集合),它可以编译C、C++、JAV、Fortran、Pascal、Object-C等语言。

gcc和g++

gcc是GCC中的GUN C Compiler(C 编译器);g++是GCC中的GUN C++ Compiler(C++编译器)。即:gcc调用了C compiler,是使用了C编译器的GCC,而g++调用了C++ compiler,是使用了C++编译器的GCC。

gcc和g++的主要区别

  • 对于 *.c和*.cpp文件,gcc分别当做c和cpp文件编译。
  • 对于 *.c和*.cpp文件,g++则统一当做cpp文件编译。
  • 使用g++编译文件时,g++会自动链接标准库STL,而gcc不会自动链接STL。

G++的使用

安装G++(Windows下)

首先打开mingw官方网站下载适用于Windows系统的mingw。


将下载后的安装程序打开,选择好安装的版本即可开始安装。

注意:下载的安装程序只是个在线安装的启动器,所以安装程序的大小一般比较小,并且安装过程需要在线安装,期间不能断开网络。
安装成功后需要配置环境变量,将安装目录下的bin文件夹加入环境变量,如:D:\mingw64\bin
打开cmd输入g++ -v,可看到输出的版本信息即为安装成功:

g++编译过程

① 预处理:
g++ -E hello.cpp -o hello.i
-E为预处理参数。hello.cpp为要进行预处理的源文件。-o为指定输出文件名,指定的文件名为hello.i。
② 编译:
g++ -S hello.i -o hello.s
-S为编译参数。hello.i为要进行编译的文件。同样使用-o指定输出文件名,输出的为汇编文件hello.s。
③ 汇编:
g++ -c hello.s -o hello.o
使用参数-c将汇编文件转换为目标文件,即机器代码。
④ 链接:
g++ hello.o -o hello
这样即可将目标文件转换为可执行文件。
⑤ 简化指令:
g++ hello.cpp -o hello
可直接通过这种方式一步到位,将cpp源文件编译为可执行文件,省略中间指令,自动执行上述四个过程。

g++编译选项

在使用g++编译时,可使用更多编译选项:
① -o FILE:指定输出文件名。
② -C:在预处理的时候,不删除注释信息,一般和-E一起使用。
③ -Wall:允许发出gcc能提供的所有有用的警告:
g++ -Wall hello.cpp -o hello
④ -Werror:把所有警告转换为错误,以在警告发生时中止编译过程。
⑤ -static:链接静态库,即执行静态链接。g++默认是动态链接方式:
g++ main.cpp -lstatic -L. -static -o main
⑥ -g:在可执行程序中包含标准调试信息, 使用该选项生成的可执行文件可以用gdb工具进行调试。
⑦ -shared:生成共享目标文件,通常用在建立共享库时。
⑧ -On:优化选项,如果在编译时指定该选项,则编译器会根据n的值(n取0到3之间)对代码进行不同程度的优化,其中-O0 表示不优化,n的值越大,优化程度越高。
⑨ -L:库文件依赖选项,该选项用于指定编译的源程序依赖的库文件路径,库文件可以是静态链接库,也可以是动态链接库,linux系统默认的库路径是/usr/lib,如果需要的库文件不在这个路径下就要用-L指定。
⑩ -I:该选项用于指定编译程序时依赖的头文件路径,linux平台默认头文件路径在/usr/include下,如果不在该目录下,则编译时需要使用该选项指定头文件所在路径。

g++多文件编译

假设在同一个文件夹下有header.h,func.cpp,main.cpp三个文件,两个源文件和一个头文件,在编译过程中一般不需要单独处理头文件,直接对两个cpp文件进行编译即可:
g++ -c func.cpp
g++ -c main.cpp
这样编译后将会生成两个目标文件:func.o,main.o。此时将两个目标文件进行链接即可:
g++ main.o func.o -o test
最终生成编译完成的text.exe可执行文件。

编译动态链接库

静态库:
是指编译链接时,把库文件的代码全部加入到可执行文件中,因此生成的文件比较大,但在运行时也就不再需要库文件了。其后缀名一般为.a。
动态库:
与之相反,在编译链接时并没有把库文件的代码加入到可执行文件中,而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。gcc/g++在编译时默认使用动态库。无论静态库,还是动态库,都是由.o文件创建的。在linux中动态链接库的后缀为.so,windows中的后缀为.dll,mac 中为.dylib。
若有头文件dynamic.h,三个.cpp文件dynamic_a.cpp、dynamic_b.cpp、dynamic_c.cpp,将这几个文件编译成一个动态库libdynamic.so的命令如下:
g++ dynamic_a.cpp dynamic_b.cpp dynamic_c.cpp -fPIC -shared -o libdynamic.so
其中:
-shared:该选项指定生成动态连接库。
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
已经生成了一个libdynamic.so的动态链接库之后,用一个程序来调用这个动态链接库,文件命名为main.cpp,则将main.cpp与libdynamic.so链接成一个可执行文件main的命令如下:
g++ main.cpp -L. -ldynamic -o main
其中:
-L.:表示要连接的库在当前目录中。
-ldynamic:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称。

Makefile

使用Makefile可以实现自动化的编译,以使用一个命令来完成以下编译工作:

  • 如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
  • 如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
  • 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。

Makefile的使用参见教程




* 你好,我是大森。如果文章内容帮到了你,你可通过下方付款二维码支持作者 *