目录
- 用 gcc 生成 .a 静态库和 .so 动态库
- Linux下静态库.a与.so库文件的生成与使用
- LinuxGCC常用命令
- GCC编译器背后的故事
- Linux 系统中终端程序最常用的光标库(curses)的主要函数
- 参考资料
用 gcc 生成 .a 静态库和 .so 动态库
- 先创建一个目录,保存本次的文件。
- 然后用gedit文本编辑器生成下面三个文件。
- 用gcc -c指令吧hello.c文件编译成.o文件,可以用ls 指令看看是否生成了hello.o文件
- 由.o文件创建静态库
用ar指令创建静态库,同样我们用ls指令查看结果。
- 第四步,在程序中使用静态库
可以使用以下方法在程序中使用静态库。
我们可以删除静态库文件试试公用函数hello是否真的连接到目标文件hello中了
- 第五步,由.o创建动态库文件
输入以下命令创建动态库:
同样的,用ls指令查看是否创建成功: - 第六步,在程序中使用动态库
我们先运行gcc命令生成目标文件,再运行它看看结果。
但是接下来./hello会提示出错,因为虽然连接时用的是当前目录的动态库,但是运行时,是到usr/lib中找库文件的,将文件libmyhello.so复制到目录/usr/lib中就OK了。
我们将文件libmyhello.so复制到目录/usr/lib中,就会成功了。
这说明了动态库在程序运行时是需要的。我们会过头看着过程,发现使用静态库和使用动态库编译成目标程序使用的gcc命令完全一样。那当静态库和动态库同名时,gcc命令会使用哪个库文件呢?抱着对问题必究到底的心情,继续下一步。 - 先删除除.c和.h外的所有文件,恢复成我们刚刚编辑完举例程序状态
- 再来创建静态库文件libmyhello.a和动态库文件libmyhello.so。
然后,我们运行gcc命令来使用函数库myhello生成目标文件hello,并运行程序hello。
从程序hello运行的结果中很容易知道,当静态库和动态库同名时,gcc命令将优先使用动态库,默认去连/usr/lib和/lib等目录中的动态库,将文件libmyhello.so复制到目录/usr/lib中即可。
Linux下静态库.a与.so库文件的生成与使用
- 先创建一个目录:
然后分别用gedit文本编辑器编辑生成所需要的四个文件A1.c、A2.c、A.h、test.c四个文件。
- 静态库.a的生成和使用
a.生成目标文件
b.生成静态库.a文件
c.使用.a库文件,创建可执行程序
3.共享库.so文件的生成与使用
a.生成目标文件(xxx.o)(此处生成.o文件必须添加"-fpic"(小模式,代码少),否则在生成.so文件时会出错)
b.生成共享库.so文件
c.使用.so库文件,创建可执行程序
发现出现错误,运行ldd test,查看连接情况
发现确实是找不到对应的.so文件。这是由于linux自身系统设定的相应的设置的原因,即其只在/liband/usr/lib下搜索对应的.so文件,故需将对应so文件拷贝到对应路径。
再次运行,即可成功。
LinuxGCC常用命令
示例程序:
这个程序,一步到位的编译指令是:gcc test.c- o test
实质上,上述编译过程是分为四个阶段进行的,即预处理、编译、汇编和连接。
- 预处理
gcc -E test.c-o test.i或gcc -E test.c
- 编译为汇编代码,预处理之后,可直接对生成的test.i文件编译,生成汇编代码:
gcc -Stest.i -o test.s
- 汇编:对于之前生成的汇编代码文件test.s,gas汇编器负责将其编译为目标文件,如下:
gcc-c test.s -o test.o
、 - 连接:对于之前生成的test.o,将其与C标准输入输出库进行连接,最终生成程序test,代码如下:
gcc test.o- o test
-多个文件的编译
通常整个程序是由多个源文件组成的,相应地也就形成了多个编译单元,使用GCC能够很好地管理这些编译单元。假设有一个由testa.c和tesb.c两个源文件组成的程序,为了对它们进行编译,并最终生成可执行程序test,可以使用下面这条命令:gcc testa.c testb.c -o test
如果同时处理的文件不止一个,GCC仍然会按照预处理、编译和链接的过程依次进行。 - 检错
gcc -pedantic illcode.c -o illcode
gcc-Wallillcode.c-oillcode
- 库文件链接
首先我们要进行编译test.c为目标文件,这个时候需要执行
gcc –c –I /usr/dev/mysql/include test.c –o test.o
最后我们把所有目标文件链接成可执行文件:
gcc –L /usr/dev/mysql/lib –lmysqlclient test.o –o test
- 强制链接时使用静态链接库
在/usr/dev/mysql/lib目录下有链接时所需要的库文件libmysqlclient.so和libmysqlclient.a,为了让GCC在链接时只用到静态链接库,可以使用下面的命令:
gcc –L /usr/dev/mysql/lib –static –lmysqlclient test.o –o test
GCC编译器背后的故事
- 准备工作
编写一个test4.c如下:
1.预处理:
2.编译:
3.汇编:
或者
4.链接
动态链接
可用size指令查看大小
如果使用命令“gcc -s tatic Hello.c -o Hello
”则会使用静态库进行链接也可以用size查看大小
分析ELF文件
LF文件格式如下图所示,位于ELFHeader和SectionHeaderTable之间的都是段(Section)。一个典型的ELF文件包含下面几个段:
.text:已编译程序的指令代码段。
.rodata:ro代表readonly,即只读数据(譬如常数const)。
.data:已初始化的C程序全局变量和静态局部变量。
.bss:未初始化的C程序全局变量和静态局部变量。
.debug:调试符号表,调试器用此段的信息帮助调试。可以使用readelf -S
查看其各个section的信息。
反汇编ELF
由于ELF文件无法被当做普通文本文件打开,如果希望直接查看一个ELF文件包含的指令和数据,需要使用反汇编的方法。使用objdump-D对其进行反汇编如下:objdump -D Hello
使用objdump-S将其反汇编并且将其C语言源代码混合显示出来:gcc -o Hello -g Hello.c ,objdump -S Hello
Linux 系统中终端程序最常用的光标库(curses)的主要函数
- 功能一、初始化和重置函数(以initscr函数开始,以endwin函数结束)
WINDOW *initscr(void); //在一个程序中只调用一次
int endwin(void);
- 功能二、键盘模式功能
int echo();//用于开启键盘输入字符
int noecho(); //用于关闭键盘输入字符
int cbreak(); //设置cbreak模式,字符一键入,直接传给程序
int nocbreak(); //关闭
int raw(); //关闭特殊字符处理
int noraw(); //同时h恢复默认模式和特殊字符处
int getch();//读取一个字符
int getstr(char *string);//读取一个字符串
- 功能三、管理屏幕功能
int addch(const chtype char_to_add);//当前位置添加字符
int addchstr(chtype *const string_to_add);//当前位置添加字符串
int printw(char *format, ...);//输出
int refresh(void);//刷新物理屏幕
int box(WINDOW *win_ptr, chtype vertical, chtype horizontal);//围绕窗口绘制方框
int insch(chtype char_to_insert); //插入一个字符(已有字符后移)
int insertln(void); //插入空白行
int delch(void);//删除光标左边的字符
int deleteln(void); //删除空白行
int beep(void); //终端响铃
int flash(void); //闪烁
chtype inch(void); //返回光标位置字符
int instr(char *string); //读取字符到string所指向的字符串中
int innstr(char *string, int numbers);//读取numbers个字符到string所指向的字符串中
int erase(void);//在屏幕的每个位置写上空白字符
int clear(void);//清除整个屏幕
int clrtobot(void);//清除光标位置到屏幕结尾的内容
int clrtoeol(void);//清除光标位置到该行行尾的内容
int move(int new_y, int new_x); //移动stdcsr的光标位置
int leaveok(WINDOW *window_ptr,bool leave_flag);//设置一个标志,用于控制在屏幕刷新后curses将物理光标放置的位置。
int attron(chtype attribute);//启用某属性
int attroff(chtype attribute);//关闭某属性
int attrset(chtype attribute);//设置某属性
int standout(void);//启动standout模式
int standend(void);//关闭standout模式
- win10下的远古时代的 BBS
在 win10 系统中,“控制面板”–>“程序”—>“启用或关闭Windows功能”,
启用 “telnet client” 和"适用于Linux的Windows子系统"(后面会使用)。
然后打开一个cmd命令行窗口,命令行输入 telnet bbs.newsmth.net,以游客身份体验一下即将绝迹的远古时代的 BBS (一个用键盘光标控制的终端程序)。
安装curses库
在Ubuntu中可以用 sudo apt-get install libncurses5-dev
安装curses库
头文件(比如curses.h)和库文件都被安装到的目录:
参考资料
chrome-extension://ibllepbpahcoppkjjllbabhnigcbffpi/http://d0.ananas.chaoxing.com/download/94fdef0ff9306a1d78c5d95704d1e248?fn=Linux+GCC%E5%B8%B8%E7%94%A8%E5%91%BD%E4%BB%A4&mt=
chrome-extension://ibllepbpahcoppkjjllbabhnigcbffpi/http://d0.ananas.chaoxing.com/download/dc36405faf8e7dc66d657fcc6b780cd7?fn=%E7%94%A8gcc%E7%94%9F%E6%88%90%E9%9D%99%E6%80%81%E5%BA%93%E5%92%8C%E5%8A%A8%E6%80%81%E5%BA%93&mt=
chrome-extension://ibllepbpahcoppkjjllbabhnigcbffpi/http://d0.ananas.chaoxing.com/download/dc36405faf8e7dc66d657fcc6b780cd7?fn=%E7%94%A8gcc%E7%94%9F%E6%88%90%E9%9D%99%E6%80%81%E5%BA%93%E5%92%8C%E5%8A%A8%E6%80%81%E5%BA%93&mt=
chrome-extension://ibllepbpahcoppkjjllbabhnigcbffpi/http://d0.ananas.chaoxing.com/download/b9616c5b28b9b0b12e4df8411148087e?fn=GCC%E7%BC%96%E8%AF%91%E5%99%A8%E8%83%8C%E5%90%8E%E7%9A%84%E6%95%85%E4%BA%8B&mt=
https://blog.youkuaiyun.com/qq_44644740/article/details/109090003