Linux系统编程
Chapter 1 系统编程入门
GCC
-
区别GCC与G++
- gcc既能编译c,也能编译c++。只不过gcc在链接的时候,不能自动链接C++的库。在编译阶段,g++会调用gcc,二者是等价的。
__cplusplus
宏:g++编译 .c 文件时会定义,按照严谨的cpp语法去执行;gcc编译 .cpp 文件时也会定义。gcc -lstdc++
即可解决gcc链接不了c++库的问题
-
-D
选项,可以指定一个编译时后的宏,可以方便调试。比如调试版本和release版本,就不用删除log了
静态库与动态库
静态库
# 编译,得到目标文件
gcc -c tes1.c tes2.c
# 打包成静态库: -r插入 -c -s起名
ar -rcs libxxx.a tes1.o tes2.o
# 使用:指定库名、库位置、头文件
gcc -o demo tes1.o tes2.o -l xxx -L ./lib -I ./include
-
优点:
- 加载速度快,因为打包到程序里面了
- 发布无需额外提供库,方便移植
-
缺点:
-
消耗资源,每个程序使用库,都要加载到内存。如果多个程序使用同一个库,那就太浪费了
-
更新发布麻烦,你把库发给别人,别人还要再编译一遍
-
动态库
# 编译得 与位置无关 的目标文件
gcc -fpic -c tes1.c tes2.c
# 编译成共享库
gcc -shared -o libxxx.so tes1.o tes2.o
# 使用共享库,指定:指定库名、库位置、头文件
# !!还要确保能找到库的绝对路径
可以使用ldd
命令来查看可执行文件所依赖的动态库,找不到的会提示"not found"。
程序执行时,加载动态库的过程是由动态加载器ld-linux.so
来完成的。他会依次寻找 elf 文件的 DT-RPATH段(进程内存空间,改不了不用管)--->环境变量 LD_DIRECTORY_PATH
--->/etc/ld.so.cache
--->/lib /usr/lib
,找不到就报错。因此可以有以下方式指定路径:
#(1)更改环境变量
export LD_DIRECTORY_PATH=$LD_DIRECTORY_PATH:{your_lib_directory}
# 当然也可以修改 ~/.bashrc 或 /etc/profile
#(2)更改 /etc/ld.so.cache,但这是一个二进制文件,要更改它的config文件
sudo echo {your_lib_directory} > /etc/ld.so.conf
#(3)添加到 /lib /usr/lib 【不推荐】
- 优点
- 可以实现进程间资源共享(共享库)
- 更新部署发布简单,用户不需要重新编译
- 可以控制何时加载动态库,使用到的时候才进入内存
- 缺点
- 加载速度比静态库稍慢
- 发布程序时需要提供依赖的动态库
makefile
- make 默认执行的是第一条规则,其他的都是为第一条服务的
- 模式匹配中,多个百分号表示的是同一串字符
.PHONY
,伪目标,那么就不会与外面的同名文件,如clean比较
GDB
GDB的功能,一般来说有:
|
-g
只是把源文件的信息加入可执行程序中,并不是嵌入了源程序。因此调试时还需要能找到源程序
命令:
set args arg_1 arg_2
:给程序设置参数
show args
:显示参数
list 文件名 : 行号/函数名
:显示某文件,改函数或行号,附近的代码l
break 文件名 : 行号/函数名
:在该处设置断点b
info break
:查看断点i
delete/disable/enable 断点编号
:查看/删除/无效/生效断点d/del/dis/ena
break [pos] if [condition]
:条件断点
start/run
:开始,到第一行停下/开始,到断点停下start/r
continue
:执行到下一个断点c
next
:执行到下一行代码(不进入函数体)n
step
:向下单步调式(有函数就进入函数)s
finish
:跳出函数体(函数里面不能有断点)
util
:跳出循环(循环内不能有可用的断点,且要停在循环的第一行/最后一行)
print/ptype 变量名
:打印变量值/打印变量类型
display + 变量名
:自动打印指定变量的值
undisplay + 编号
:取消打印对应变量
info display
:查看显示信息i
set var 变量名 = 变量值
:更改变量的值
set disassemble-nextline on
:设置自动输出下一行代码的汇编
文件IO
标准C库IO函数
C库的IO函数是可以跨平台的。跨平台,要么是像java那样不同平台开发不同的虚拟机,要么是调用不同平台的系统API,从而统一接口。
标准C库带有缓冲区,因此效率是更高的
C库函数的man手册等级是3,可以man 3 fwrite
UNIX系统IO
C库有缓冲区,可以提高读写效率,但注意,是效率,而不是速度。在网络通信情境中,我们希望能迅速收到对方发来的消息,那么此时应该使用系统IO,即时读写。总不能我发来的信息,等半天了你还在缓冲区里呢
标签:文件,gcc,函数,lib,编程,网络,编译,Linux,断点 From: https://www.cnblogs.com/shuaikai/p/17212577.html