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

目录

 gcc|g++ 

程序翻译

 预处理

编译 

汇编 

链接 

动静态库 

动态链接|静态链接 

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

构建项目

清理项目 

 makefile|.PHONY

Linux下进度条实现


 

 gcc|g++ 

输入gcc -v和g++ -v

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

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

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

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

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

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

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

程序翻译

 我们给test.c书写代码

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

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

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

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

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

 预处理

 gcc -E mytest.c -o mytest.i 

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

我们比较俩个文件

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

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

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

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

编译 

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

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

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

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

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

汇编 

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

gcc -c mytest.s -o mytest.o

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

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

 

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

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

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

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

链接 

输入gcc mytest.o -o mytest

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

  

动静态库 

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

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

 圈出来的是用动态库

 动态链接:需要动态库

静态链接:需要静态库

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

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

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

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

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

库提供C语言方法的实现

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

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

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

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

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

动态链接|静态链接 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

构建项目

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

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

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

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

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

我们进入makefile之后,编写makefile

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

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

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

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

 退出后查看

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

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

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

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

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

清理项目 

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

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

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

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

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

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

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

对原代码做修改

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

 重新清理,再重新构建

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

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

 makefile|.PHONY

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

 我们修改顺序

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

 make,默认执行clean

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

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

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

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

,而make clean可以多次执行

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

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

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

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

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

我们一般只给clear使用.PHONY

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

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

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

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

stat可查看三个时间

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

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

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

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

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

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

test.h

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

 test.c

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

 main.c

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

 运行这些代码

 运行结果

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

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

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

对makefile重新编辑 

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

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

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

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

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

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

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

 我们点击生成解决方案

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

 文件内容变多

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

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

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

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

Linux下进度条实现

 创建一个pro.c和makefile文件

运行pro.c,先printf后sleep

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

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

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

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

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

如果想立即刷新就要用fflush

这样就是先打印,再sleep

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

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

 回车和换行不是一回事

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

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

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

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

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

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

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

#include 
#include 
#include 

#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;
}

你可能感兴趣的:(Linux,linux,服务器,c++)