Linux —— 编译器gcc/g++

目录

程序编译过程

gcc选项

函数库

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

  • gcc是GCC中的GUN C Compiler(C 编译器),根据文件后缀(.c/.cpp),调用对应的编译器;

  • g++是GCC中的GUN C++ Compiler(C++编译器),只当着cpp文件编译,会自动链接STL;

[wz@VM-4-4-centos ~]$ gcc test.cpp
/tmp/ccifuncc.o: In function `main':
test.cpp:(.text+0xa): undefined reference to `std::cout'
test.cpp:(.text+0xf): undefined reference to `std::basic_ostream >& std::operator<<  >(std::basic_ostream >&, char const*)'
test.cpp:(.text+0x14): undefined reference to `std::basic_ostream >& std::endl >(std::basic_ostream >&)'
test.cpp:(.text+0x1c): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
/tmp/ccifuncc.o: In function `__static_initialization_and_destruction_0(int, int)':
test.cpp:(.text+0x4a): undefined reference to `std::ios_base::Init::Init()'
test.cpp:(.text+0x59): undefined reference to `std::ios_base::Init::~Init()'
collect2: error: ld returned 1 exit status
[wz@VM-4-4-centos ~]$ g++ test.c 或 gcc -lstdc++ test.cpp

程序编译过程

  • 预处理(test.c -> test.i)
    • 头文件包含,宏替换,删注释,条件编译等
//预处理
[wz@VM-4-4-centos ~]$ gcc -E test.c -o test.i

Linux —— 编译器gcc/g++_第1张图片

  • 编译(语言代码编译为汇编代码,test.i -> test.s)
    • 语法分析,词法分析,语义分析,符号汇总
//编译
[wz@VM-4-4-centos ~]$ gcc -S test.i -o test.s

Linux —— 编译器gcc/g++_第2张图片

  • 汇编(汇编代码转化为二进制代码,test.s -> test.o)
    • 目标文件
//汇编
[wz@VM-4-4-centos ~]$ gcc -c test.s -o test.o

Linux —— 编译器gcc/g++_第3张图片

  • 链接(目标文件和库链接,test.o -> test)
    • 可执行文件
//链接
[wz@VM-4-4-centos ~]$ gcc test.o -o test
//执行
[wz@VM-4-4-centos ~]$ ./test 
num=100

附:

  • gcc -E test.c -o test.i
  • gcc -S test.i -o test.s
  • gcc -c test.s -o test.o
  • gcc test.o -o test

gcc选项

  • -E,只激活预处理;
  • -S,编译到汇编语言;
  • -c,编译到目标二进制代码;
  • -o,输出到指定文件;
  • -static,采用静态链接;
  • -g,生成调试信息;
  • -shared,尽量使用动态库;
  • -O0,-O1,-O2,O3,编译优化选项的4个级别,0是没有优化;
  • -w,不生成警告信息;
  • -Wall,生成所有警告信息;

函数库

即函数的实现,默认路径/usr/lib、/usr/lib64;

  • 静态库,是指编译链接时,将库文件代码直接加入到可执行文件中,生成的文件比较大,但运行时无需库文件,后缀一般为.a;
  • 动态库,是指编译链接时,没有将库文件代码加入到可执行文件中,而是在程序执行时由链接文件加载库,可节省开销,后缀一般为.so;gcc编译时默认使用动态库;
[wz@VM-4-4-centos ~]$ ll -h test_*
-rwxrwxr-x 1 wz wz 8.3K Mar 13 19:48 test_dynamically
-rwxrwxr-x 1 wz wz 842K Mar 13 19:54 test_static
//ldd用于打印程序或者库文件所依赖的共享库列表
//file识别文件类型
[wz@VM-4-4-centos ~]$ ldd test_dynamically 
	linux-vdso.so.1 =>  (0x00007ffd77fd4000)
	/$LIB/libonion.so => /lib64/libonion.so (0x00007fbce337e000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fbce2e97000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fbce2c93000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fbce3265000)
[wz@VM-4-4-centos ~]$ file test_dynamically 
test_dynamically: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), 
dynamically linked (uses shared libs), for GNU/Linux 2.6.32,
BuildID[sha1]=1c9e02830856285e3dd7a92c807cd755880fd291, not stripped
[wz@VM-4-4-centos ~]$ ldd test_static 
	not a dynamic executable
[wz@VM-4-4-centos ~]$ file test_static 
test_static: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), 
statically linked, for GNU/Linux 2.6.32,
BuildID[sha1]=ce5b8ce1725cf5a7b14a04f08b7951afa98656fb, not stripped

你可能感兴趣的:(操作系统,linux)