LINUX下感受编译器的背后

一、gcc生成静态库和动态库

1.首先创建一个目录

在这里插入图片描述
接着在该目录下编写程序生成hello.h、hello.c、main.c,程序分别为
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
hello.h

#ifndef HELLO_H 
#define HELLO_H 
void hello(const char *name); 
#endif //HELLO_H

hello.c

#include <stdio.h> 
#include "hello.h"
void hello(const char *name) 
{
	printf("Hello %s!\n", name);
}
main.c
#include "hello.h" 
int main() 
{
	hello("everyone"); 
	return 0; 
}

2.将hello.c文件编译成.o文件并使用ls命令进行查看

在这里插入图片描述
在这里插入图片描述

3.由.o文件创建静态库

静态库文件名的命名规范 lib为前缀,紧接着跟静态库名,扩展名为.a。例如:我们将创建的静态库名为 myhello,则静态库文件名就是 libmyhello.a。在创建和使用静态库时, 需要注意这点。创建静态库用 ar 命令。在系统提示符下键入以下命令将创建静态库文件libmyhello.a。
在这里插入图片描述
当看到生成.a文件时就生成成功了。
4.使用静态库
用 gcc 命令生成目标文件时指明静态库名,gcc 将会从静态库中将公用函数连接到目标文件中。
使用以下命令

gcc main.c libmyhello.a -o hello

在这里插入图片描述
最后删除静态库后看一下hello是否真的链接到目标文件中
发现确实是可以的

在这里插入图片描述
5.创建并使用动态库
动态库的后缀名为.so
我们要使用命令

gcc -shared -fPIC -o libmyhello.so hello.o

再进行查看是否生成了.so文件
在这里插入图片描述
这就说明生成动态库成功了
接着在程序中使用动态库,要用以下命令

gcc -o hello main.c -L. -lmyhello

但我们输入./hello后发现运行不起,这是因为运行行 hello程序时在在/usr/lib 中找不到该库文件,我们要输入以下命令

sudo mv libmyhello.so /usr/lib

将文件 libmyhello.so 移动到目录/usr/lib 中,这样就可以运行啦
在这里插入图片描述

二、静态库与动态库生成文件大小

1.编写一个x2x函数,一个x2y函数,main1函数代码将调用x2x和x2y,将这3个函数分别写成单独的3个 .c文件。并用gcc进行编译。
在这里插入图片描述
在这里插入图片描述
程序如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#ifndef MAIN1_H
#define MAIN1_H
float x2x(int a,int b);
float x2y(int a,int b);
#endif//MAIN_H
#include<stdio.h>
float x2x(int a,int b)
{
float c;
c=a+b;
return c;
}
#include<stdio.h>
float x2y(int a,int b)
{
float c;
c=a/b;
return c;
}
#include"main1.h"
#include"stdio.h"
int main()
{
int a,b;
float c,d;
scanf("%d%d",&a,&b);
c=x2x(a,b);
d=x2y(a,b);
printf("c=%f",c);
printf("d=%f",d);
return 0; 
}

2.接着将x2x,x2y函数生成静态文件库并查看

ar -crv libmain1.a x2x.o x2y.o

在这里插入图片描述
3.用gcc将主函数的目标文件与静态库链接,生成可执行文件的大小。

gcc -shared -fPIC -o libmain1.so x2x.o x2y.o
gcc -o main2 main1.c libmain1.so

接着并用ls -la命令查看
在这里插入图片描述
4.使用命令生成动态库

gcc -shared -fPIC -o libmain1.so x2x.o x2
gcc -o main2 main1.c libmain1.so

过程与之前差不多,最后得出动态库的大小,可以发现,静态库比动态库小很多,生成的可执行文件大小也有差别。

三、gcc命令与as汇编编译器

1.gcc应用,按照书上的程序命令进行编译
先对程序进行一些预处理,预编,汇编,再查看一些大小属性之类的。

在这里插入图片描述
2.接着分析ELF文件
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
3.下载安装as汇编编译器
并对给出的程序hello.asm进行编译
在这里插入图片描述
最后程序运行正常。
程序如下:
在这里插入图片描述
再查看一下此文件的大小
在这里插入图片描述

四、第三方库函数

1.光标库(curses)的主要函数功能,curses函数库能够优化光标的移动并最小化需要对屏幕进行的刷新,从而也减少了必须向字符终端发送的字符数目。
清除屏幕:

int erase(void);//在屏幕的每个位置写上空白字符
int clear(void);//使用一个终端命令来清除整个屏幕,相当于vi内的Ctrl+L
//内部调用了clearok来执行清屏操作,(在下次调用refresh时可以重现屏幕原文)

int clrtobot(void);//清除光标位置到屏幕结尾的内容
int clrtoeol(void);//清除光标位置到该行行尾的内容

窗口移动和更新屏幕:

int mvwin(WINDOW *win, int new_y, int new_x);   //移动窗口
int wrefresh(WINDOW *win);
int wclear(WINDOW *win);
int werase(WINDOW *win);
//类似于上面的refresh, clear, erase,但是此时针对特定窗口操作,而不是stdcur

int touchwin(WINDOW *win);     //指定该窗口内容已改变、
//下次wrefresh时,需重绘窗口。利用该函数,安排要显示的窗口
	
int scrollok(WINDOW *win, bool flag);    //指定是否允许窗口卷屏
int scroll(WINDOW *win);   //把窗口内容上卷一行

移动光标:

int move(int new_y, int new_x);    //移动stdcsr的光标位置
int leaveok(WINDOW *window_ptr,bool leave_flag);
//设置一个标志,用于控制在屏幕刷新后curses将物理光标放置的位置。

安装couses库
使用命令

sudo apt-get install libncurses5-dev

curses函数库的头文件和库文件就被分别安装在/usr/include/和/usr/lib/下

最后贪吃蛇游戏代码链接
http://www.linuxidc.com/Linux/2011-08/41375.htm

总结:在此次试验中,我清晰的感受到了一个程序的编译的全过程,并且自己亲手创建了静态库和动态库并比较大小,收获颇丰,感谢老师。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值