Black学Linux+Gcc、G++与make

本文深入解析GCC编译器的工作流程,包括预处理、编译、链接等关键阶段,阐述如何通过GCC选项控制编译过程,以及make工具在大型项目中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Gcc的编译过程

总过程

  1. 源代码.c文件同头文件.h进入预处理器进行预处理;
  2. 预处理器生成的文件进入编译器进行编译生成编译文件(目标代理.o文件);
  3. .o文件再进入链接器将库代码与.o文件进行链接,生成可执行文件。
  4. 如:gcc -o hello hello.c。hello.c文件生成hello的可执行文件。
  5. 输入命令:ldd hello可以查看该可执行文件链接了那些库文件
  6. 输入命令:nm hello可以看到该可执行文件一共用了哪些函数
  7. gcc只是一个编译器,使用Gcc一定要自己控制这三个部分,而在windows中如VS这么一个IDE中,其将编译的三个部分集成在一起了,所以不用人为去做。

预编译

  1. gcc -o hello.e -E hello.c
  2. 这行代码告诉gcc对源程序hello.c进行预编译,预编译的结果输出到hello.e文件中
  3. 对比hello.c和hello.e文件会发现,hello.e就是把hello.c中头文件的内容全部加载进去

编译

  1. gcc -o hello.o -c hello.c
  2. 只编译不链接,生成的hello.o文件不能执行,因为还没有链接程序当中调用的库函数,hello.o是当前程序机器语言

链接

  1. gcc -o hello hello.c
  2. 生成可执行文件hello,就是对上一步的编译文件进行链接

必要性

  1. 一般情况下预编译不需要干预

  2. 当有多个.c文件一起使用时,需要对这多个.c文件进行编译生成.o文件

  3. 这多个.c文件里面的函数互相调用,所以需要将编译生成的多个.o文件进行链接,生成一个可执行文件

  4. 如有:hello.c add.c add.h文件,add.h文件对add.c里面的函数进行声明,其中hello.c包含add.h头文件,在里面调用了add.c里面的函数,编译过程如下:

    gcc -o hello.o -c hello.c ;
    gcc -o add.o -c add.c ;
    gcc -o hello add.o hello.o ;

Gcc常用选项

Gcc文件类型


C与C++是两种不同的语言,在Gcc的链接过程中默认只链接c的标准库,并不链接C++的标准库,在变异.cpp文件时,需要指定链接的库文件,使用 -l参数:
如:gcc -o hello hello.cpp -lstdc++gcc -lstdc++ -o hello hello.cpp

安装g++

rpm -ivh libstdc++-devel-4.4.6-4.e16.i686.rpm  
rpm -ivh gcc-c++-4.4.6-4.e16.i686.rpm    

C++程序使用g++来编译,以避免gcc默认链接C的标准库

make

make的存在

  1. 除非最简单的项目,任何一个商业项目都会包含多个源代码,而且在编译的时候会有很长很复杂的指令
  2. 编译过程中还需要使用那些很少而且很难记忆的编译选项
  3. make是控制编译或者重复编译软件的工具
  4. make可以自动管理软件的编译内容、方式和时机,从而使程序员把更多的精力集中在编写代码上

make是怎样完成工作的

  1. makefile 是一个文本形式的脚本文件,其中包含一些规则告诉make编译那些文件,怎么样编译以及在什么条件下编译

  2. makefile规则遵守以下通用形式:
    target:dependency [dependency[···]]
    command
    command
    [···]
    每一个command第一个字符必须是tab键,而不是空格键,不然make会报错停止
    target是标号,dependency是依赖关系,make每次只执行第一个标号后的命令,后面的标号如果没有依赖关系不会执行,除非是在make时添加需要执行的标号作为参数

  3. 用vi编辑一个简单的makefile,内容如下:
    start:
    gcc -o hello hello.c
    输入make,makefile的内容就执行了

  4. 稍微复杂一点:
    start:hello.o
    gcc -o hello hello.o
    hello.o:
    gcc -o hello.o -c hello.c
    start是标号,后面的hello.o代表依赖关系,make先执行了hello.o后面的命令,在执行start后面的命令

  5. 进一步完善:
    start:hello.o
    gcc -o hello hello.o
    @echo'-------------OK-----------'
    hello.o:
    gcc -o hello.o -c hello.c
    clean:
    rm -f hello.o
    增加@echo,显示编译成功语句,为了不将语句本身输出,所以前面加@符号
    增加了target clean
    输入make clean,make会直接执行clean其下的command

  6. 为了简化编辑和维护makefile,可以在makefile中使用变量。
     varname=some_text
    把变量用括号括起来,前面加KaTeX parse error: Expected 'EOF', got '&' at position 16: 就可以引用该变量的值。 &̲emsp;(varname)
    按照惯例makefile的变量都是大写(只是习惯而已,不是必须的)。
    在makefile中使用变量:
    CC=gcc
    SRCS=hello.c
    OBJS=$(SRCS:.c=.o)
    EXEC=hello

    start:hello.o
    $(CC) -o $(EXEC) $(OBJS)
    @echo '---------------ok---------------'
    hello.o:
    $(CC) -o $(OBJS) -c $(SRCS)
    clean:
    rm -f hello.o
    增加变量SRCS、OBJS、EXEC,每个引用变量CC的地方的展开成变量的值
    OBJS=$(SRCS:.c=.o),意思是将SRCS变量中的.c替换为.o

  7. 模式规则
    .SUFFIXES:.c .o
    表示任何的x.c文件与x.o关联
    -.c.o:
    表示make定义了一些规则,任何x.o文件都从x.c编译而来
    make定义了一些有用的预定义变量

  8. 在makefile使用自动变量和模式规则的例子
    .SUFFIXES:.c .o ##SUFFIXES是后缀的意思
    CC=gcc
    SRCS=hello.c\
    pub.c
    OBJS=$(SRCS:.c=.o)
    EXEC=hello
    strat:$(OBJS)
    $(CC) -o $(EXEC) $(OBJS)
    @echo'------------OK---------------'
    .c.o:
    $(CC) -o $@ -c $<
    clean:
    rm -f $(OBJS)

  9. 常见的make出错信息:
     No rule to make target ‘target’.Stop
    makefile中没有包含创建指定target所需要的规则,而且也没有默认规则可用。
     ‘target’ is up to date
    指定的target相关文件没有变化。
     command:Command not found
    make找不到命令,通常是因为命令被拼写错误或者不在$PATH路径下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值