Linux | gcc 的基本使用

Linux | gcc 的基本使用

一、gcc常用选项及对应释义

选项作用示例解释
-o <filename>指定输出文件的名称gcc main.c -o my_program链接,将 main.c 编译为可执行文件,并将输出文件命名为 my_program。若不使用此选项,GCC 默认生成 a.out
-c只编译源文件,生成 .o 对象文件,不进行链接操作gcc -c file1.cfile1.c 编译为 file1.o 对象文件,以便后续将多个 .o 对象文件进行链接
-Wall启用大部分警告信息gcc -Wall main.c -o main在编译 main.c 时,显示如未使用的变量、类型不匹配、函数参数不匹配等警告,助于发现代码潜在问题
-O[level]优化编译生成的代码,提高性能gcc -O2 main.c -o main-O-O1 为基本优化,能提升性能且不显著增加编译时间; -O2 会更深入优化代码,性能更好但可能增加编译时间; -O3 为最高级别优化,可能使代码增大但性能提升显著,也可能增加编译时间和内存消耗
-g生成调试信息,允许使用调试工具(如 gdb)对程序进行调试gcc -g main.c -o main生成含调试信息的可执行文件 main,可使用 gdb main 查看源代码、设断点、检查变量值等
-I <directory>添加头文件搜索目录gcc -I/path/to/headers main.c -o mainmain.c 包含的头文件不在系统默认搜索目录时,使用该选项添加 /path/to/headers 作为搜索目录
-L <directory>指定库文件的搜索目录gcc main.c -L/path/to/libs -lmylib -o main告知 GCC 在 /path/to/libs 目录下搜索库文件
-l <library>链接库文件gcc main.c -L/path/to/libs -lmylib -o main假设要链接名为 libmylib.alibmylib.so 的库,使用 -lmylib,GCC 会自动添加 lib 前缀和 .a.so 后缀,并在 -L 指定目录和系统默认目录中搜索
-E只运行 C 预处理器,将源文件展开为 .i 文件,不进行编译、汇编和链接gcc -E main.c -o main.imain.c 展开为 main.i,可查看预处理器的处理结果
-S将 C 源文件编译为汇编代码,生成 .s 文件gcc -S main.c -o main.smain.c 编译为汇编代码文件 main.s,可查看生成的汇编代码
-static链接静态库而不是动态库gcc main.c -static -o main强制使用静态库进行链接,生成的可执行文件包含所有库代码,体积大但不依赖外部库文件,便于移植
-shared生成共享库(动态库)gcc -shared -fPIC file1.c file2.c -o libmylib.so生成动态库 libmylib.so-fPIC 确保生成代码位置无关,使库可在不同内存位置加载
-v显示编译过程的详细信息,包括编译器的调用、搜索路径等gcc -v main.c -o main显示编译 main.c 时的详细信息,如编译器版本、搜索的头文件目录、库目录等

二、gcc编译的完整步骤

1、预处理

实例: gcc –E hello.c –o hello.i

将hello.c文件进行预处理,处理出来的文件是hello.i

其中选项**“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。 选项“-o”是指目标文件,“.i”**文件为已经过预处理的C原始程序。

2、编译(生成汇编)

实例: gcc –S hello.i –o hello.s

将hello.i文件进行编译,生成汇编文件hello.s

在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。 用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码

3、汇编(生成机器可识别码)

实例: gcc –c hello.s –o hello.o

汇编阶段是把编译阶段生成的“.s”文件转成目标文件 读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了

4、链接

实例:gcc hello.o –o hello

将多个目标文件(如hello.o)和库文件组合成一个可执行文件(如hello)的过程,gcc中默认形成的可执行程序是动态链接的

进行静态链接:gcc -static hello.o -o hello

一般云服务器中,C/C++没有安装静态库,可以如下安装:

yum(Centos)/apt(Ubuntu) install glibc-static libstdc++-std -y

动静态库
  • 静态库
    • 静态库是一些目标文件(通常以 .o 结尾)的集合,通常打包成一个文件,以 .a 为后缀。
    • 它是在程序编译时被链接到可执行文件中的,包含了程序所需的库函数和数据的实际代码。
  • 动态库
    • 动态库也称为共享库,通常以 .so 为后缀(在 Windows 系统中通常是 .dll)。
    • 它包含了可被多个程序共享的库函数和数据的代码,但不会在编译时被复制到可执行文件中,而是在程序运行时被加载。

示意图:

静态库:在这里插入图片描述

动态库:
在这里插入图片描述

三、gcc常用命令

