【Linux】gcc/g++配置

前言

这是我自己学习Linux系统编程的第三篇笔记。后期我会继续把Linux系统编程笔记开源至博客上。 上一期笔记是关于Linux的Vim文本编辑器:

编译链接的过程

1. 编译链接的过程预处理---> 编译---> 汇编---> 连接 。 2. 预处理阶段头文件展开宏替换去除注释 。 3. 编译阶段生成汇编语言 。 4. 汇编阶段生成二进制的目标文件。 5. 链接阶段生成一个可执行程序

1. 预处理指令gcc -E xxx.c -o xxx.i 2. 编译阶段指令gcc -S xxx.i -o xxx.s 3. 汇编阶段指令gcc -c xxx.s -o xxx.o 4. 链接阶段指令gcc xxx.o -o xxx

动静态库

1. 分为动态库静态库。 2. 在Linux下,动态库类型为libxxx.so静态库类型为libxxx.a。 3. 使用动态链接需要动态库,使用静态链接需要静态库。 4. Linux一般只会存在动态库静态库需要自己去下载安装。 5. 安装静态库的指令sudo yum install glibc-static libstdc++-static -y 6. 静态库存在两个缺点一个优点

  • 浪费空间(缺点) :静态库在使用时,会将库中被引用的代码完整地复制到最终生成的可执行文件中。如果多个程序都使用了同一个静态库,那么每个程序都会各自包含一份该库的副本。
  • 更新困难(缺点) :静态库的代码是直接嵌入到可执行文件中的,因此在库被更新后,所有依赖该库的程序都需要重新编译并链接新的库版本,才能使用更新后的功能。
  • 不依赖库(优点)

7. 动态库是共享的,一旦丢失,所有依赖动态库的程序都会出错。

动静态链接

1. 实际开发中,可能会存在多个 .c 文件,这些 .c 文件之间存在多种依赖关系,如函数调用等。但是每个 .c 文件都是独立进行编译产生对应数量的 .o 文件。所以为了满足这种依赖关系,则需要将这些 .c 文件产生的 .o 文件进行链接,从而形成一个可执行程序。这个链接的过程就是静态链接。 2. 动态链接编译时也会将每个 .c 文件编译为 .o 文件。但与静态链接不同,这些 .o 文件在链接阶段并不会直接包含库函数的具体实现,而是记录对动态链接库的引用。当程序运行时,操作系统的动态链接器会根据这些引用加载相应的动态库到内存,并完成符号解析和绑定,使得程序能够调用库中的函数。 3. gcc默认生成的可执行程序是通过动态链接的方式构建的如果需要生成静态链接的可执行程序则必须显式地使用gcc-static选项,强制链接器将所有依赖的库函数直接嵌入到最终的可执行文件中,从而避免运行时对动态库的依赖。

Make/Makefile

make/makefile定义

1. make是一个命令makefile是一个文件。 2. make执行时,会自顶向下扫描makefile文件并默认将makefile文件中定义的第一个目标作为最终构建的目标。如果需要构建其他特定的目标文件,则可以通过命令行显式指定目标名称,即使用 make targetfile 的方式来生成指定的目标。 3. makefile文件中的注释用 #

配置基本的makefile文件

vim makefile使用vim文本编辑器配置makefile文件

  1. mytest:--->目标文件,1.c--->依赖文件列表
  2. gcc 1.c -o mytest --->依赖方法
  3. .PHONY:clean ---> 伪目标(伪目标的依赖方法总是会被执行)忽略对比时间
  4. clean:--->目标文件
  5. rm -f mytest--->依赖方法

1. 使用make命令时,初次运行会依据makefile中定义的规则编译第一个目标文件。后续执行make时,若该目标文件存在且其依赖的源文件未更新则不会重新编译,直接认为目标文件是最新的。 2. 系统通过对比源文件Modify时间可执行程序Modify时间从而判断源文件是否更新。 3. 伪目标的依赖方法总是会被执行因为其并不需要判断文件是否更新

make自动推导机制

1. make会在当前目录下寻找名为Makefilemakefile的文件。如果找不到会报错退出。 2. 在找到Makefilemakefile文件后,make会默认以文件中的第一个目标作为最终构建目标。 3. 如果目标文件不存在make会尝试根据规则生成它;如果目标文件存在但依赖文件比目标文件新,则认为目标文件已过期,需要重新生成。 4. 如果某个依赖文件不存在或过期make会继续查找是否有规则可以生成该依赖文件,直到所有依赖都被满足。 5. 当所有依赖都满足时make会执行与目标相关的命令来生成目标文件。 6. 如果某个依赖文件缺失且没有规则生成它,make会报错并退出。

配置通用的makefile文件

1. makefile文件中也可以定义变量,后面在使用变量时需要使用 $(variable) 的形式。 2. makefile文件中的命令执行后默认回显,如果不需要回显则在命令前面加上@

代码语言:javascript代码运行次数:0运行复制
BIN=mytest                                                                        
SRC=$(shell ls *.c)                                  
OBJ=$(SRC:.c=.o)                   
CC=gcc            
RM=rm -f                                      
                                      
$(BIN):$(OBJ)            
    $(CC) $(OBJ) -o $(BIN)                                                                                                                                                                    
.PHONY:clean           
clean:
    $(RM) $(OBJ) $(BIN)                                           

编写系统程序---进度条

回车与换行

1. 回车返回到这一行的行首。 2. 换行直接跳到下一行并不会回到行首。 3. C/C++中的\n兼具有回车换行的功能。

缓冲区

1. 向显示器打印信息时,只有强制刷新或者程序运行结束之后才会执行。 2. \n兼具有强制刷新的功能。 3. fflush(stdout)函数可以强制刷新当前显示器

完整代码

test.h
代码语言:javascript代码运行次数:0运行复制
 #include <stdio.h>
#include <unistd.h>

void flush_progress(double total,double current);   
test.c
代码语言:javascript代码运行次数:0运行复制
#include "test.h"

void flush_progress(double total,double current)
{
    char nums[1001]={0};
    double rate=(current*100/total);                                                 
    int num=(int)rate;                               
    int i=0;                          
    for(i=0;i<num;i++)
    {                                         
        nums[i]='#';                                                                                                                                                                          
    }                  
    printf("[%-100s][%.2lf%%]\r",nums,rate);
    fflush(stdout);    
}
main.c
代码语言:javascript代码运行次数:0运行复制
#include  "test.c"
double total=1024.0;
double speed=2.0;
double current=0;

void download()
{
    while(current<=total)
    {
        flush_progress(total,current);                                                                                                                                                        
        usleep(40000);
        current+=speed;
    }
    printf("\n");
}

int main()
{
    download();
    return 0;
}

致谢

感谢您花时间阅读这篇文章!如果您对本文有任何疑问、建议或是想要分享您的看法,请不要犹豫,在评论区留下您的宝贵意见。每一次互动都是我前进的动力,您的支持是我最大的鼓励。期待与您的交流,让我们共同成长,探索技术世界的无限可能!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2025-04-30,如有侵权请联系 cloudcommunity@tencent 删除linuxgcc编译程序配置