GCC之g++

1.1 GCC简史和简介

1.1.1 GCC简述

最初的GNU C编译器(GCC)是由GNU项目的创始人Richard Stallman开发的。Richard Stallman于1984年创建了GNU项目,以创建一个完整的类Unix操作系统作为自由软件,以促进计算机用户和程序员之间的自由和合作。

GCC,以前用于“ GNU C编译器 ”,已经不断发展,支持多种语言,如C(gcc),C ++(g++),Objective-C,Objective-C ++,Java(gcj),Fortran(gfortran),Ada(gnat),Go(gccgo),OpenMP,Cilk Plus和OpenAcc。它现在被称为“ GNU编译器集合 ”。海湾合作委员会的母址是http://gcc.gnu.org/。目前的版本是GCC 7.3,发布于2018-01-25。

GCC是所谓的“ GNU工具链 ” 的关键组件,用于开发应用程序和编写操作系统。

1.1.2 GNU工具链包括

GNU编译器集合(GCC):支持多种语言的编译器套件,例如C / C ++和Objective-C / C ++。
GNU Make:用于编译和构建应用程序的自动化工具。
GNU Binutils:一套二进制实用工具,包括链接器和汇编器。
GNU调试器(GDB)。
GNU Autotools:一个构建系统,包括Autoconf,Autoheader,Automake和Libtool。
GNU Bison:一个解析器生成器(类似于lex和yacc)。
GCC是可移植的,可在许多操作平台上运行。GCC(和GNU工具链)目前在所有Unix上都可用。它们也被移植到Windows(由Cygwin,MinGW和MinGW-W64)。GCC也是一个交叉编译器,用于在不同平台上生成可执行文件。

1.1.3 GCC版本

各种GCC版本是:

GCC版本1(1987):支持C的初始版本
GCC第2版(1992):支持C ++。
GCC版本3(2001):结合ECGS(实验GNU编译器系统),改进优化。
GCC第4版(2005年):
海湾合作委员会第5版(2015年):
GCC第6版(2016年):
GCC第7版(2017年):

1.1.3 C ++标准支持

有各种C ++标准:

C ++ 98
C ++ 11(又名C ++ 0x)
C ++ 14(又名C ++ 1y)
C ++ 17(又名C ++ 1z)
C ++ 2a(2020年下一个计划标准)
默认模式是C ++ 98(适用于6.1之前的GCC版本)和C ++ 14(适用于GCC 6.1及更高版本)。

1.1.3 指定C++标准

您可以使用命令行标志-std显式指定C ++标准。例如,

-std=c++98,或-std=gnu++98(带有GNU扩展的C ++ 98)
-std=c++11,或-std=gnu++11(带有GNU扩展的C ++ 11)
-std=c++14,或-std=gnu++14(带有GNU扩展的C ++ 14),GCC 6.1及更高版本的默认模式。
-std=c++17或者-std=gnu++17(带有GNU扩展的C ++ 17),实验性的。
-std=c++2a,或-std=gnu++2a(带有GNU扩展的C ++ 2a),实验性的。

1.2 GCC 编译器选项

  • -o:指定输出可执行文件名。
  • -Wall:输出所有的debug信息。
  • -g:生成debug信息(generates additional symbolic debuggging information for use with gdb debugger.)
$ g ++ -Wall -g -o Hello Hello.cpp

编译多个源文件成为一个可执行文件,一行完成

$ g ++ -o myprog file1.cpp file2.cpp 

编译多个源文件成为一个可执行文件,多行完成

$ g ++ -c file1.cpp 
$ g ++ -c file2.cpp 
$ g ++ -o myprog file1.o file2.o

向已有的可执行文件上面添加一个二进制库

// Compile-only with -c option
$ g++ -c -Wall -g Hello.cpp
// Link object file(s) into an executable
$ g++ -g -o Hello Hello.o

通过-v 展示详细的编译过程

