Linux程序设计[笔记]

第一章 基础知识

1.1 Linux 程序设计常识

  • GCC:GNU 编译器集,它包括 GNU C 编译器
  • G++:C++ 编译器,是 GCC 的一部分
  • C 语言编译器被简称为 cc

1.2 一些标准路径

  • /bin:二进制文件目录,用于存放启动系统时用到的程序
  • /usr/bin:用户二进制文件目录,用于存放用户使用的标准程序
  • /usr/local/bin:本地二进制文件目录,用于存放软件安装的程序
  • /usr/sbin/sbin:系统管理员登陆后使用 PATH 变量可能还包含,系统管理程序的目录
  • /opt:可选的操作系统组件和第三方应用程序可能被安装在此
  • lib/usr/lib:标准系统库文件

关键位置:

  • 系统管理员一般喜欢使用 /opt/usr/local 因为升级操作系统时只有这两个目录需要保留
  • gcc 一般位于 /usr/bin/usr/local/bin/usr/lib/gcc
  • C 语言头文件位于 /usr/include 及其子目录。哪些依赖 Linux 版本的头文件通常在 /usr/include/sys/usr/include/linux

1.3 头文件与库文件之 gcc 使用

  • -I/目录:包含非标准位置的头文件

  • -L/目录: 添加非标准位置的库


库文件名:libc 指 C语言库,libm 指数学库;后缀 .a 代表传统静态函数库,.so 代表共享函数库

  • 拓展
    • 静态库的缺点:如果同时运行很多程序都使用来自同意函数库的函数,内存中就会有同一函数的多份副本,造成资源浪费。

1.4 静态库实验

1
2
3
4
5
6
7
// fred.c
#include <stdio.h>

void fred(int arg)
{
printf("fred: we passed %d\n", arg);
}
1
2
3
4
5
6
7
// bill.c
#include <stdio.h>

void bill(char *arg)
{
printf("bill: we passed %s\n", arg);
}
  • gcc -c bill.c fred.c 只编译不链接,生成两个对应的 .o 文件
  • 为库文件创建一个头文件 lib.h
1
2
3
// lib.h
void bill(char *);
void fred(int);
  • 编写调用程序 program.c
1
2
3
4
5
6
7
8
#include <stdlib.h>
#include "lib.h"

int main()
{
bill("Hello World");
exit(0);
}
  • 编译调用程序并为编译器显示指定目标文件,并与编译好的 bill.o 链接
1
2
3
gcc -c program.c
gcc -o program program.o bill.o
./program

image-20210622115212840


1.4.1 将目标文件添加到归档文件(创建并使用一个库文件)

  • ar crv libfoo.a bill.o fred.o

  • 使用库文件

    • 方法一:在当前文件列表直接使用:gcc -o program program.o libfoo.a
    • 方法二:使用 -L 访问函数库:gcc -o program program.o -L. -lfoo
      • -L. 表示在当前目录查找库函数;-lfoo 表示使用 libfoo.a 的函数库(或者 libfoo.so 如果存在的话)

1.5 共享库

  • 与静态库的区别:程序本身不在包含库文件的代码,而是引用运行时可访问的共享代码。当编译好的程序被装载到内存中执行时,函数引用被解析成对共享库的调用。
  • 共享库的优点
    • 系统只需要保留一个共享库副本
    • 共享库的更新可以独立于依赖它的程序

1.5.1 如何配置使系统搜索额外的共享库位置

  • 修改 /etc/ld.so.conf 文件
  • 执行 ldconfig 生效

1.5.2 如何查看一个程序需要的共享库

  • ldd 程序名,比如

image-20210622164051603

第九章 开发工具

9.1 make 与 makefile

  • 作用:控制源代码的编译(make 命令会根据 makefile 文件确定目标文件的创建顺序以及正确的规则调用顺序)

9.1.1 make 命令的选项

  • -k:遇到错误也继续执行
  • -n:输出将要执行的下一步操作
  • -f <filename>:告诉 make 将哪个文件作为 makefile
    • 如果不存在这个选项,make 会先找名为 makefile 的文件,不存在就再找 Makefile

9.1.2 依赖关系的写法

目标名称: 依赖的文件列表

  • 举例:

    最终的程序 myapp 依赖 main.o 2.o 3.o;main.o 依赖 main.c a.h;2.o 依赖 2.c a.h b.h,3.o 依赖 3.c b.h c.h。

    所以 main.o 受 main.c 和 a.h 影响,这两个文件修改了都要重新编译 main.c 以重建 main.o

1
2
3
4
myapp: main.o 2.o 3.o
main.o: main.c a.h
2.o: 2.c a.h b.h
3.o: 3.c b.h c.h

9.1.3 编写规则

注意:makefile 中空格和制表符是有区别的
  • 规则所在行必须以制表符开头
  • makefile 中的行不能以空格结尾
1
2
3
4
5
6
7
8
myapp: main.o 2.o 3.o
gcc -o myapp main.o 2.o 3.o
main.o: main.c a.h
gcc -c main.c
2.o: 2.c a.h b.h
gcc -c 2.c
3.o: 3.c b.h c.h
gcc -c 3.c

9.1.4 makefile 中的宏

makefile 文件中的宏通常被用于设置编译器的选项、头文件目录等

1
2
3
4
5
6
7
8
9
10
11
12
all: myapp

# Which compiler
CC = gcc

# Where are include files kept
INCLUDE = .

myapp: main.o 2.o 3.o
$(CC) -o myapp main.o 2.o 3.o

...

9.1.5 makefile 中的特殊字符

  • -:告诉 make 命令忽略所有错误
  • @:告诉 make 在执行某条命令之前不要将该命令显示在标准输出上

第十一章 进程和信号



----------- 本文结束 -----------




0%