Linux系统编程01-简介、GCC与常用路径

简介

如何理解系统编程?

  1. 分析程序
  2. 学习系统调用
  3. 编程实现

内核提供的系统资源与服务

  • 处理器(Processor)
    内核安排一个程序何时开始、暂停、恢复、终止
  • 输入输出(I/O)
    程序中的所有输入输出数据必须流经内核,保证了正确性、有效性、安全性
  • 进程管理(Process Management)
    新建进程、终止进程、进程调度等都是内核的任务
  • 内存(Memory)
    内存管理:分配、回收、阻止内存被其他进程非法访问
  • 设备(Device)
    内核能屏蔽掉不同外设操作方式的差异
  • 计时器(Timers)
    内核通过系统调用向应用程序提供计时器服务
  • 进程间通信(Interprocess Communication)
    内核提供进程间通信的服务
  • 网络(Networking)
    网络通信是进程间通信的特殊形式,由内核提供服务

Linux多用户工作

用户名密码通过验证,系统启动shell进程,把用户交给这个进程,由该进程处理用户请求,每个用户有专属的shell进程,shell与用户之间的连接由内核控制,用户注销时,内核结束分配给该用户的进程。

一些常用的指令

目录类操作指令:
ls
cd
pwd
mkdir
rmdir(空目录)

文件操作:
cat
more
less
pg
cp
rm
mv
lpr(打印文件)

fortune程序:
fortune cookie, 带有祝福或哲理的纸条

bc命令:计算器
可以处理很大的数,能进行幂运算 100^3, 支持编程

后台运行:
ctrl+z 可以后台运行并且处于暂停状态,
jobs 命令可以查看当前由多少后台运行的命令,显示任务ID
输入 fg 命令可以把后台命令在恢复前台执行,也可以根据ID指定恢复

文件的权限结构

r w x		r w x	r w x		
user		group	other

r:read w:write x:excute

GCC

GCC(GNU Compiler Collection) GNU编译器套件, 支持C的"方言", 可用命令行选项来控制编译器在翻译源代码时应该遵循哪个 C 标准。当使用命令行参数-std=c99 启动 GCC 时,编译器支持 C99 标准。

安装: sudo apt install gcc g++

查看版本: gcc/g++ -v/--version

GCC工作流程

GCC常用参数

gcc编译选项 说明
-E 预处理指定的源文件, 不进行编译
-S 编译指定的源文件, 但不进行汇编
-c 编译,汇编指定的源文件, 但是不进行链接
file2 -o file1 将文件file2 编译成可执行文件file1
-I directory 指定include包含文件的搜索目录
-g 编译时生成调试信息
-D 程序编译时, 指定一个宏
-w 不生成警告信息
-Wall 生成所有警告信息
-On n取0~3, 编译器的4个优化级别, -O0无优化, -O3基本最高
-l 程序编译时, 指定使用的库
-L 指定编译时, 搜索库的路径
-fPIC/fpic 生成与位置无关的代码
-shared 生成共享目标文件, 通常用在建立共享库时
-std 指定C方言 , -std=c99

一些重点路径

Linux中存储系统程序的标准路径:

  • /bin: 二进制文件目录, 存放启动系统时程序
  • /usr/bin: 用户二进制文件目录, 存放用户使用程序
  • /usr/local/bin: 本地二进制文件目录, 存放软件安装程序

用户应用程序:

  • /usr/bin
  • /usr/local/bin
  • /opt

头文件:

  • /usr/include (C语言)
  • /usr/include/linux (特定Linux版本头文件)
  • /usr/include/c++ (GNU C++)

编译时, -I 标志指定非标准位置的头文件目录
gcc -I/usr/openwin/include fred.c

可以用grep搜索某函数原型头文件:

cd /usr/include; grep EXIT_ *.h

stdlib.h:#define        EXIT_FAILURE    1       /* Failing exit status.  */
stdlib.h:#define        EXIT_SUCCESS    0       /* Successful exit status.  */

库文件:(预先编译好的函数集合)

  • /lib
  • /usr/lib

库文件名字以lib开头, .a静态库, .so共享库, 可以通过完整库文件路径或 -l 标志指定库:

gcc -o fred fred.c /usr/lib/libm.a

gcc -o fred fred.c -lm 代表标准库目录中名为 libm.a 的库

使用 -L 标志增加库搜索路径:

gcc x11fred.c -o x11fred -L/usr/openwin/lib -lX11 用 /usr/openwin/lib 目录中 libX11 库来编译连接程序 x11fred

静态库

  1. 生成目标文件 gcc -c *.c
  2. ar程序创建归档文件(archive) ar crv libfoo.a bill.o fred.o
    • c:创建一个新的归档文件。如果指定的归档文件已经存在,则替换它。如果归档文件不存在,则创建一个新的归档文件。
    • r:向归档文件中插入(或替换)文件。如果指定的文件已经存在于归档文件中,则替换它。否则,将该文件插入到归档文件的末尾。
    • v:显示详细的操作信息。执行操作时,会显示每个插入或替换的文件的名称。
  3. 链接静态库 gcc -o program program.o libfoo.a, 或者指定库目录文件的方式 gcc -o program program.o -L. -lfoo
  4. 使用nm命令查看目标文件/函数库/可执行文件中包含的函数 nm libfoo.a, nm program.o

共享库

  1. 创建共享库libfoo.so gcc -shared -fPIC -o libfoo.so bill.c fred.c (-fPIC 表示生成位置独立的代码(Position Independent Code,PIC)。生成的代码可以在内存中的任何位置加载和执行,而不依赖于特定的内存布局。这个选项告诉编译器生成适用于共享库的代码。)
  2. 链接共享库创建可执行文件 gcc -o program program.c -L. -lfoo
  3. 运行程序报错: ./program: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory
  4. 设置库目录: export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH 或者 sudo mv libfoo.so /usr/lib
  5. 使用 ldd 查看一个程序的共享库 ldd program
linux-vdso.so.1 (0x00007ffc6affe000)
libfoo.so => ./libfoo.so (0x00007fccedfca000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcceddce000)
/lib64/ld-linux-x86-64.so.2 (0x00007fccedfd6000)

man 文档

man文档分为8个小节,每个小节包含了不同的内容,具体如下:

  1. 用户命令(常用的命令,比如ls、cd等)
  2. 系统调用(与操作系统内核交互的函数)
  3. C库函数(标准C库中的函数)
  4. 特殊文件(通常是/dev目录下的设备文件)
  5. 文件格式和约定(文件格式,比如passwd文件的格式,以及约定,比如man文档的格式)
  6. 游戏和屏幕保护程序
  7. 杂项(包括许多的惯例和协议,比如mailcap文件的格式)
  8. 系统管理命令和守护进程(系统管理工具,如mount、reboot等)
posted @ 2022-10-14 21:59  言叶以上  阅读(38)  评论(0编辑  收藏  举报