GCC 和 G++ 的学习笔记

GNU编译器集合(GNU Compiler Collection , GCC)是由GNU项目产生的编译器系统,支持各种编程语言。GCC是GNU工具链的一个关键组件,也是与GNU和Linux(包括Linux内核)相关的大多数项目的标准编译器。GCC包括了C、C++等语言的标准库文件。
了解更多:官网

同时, “GCC”也是编译器最通用的名字,主要用于强调编译C程序,当强调编译C++程序时更常用“G++”。

2. 什么是 G++ ?

G++ 是一个编译器,而不仅仅是一个预处理器。G++ 直接从C++程序源代码构建目标代码。这里没有该程序的中间C版本。(相反,其他一些实现可能使用从您的c++源代码生成C程序的程序。)即使它们根据文件类型自动确定调用哪个后端(cc1 cc1plus…),除非用-x语言覆盖,它们还是有一些区别。它们默认的最重要的区别可能是它们自动链接的库。根据GCC的在线文档 link option 和 how g++ is invoked,g++相当于gcc -xc++ -lstdc++ -shared-libgcc(第一个是编译器选项,第二个是链接器选项)。这可以通过使用-v选项运行两者来检查(它显示正在运行的后端工具链命令)。
参考:GCC vs G++      What is the difference between g++ and gcc?

3. 命令行下使用 gcc 和 g++

g++命令是一个GNU c++编译器调用命令,用于预处理、编译、汇编和链接源代码以生成可执行文件。(C 程序可以使用 gcc命令)

g++ --version //查看版本  或者 g++ -v

g++ file_name1.cpp file_name2.cpp //编译链接并生成可执行文件 --> .exe / .out (默认为a.out/a.exe, 这个命令好像不能设置目标文件名,区别于 g++ -o)

g++ -S file_name.cpp //编译,不汇编不链接,生成汇编代码 --> .s

g++ -c file_name.cpp //编译和汇编得到目标文件 --> .o

g++ -o target_name.exe file_name1.cpp file_name2.cpp //编译汇编链接得到可执行文件,要设定目标文件名字(默认为a.out/a.exe)

g++ -o target_name.exe file_name1.o file_name2.o //直接从目标文件生成可执行文件,并设定目标文件名字

g++ -Wall file_name.cpp //输出编译过程中的警告信息

g++ -Wall -g -o file_name.exe file_name.cpp  //-g 使用gdb调试器生成附加的符号调试信息。

g++ -v -o file_name.exe file_name.cpp  //-v 查看详细的编译过程。verbose

参考:Compiling with g++

更多:GCC参数详解

4. 什么是mingw-w64 和 cygwin?

mingw-w64:Minimalist GNU for Windows - windows64。 (GCC for Windows 64 & 32)

cygwin:Cygwin是一个Windows上使用的类unix的环境和命令行界面。Cygwin非常庞大,包括大多数Unix工具和实用程序。它还包括常用的Bash shell。

5. 什么是 GDB ?

The GNU Project Debugger

6. [-fpermissive] 是什么?

Downgrade some diagnostics about nonconformant code from errors to warnings. 
Thus, using -fpermissive will allow some nonconforming code to compile. (from the docs )

将有关不一致代码的诊断从错误降级为警告。因此,使用-fpermissive将允许编译一些不符合要求的代码。

7. compile vs link vs build 

compile: 源码 (source code)-> 目标代码 (object code)

link: 将目标代码和库代码和启动代码结合在一起 -> 可执行文件 (raw executable)

build: 由编译和链接组成的序列,可能还包括其他任务,比如创建安装程序。

 8. 静态库与共享库 (Static Library vs. Shared Library)

库是一些预编译目标文件,可以通过链接器链接到程序中的。例如系统函数printf()和sqrt()。有两种类型的外部库:静态库和共享库。

1. 静态库的文件扩展名为".a"(unix中的archive file) 或".lib"(Windows中的library)。当将程序链接到静态库时,程序中使用的外部函数的机器码将会被复制到可执行文件中,因此静态链接是在linking阶段完成的。静态库可以通过“ar.exe”存档程序创建。

2. 共享库的文件扩展名为".so"(unix中的shared objects)或".dll"(dynamic link library,动态链接库)。当程序链接到共享库时,只在可执行文件中创建一个表。在可执行文件开始运行之前,操作系统加载外部函数所需的机器码,这就是所谓的动态链接。动态链接使可执行文件更小并节省磁盘空间,因为库的一个副本可以在多个程序之间共享。此外,大多数操作系统允许内存中共享库的一个副本被所有运行的程序使用,从而节省内存。可以升级共享库代码,而不需要重新编译程序。因此动态链接是在程序运行时完成的。

p.s. 可以通过“nm filename” 列出库的内容。

 9. GNU Make

“make”工具自动化了从源代码构建可执行文件的常见方面。"make" 使用 makefile,包含了一系列关于如何build可执行文件的规则。

makefile由一组规则组成。规则由3部分组成:目标、先决条件列表和命令(a target, a list of pre-requisites and a command),如下所示:

target: pre-req-1 pre-req-2 ...
    command

e.g.:
all: hello.exe
hello.exe: hello.o gcc -o hello.exe hello.o
hello.o: hello.c gcc -c hello.c
clean: rm hello.o hello.exe

补充材料: GCC and Make Compiling, Linking and Building C/C++ Applications

 

原文地址:https://www.cnblogs.com/tristatl/p/13167203.html