嵌入式—编译器背后的故事

一、可执行程序的组装

1.用gcc生成静态库和动态库

(1) 第 1 步:编辑生成例子程序 hello.h、hello.c 和 main.c。
先创建一个作业目录,保存本次练习的文件。

#mkdir test1
#cd test1

然后用 vim文本编辑器编辑生成所需要的 3 个文件。
程序1:

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

程序2:

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

程序3:

#include "hello.h"
int main()
{
hello("everyone");
return 0;
}

在这里插入图片描述

(2) 第 2 步:将 hello.c 编译成.o 文件。
在系统提示符下键入以下命令得到 hello.o 文件。

gcc -c hello.c

我们运行 ls 命令看看是否生存了 hello.o 文件

在这里插入图片描述

在 ls 命令结果中,我们看到了 hello.o 文件

(3) 第 3 步:由.o 文件创建静态库。
创建静态库用 ar 命令。在系统提示符下键入以下命令将创建静态库文件 libmyhello.a。

 ar -crv libmyhello.a hello.o

我们同样运行 ls 命令查看结果:

ls
hello.c hello.h hello.o libmyhello.a main.c

在这里插入图片描述

(4) 第 4 步:在程序中使用静态库。
下面先生成目标程序 hello,然后运行 hello 程序。

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

运行结果
在这里插入图片描述

删除静态库文件

# rm libmyhello.a
rm: remove regular file `libmyhello.a'? y
# ./hello
Hello everyone!
#

在这里插入图片描述

程序照常运行
在 Linux 中创建动态库
(5) 第 5 步:由.o 文件创建动态库文件
在系统提示符下键入以下命令得到动态库文件 libmyhello.so

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

使用is命令

# ls
hello.c hello.h hello.o libmyhello.so main.c

在这里插入图片描述

(6) 第 6 步:在程序中使用动态库

我们先运行 gcc 命令生成目标文件,再运行

# gcc -o hello main.c -L. -lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shar
ed object file: No such file or directory

运行结果
在这里插入图片描述

再来创建静态库文件 libmyhello.a 和动态库文件 libmyhello.so

# gcc -c hello.c
# ar -cr libmyhello.a hello.o (或-cvr )
# gcc -shared -fPIC -o libmyhello.so hello.o
# ls
hello.c hello.h hello.o libmyhello.a libmyhello.so main.c

运行 gcc 命令来使用函数库 myhello 生成目标文件 hello,并运行程序 hello

# gcc -o hello main.c -L. –lmyhello
# ./hello
./hello: error while loading shared libraries: libmyhello.so: cannot open shar
ed object file: No such file or directory

在这里插入图片描述

2.静态库应用

除了x2x函数之外,再扩展写一个x2y函数(功能自定),main函数代码将调用x2x和x2y ;将这3个函数分别写成单独的3个 .c文件,并用gcc分别编译为3个.o 目标文件;将x2x、x2y目标文件用 ar工具生成1个 .a 静态库文件, 然后用 gcc将 main函数的目标文件与此静态库文件进行链接,生成最终的可执行程序,记录文件的大小
(1)建立文件

#gedit sub1.c
#gedit sub2.c
#gedit main.c

在这里插入图片描述

(2)函数的编写
sub1.c

float x2x(float a, float b) {
	return a * b;
}

sub2.c

float x2y(float a, float b) {
	return a - b;
}

main.c

#include<stdio.h>
extern float x2x(float a, float b);
extern float x2y(float a, float b);
int main() {
	float a = 3;
	float b = 2;
	printf("ax2xb=%f\n",x2x(a,b));
    printf("ax2yb=%f\n",x2y(a,b));        
}

(3)编译.o文件并建立连接

#gcc -c sub1.c
#gcc -c sub2.c
#gcc -c main.c
ls

运行结果
在这里插入图片描述
(4)生成静态库文件

#ar -crv 1.a sub1.o sub2.o

程序结果
在这里插入图片描述
文件大小
在这里插入图片描述

3.动态库应用

(1)建立文件

#rm 1.a
#rm sub1
ls

(2)建立动态库文件链接

#gcc -shared -fPIC -o 2.so sub1.o sub2.o

运行结果
在这里插入图片描述

4.总结

以上可见,静态库的文件大小略大于动态库的文件大小

二、Gcc不是一个人在战斗

1.Linux Gcc常用命令

(1)编译

//test.c
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}

(2)预处理

gcc -E test.c -o test.i

运行结果
在这里插入图片描述
(3)编译为汇编代码

gcc -S test.i -o test.s

在这里插入图片描述
(4)汇编

gcc -c test.s -o test.o

在这里插入图片描述
(5)连接

gcc test.o -o test

在这里插入图片描述
(6)多个程序文件的编译
假设有一个由 test1.c 和 test2.c 两个源文件组成的程序,为了对它们进行编译,并最终生成可执行程序 test,可以使用下面这条命令:

gcc test1.c test2.c -o test

如果同时处理的文件不止一个,深究起来,上面这条命令大致相当于依次执行如下三条命令:

gcc -c test1.c -o test1.o
gcc -c test2.c -o test2.o
gcc test1.o test2.o -o test

(7)检错

gcc -pedantic illcode.c -o illcode

除了-pedantic 之外,GCC 还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W 开头,其中最有价值的当数-Wall 了,使用它能够使 GCC 产生尽可能多的警告信息。

gcc -Wall illcode.c -o illcode

在编译程序时带上-Werror 选项,那么 GCC 会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改,如下:

gcc -Werror test.c -o test

运行结果
在这里插入图片描述
(8)库文件连接
编译可执行文件

gcc –c –I /usr/dev/mysql/include test.c –o test.o

连接

gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test

(9)强制链接时使用静态链接库
默认情况下, GCC 在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话可以在编译时加上-static 选项,强制使用静态链接库。
在/usr/dev/mysql/lib 目录下有链接时所需要的库文件 libmysqlclient.so 和 libmysqlclient.a,为了让GCC 在链接时只用到静态链接库,可以使用下面的命令:

gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test

2.nasm安装和应用

(1)安装

sudo apt-get install nasm//安装nasm
nasm -version//查看版本

在这里插入图片描述

(2)应用
编译

nasm -f elf64 hello.asm

连接

ld -s -o hello hello.o

运行

./hello

运行结果
在这里插入图片描述
在这里插入图片描述

nasm比gcc生成的文件要小

三、借助第三方库函数完成代码设计

1.光标库

函数名功能
initscr()初始化curses库和tty
endwin()关闭curses并重置tty
refresh()使屏幕按照你的意图显示
addstr(s)在当前位置画字符串s
addch(c)在当前位置画字符c
clear()清屏

2.BBS

在 win10 系统中,“控制面板”–>“程序”—>“启用或关闭Windows功能”,启用 “telnet client” 和"适用于Linux的Windows子系统"(后面会使用)。 然后打开一个cmd命令行窗口,命令行输入 telnet bbs.newsmth.net,以游客身份体验一下即将绝迹的远古时代的 BBS
在这里插入图片描述

3.安装curses库

代码如下

sudo apt-get install libncurses5-dev

安装完成
在这里插入图片描述

4.贪吃蛇游戏

(1)建立文件
在这里插入图片描述
(2)游戏运行
在这里插入图片描述

四、总结

此次任务较多,实仿较简单,安装过程遇到了一些困难,整个过程持续时间较长。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值