1、基本编译命令

  1. gcc source.c -o executable
    • gcc:调用 GCC 编译器。
    • source.c:要编译的 C 语言源文件。
    • -o executable:指定输出的可执行文件名称为 executable。如果不使用 -o 选项,GCC 会默认生成一个名为 a.out 的可执行文件。

2、编译多个源文件

  1. gcc file1.c file2.c file3.c -o output
    • 可以将多个源文件(如 file1.cfile2.cfile3.c)一起编译,并将生成的可执行文件命名为 output
    • 这对于将程序拆分成多个源文件进行模块化开发时非常有用。

3、添加头文件搜索路径

  1. gcc -I/path/to/headers source.c -o executable
    • -I:指定头文件的搜索路径。在编译时,如果源文件中包含的头文件不在系统默认的搜索路径中,可以使用 -I 来添加额外的搜索路径。
    • /path/to/headers:是你要添加的头文件所在的目录路径。

4、显示警告信息

  1. gcc -Wall source.c -o executable
    • -Wall:启用大多数警告信息。使用该选项可以帮助你发现代码中的潜在问题,如未使用的变量、类型不匹配等。
    • 示例:
    #include <stdio.h>
    int main() {
        int a; // 未使用的变量
        printf("Hello, World!\n");
        return 0;
    }
    
    • 使用 gcc source.c -o executable 可能不会显示任何警告,但使用 gcc -Wall source.c -o executable 会显示未使用变量 a 的警告信息。

5、生成调试信息

  1. gcc -g source.c -o executable
    • -g:生成调试信息,允许使用调试工具(如 gdb)对程序进行调试。
    • 这样,在使用 gdb executable 调试程序时,可以查看源代码、设置断点、查看变量的值等。

6、优化编译

  1. gcc -O[level] source.c -o executable

    • -O-O1:进行基本的优化,提高代码性能。
    • -O2:进行更高级的优化,通常会进一步提高性能,但可能会增加编译时间。
    • -O3:最高级别的优化,可能会导致代码大小增加,但性能可能会有显著提升。
    • 示例:
    #include <stdio.h>
    int main() {
        int i;
        for (i = 0; i < 1000000; i++) {
            // 循环代码
        }
        return 0;
    }
    
    • gcc -O2 source.c -o executable 会对循环等代码进行优化,以提高性能。

7、生成静态库

  1. gcc -c file1.c file2.c
    • -c:只编译源文件,生成 .o 对象文件,不进行链接。
    • ar rcs libname.a file1.o file2.o
    • ar:用于创建、修改或提取静态库。
    • rcsr 表示将对象文件添加到库中,c 表示创建库,如果需要则不显示警告,s 表示创建索引。
    • libname.a:要创建的静态库名称。
    • file1.ofile2.o:编译生成的对象文件。

8、生成动态库

  1. gcc -shared -fPIC file1.c file2.c -o libname.so
    • -shared:生成共享库(动态库)。
    • -fPIC(Position Independent Code):生成位置无关代码,是创建动态库的必要条件,确保代码在不同内存位置加载时能正常运行。
    • libname.so:生成的动态库名称。

9、链接静态库或动态库

  1. gcc source.c -L/path/to/lib -lname -o executable

    • -L:指定库文件的搜索路径。
    • -lname:链接名为 libname.solibname.a 的库,GCC 会自动在 -L 指定的路径和系统默认路径中搜索库文件。
    • 示例:
    #include <stdio.h>
    #include "mylib.h"
    int main() {
        my_function(); // 假设该函数在库中定义
        return 0;
    }
    
    • 如果 mylib 是一个库,gcc source.c -L/path/to/lib -lmylib -o executable 将链接该库。

10、预处理器选项

  1. gcc -E source.c -o source.i
    • -E:只运行 C 预处理器,将源文件展开为 .i 文件,包括头文件展开、宏替换等,不进行编译、汇编和链接。

11、查看汇编代码

  1. gcc -S source.c -o source.s
    • -S:将 C 源文件编译为汇编代码,生成 .s 文件。

这些是 GCC 编译器常用的命令和选项,根据你的需求,可以灵活使用它们来编译、优化、调试 C 语言程序,并管理库文件。不同的选项可以组合使用,以达到更好的开发和调试效果。

注意:

  • 确保使用的编译选项符合你的开发目标,例如,在调试阶段使用 -g 生成调试信息,在发布阶段使用 -O2-O3 进行优化。
  • 对于复杂的项目,使用 MakefileCMake 等构建工具可以更方便地管理编译选项和依赖关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值