“C语言” 读书札记(六)之[Linux下C语言编程环境Make命令和Makefile] 川山甲 博客园

摘要:
关于“C语言”的阅读笔记(6)【C语言编程环境在Linux下生成命令和Makefile】-川山家-博客花园“C语言》阅读笔记(5,这些源文件的处理步骤通常由Makefiles管理。当make不接受参数时,将自动执行第一个目标。事实上,环境变量也被解释为make中make的变量——比如上面Makefile中的clean。

“C语言” 读书札记(六)之[Linux下C语言编程环境Make命令和Makefile] - 川山甲 - 博客园

“C语言” 读书札记(六)之[Linux下C语言编程环境Make命令和Makefile]
介绍
一般程序都是由多个源文件编译链接而成的,这些源文件的处理步骤通常由Makefile文件管理。
用途
make工具用来进行协调的工具,可以根据程序模块的修改情况重新编译链接目标代码,以保证目标代码总是由它的最新模块组成。
准备:
要使用make,准备Makefile的文件(也可以准备其他文件如GNUMakefile或makefile,推荐使用Makefile),它描述了软件包中各个文件之间的关系,提供了更新每个文件的命令。
方便使用:
当一个适当的Makefile存在时,每次改变某些源文件,用简单的shell命令(make),将足以完成所有必需的重新编译。
原理:
make 程序利用Makefile的数据和每个文件最新一次更改的时间来确定哪些文件需要更新;对每个需要更新的文件,make程序使用Makefile中定义的命令来更新它。
格式:
复制代码
#用“井”号表明注释。
target(要生成的文件): dependencies(被依赖的文件)
#命令前面用的是“tab”而非空格。误用空格是初学者容易犯的错误!
命令1
命令2
命令3
.
.
.
命令n
#可以使用“\”表示续行。注意,“\”之后不能有空格!
复制代码
target通常是我们要生成的文件的名字,摆放的顺序不重要,但第一个target是默认的target。当make不带参数时,自动执行第一个target。target也可以是要求make完成的动作,执行这种target后并不能得到和target同名的文件,因此,也称为伪target(phony target)。
dependencies是生成target所需的文件名列表。依赖可以为空,常用的“clean”target就常常没有依赖,只有命令。
命令可以是任何一个shell能运行的命令。
案例:
比如生成exe文件,它由2个目标代码某块组成,分别为module1.o和module2.o
module1.h文件
int module1 = 1;
module1.c文件
#include "module1.h"
void print1(){
printf("var module1:%d\n", module1);
}
module2.h文件
int module2 = 2;
module2.c文件
复制代码
#include <stdio.h>
#include "module2.h"
void print2(){
printf("var module2:%d\n", module2);
}
int main(){
print1();
print2();
return 0;
}
复制代码
编译
Makefile文件
复制代码
exe:module2.o module1.o
gcc -g module1.o module2.o -o exe
module2.o:module2.h module2.c
gcc -g -c module2.c
module1.o:module1.h module1.c
gcc -g -c module1.c
clean:
rm -f exe *.o
复制代码
截图
规则
在编写完源程序文件后,从中生成需要的Makefile规则。
最基本的编写规则的方法是从最终的源程序文件开始一个一个的查看源码文件,把它们要生成的目标文件做为目标,而C语言源码文件和源码文件包含的头文件作为依赖文件生成规则。
目标和条件之间的关系是:欲更新目标,必须首先更新它的所有条件;所有条件中只要有一个条件被更新了,目标也必须随之被更新。所谓“更新”就是执行一遍规则中的命令列表,命令列表中的每条命令必须以一个Tab开头,注意不能是空格,Makefile的格式不像C语言的缩进那么随意,对于Makefile中的每个以Tab开头的命令,make会创建一个Shell进程去执行它。
Makefile中的变量
Makefile中变量就像一个环境变量。事实上环境变量在make中也被解释成make的变量。
作用:
保存文件名列表。——可以方便地加入新的目标文件而且不易出错。
保存编译器参数。——在很多源代码编译时,gcc需要很长的参数选项,在很多情况下,所有的编译命令使用一组相同的选项,如果把这组选项使用一个变量表示,那么可以把这个变量放在所有引用编译器的地方。(当要改变选项的时候,只需改变一次这个变量内容即可)
语法:
变量:“变量”指的是用一个字符串代替另一个字符串的功能。在makefile中可以使用“=”号来定义变量,使用“$(变量名)”来使用变量;还可以用“:=”追加变量的内容。习惯上,变量名使用大写。
定义:
变量名=字符串
使用:
$(变量名)
追加:
变量名:=字符串
案例:进化上面的Makefile
复制代码
OBJS=module1.o module2.o
C=-c
CC=gcc
exe:$(OBJS)
$(CC) -g $(OBJS) -o exe
module2.o:module2.h module2.c
$(CC) -g $(C) module2.c
module1.o:module1.h module1.c
$(CC) -g $(C) module1.c
clean:
rm -f exe *.o
复制代码
伪目标
首先要明确,并不是所有的目标文件都对应于磁盘文件,有的目标文件的存在只是为了形成一条规则,从而使make完成特定的工作,并不生成新的目标文件,这样的目标称为伪目标。——如上面Makefile中的clean。常用的还有all。
放例子:
复制代码
all:exe1 exe2
exe1:exe1.c exe1.h
gcc exe1.c -o exe1
exe2:exe2.c exe2.h
gcc exe2.c -o exe2
clean:
rm -f exe*
复制代码
其中的all和clean都为伪目标。伪目标文件是不存在的。注意上面例子中第一条规则下的命令行为空,make不会执行任何动作,只是检查依赖文件的更新情况, 扫描剩下的几条规则并执行相应的编译命令生成可执行文件。
条件语句
条件语句可以将一个变量与其他变量的值进行比较,或将一个变量与一个字符串常量相比较。——这样就可以根据变量的值执行或忽略Makefile文件中的一部分脚本。
注意:条件语句用于控制make时间看见的Makefile文件部分,而不能用于执行时控制shell命令。
条件语句3条指令:ifeq, else 和endif
放样例:
ifeq($(VAR), 1)
gcc -o exe1 module
else
gcc -o exe2 module
endif
调试make
我们在很多语言中都要用到调试,那么我们自然对make也要想到调试了。
make的调试很简单,只需通过-d选项可是make在执行命令时打印调试信息。
这些信息包括:
1、make重新编译时需要检查的文件
2、哪些文件被比较以及比较的结果
3、需要重新生成的文件
4、make将要使用的隐含规则
5、make实际执行的隐含规则和命令
放截图样例(一部分)
参考文献
make - 维基百科,自由的百科全书
第 22 章 Makefile基础
总结
想要熟练地掌握make工具,必需通过不断的练习并参考其他Makefile的例子。
我会在后期的开发学习中不断完善这篇博文。
推荐
分类: C Language
标签: C Language

免责声明:文章转载自《“C语言” 读书札记(六)之[Linux下C语言编程环境Make命令和Makefile] 川山甲 博客园》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【转】python win32api win32gui win32con 简单操作教程(窗口句柄 发送消息 常用方法 键盘输入)临时表与表变量深入探究下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

leetcode691:Stickers to Spell Word

题目链接给定一个字符串target和一个字符串数组stickers[],要求从stickers中选取尽量少的字符串,以这些字符串所包含的字母为原材料,拼出target。其中:对于stickers中的每个字符串,可以使用多次。target和stichers中的字符串字符集全部为小写字母集。 分析 初看这道题,这是一个整数规划问题。target为aabbb,s...

Activity快速入门理解

​ 在Java领域,JBPM和Activity是两个主流的工作流系统,而Activity的出现无疑将会取代JBPM(Activity的开发者就是从Jbpm开发者出来的 1. 1个插件 在Eclipse中安装Activity插件,让你可以在Eclipse中绘制Activity工作流图 2. 1个引擎 ProcessEngine对象,Activity工作流引擎...

linux的shadow文件

在《Python绝技》这本书的第一个小程序首先展示了针对与unix系统中shadow文件密码的暴力破解的能力,因为之前只是对shadow文件停留在保存了用户密码的阶段,但并没有详细研究,所以周末两天特地花时间好好研究了一下。1.passwd文件和shadow文件在unix早些时候是没有/etc/shadow这个文件的。一个用户的所有信息都只是保存在/etc...

(转) Linux命令学习手册-arp命令

arp 原文:http://blog.chinaunix.net/uid-9525959-id-3318814.html [功能] 管理系统的arp缓存。 [描述] 用来管理系统的arp缓存,常用的命令包括: arp:显示所有的表项。 arp-daddress:删除一个arp表项。 arp-s address hw_addr:设置一个arp表项。 常用参数...

C# 关键字extern用法

修饰符用于声明在外部实现的方法。extern 修饰符的常见用法是在使用 Interop 服务调入非托管代码时与 DllImport 属性一起使用;在这种情况下,该方法还必须声明为 static,如下面的示例所示:[DllImport("avifil32.dll")]private static extern void AVIFileInit();注意ext...

Linux /proc/$pid部分内容详解

auxv /proc/[pid]/auxv包含传递给进程的ELF解释器信息,格式是每一项都是一个unsigned long长度的ID加上一个unsigned long长度的值。最后一项以连续的两个0x00开头。举例如下: # hexdump -x /proc/2948/auxv 0000000 0021 0000 0000 0000...