• [linux学习笔记]02 gcc安装与使用


    安装gcc:sudo apt-get install gcc

    一. 程序从源代码到可执行目标文件的四个阶段:

    1. -E 预编译 —>.i文件
    2. -S 编译 —>.s文件 内容为汇编语言
    3. -c 汇编 —>.o文件
    4. -static 链接 —>.out文件
    foo.c文件
    int foo()
    {
    	int sum {};
    	for (int i {};i < 10; i++)
    		sum += i;
    	return sum;
    }
    
    b.c文件
    int foo(); // 函数声明
    int main()
    {
    	printf("sum = %d",sum);
    }
    
    #进行编译,每个源文件单独编译,形成.o可重定位目标文件,a.o及b.o
    gcc -c foo.c
    gcc -c b.c
    #b.c中调用了a.c中的函数,因此两个.o目标文件需要经过链接
    gcc foo.o b.o -static #默认生成a.out,想要生成指定名称的.out文件
    gcc foo.o b.o -static -o cal.out
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    二. GCC编译器有很多参数,可以对编译过程进行控制,下面介绍一些常用的参数:

    1. -o参数:指定编译后的可执行文件名。
      gcc -o test test.c
      上面的命令会将test.c文件编译成可执行文件test。

    2. -c参数:只编译不链接,生成目标文件。
      gcc -c test.c
      上面的命令会将test.c文件编译成目标文件test.o,但是不进行链接操作

    3. -E参数:只进行预处理,不进行编译。
      gcc -E test.c
      上面的命令会对test.c文件进行预处理,输出预处理结果到屏幕上。

    4. -Wall参数:显示所有警告信息。
      gcc -Wall test.c
      上面的命令会编译test.c文件,并显示所有警告信息。

    5. -g参数:为可执行文件添加调试信息。
      gcc -g test.c
      上面的命令会将test.c文件编译成可执行文件test,并加入调试信息。

    6. gcc -S test.c
      生成a.s文本文件,是一个汇编语言的文件

    7. objdump -d test.o
      可对二进制文件进行反汇编

    // a.c
    int main(){}
    
    // 使用gcc对a.c进行编译
    gcc -c a.c	// 默认生成a.o文件
    
    // 使用objdump进行反汇编
    objdump -d a.o
    
    =====================输出结果如下============================
    a.o:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    0000000000000000 <main>:
       0:   f3 0f 1e fa             endbr64
       4:   55                      push   %rbp
       5:   48 89 e5                mov    %rsp,%rbp
       8:   b8 00 00 00 00          mov    $0x0,%eax
       d:   5d                      pop    %rbp
       e:   c3                      ret
    ============================================================
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    1. gcc test.c
      直接生成test.out可执行文件
      .o文件与.out文件
      .o文件是由各个单独的源文件经编译后生成的可重定位的目标文件。
      .out文件时可执行目标文件,是由.o文件经过链接后形成的。
    2. gcc test.c --verbose
      如果没有–verbose选项,我们看不到gcc命令的执行过程。加入verbose选项后,可以得到编译过程中命令执行的具体过程`
    gcc a.c --verbose
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/11/lto-wrapper
    OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa
    OFFLOAD_TARGET_DEFAULT=1
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Ubuntu 11.4.0-1ubuntu1~22.04' --with-bugurl=file:///usr/share/doc/gcc-11/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-11 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --enable-cet --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-11-XeT9lY/gcc-11-11.4.0/debian/tmp-gcn/usr --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --with-build-config=bootstrap-lto-lean --enable-link-serialization=2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. gcc -m32 test.c
      指定gcc编译一个32位的文件(默认为64位),可通过file test.out查看
      报错,需要安装支持32位gcc操作系统支持包
    lynn@Lynn:~$ gcc -m32 a.c
    In file included from a.c:1:
    /usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: No such file or directory
       27 | #include <bits/libc-header-start.h>
          |          ^~~~~~~~~~~~~~~~~~~~~~~~~~
    compilation terminated.
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    sudo apt-get install libc6-dev-i386 安装即可
    file a.out
    
    • 1
    • 2
    a.out: ELF 32-bit LSB pie executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, BuildID[sha1]=5de634f9888570957ea78319d4b647b1f120899c, for GNU/Linux 3.2.0, not stripped
    
    • 1
    1. gcc a.c -I./ 或者 gcc a.c -I.
      将当前目录添加到标准库目录处,这使得我们可以使用<>包含自己的头文件,而不是""双引号。
      #include

    三. C文件与C++文件的链接

    如果期望将文件看作C文件而不是C++文件,需要在该函数的声明处添加extern “C”关键字

    // foo.c
    extern "C" {	// 在函数定义中添加extern "C" 关键字
    int foo() {return 10;}
    }
    
    • 1
    • 2
    • 3
    • 4
    // cal.cpp
    #include 
    extern "C" {int foo();}	// 在函数声明中亦需要添加extern "C" 关键字
    int main()
    {
    	std::cout << "Sum= " << foo() << std::endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    #声明为extern "C" 的C文件在编译后使用的函数名不变,而C++的函数名为编译器指定(考虑到模板的不同函数示例拥有相同的函数名但有不同的函数签名)
    g++ -c cal.cpp
    g++ -c foo.c
    objdump -d foo.o
    g++ foo.o cal.o -static -o cal.out
    ==========================================================
    foo.o:     file format elf64-x86-64
    
    
    Disassembly of section .text:
    
    0000000000000000 <foo>:
       0:   f3 0f 1e fa             endbr64
       4:   55                      push   %rbp
       5:   48 89 e5                mov    %rsp,%rbp
       8:   c7 45 f8 00 00 00 00    movl   $0x0,-0x8(%rbp)
       f:   c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
      16:   eb 0a                   jmp    22 <foo+0x22>
      18:   8b 45 fc                mov    -0x4(%rbp),%eax
      1b:   01 45 f8                add    %eax,-0x8(%rbp)
      1e:   83 45 fc 01             addl   $0x1,-0x4(%rbp)
      22:   83 7d fc 09             cmpl   $0x9,-0x4(%rbp)
      26:   7e f0                   jle    18 <foo+0x18>
      28:   8b 45 f8                mov    -0x8(%rbp),%eax
      2b:   5d                      pop    %rbp
      2c:   c3                      ret
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
  • 相关阅读:
    5年测试工程师在公司被看轻,只因不会自动化测试...
    【JS逆向系列】某服务器平台sm系列算法分析
    小阿轩yx-Nginx 网站服务
    GitLab 内存、cpu资源占用过大问题解决
    微积分 - 导数
    P1494 [国家集训队] 小 Z 的袜子
    百度飞桨公布最新成果:凝聚535万开发者,服务20万家企事业单位
    vue组件
    玩转Jetson Nano(四):TensorRT图像识别
    外卖项目03---分类管理业务开发
  • 原文地址:https://blog.csdn.net/lynn_flame/article/details/132628014