编译器背后的故事

可执行程序是如何被组装的?

用gcc生成动态库和静态库

1.编辑并生成hello.h, hello.c和main.c
程序:hello.h
在这里插入图片描述
hello.c
在这里插入图片描述
main.c
在这里插入图片描述
2.将hello.c编译成.o文件

在这里插入图片描述
在这里插入图片描述
3.由.o创建静态库
在这里插入图片描述
4.在程序中使用静态库
在这里插入图片描述
删除静态库试试公用函数hello是否连接到了目标文件hello中
在这里插入图片描述

5.由.o文件创建动态库
在这里插入图片描述
6.在程序中使用动态库
在这里插入图片描述
错误提示找不到libmyhello.so,是因为程序在运行的时候需要在/usr/lib中查找需要的动态文件库,我们将libmyhello.so复制到/usr/lib中再试试
在这里插入图片描述
成功了!这也进一步说明了程序运行的时候需要动态库。那么当静态库和动态库重名的时候gcc会使用哪个文件呢?
先删除出.c .h文件以外的所有文件,恢复到刚刚完成编辑程序的状态
在这里插入图片描述
再创建libmyhello.a的静态文件和libmyhello.so的动态文件
在这里插入图片描述
使用gcc命令使用函数库myhello生成目标文件hello并运行hello
在这里插入图片描述
从结果可知gcc会优先使用动态库

静态库.a与.so库文件的生成与使用

1.创建A1.c , A2.c , A.h , test.c
A1.c
在这里插入图片描述
A2.c在这里插入图片描述
A.h
在这里插入图片描述
test.c在这里插入图片描述

在这里插入图片描述

生成目标文件(xxx.o)
在这里插入图片描述

在这里插入图片描述
生成静态库.a文件在这里插入图片描述
使用.a库文件,创建可执行程序
在这里插入图片描述
共享库.so文件的生成与使用:
生成目标文件
在这里插入图片描述
生成共享库.so文件
在这里插入图片描述
使用.so库文件,创建可执行程序
在这里插入图片描述

在这里插入图片描述
发现了错误,运行ldd test,查看连接情况在这里插入图片描述
发现找不到对应的.so文件,需要将相应的.so文件拷贝到对应的路径
在这里插入图片描述
再次执行在这里插入图片描述

同时,可以直接使用gcc -o test test.c -L. -lname

集合各软件用途的GCC编译工具

linux GCC常用命令

示例程序:
在这里插入图片描述
一步到位的编译指令是:

gcc test.c -o test

实质上,上述编译过程是分为四个阶段进行的,即预处理,编译,汇编和连接

预处理
gcc -E test.c -o test.i 或 gcc -E test.c
编译为汇编代码
gcc -S test.i -o test.s
汇编
gcc -c test.s -o test.o
连接
gcc test.o -o test
多个程序文件的编译

假设有test1.c和test2.c两个源文件组成的程序,为了对他们进行编译并最终生成可执行程序test,可以使用下面这条命令

gcc test1.c test2.c -o test
检错
gcc -pedantic illcode.c -o illcode
gcc -Wall illcode.c -o illcode
gcc -Werror illcode.c -o illcode

pedantic 和Wall都能帮助发现一些错误,而Werror会让GCC在产生警告的地方停止编译

库文件连接

1.首先进行编译test.c为目标文件

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

2.链接
把所有目标文件链接成可执行文件

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

3强制连接是使用静态链接库

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

代码库相关

一些光标库的基本函数功能\

在ubantu安装curses,用到以下指令

sudo apt-get install libncurses5-dev 

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

  • initscr()

    initscr()是一般 curses 程式必须先呼叫的函数, 一但这个函数被呼叫之後, 系统将根据终端机的形态并启动 curses 模式.

  • endwin()
    urses 通常以呼叫 endwin() 来结束程式. endwin() 可用来关闭curses 模式, 或是暂时的跳离 curses 模式.如果您在程式中须要call shell ( 如呼叫 system() 函式 ) 或是需要做 system call,就必须先以  endwin()  暂时跳离  curses 模式.  最后再以wrefresh() doupdate() 来重返 curses 模式.

  • nl()
    nonl()

    用来决定当输入资料时, 按下 RETURN 键是否被对应为 NEWLINE 字元 ( 如 \n ).
    而输出资料时, NEWLINE 字元是否被对应为 RETURN 和 LINDFEED系统预设是开启的.

远古时代的BBS

“控制面板—>程序—>启用或关闭Windows功能”,启用"telnet client" 和"适用于Linux的Windows子系统"在这里插入图片描述

在这里插入图片描述
然后打开一个cmd命令行窗口,命令行输入 telnet bbs.newsmth.net,以游客身份体验一下即将绝迹的远古时代的 BBS (一个用键盘光标控制的终端程序)
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值