• 【Linux】gcc的使用和makefile


    1.gcc编译工具

    格式 :gcc [选项] 要编译的文件 [选项] [目标文件]

    1.1预处理

    • 预处理的功能主要包括宏定义替换,文件包含,条件编译,去注释
    • 预处理指令是以#号开头的代码行
    • gcc -E hello.c -o hello.i
    • 选项E,改选项的作用是让gcc在预处理结束后停止编译过程
    • 选项 -o是指目标文件,".i"文件为已经处理过的C原始程序。

    生成project.cpp文件

    image-20220626013306209

    $ g++ -E project1.cpp -o project1.i
    
    • 1

    image-20220626013500900

    1.2编译(生成汇编)

    • 在这个阶段,gcc/g++需要检查代码的规范性,语法错误。无错误后翻译为汇编代码
    • 形成符号表
    • 在编译过程中,.i文件生成为.s文件。
    • 实例:gcc/g++ -S hello.i -o hello.s
    $ g++ -S project1.i -o project1.s
    #生成.s文件
    
    • 1
    • 2

    image-20220626013621924

    1.3汇编(生成机器码)

    • 汇编阶段是编译阶段生成的.s文件转成.o文件
    • 汇总符号表
    • 实例:gcc/g++ -c hello.s -o hello.o
    • 二进制文件不可执行
    $ g++ -c project1.s -o project1.o
    #如果是 -C(大写),那么会直接生成可执行文件
    
    • 1
    • 2

    image-20220626013802602

    这一步仅仅只是将自己写的程序转换为二进制,其中的库函数等需要在链接过程中生成二进制码。

    1.4链接(生成可执行文件或库文件)

    • 在成功编译之后进入链接阶段
    • 实例:gcc/g++ hello.o -o hello
    $ g++ project2.o -o project2
    $ ./project2
    hello world
    
    • 1
    • 2
    • 3

    1.5查看链接库(ldd 可执行程序)

    #project2是可执行程序
    $ ldd project2
    	linux-vdso.so.1 =>  (0x00007ffe2b5dd000)
    	/$LIB/libonion.so => /lib64/libonion.so (0x00007f495b4f9000)
    	libstdc++.so.6 => /home/west/.VimForCpp/vim/bundle/YCM.so/el7.x86_64/libstdc++.so.6 (0x00007f495b05f000)
    	libm.so.6 => /lib64/libm.so.6 (0x00007f495ad5d000)
    	libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f495ab47000)
    	libc.so.6 => /lib64/libc.so.6 (0x00007f495a779000)
    	libdl.so.2 => /lib64/libdl.so.2 (0x00007f495a575000)
    	/lib64/ld-linux-x86-64.so.2 (0x00007f495b3e0000)
    # .so表示动态库		.a标记静态库
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在linux中库真正的名字是:去掉前缀lib,去掉后缀.xxx,剩下的是库的名字

    libstdc++.so.6 的库名是stdc++ (去掉前缀lib,后缀.so.6);

    libc.so.6的库名是 c(去掉前缀lib,去掉后缀.so.6)

    多文件的情况,最好是将多文件统一编译为多个.o文件,最好生成一个可执行文件

    2.Linux项目自动化构建工具-make/Makefile

    make是命令,makefile是一个文件

    $ touch main.c test.c test.h
    
    • 1

    以下面的程序为例:

    image-20220626215603169

    编写makefile文件

    image-20220626230911291

    $ ls
    main.c  makefile  test.c  test.h
    $ make
    gcc main.c test.c -o mybin
    $ ls
    main.c  makefile  mybin  test.c  test.h
    #通过make命令就生成了mybin可执行程序
    #运行该可执行程序
    $ ./mybin
    0 1 2 3 4 5 6 7 8 9 
    #删除该程序
    $ make clean
    rm -f mybin
    $ ls
    main.c  makefile  test.c  test.h
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    2.1makefile文件的编写

    .PHONY:mybin   #表示mybin可以总是执行
    mybin:main.c test.c  #顶行-------依赖关系
         gcc main.c test.c -o mybin #TAB键开头-----依赖方法
         
    .PHONY:clean  #顶行------表示可以无障碍运行
    clean:        #顶行-----伪目标
         rm -f mybin   #TAB键-----方法
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    1.依赖关系:

    mybin:main.c test.c表示的是依赖关系,表示可执行程序mybin依赖main.c和test.c

    2.依赖方法

    gcc main.c test.c -o mybin表示依赖方法:生成mybin可执行程序的方法

    .PHONY:clean  #顶行
    clean:        #顶行
         rm -f mybin   #TAB键
    
    • 1
    • 2
    • 3

    .PHONY:可以理解为makefile的关键字,.PHONY:clean表示伪目标,伪目标总是被执行,表示依赖关系是否可以无障碍运行。

    2.makefile的执行

    mybin:main.c test.c  #顶行  依赖关系
         gcc main.c test.c -o mybin #TAB键开头   依赖方法
    .PHONY:clean  #顶行
    clean:        #顶行
         rm -f mybin   #TAB键
    
    • 1
    • 2
    • 3
    • 4
    • 5

    makefile默认的执行顺序为从上往下执行,且生成一个默认的可执行文件。在这里默认生成的可执行文件为mybin,所以执行clean的时候需要指令make clean跳转至程序clean

    2.3函数写法

    同样是上面的文件和程序

    makefile文件
    
    mybin:main.o test.o  #依赖关系
    	gcc $^ -o $@      #依赖方法
    # ^表示上方的使用依赖文件,@表示可执行文件
    #main.o:main.c
    #	gcc -c main.c   #生成同名的.o文件
    #test.o:test.c
    #	gcc -c test.c   #生成同名的.o文件
    ########简写#########
    %.o:%.c
    	gcc -c $<
    ####批量生成.o文件####
    .PHONY:clean
    clean:
    	rm -f *.o mybin  #删除所有的.o文件和mybin
    
    
    ###########第二种写法############
    mybin:main.c test.c
    	gcc $^ -o $@
    .PHONY:clean
    clean:
    	rm -f mybin
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    最后的makefile文件

    #mybin:main.o test.o  #依赖关系
    mybin:*.c      #依赖文件列表是该目录下所有的.c文件
    	gcc $^ -o $@      #依赖方法
    # $^代表依赖文件列表  $@目标文件
    ###########伪目标的声明############
    %.o:%.c
    # %.c:当前目录下所有文件的.c文件 
    # %.o:对应.c形成的.o文件
    	gcc -c $<
    # $<:将%.c代表的源文件一个一个拿出来,用gcc编译生成对应的.o文件(这里的选项是-c所以生成.o文件)
    .PHONY:clean
    clean:
    	rm -f *.o mybin  #  *.o表示所有的.o文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    TST嘉硕车规晶振应用场景大全|KOYUELEC光与电子
    Leetcode24-两两交换链表中的节点详解
    抖音seo矩阵系统源码开发开源型私有化部署方案
    【毕业设计源码】基于微信小程序的特产商城系统设计与实现
    预测足球世界杯比赛
    uniapp音频加进度条加蓝牙ibecon设备搜索
    详解 Apache SkyWalking OAP 的分布式计算
    Vue3使用dataV报错问题解决
    树形DP 复习笔记
    some和every
  • 原文地址:https://blog.csdn.net/qq_53893431/article/details/125476833