Linux—— gcc|g++|程序翻译|预处理编译|汇编|链接|动静态库 动态链接|静态链接|Linux项目自动化构建工具-make/Makefile构建项目

发布于:2022-12-13 ⋅ 阅读:(4962) ⋅ 点赞:(5)

目录

 gcc|g++ 

程序翻译

 预处理

编译 

汇编 

链接 

动静态库 

动态链接|静态链接 

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

构建项目

清理项目 

 makefile|.PHONY

Linux下进度条实现


 

 gcc|g++ 

输入gcc -v和g++ -v

 如果没有g++,输入sudo yum install -y gcc-c++,即可安装

默认的enonos7.6or8 默认匹配的gcc版本是4.8

gcc是一个专门用来编译链接c语言的编译器g++(c++),g++可以编译C或C++,gcc只能编译C

查看gcc或g++版本gcc/g++ -v

程序翻译

 我们给test.c书写代码

 

 推出后输入gcc mytest.c -o mytest或gcc -o mytest mytest.c,这个操作是把文本文件一步变成可执行程序

 mytest可以看到是一堆二进制命令

 预处理

 gcc -E mytest.c -o mytest.i 

把预处理的文件写到mytest.i中,-E选项从现在开始进行程序的翻译,如果预处理完成,就停下来

我们比较俩个文件

 这是把头文件的内容拷贝到了原文件中,这里看到的大多是头文件内容,有的头文件里面又有其它的头文件

进行了宏替换,去注释,条件编译,头文件展开

编译 

 输入gcc -S mytst.i -o mytest.s

-S从现在开始进行程序的翻译,如果编译完成就停下来

 

 打开后mytest.s全是汇编语言

汇编 

把汇编语言转换成二进制文件

gcc -c mytest.s -o mytest.o

-c:从现在开始进行程序翻译,如果汇编完成就停下来

mytest.o文件叫可重定向目标文件,这个重定向跟之前学过的那个重定向没有一点关系

 

 打开后长这样,这个文件不能被执行

 这个文件叫可重定位二进制文件

链接 

输入gcc mytest.o -o mytest

 

  

动静态库 

 ldd和file可查看依赖的库文件

 圈出来的是用动态库

 动态链接:需要动态库

静态链接:需要静态库

给文件写这样一份代码,注意没有头文件

 虽然没有头文件但是能编译过,这是因为头文件在linux中/lib64这个位置,能编译完成是因为依赖于库文件

 头文件提供C语言的方法列表,方法的声明

库提供C语言方法的实现

自己写的程序包含头文件,使用头文件提供的方法,链接库文件,最终形成了可执行程序

Linux:.so(动态库) .a(静态库)

Windows:.dll(动态库) .lib(静态库)

安装vs2019/2022时,同时会安装库文件

C程序是脱离不开库文件的

动态链接|静态链接 

 链接:把自己的目标文件和库文件链接起来

静态链接:将库中方法的实现,拷贝到我们的可执行程序中

动态链接:将库中方法的地址,填入到我们的可执行程序中,建立关联

静态的方法会占用资源,动态节省资源

我们所用的库存在这个位置

 gcc/g++默认形成的可执行程序是动态链接的,若想静态链接输入gcc mytest.c -o mytest -static就能达到静态链接的效果,下图是动态链接

 -satic:表面使用静态链接的方法,形成可执行程序

vs下编译的程序是动态链接

输入:sudo yum install -y glibc-static安装C静态库

           sudo yum install -y libstdc++-static安装C++静态库

 我们可以看到静态库比动态库大很多

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

构建项目

make是一个命令,makefile是一个文件

创建一个makefile文件,可首字母大写,也可首字母小写

 

 makefile:1.依赖关系2.依赖方法

编写makefile是为了构建项目,即使用makefile把我们的原代码编译自动形成可执行程序

我们进入makefile之后,编写makefile

我们要生成mytest,mytest的生成依赖于test.c,目标文件:依赖文件列表

 第二行是依赖方法,要以tab开头

 退出后查看

 如果想编译test.c,我们直接输入make就行

输入make后会自动调用我们刚才所写的依赖方法

 

清理项目 

清理文件也要写一个依赖关系,名字随便取,这里取clean,依赖文件列表可以不依赖任何文件,这里为空

 PHONY是一个关键字,让clean成为伪目标

mytest和clean是目标,如果被PHONY修饰后就是伪目标

 写好后,如果想直接清理项目 输入make clean

 如果想形成可执行程序,直接make

对原代码做修改

 重新清理,再重新构建

 

 makefile|.PHONY

 

 我们修改顺序

 make,默认执行clean

 输入make mytest,才会生成mytest文件

 makefile自顶向下扫描只会帮我们执行第一个遇到的目标文件

.PHONY叫做伪目标,伪目标特点:总是被执行的

我们把顺序调回来,多次输入make,我们发现只执行一次make

,而make clean可以多次执行

 

 如果让.PHONY修饰mytest,make mytest就可以多次执行

 所以被.PHONY修饰的是总被执行的,根据依赖关系,执行依赖方法,

我们一般只给clear使用.PHONY

去掉.PHONY后这个报错是,文件已经是最新的

 当修改test.c之后,又能执行make了

 这是因为:makefile是通过得知文件的修改时间来确定程序是否是最新的

stat可查看三个时间

 Access:文件最近被访问的时间

Modify:文件最近的修改内容时间

Change:文件属性的变化时间,如权限变化,大小

makefile是通过比较原文件test.c和可执行程序mytest的时间来确定makefile是否执行make

,test.c的建立时间一定比mytest的建立时间要早

test.h

 test.c

 main.c

 运行这些代码

 运行结果

 我们一般让.c文件编译成.o文件,然后再加上动态库libc.so,之后合并连接,形成可执行

对makefile重新编辑 

 

make的时候会进行顺序的调整,我们加上清理步骤

 

 make和clean相当于vs中生成和清理解决方案

 我们点击生成解决方案

 文件内容变多

 点清理解决方案,变成这样

 文件里面的obj文件,形成了exe程序(可执行程序)

Linux下进度条实现

 创建一个pro.c和makefile文件

运行pro.c,先printf后sleep

 删掉\n之后,执行程序我们看到的是先执行sleep后再打印

 这是因为程序按顺序执行了printf只不过信息没有被立马显示出来,这是因为C语言是会给我们提供输出缓冲区的,根据特定的刷新策略来进行刷新。

输出缓冲区可以理解成C语言给我们提供的一段内存空间

显示器设备,一般的刷新策略是行刷新,碰到\n,就把\n之前的所有字符全部显示出来

如果想立即刷新就要用fflush

这样就是先打印,再sleep

stdout标准输出,这就是打印完立刻刷新

 回车和换行不是一回事

回车:将写入的位置回到下一行的最开始\r

换行:回到下一行的该位置\n

 加上\r,没有刷新是因为被放到了缓冲区当中,加上fflush之后可以显示

 这样就写了一个倒计时程序

 接下来,我们写一个进度条

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define NUM 102

int main()
{
    char bar[NUM];
    memset(bar, 0 ,sizeof(bar));
    const char *lable="|/-\\"; //4符号
    int cnt = 0;
    while(cnt <= 100)
    {
        printf("[%-100s][%d%%] %c\r", bar, cnt, lable[cnt%4]);
        bar[cnt++] = '#';
        fflush(stdout);
        usleep(30000);
    }
    printf("\n");
    return 0;
}

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到