gcc -v -o hello.exe hello.c

另外,还可以用–shared参数,生成动态链接库(Shared Library)

1.3 GCC编译过程

在这里插入图片描述

  1. Preprocessor(预处理):
$  cpp hello.c> hello.i
  1. Compiler(编译)
$ gcc -S hello.i
  1. Assembler(汇编)
$ as -o hello.o hello.s
  1. Linker(链接)
$ ld -o hello.exe hello.o ... libraries ...

1.4 Headers (.h), Static Libraries (.lib, .a) and Shared Library (.dll, .so)

1.4.1 静态库 (static library )

  • A static library has file extension of “.a” (archive file) in Unixes or “.lib” (library) in Windows.
  • When your program is linked against a static library, the machine code of external functions used in your program is copied into the executable.
  • A static library can be created via the archive program “ar.exe”.

1.4.2 动态库(shared library)

  • A shared library has file extension of “.so” (shared objects) in Unixes or “.dll” (dynamic link library) in Windows.
  • When your program is linked against a shared library, only a small table is created in the executable.
  • Before the executable starts running, the operating system loads the machine code needed for the external functions - a process known as dynamic linking。(注意不是函数调用时候才加载,而是load进程前就已经加载了!!!)
  • better than static library
    • ①:Dynamic linking makes executable files smaller and saves disk space, because one copy of a library can be shared between multiple programs.
    • ②:Furthermore, most operating systems allows one copy of a shared library in memory to be used by all running programs, thus, saving memory.
    • ③:The shared library codes can be upgraded without the need to recompile your program.
      Because of the advantage of dynamic linking, GCC, by default, links to the shared library if it is available.

1.4.3 Searching for Header and Libraries (-I, -L and -l)

When compiling the program,

  • the compiler needs the header files to compile the source codes
  • the linker needs the libraries to resolve external references from other object files or libraries.
    The compiler and linker will not find the headers/libraries unless you set the appropriate options.

1.4.4 for Header Paths

For each of the headers used in your source (via #include directives), the compiler searches the so-called include-paths for these headers.

  • The include-paths are specified via -Idir option
  • or environment variable CPATH.

1.4.5 for Header Files

Since the header’s filename is known (e.g., iostream.h, stdio.h), the compiler only needs the directories.(由于头文件的文件名已经给了,所以编译器只需要知道该到什么路径里面去找,所以只需要给编译器提供头文件路径名就好)

1.4.6 for library paths

The linker needs to know both the directories as well as the library names.
Hence, two options need to be specified.

  • The linker searches the so-called library-paths for libraries needed to link the program into an executable.
    • The library-path is specified via -Ldir option (uppercase ‘L’ followed by the directory path)
    • or environment variable LIBRARY_PATH.

1.4.7 for library Files

In addition, you also have to specify the library name.
- In Unixes, the library libxxx.a is specified via -lxxx option (lowercase letter ‘l’, without the prefix “lib” and “.a” extension).
- In Windows, provide the full name such as -lxxx.lib.

留坑待填

https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html
https://www.cnblogs.com/king-lps/p/7757919.html
http://www.cnblogs.com/skynet/p/3372855.html
http://www.cnblogs.com/skynet/p/3372855.html

P.S:.o 是二进制文件,.o 文件通过linker链接以后,会生成**.a**、.so库文件或是可执行文件文件

  • 注意,头文件是头文件,库文件是库文件,编译器无法通过你include哪些头文件而得知你需要哪些库文件,
  • 大部分情况下,一个库文件对应一个头文件,
    • 有些时候多个库文件对应一个头文件
    • 有时候一个库文件对应多个头文件
    • 还有时候是非常复杂的多对多的关系
  • 所以你必须要告诉编译器
    • 头文件搜索路径(所有可能路径)
    • 库文件的搜索路径(所有可能路径)
    • 所有库文件的名称
  • 标准头文件和库,不用你管,C++编译器会自动搞好
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值