GNU C语言开发环境
1. GNU C 编译器
2. GNU make 项目管理工具
3. 创建和使用函数库
4. GNU C 函数库(glibc)
1.GNU C 编译器
使用 c语言 编写的代码,运行前必须经过编译和链接,最终生成可执行程序。(编译,编译语言源代码;链接,链接引用的函数库。)这个孕育的过程,需要一些工具、一些函数库,其中这个工具就叫做“编译器”。
GNU C 编译器叫做 gcc,gcc包含了预处理器、编译器、汇编器、链接器等。语法格式:
$ gcc [option] dest_file source_file
选 项 | 功 能 |
---|---|
Wall | 打印警告信息 |
g | 添加调试信息到输出文件 |
O o0 o1 o2 | 优化选项,多个同时出现时,最后一个生效 |
I | 指定头文件搜索路径,可以出现多个 |
L | 指定库文件搜索路径,可以出现多个 |
l | 指定引用的库 |
static | 使用静态链接 |
shared | 使用动态链接 |
E | 输出预处理后的文件 |
S | 编译生成的汇编文件(.s) |
c | 编译生成的目标文件(.o) |
o | 指定输出的文件名(default:a.out) |
编译hello world为例:
2.GNU make 项目管理工具
项目中,常采用模块化开发,将系统分解为多个模块,每个模块完成特定的功能。如此分了模块,便会出现多个源代码文件。在调试阶段,可能会反复编译链接,会出现繁琐的重复操作。于是,make 应运而生,来代替手动的繁琐重复操作。make 还可以规避编译未修改源代码的文件。
2.1.格式
make 工具可以从文本文件读取编译规则,每条规则的语法如下:
目标列表:依赖的文件列表 <tab>命令1 # 每行命令的开头必须有一个 tab空白符 <tab>命令2 # 可以存在多条命令
每条规则由:依赖关系和命令两部分组成。所有的命令开头需要有个tab,以#开头表示注释的内容。
make 命令的语法:
$ make [option] [目标] // 创建指定的目标(默认首个目标) $ make -h // 显示所有的make选项
规则文件 Makefile 举例:
hello:hello.o gcc -o hello hello.o hello.o:hello.c gcc -c -o hello.o hello.c clean: rm -f *.o
2.2.变量
变量的定义和引用,跟 Shell 中一样。
CC = gcc INSTALL = install CFLAGS = -O2 -Wall -W -Wshadow OBJS = main.o prelogin.o postlogin.o privsock.o \ tunables.o secbuf.o ls.o .c.o: $(CC) -c $*.c $(CFLAGS) $(IFLAGS) install: if [ -x /usr/local/sbin ]; then \ $(INSTALL) -m 755 fint /usr/local/sbin/fint; \ else \ $(INSTALL) -m 755 fint /usr/sbin/fint; fi
GNU make 预定义了一些变量,在 Makefile 文件中可以直接使用,也可以对这些变量进行重新定义。
预定义变量 | 含义 | 默认值 |
---|---|---|
RM | 删除文件 | rm -r |
$^ | 规则中出现所有依赖文件 | |
$< | 第一个依赖文件的名称 | |
$? | 规则中出现所有依赖文件 (修改日期比目标创建时间新) | |
$* | 目标文件名称(略去扩展名) | |
$@ | 目标文件名称 |
2.3.通配符
允许在规则中使用通配符,支持三种通配符:“*”、“%”、“?”、“[]”。例子见2.4节
2.4.规则
常见规则
规则有时常常简化,分别称为隐含规则、后缀规则、模式规则。
c程序中,由 .c 生成 .o 文件时,在未给出命令时,由 make 自动添加。
生成目标文件时,依赖是个头文件
目标文件是个伪目标,“make clean”、“make install”命令执行时激活伪目标。
2.后缀规则 定义了将具有某后缀的文件转换为具有另外后缀的文件的方法。
3.模式规则 定义了一类具有相同行为特点的规则,%表示通配。
如此,改写规则文件
|
2.5.搜索路径
处理的文件较多时,目录结构较复杂。当需要推导文件的依赖关系时,又需要指明路径。make 的解决方法是,提供一个供搜索的路径,不必指明目录信息。设置一个 VPATH 变量,若当前目录没有找到文件时,就去搜索该变量的路径信息。
VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD)) export srctree objtree VPATH
2.6.显示命令
打印一些信息到屏幕……
Makefile 文件中
| 普通赋值 | ||
| 避免变量递归赋值 | ||
| 首次定义的变量才会被赋值 | ||
| 追加变量的值 |
3.创建和使用函数库
函数库可分为两种类型,静态库和共享库。函数库是由某些目标文件(.o)组成的,静态库命名为 libxxx.a,动态库常命名为 libxxx.so。编译器在链接阶段,会把静态库嵌入至可执行文件中,会把动态库的“快捷方式”存储到可执行文件中。
3.1.静态库
静态库有 ar 工具创建。ar 命令语法如下:
$ ar [option] [tarfile] filelist
选 项 | 功 能 |
---|---|
-d | 从库中删除对象 |
-r | 向库中插入对象(存在则替换) |
-t | 显示库中对象列表 |
-x | 从库中提取对象 |
-c | 创建库 |
写两个c源程序,分别为一个函数,制作一个静态库。
extern int add(int x, int y) extern int count(int * p);
写一个主程序,调用刚刚生成的库 libmy.a 。
3.2.动态库
创建共享库(动态库),使用gcc命令创建。使用共享库,编译主程序。
4.GNU C 函数库(glibc)
Linux系统中 glibc 常用库文件目录
头文件 /usr/include // 系统头文件 /usr/local/include // 本地头文件 函数库 /lib // 系统必备共享库 /usr/lib // 标准共享库和静态库 /usr/X11R6/lib // X11R6 的函数库 /usr/local/lib // 本地函数库
添加库,除了把库文件放到以上路径,还可以自定义路径