构建程序
大多数程序使用简单的两个命令序列构建:
./配置制作
./配置制作
这个 配置 program 是一个 shell 脚本,它与源代码树一起提供。 它的工作是分析 构建环境. 大多数源代码被设计为 手提. 也就是说,它旨在建立在不止一种类 Unix 系统上。 但是为了做到这一点,源代码可能需要在构建过程中进行轻微调整以适应系统之间的差异。 配置 还会检查是否安装了必要的外部工具和组件。 让我们跑 配置。 自 配置 没有位于 shell 通常期望程序所在的位置,我们必须通过在命令前面加上前缀来明确地告诉 shell 它的位置 ./ 指示程序位于当前工作目录中:
[me@linuxbox 字典-1.11]$ /配置
[me@linuxbox 字典-1.11]$ /配置
configure 将在测试和配置构建时输出大量消息。 完成后,它看起来像这样:
检查 libintl.h 的存在...是的 检查 libintl.h... 是的
检查包含 gettext 的库...不需要配置:创建 ./config.status
config.status:创建Makefile config.status:创建diction.1 config.status:创建diction.texi config.status:创建diction.spec config.status:创建style.1 config.status:创建test/rundiction config.status:创建 config.h [me@linuxbox diction-1.11]$
检查 libintl.h 的存在...是的 检查 libintl.h... 是的
检查包含 gettext 的库...不需要配置:创建 ./config.status
config.status:创建Makefile config.status:创建diction.1 config.status:创建diction.texi config.status:创建diction.spec config.status:创建style.1 config.status:创建test/rundiction config.status:创建 config.h [me@linuxbox diction-1.11]$
这里重要的是没有错误消息。 如果存在,则配置失败,并且在纠正错误之前不会构建程序。
我们看到, 配置 在我们的源目录中创建了几个新文件。 最重要的是 生成文件. 生成文件 是一个配置文件,它指示 使 program 确切地说明如何构建程序。 没有它, 使 将拒绝运行。 生成文件 是一个普通的文本文件,所以我们可以查看:
[me@linuxbox 字典-1.11]$ 少生成文件
[me@linuxbox 字典-1.11]$ 少生成文件
这个 使 程序将输入作为输入 生成文件 (通常命名为 生成文件),它描述了构成完成程序的组件之间的关系和依赖关系。
makefile 的第一部分定义了在 makefile 的后面部分中替换的变量。 例如,我们看到这一行:
CC=gcc
CC=gcc
它将 C 编译器定义为 GCC. 在 makefile 的后面,我们看到了一个使用它的实例:
措辞:
字典.o 句子.o 杂项.o getopt.o getopt1.o
$(CC) -o $@ $(LDFLAGS) 字典.o 句子.o 杂项.o \ getopt.o getopt1.o $(LIBS)
措辞:
此处执行替换,值 $(抄送) 被替换 GCC 在运行时。
大多数 makefile 由行组成,这些行定义了一个 目标,在这种情况下,可执行文件 指示,以及它所依赖的文件。 其余行描述从其组件创建目标所需的命令。 我们在这个例子中看到可执行文件 指示 (最终产品之一)取决于 字典.o, 句子.o, 杂项, 获取选项和 getopt1.o. 稍后,在 makefile 中,我们看到每个目标的定义:
字典.o:
getopt.o:getopt1.o:misc.o:
diction.c config.h getopt.h misc.h 句子.h
getopt.c getopt.h getopt_int.h getopt1.c getopt.h getopt_int.h Misc.c config.h Misc.h
字典.o:
getopt.o:getopt1.o:misc.o:
句子.o:
风格.o:
句子.c config.h misc.h 句子.h
style.c config.h getopt.h misc.h 句子.h
句子.o:
风格.o:
但是,我们没有看到为它们指定的任何命令。 这是由文件前面的一个通用目标处理的,它描述了用于编译任何 .c 文件成一个 .o 文件:
.co:
$(CC) -c $(CPPFLAGS) $(CFLAGS) $
.co:
$(CC) -c $(CPPFLAGS) $(CFLAGS) $
这一切看起来都非常复杂。 为什么不简单地列出编译零件的所有步骤并完成它呢? 这个问题的答案很快就会清楚。 与此同时,让我们跑 使 并构建我们的程序:
[me@linuxbox 字典-1.11]$ 使
[me@linuxbox 字典-1.11]$ 使
这个 使 程序将运行,使用的内容 生成文件 以指导其行动。 它会产生很多消息。
完成后,我们将看到所有目标现在都出现在我们的目录中:
[我@linuxbox | dict-1.11]$ ls | |||
配置猜测 | 德宝 | en | 安装-sh | 句子.c |
配置文件 | 指示 | EN_GB | 生成文件 | 句子.h |
配置文件 | 第 1 条 | en_GB.mo | 生成文件 | 句子.o |
配置日志 | 字典 1.in | en_GB.po | 杂项c | 样式 |
配置状态 | 字典.c | getopt1.c | 杂项 | 风格.1 |
配置文件 | 字典.o | getopt1.o | 杂项 | 样式.1.in |
配置 | 字典 | getopt.c | 最新消息 | 样式.c |
配置 | 字典.spec | getopt.h | nl | 风格.o |
复印 | 字典.spec.in | getopt_int.h | 莫 | 测试 |
de | 词典.texi | 获取选项 | 荷兰邮政 | |
演示 | 字典.texi.in | 载点 | 读我 |
在文件中,我们看到 指示 和 样式,我们开始构建的程序。 恭喜! 我们刚刚从源代码编译了我们的第一个程序!
但出于好奇,让我们跑 使 再次:
[me@linuxbox 字典-1.11]$ 使
make:对“所有人”无事可做。
[me@linuxbox 字典-1.11]$ 使
make:对“所有人”无事可做。
它只会产生这个奇怪的消息。 这是怎么回事? 为什么它没有再次构建程序? 啊,这就是魔法 使. 而不是简单地重新构建所有东西, 使 只建造需要建造的东西。 在所有目标都存在的情况下, 使 决定无事可做。 我们可以通过删除其中一个目标并再次运行 make 来查看它的作用来证明这一点。 让我们摆脱中间目标之一:
[me@linuxbox 字典-1.11]$ rm getopt.o
[me@linuxbox 字典-1.11]$ 使
[me@linuxbox 字典-1.11]$ rm getopt.o
[me@linuxbox 字典-1.11]$ 使
我们看到 使 重建它并重新链接 指示 和 样式 程序,因为它们依赖于缺少的模块。 这种行为还指出了另一个重要特征 使: 它使目标保持最新。 使 坚持目标比它们的依赖更新。 这是完全有道理的,因为程序员经常会更新一些源代码,然后使用 使 构建新版本的成品。 使 确保基于更新的代码构建需要构建的所有内容。 如果我们使用 触摸 “更新”其中一个源代码文件的程序,我们可以看到这种情况发生:
[me@linuxbox 字典-1.11]$ ls -l 字典 getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:14 字典
-rw-r--r-- 1 我我 33125 2007-03-30 17:45 getopt.c [me@linuxbox diction-1.11]$ 触摸getopt.c
[me@linuxbox 字典-1.11]$ ls -l 字典 getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:14 字典
-rw-r--r-- 1 我我 33125 2009-03-05 06:23 getopt.c [me@linuxbox diction-1.11]$ 使
[me@linuxbox 字典-1.11]$ ls -l 字典 getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:14 字典
-rw-r--r-- 1 我我 33125 2007-03-30 17:45 getopt.c [me@linuxbox diction-1.11]$ 触摸getopt.c
[me@linuxbox 字典-1.11]$ ls -l 字典 getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:14 字典
-rw-r--r-- 1 我我 33125 2009-03-05 06:23 getopt.c [me@linuxbox diction-1.11]$ 使
后 使 运行,我们看到它已将目标恢复为比依赖项更新:
[me@linuxbox 字典-1.11]$ ls -l 字典 getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:24 字典
-rw-r--r-- 1 我我 33125 2009-03-05 06:23 getopt.c
[me@linuxbox 字典-1.11]$ ls -l 字典 getopt.c
-rwxr-xr-x 1 me me 37164 2009-03-05 06:24 字典
-rw-r--r-- 1 我我 33125 2009-03-05 06:23 getopt.c
的能力 使 智能地只构建需要构建的东西对程序员来说是一个很大的好处。 虽然我们的小项目节省的时间可能不是很明显,但它
对于较大的项目非常重要。 请记住,Linux 内核(一个不断修改和改进的程序)包含几个 百万 代码行。