linux makefile 初学者学习心得
Linux 程序设计学习笔记----动手编写makefile文件——微信科技
Linux 程序设计学习笔记----动手编写makefile文件——微信科技Befroe Beginning.之前定了暑假的plan ,关于Linux的书籍现在在看的是ALP和Linux高级程序设计(杨宗德)第三版.在计划中的是Linux高级环境编程.现在开始关于Linux程序设计的第一篇学习笔记.本来打算把名字写成教程,不过觉得自己完全是新手在自学,还是写学习笔记比较负责和适合.希望可以一起学习进步.(微信科技:最具权威IT培训机构)引入首先我们假设这样一个场景.我们有一个程序包含了三个文件,分别是源码文件main_plus,c和function_plus.c以及头文件mydefine_plus.h.其中main主要是调用功能函数,功能函数则是实现简单的累加,头文件声明函数和一些库函数.代码分别如下:main_plus.c[cpp] view plaincopyprint?/******************************************************************** *****> File Name: main_plus.c> Author: suool> Mail: 1020935219@> Created Time: 2014年07月23日星期三 17时31分23秒********************************************************************* ***//**@file main_plus.c *//** 接收参数,调用功能函数,输出结果. */#include "mydefine_plus.h"int main(void){int a=0, b=0;printf("这是一个求和的程序,请输入数字a和b,程序讲输出a到b的累加结果.\n");printf("Please enter integer a:");scanf("%d", &a);printf("\nPlease enter integer b:");scanf("%d", &b);if(a>b){printf("\nThe sum is %d\n", plus(b,a));}else{printf("\nThe sum is %d\n", plus(a,b));}return 0;}function_plus.c[cpp] view plaincopyprint?/******************************************************************** *****> File Name: function_plus.c> Author: suool> Mail: 1020935219@> Created Time: 2014年07月23日星期三 17时31分40秒******************************************************************** ****//**@file function_plus.c *//** 对a到b的累加求和*/#include "mydefine_plus.h"int plus(int a, int b){int sum = a;int i;for (i=a+1; i<=b; i++){sum += i;}return sum;}mydefine_plus.h.[cpp] view plaincopyprint?/******************************************************************** *****> File Name: mydefine_plus.h> Author: suool> Mail: 1020935219@> Created Time: 2014年07月23日星期三 17时36分16秒********************************************************************* ***//** @file mydefine_plus.h *//** 函数声明和包含*/#ifndef _MYDEFINE_PLUS_H#define _MYDEFINE_PLUS_H#include <stdio.h>int plus(int a, int b);#endif现在我们要编译这个程序,我们可以怎么做呢?这就是这次要解决的问题.(微信科技:最具权威IT培训机构)make文件编写对于上面的问题,我们传统的解决方法是这样的:即是分别编译这两个文件,然后链接变成目标可执行文件,当然,对于三个甚至五个的这样的程序都是可以的,但是如果对于更大的程序呢? 或者我们修改了某个程序,难道要重新编写这些命令?显然,这不是一个明智的选择,因此,我们便导出make文件,即自动执行编译的文件.只要执行一下make命令,everything is done !so, let`s see how to do it.首先我们先把这个程序的文件的makefile文件贴一下,如下:makefile[cpp] view plaincopyprint?main : main_plus.o function_plus.ogcc -o main main_plus.o function_plus.omain_plus.o : main_plus.c mydefine_plus.hgcc -c main_plus.cfunction_plus.o : function_plus.c mydefine_plus.hgcc -c function_plus.cclean:rm -f *.o mainmakefile文件的注释是#后面的语句.有Makefile文件后,不管我们什么时候修改了源程序当中的什么文件,我们只要执行make命令,我们的编译器都只会去编译与我们修改的文件有关的文件,其它的文件不会处理.验证如下:先执行一次make命令,如下:这次自动编译了两个c文件,我们现在修改function_plus.c文件,再次执行make命令,结果如下:这次只是对刚刚修改的文件进行了编译.(微信科技:最具权威IT培训机构)makefile文件编写规则观察其结构我们可以得出make文件的编写基本规则:Makefile文件中,注释以"#"开始Makefile文件中最重要的是描述文件的依赖关系的说明,其一般的格式为:target : componentsTAB rule即是这样:目标:需要的条件(注意冒号两边有空格)命令(注意前面用tab键开头)解释一下:1 目标可以是一个或多个,可以是Object File,也可以是执行文件,甚至可以是一个标签。
Makefile学习心得17页PPT
完整Makefile里包含什么
显式规则
由Makefile的书写者明显指出,要生成的文件,文件的依赖关系和生成的命令
要用以Tab开头) cn_work.o : cn_work.c gcc -c cn_work.c -o cn_work main.o : main.c cn_work.h gcc -c main.c -o main.o fun.o : fun.c fun.h gcc -c fun.c -o fun.o clean: rm -f cn_work *.o
如: foo.o : foo.c defs.h
依赖关系
gcc -o foo.o foo.c 生成目标的方法(方式)
隐晦规则
make有自动推导的功能,这样我们就可以简略地书写Makefile
如:
foo.o : foo.c (.o文件自己推导出同名的依赖文件.c.)
变量定义
这里面的变量一般都是字符串,他有点像c语言的宏
-c参数,只编译,不连接成为可执行文件,编译器只是由输 入的.c等源代码文件生成.o为后缀的目标文件
多目录下Makefile的写法(1)
目标:在工作目录下有4个文件夹 分别是 sources(源文件) obj (中 间文件)headers(头文件) bin(目标文件)
sources里面有 main.c cn_work.c fun.c obj 里面最初没有文件 headers 里面有 fun.h cn_work.h 最终目标取名为 cn_work 它应存放到bin里面 开始写Makefile的预备知识:
ARM+Linux学习总结(2)——Makefile
ARM+Linux学习总结(2)——Makefile1. Makefile 简介Makefile 是和 make 命令⼀起配合使⽤的.很多⼤型项⽬的编译都是通过 Makefile 来组织的, 如果没有 Makefile, 那很多项⽬中各种库和代码之间的依赖关系不知会多复杂. Makefile的组织流程的能⼒如此之强, 不仅可以⽤来编译项⽬, 还可以⽤来组织我们平时的⼀些⽇常操作. 这个需要⼤家发挥⾃⼰的想象⼒.1.1 Makefile 主要的 5个部分 (显⽰规则, 隐晦规则, 变量定义, ⽂件指⽰, 注释)Makefile基本格式如下:target ... : prerequisites ...command......其中,target - ⽬标⽂件, 可以是 Object File, 也可以是可执⾏⽂件prerequisites - ⽣成 target 所需要的⽂件或者⽬标command - make需要执⾏的命令 (任意的shell命令), Makefile中的命令必须以 [tab] 开头1. 显⽰规则 :: 说明如何⽣成⼀个或多个⽬标⽂件(包括⽣成的⽂件, ⽂件的依赖⽂件, ⽣成的命令)2. 隐晦规则 :: make的⾃动推导功能所执⾏的规则3. 变量定义 :: Makefile中定义的变量4. ⽂件指⽰ :: Makefile中引⽤其他Makefile; 指定Makefile中有效部分; 定义⼀个多⾏命令5. 注释 :: Makefile只有⾏注释 "#", 如果要使⽤或者输出"#"字符, 需要进⾏转义, "\#"1.2 GNU make 的⼯作⽅式1. 读⼊主Makefile (主Makefile中可以引⽤其他Makefile)2. 读⼊被include的其他Makefile3. 初始化⽂件中的变量4. 推导隐晦规则, 并分析所有规则5. 为所有的⽬标⽂件创建依赖关系链6. 根据依赖关系, 决定哪些⽬标要重新⽣成7. 执⾏⽣成命令2. Makefile 初级语法2.1 Makefile 规则2.1.1 规则语法规则主要有2部分: 依赖关系和⽣成⽬标的⽅法.语法有以下2种:target ... : prerequisites ...command...或者target ... : prerequisites ; commandcommand...*注* command太长, 可以⽤ "\" 作为换⾏符2.1.2 规则中的通配符* :: 表⽰任意⼀个或多个字符:: 表⽰任意⼀个字符[...] :: ex. [abcd] 表⽰a,b,c,d中任意⼀个字符, [^abcd]表⽰除a,b,c,d以外的字符, [0-9]表⽰ 0~9中任意⼀个数字~ :: 表⽰⽤户的home⽬录2.1.3 路径搜索当⼀个Makefile中涉及到⼤量源⽂件时(这些源⽂件和Makefile极有可能不在同⼀个⽬录中),这时, 最好将源⽂件的路径明确在Makefile中, 便于编译时查找. Makefile中有个特殊的变量 VPATH 就是完成这个功能的.指定了 VPATH 之后, 如果当前⽬录中没有找到相应⽂件或依赖的⽂件, Makefile 回到 VPATH 指定的路径中再去查找..VPATH 使⽤⽅法:vpath <directories> :: 当前⽬录中找不到⽂件时, 就从<directories>中搜索vpath <pattern> <directories> :: 符合<pattern>格式的⽂件, 就从<directories>中搜索vpath <pattern> :: 清除符合<pattern>格式的⽂件搜索路径vpath :: 清除所有已经设置好的⽂件路径# ⽰例1 - 当前⽬录中找不到⽂件时, 按顺序从 src⽬录 ../parent-dir⽬录中查找⽂件VPATH src:../parent-dir# ⽰例2 - .h结尾的⽂件都从 ./header ⽬录中查找VPATH %.h ./header# ⽰例3 - 清除⽰例2中设置的规则VPATH %.h# ⽰例4 - 清除所有VPATH的设置VPATH2.2 Makefile 中的变量2.2.1 变量定义 ( = or := )OBJS = programA.o programB.oOBJS-ADD = $(OBJS) programC.o# 或者OBJS := programA.o programB.oOBJS-ADD := $(OBJS) programC.o其中 = 和 := 的区别在于, := 只能使⽤前⾯定义好的变量, = 可以使⽤后⾯定义的变量测试 =# Makefile内容OBJS2 = $(OBJS1) programC.oOBJS1 = programA.o programB.oall:@echo $(OBJS2)# bash中执⾏ make, 可以看出虽然 OBJS1 是在 OBJS2 之后定义的, 但在 OBJS2中可以提前使⽤$ makeprogramA.o programB.o programC.o测试 :=# Makefile内容OBJS2 := $(OBJS1) programC.oOBJS1 := programA.o programB.oall:@echo $(OBJS2)# bash中执⾏ make, 可以看出 OBJS2 中的 $(OBJS1) 为空$ makeprogramC.o#Makefile内容#变量定义obj-m:=gpio_driver.oPWD:=$(shell pwd)KERNEL_PATH:=/lib/modules/3.11.0-15-generic/buildKDIR:=$(KERNEL_PATH)all:$(MAKE) -C $(KDIR) M=$(PWD)clean:rm -rf *.ko *.order *.symvers *.cmd *.o *.mod.c *.tmp_versions .*.cmd .tmp_versions#all伪指令下的命令含义:当make的⽬标为all时,-C $(KDIR) 指明跳转到内核源码⽬录下读取那⾥的\Makefile;M=$(PWD) 表明然后返回到当前⽬录继续读⼊、执⾏当前的Makefile。
linuxmakefile初学者学习心得
linuxmakefile初学者学习心得第一篇:linux makefile 初学者学习心得在学习linux系统中认识到了makefile是必须要掌握的,一开始对于makefile(翻译:生成文件)不理解,经过几天的学习对makefile也有了一定的理解:一、Makefile的作用:makefile 关系到整个工程的编译规则,一个工程文件不计其数,其按类型,功能,模块分别放在不同的目录下,makefile定义了一些规则来指定,哪些文件需要先编译,哪些文件需要重新编译,甚至进行更复杂的功能操作,因为makefile就像一个shell脚本一样,其中也可以执行操作系统命令。
也就是通过makefile规则编写makefile文件来实现执行文件的生成,makefile对于多个文件生成的执行文件,若有某个发生改变后,makefile可以发现直接去编译,从而减少了从头开始编译的时间,提高编译效率,同时也可以很方便的修改文件,添加或者删去某些文件。
二、Makefile的规则:1.隐晦规则:就是利用make 的自动推导的功能2.显示规则:就是显示的在命令行中写出目标文件的依赖关系3.变量的定义:就变量的宏替换4.文件指示:其中包括三部分的内容,一个是在一个makefile中引用另一个makefile,就像c语言中的include 一样;另一个是根据某些情况指定makefile中的有效部分,就像c语言的预编译#ifdef一样;还有一个就是定义一个多行的命令。
5.注释:只有行注释用#号字符注释如果你的makefile中用到了# 你可以用“#“转义一、把源代码编译成目标代码一般是一个规则。
二、把所有中间文件编译链接在一起也是一个规则。
编译需要一定的依赖文件,例如把一个.c文件编译为一个可执行文件,则一般是通过:先有.c再到.o然后到执行文件例子:#要想生成hello.o目标,必须先有hello.c, 然后调用命令行gcc编译生成hello.o 依赖对象hello.c hello.o:hello.c gcc –c hello.c –o hello.o要想生成执行程序hello,必须先执行规则hello.o, 然后调用命令行gcc链接生成hello hello:hello.ogcc hello.o –o hello 在例子中hello.o要依赖hello.c调用gcc编译器才能生成,执行文件hello要依赖hello.oMakefile可以理解为由make程序进行解释的一种特殊脚本。
学写makefile一点心得
学写makefile一点心得var=-Wall –gCC=gccCC+=$(var)str=${wildcard *.c}obj=${patsubst %.c,%.o,$(str)}xxx:$(obj)$(CC) $^ -o $@$(obj):%.o:%.c$(CC) -c$^ -o $@clean:@$(RM) xxx $(obj)这是在用makefile编写的一个程序。
在当前makefile的目录中,有四个文件,分别是a.c、b.c、file_inc.h和main.c四个文件,其中a.c、b.c、file_inc.h 三个是一起构成的源程序,main.c是另外的,它们之间不关联。
str=$(wildcard *.c) 是一个函数来表示,其函数原型为:$(wildcard PATTERN)函数名称:获取匹配模式文件名函数—wildcard函数功能:列出当前目录下所有符合模式“PATTERN”格式的文件名。
返回值:空格分割的、存在当前目录下的所有符合模式“PATTERN”的文件名。
函数说明:“PATTERN”使用shell可识别的通配符,包括“?”(单字符)、“*”(多字符)等。
obj=$(patsubst %.c,%.o,$(str)) 这也是一个函数,其原型为:$(patsubst PATTERN,REPLACEMENT,TEXT)函数名称:模式替换函数—patsubst。
函数功能:搜索“TEXT”中以空格分开的单词,将符合模式“TATTERN”替换为“REPLACEMENT”。
参数“PATTERN”中可以使用模式通配符“%”来代表一个单词中的若干字符。
如果参数“REPLACEMENT”中也包含一个“%”,那么“REPLACEMENT”中的“%”将是“TATTERN”中的那个“%”所代表的字符串。
在“TATTERN”和“REPLACEMENT”中,只有第一个“%”被作为模式字符来处理,后续的作为字符本上来处理。
学习Linux的心得(精选6篇)
学习Linux的心得学习Linux的心得(精选6篇)在平日里,心中难免会有一些新的想法,应该马上记录下来,写一篇心得体会,这样能够给人努力向前的动力。
一起来学习心得体会是如何写的吧,以下是小编为大家整理的学习Linux的心得,希望对大家有所帮助。
学习Linux的心得篇1本学期对于Linux系统的学习,让我对Linux有了一定的了解。
我知道了Linux只是个内核。
现在的Linux操作系统,都是用这么一个内核,加上其它的应用程序构成的。
Linux最大的特点就是其开源性,这一点是十分难得的,这也是它能够存在到现在的原因之一,使其在金融、安全等部门有很重要的应用。
学习Linux,首先我们应该从基础开始学起。
对Linux操作系统的功能、版本、特点,以及Linux系统安装和图形环境有较全面的了解。
Linux命令是必须学习的。
虽然Linux桌面应用发展很快,但是命令在Linux中依然有很强的生命力。
Linux是一个命令行组成的操作系统,精髓在命令行,学习如何在安全的环境中执行系统命令,包括有关文件、目录、文件系统、进程等概念,如何使用相应的命令对文件、目录、进程等进行管理,了解遇到问题时,如何找到帮助信息等。
Linux常用命令,有echo 命令、date命令、passwd命令、file命令、ls命令、touch命令等。
要明白学好Linux不是一件一蹴而就的事,一定要能坚持使用它,特别是在学习初期。
要增加自己的Linux技能,只有通过实践来实现。
只要多动手,就一定会有收获。
遇到问题时要自己去寻找答案,在寻找答案的过程中,会学到更多知识。
应该说目前我们对于Linux的学习只是入门而已,学习Linux是一个长期的过程,很耗时间。
作为电子信息工程专业的学生,对我们来说,Linux将来主要应用于嵌入式Linux系统的开发,这非一日之功,我们还需要不断深入地学习它。
最后,衷心感谢唐磊老师一学期来的辛苦教学,唐老师幽默风趣的教学方式给我们的课堂带来很多欢乐。
Makefile学习
Makefile学习Makefile ⽂件描述了 Linux 系统下 C/C++ ⼯程的编译规则,它⽤来⾃动化编译 C/C++ 项⽬。
⼀旦写编写好 Makefile ⽂件,只需要⼀个 make 命令,整个⼯程就开始⾃动编译,不再需要⼿动执⾏ GCC 命令。
⼀个中⼤型 C/C++ ⼯程的源⽂件有成百上千个,它们按照功能、模块、类型分别放在不同的⽬录中,Makefile ⽂件定义了⼀系列规则,指明了源⽂件的编译顺序、依赖关系、是否需要重新编译等。
参考:1. Makefile⽂件是什么?Windows环境:如果你是在 Windows 下作开发的话不需要去考虑这个问题,因为 Windows 下的集成开发环境(IDE)已经内置了 Makefile,或者说会⾃动⽣成 Makefile,我们不⽤去⼿动编写。
Linux环境:Linux 中却不能这样,需要我们去⼿动的完成这项⼯作。
不懂 Makefile,就操作不了多⽂件编程,就完成不了相对于⼤的⼯程项⽬的操作。
Makefile 可以简单的认为是⼀个⼯程⽂件的编译规则,描述了整个⼯程的编译和链接等规则。
其中包含了那些⽂件需要编译,那些⽂件不需要编译,那些⽂件需要先编译,那些⽂件需要后编译,那些⽂件需要重建等等。
编译整个⼯程需要涉及到的,在 Makefile 中都可以进⾏描述。
换句话说,Makefile 可以使得我们的项⽬⼯程的编译变得⾃动化,不需要每次都⼿动输⼊⼀堆源⽂件和参数。
以 Linux 下的C语⾔开发为例来具体说明⼀下,多⽂件编译⽣成⼀个⽂件,编译的命令如下所⽰:gcc -o outfile name1.c name2.c ...outfile 要⽣成的可执⾏程序的名字,nameN.c 是源⽂件的名字。
这是我们在 Linux 下使⽤ gcc 编译器编译 C ⽂件的例⼦。
如果我们遇到的源⽂件的数量不是很多的话,可以选择这样的编译⽅式。
如果源⽂件⾮常的多的话,就会遇到下⾯的这些问题:1) 编译的时候需要链接库的的问题。
Linux_Make(Makefile)由浅入深的学习与示例剖析
经过长时间学习和研究linux GNU make工程管理器,现在把学习心得与大家分享一下,希望本文能教会您一些有用的东西。
make工具,是所有想在Linux/Unix系统上编程的用户都需要且必须掌握的工具。
如果您写的程序没有用到make工具,则说明您写的程序仅仅是个人练习小程序,称不上有实用价值的程序,因此我们必须学习、掌握并灵活运用它。
在Linux/UNIX 系统中,习惯使用Makefile或makfile 文件作为make命令目标文件。
Make 工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互依赖关系并自动维护编译工作。
而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。
一、多文件编译的总体结构如下图所示,本示例共包含float类型加法、加法头函数、int类型加法、main主函数、float 类型减法、减法头函数、int类型减法主函数view plaincopy to clipboardprint? .........10........20........30........40........50........60........70........80........90........100.......110. (12)0.......130.......140. (150)#include "add.h"#include "sub.h"#include <stdio.h>int main(){int x, y;float a, b;x=5;y=2;a=5.5;b=2.2;printf("%d + %d = %d\n", x, y, add_int(x, y));printf("%3.1f + %3.1f = %3.1f\n", a, b, add_float(a, b));printf("%d - %d = %d\n", x, y, sub_int(x, y));printf("%3.1f - %3.1f = %3.1f\n", a, b, sub_float(a, b));return 0;}#include "add.h"#include "sub.h"#include <stdio.h>int main(){int x, y;float a, b;x=5;y=2;a=5.5;b=2.2;printf("%d + %d = %d\n", x, y, add_int(x, y));printf("%3.1f + %3.1f = %3.1f\n", a, b, add_float(a, b));printf("%d - %d = %d\n", x, y, sub_int(x, y));printf("%3.1f - %3.1f = %3.1f\n", a, b, sub_float(a, b));return 0;}加法头函数view plaincopy to clipboardprint? .........10........20........30........40........50........60........70........80........90........100.......110. (12)0.......130.......140. (150)/* add.h */#ifndef _ADD_H_#define _ADD_H_extern int add_int(int x, int y);extern float add_float(float x, float y);#endif/* add.h */#ifndef _ADD_H_#define _ADD_H_extern int add_int(int x, int y);extern float add_float(float x, float y);#endifint类型加法view plaincopy to clipboardprint? .........10........20........30........40........50........60........70........80........90........100.......110. (12)0.......130.......140. (150)/* add_int.c */int add_int(int x, int y){return x+y;}/* add_int.c */int add_int(int x, int y){return x+y;}float类型加法view plaincopy to clipboardprint? .........10........20........30........40........50........60........70........80........90........100.......110. (12)0.......130.......140. (150)/* add_float.c */float add_float(float x, float y){return x+y;}~/* add_float.c */float add_float(float x, float y){return x+y;}~减法头函数view plaincopy to clipboardprint? .........10........20........30........40........50........60........70........80........90........100.......110. (12)0.......130.......140. (150)/* sub.h */#ifndef _SUB_H_#define _SUB_H_extern int sub_int(int x, int y);extern float sub_float(float x, float y);#endif/* sub.h */#ifndef _SUB_H_#define _SUB_H_extern int sub_int(int x, int y);extern float sub_float(float x, float y);#endifint类型减法view plaincopy to clipboardprint?/* sub_int.c */int sub_int(int x, int y){return x-y;}/* sub_int.c */int sub_int(int x, int y){return x-y;}float类型减法view plaincopy to clipboardprint? .........10........20........30........40........50........60........70........80........90........100.......110. (12)0.......130.......140. (150)/* sub_float.c */float sub_float(float x, float y){return x-y;}/* sub_float.c */float sub_float(float x, float y){return x-y;}二、方法1 (多文件编译)直接在Linux的Shell环境中,分别依次利用gcc -c *.c -o *.o命令进行编译,并链接生成可执行文件,具体做法如下:依次编译上述文件:编译后的结果文件:然后,直接利用gcc -o main add_int.o add_float.o sub_int.o sub_float.o main.o命令,链接、编译成目标可执行文件main最后,输入./main 运行结果评析:此方法遵照单文件编译方法,过程清晰、直观易懂;但效率很低,在编译文件数量很大或源文件修改时,此方法效率很低,且难以维护三、方法2 (多文件编译——使用makefile )此方法为了避免方法1的不足,利用Linux GNU make工程管理器,进行编译、管理源文件。
【重要】调用makefile(多目录嵌套调用、变量使用)
obj2 = main2.o lib.o
all : edit1 edit2
edit1 : $(obj1)
gcc -o./main1/edit1 ./main1/main1.o lib.o
main1.o : main1.c
$(MAKE) -C./main1
gcc -csub2.c
都很简单对吧,就一条正常的编译命令,最后是根目录下的makefile:
VPATH=./sub1 ./sub2
obj=main.o sub1.o sub2.o
edit : $(obj)
gcc -oedit main.o ./sub1/sub1.o ./sub2/sub2.o
$(MAKE) -C$(s1)
lib.o : lib.c
gcc -clib.c
edit2 : $(ob2)/main2.o lib.o
main2.o : $(s2)/main2.c
$(MAKE) -C$(s2)
main1.c和main2.c里都有主函数,需要调用lib.c里的求和函数,只是所传递的参数值不同。要求通过根目录下的makefile嵌套调用子目录下的makefile来编译,最后链接生成可执行文件edit1和edit2,最后执行edit1和edit2应该能得到两个不同的值(也就是lib.c所求得的和)。
好了,我就不贴三个源文件的C代码了,大家自己写用来测试,我就直接贴makefile的编写了。
首先是子目录sub1下的makefile:
sub1.o : sub1.c
gcc-c sub1.c
接下来是子目录sub2下的makefile:
makefile学习心得
Makefile学习心得1.Makefile在单一目录下的编译a)Makefile主要运用于工程的管理,使工程能自动按需求来编译,对于单目录来说,可以用非常简单的命令来:目录:依赖(所有的源文件):命令(需要什么就怎么编)b)例程:所有文件都在一个目录下i.all:mkfifo_server mkfifo_clientii..PHONY:alliii.mkfifo_server:mkfifo_server.civ.gcc -o $@ $^v.mkfifo_client:mkfifo_client.cvi.gcc -o $@ $^2.关键在于对多级目录下的各大程序的编译与库的编译与链接问题。
a)对于多级目录下各自编译问题:i.在各源文件目录下编写各源文件的编译Makefileii.在顶层目录下编写的Makefile需要指定各源文件的路径,可以用通配符来表示iii.用$(MAKE) -C进入到各目录分别编译,这里有一个非常重要的技巧那就是make 对目录的并行处理,也就是伪目标的一个重要运用iv.例程:在顶层目录下有socket mkfifo两个目录1.DIR := $(shell pwd)2.SUBDIR := socket mkfifo3..PHONY:all subdir $(SUBDIR)4.all:creat complie subdir $(SUBDIR)5.creat:6.@mkdir -p $(DIR)/socket27.@cp -rf $(DIR)/socket/* $(DIR)/socket2plie:9.@make -C $(DIR)/socket10.#subdir:$(SUBDIR)11.$(SUBDIR):12.$(MAKE) -C $@13.socket:mkfifo14.Socket mkfifo 目录下的Makefile可以参照单目录下的Makefile来写15.特别要注意的一点是一定要声明subdir与$(SUBDIR)为伪目标否则编译只能编译第一个目录b)在不同目录下编译生成库文件,并链接生成可执行文件i.在需要编译成库文件的目录下写源程序,头文件和编译成库的Makefileii.在顶层目录下写主函数用以链接库文件,调用库文件中的函数来执行iii.在顶层目录下编写Makefile,这一层的Makefile主要工作是,设置各目录的路径,可以按照上面的做法用伪目标先进入各目录编译库文件,然后再链接各库生成可执行文件iv.例程:在顶层目录下有一个helloworld子目录,用来编译生成静态库文件1.DIR:=$(shell pwd)2.SUBDIR:=$(DIR)/helloworld3..PHONY:all4.all:subdir main clean5.subdir:6.$(MAKE) -C $(SUBDIR)7.main:main.c8.gcc -o $@ $^ $(SUBDIR)/*.a9.clean:10.cd $(SUBDIR) && rm -rf *.o11.Helloworld目录下的Makefilea)libhello.a:hello.ob)ar rcs $@ $^c)#hello.o:hello.cd)# gcc -c $^ -o $@12.注意:库文件在生成后最用一个变量来表示,此处不再描述,helloworld文件中的Makefile最后两句可以注释掉,make可以利用其隐式规则自动进行推导,动态库的制作与编译链接与静态库差不多,可以照此推导3.Makefile生成动态库a)这个与上面生成静态库的方法有点类似,只是生成动态库的命令有点不同,并且也要指定库文件所在的目录b)例程:与上静态库中一样,只是改为编译成动态库,并在顶层Makefile中将其拷贝到/usr/bin目录下i.DIR:=$(shell pwd)ii.SUBDIR:=$(DIR)/helloworldiii.LIB:=/usr/biniv..PHONY:allv.all:subdir mov main cleanvi.subdir:vii.$(MAKE) -C $(SUBDIR)viii.mov:ix.@cp -rf $(SUBDIR)/*.so $(LIB)x.main:main.cxi.gcc -o $@ $^ $(LIB)/libhello.soxii.clean:xiii.cd $(SUBDIR) && rm -rf *.oxiv.Helloworld目录中的Makefile编写1.libhello.so:hello.o2.gcc -shared -fPIC $^ -o $@3.# ar rcs $@ $^4.#hello.o:hello.c5.# gcc -c $^ -o $@总结:Makefile的编写主要只是做了一些文件位置与变量设置工作,其实编译还是和一条条命令是一样的,只是一个根据条件将文件合理配置的一个过程,以方便管理,其中所有的命令在执行文件时都是需要指定路径的,特别重要的一点是伪目标在多目录下的运用。
makefile学习笔记
1,以#开头的行为注释行,相当于C语言的// ,在makefile中是区分大小写的,make和MAKE是不一样的。
如果需要在makefile中使用#的符号,就要用反斜杠\#转义成#本身的意义2,makefile格式目标:依赖文件1,依赖文件2命令–依赖文件后缀依赖文件1,依赖文件2,目标注意:命令行必须以单个的TAB字符进行缩进,不能是空格当然也可以跟目标和依赖文件在一行,不过要以;隔开3,宏定义在linux中其实就是变量定义,在引用宏时必须在宏前加上$符号,而且如果变量名的长度超过一个字符,在引用时必须加圆括号()。
注意:$Z=$(Z),$(2),$(CFLAGS)都是有效的变量4,$*,$@,$?,$<四个特殊的宏的值在执行命令的过程中会发生相应的变化(自动化变量)5,宏的定义很简单,格式为:变量=变量值6,反斜杠(\)有时在makefile中是换行符的意思。
7,隐晦规则指的就是.o文件自己推导出同名的依赖文件.c.8,伪目标的格式可以为:.PHONY: cleanclean:rm edit $(obiect)―.PHONY‖表示,clean是个伪目标文件。
9,有些是在命令的前面加上减号如:如上句的:-rm edit $(obiect)也许某些文件出现问题,但不要管,继续做后面的事,这个减号的作用就是加强保障,还有一个全局的办法就是给make加上“-I‖或是“ignore-errors‖参数,那么makefile中所有的命令都会忽略错误。
还有一个就是make的参数是”-k‖或是“-keep-going‖,这个参数的意思是如果规则中的命令出错了,那么就终止该规则的执行,但继续执行其它规则。
10,makefile 工作执行的步骤:1)、读入所有的Makefile。
2)、读入被include的其它Makefile。
3)、初始化文件中的变量。
4)、推导隐晦规则,并分析所有规则。
5)、为所有的目标文件创建依赖关系链。
linux编译----makefile的思考与总结
linux编译----makefile的思考与总结在⼀个⼤型项⽬中,要知晓代码结构,顶层makefile的分析是⽐不可少的⾸先先看顶层makefile的分析,这是⼀个实际的公司的makefile,可能回涉及⼀些专业东西看不太懂,忽略即可先来分析顶层makefile# define BNT6000 Terminal's release version.VERSION = 3PATCHLEVEL = 0SUBLEVEL = 0EXTRAVERSION = 1ACA_RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL).$(EXTRAVERSION)#定义了⼀些参数,主要⽤于⽣成产品版本号include Makefile.inc#在 Makefile 使⽤ include 关键字可以把别的 Makefile 包含进来,这很像 C 语⾔的 #include,被包含的⽂件会原模原样的放在当前⽂件的包含位置。
#makefile.inc其实就是定义了⼀些编译参数,⽬录,以及编译⽅法!# directories visited install, programs, check, etc.# acadb#export TOPDIR := $(shell pwd) #如果你要传递变量到下级 Makefile 中,那么你可以使⽤这样的声明: exportexport MAINDIR := $(TOPDIR)/mainexport SDKDIR := $(TOPDIR)/sdkexport INCDIR := $(TOPDIR)/util#subdir都是⼀些⼦⽬录SUBDIRS=util protocol netcomm STM32COMM center Rs232 record record/2012 audio lcd printer update jilt BD $(module_dir) format apply main pack all: bnt6000bnt6000: copy_lib@echo "#define BUILD_DATE \"`date +%Y-%m-%d`\"" > $(INCDIR)/version.h@echo "#define SW_VER \"$(SOFTWARE_VERSION)\"" >> $(INCDIR)/version.h@echo "#define BUILD_SVN_NO \"`svn info | grep "Last Changed Rev: " | sed -e "s/Last Changed Rev: //g"`\"" >> $(INCDIR)/version.h@echo "#define SW_VERSION SW_VER\",build:\"BUILD_SVN_NO\":\"BUILD_DATE\"\\0\"" >> $(INCDIR)/version.h@echo "#define PRODUCT_TYPE \"$(PRODUCT_TYPE)\"" >> $(INCDIR)/version.h@for d in $(SUBDIRS); do (cd $$d && $(MAKE)); done # ⼀种语法结构,进⼊⼦⽬录并且分别编译!copy_lib:ifeq ($(COMM_MODULE), G3)cp audio/libsqlite3-3g.so -dpRf audio/libsqlite3.socp util/libcurl_3g.so.4 -dpRf util/libcurl.socp util/libzlog_3g.so.1.1 -dpRf util/libzlog.soelsecp audio/libsqlite3-2g.so -dpRf audio/libsqlite3.socp util/libcurl_2g.so.4 -dpRf util/libcurl.socp util/libzlog_2g.so.1.1 -dpRf util/libzlog.soendifinstall: auth# @if [ "$LOGNAME" != "root" ]; then echo "Only root can install, quit!"; exit 1; fi# mkdir -p $(HOME)/workspacemkdir -p $(PREFIX)mkdir -p $(PREFIX)/bin $(PREFIX)/etc $(PREFIX)/lib $(PREFIX)/include@for d in $(SUBDIRS); do (cd $$d && $(MAKE) install); done# chown root.root $(PREFIX)/bin/*uninstall:# @if [ "$LOGNAME" != "root" ]; then echo "Only root can uninstall, quit!"; exit 1; fi@for d in $(SUBDIRS); do (cd $$d && $(MAKE) uninstall); done@rm -f $(PREFIX)/include/*.h@rm -f $(PREFIX)/lib/*.aimg:./main/mkimg.ramfsbuild:@echo "just for packing atomically---------------------------------------------start---------"cd ./bin&& ./build.shclean:@for d in $(SUBDIRS); do (cd $$d && $(MAKE) clean); donemake clean -C avhelp:@echo "Auth Server makefile."@echo "version : $(ACA_RELEASE)"@echo@echo "Syntax:"@echo " aca -- make all auth source code. It is default make."@echo " clean -- make clean all auth source code."@echo " install -- make all auth source code, and then install programs to DESDIR."@echo " uninstall -- uninstall programs from DESDIR."@echo " help -- print this help."# Define ACA Release Version.version.h: ./Makefile@echo "/*" > .ver@echo " * version.h" >> .ver@echo " *" >> .ver@echo " * Copyright (C) 2007 UNIS." >> .ver@echo " *" >> .ver@echo " * ACA Release Version." >> .ver@echo " * This file comes from Makefile. Do not modify it manually." >> .ver@echo " */" >> .ver@echo >> .ver@echo \#define ACA_RELEASE \"$(ACA_RELEASE)\" >> .ver@echo \#define ACA_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver@echo '#define ACA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver@mv -f .ver $@@sed '/[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/ c $(ACA_RELEASE)' etc/version > /tmp/version.1@cp -dpRf /tmp/version.1 etc/version@rm -f /tmp/versioninclude Makefile.inc 在 Makefile 使⽤ include 关键字可以把别的 Makefile 包含进来,这很像 C 语⾔的 #include,被包含的⽂件会原模原样的放在当前⽂件的包含位置。
学习Linux的心得精选四篇
学习Linux的心得学习Linux的心得「篇一」Windows操作系统是目前世界上使用最广泛的操作系,但是在企业级服务应用上则是Linux系统更为专业与出名,也许听到Linux操作系统会觉得陌生,Android操作系统(安卓)就是基于Linux平台的开源手机操作系统,在个人电脑桌面操作系统有ubuntu、centos、Fedora等都是基于linux。
这个号称“全地球人的操作系统”,以其免费、安全、稳定等优点获得人们的广泛好评。
作为计算机专业的学生,Linux是一门值得深入学习的课程。
我们身处网络发达的年代,网络科技发展速度非常之快,所以,我们的学习范围不应只局限于课本局限于校园,不断学习新的知识,接触新的环境,才能更全面地了解网络发展的新趋势。
4月,我们有幸参加了学校与华清远见教育集团组织的“Linux课程实训”。
实训主要内容为嵌入式Linux服务器搭建,本次实训课程我们学习了部分Linux的基本操作命令,了解了服务器的主要工作原理和流程,在Linux操作系统上如何搭建服务器,服务器与客户端之间如何建立连接,数据的访问读取,上传和下载文件等。
尽管课程安排紧凑,老师讲课速度较快,同学们跟着老师的思路走,还是会有很多收获。
纸上得来终觉浅,绝知此事要躬行。
在学校的课堂上,我们所学的更多的是课本上的理论知识,实训课程中,老师除了讲解理论知识外,还会简单介绍自己的工作和实战经验,这样的实训课程除了强化我们所学的理论知识外,还让我们粗略了解到我们所学的知识能够用在什么地方;如果从事这方面的的工作,在企业里我们还需要掌握哪些技能等。
由此可见,实战经验很重要,就如在给我们讲课的时侯,老师编译程序时也会出现问题,可实战经验丰富,就能快速地找出问题并解决。
很感谢学校提供这样的一次机会,让我们更深刻地了解到,希望今后会有更多实训机会,让我们能够用所学的理论知识去开展更多的实践,学以致用,格物致知。
学习Linux的心得「篇二」学习Linux,应该怎样学,主要学些什么,一位Linux热心学习者,一段学习Linux的风云经验,历时十二个小时的思考总结,近十位网络Linux学习者权威肯定,为您学习Linux指明方向。
Makefile使用教程及实践总结
Makefile简明使用教程及实践总结杨小玉2011-02-16目录一、自动化编译器配置文件简介 (2)1.1什么是make命令 (2)1.2为什么要使用make命令 (2)1.3Makefile文件的结构与作用 (3)1.4 Makefile应用举例: (4)二、MakeFile规则和几种目标 (7)2.1 Makefile规则 (7)2.1.1显式规则 (7)2.1.2隐含规则 (7)2.1.3后缀规则(在高版本make命令中已由模式规则取代) (8)2.1.4模式规则 (8)2.1.5清空目标文件的规则 (8)2.2 Makefile文件的几种目标 (8)2.2.1指定目标——根据依赖生成指定目标文件。
(8)2.2.2伪目标 (8)2.2.3多目标 (9)2.2.4标准目标 (10)2.2.5特殊目标 (10)三、MakeFile的变量 (10)3.1变量定义两种方式: (11)3.1.1递归展开变量: (11)3.1.2直接展开变量: (11)3.2MakeFile的变量高级用法 (11)3.2.1变量值的替换: (11)3.2.2变量嵌套 (12)3.2.3变量取值 (12)3.2.4系统环境变量 (13)3.2.5自动化变量 (13)3.2.6预定义变量 (13)四、MakeFile的执行 (14)4.1目录搜寻 (14)4.2make的嵌套执行 (15)4.3Makefile包含 (15)4.4条件执行 (15)4.5Makefile的命令行选项 (16)五、make内嵌函数 (16)5.1文本处理函数 (16)5.2文件名处理函数 (17)5.3foreach函数 (18)5.4 if函数 (18)5.5 origin函数 (18)5.6 shell函数 (18)六、encode下Makefile执行过程分析 (18)6.1make执行过程 (22)6.2 make install 执行过程 (22)一、自动化编译器配置文件简介1.1什么是make命令Make命令是对Makefile文件进行解释执行的命令。
Makefile入门到精通
跟我一起写 Makefile1 概述——什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一 个好的和professional的程序员,makefile还是要懂。
这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要 了解HTML的标识的含义。
特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具 备完成大型工程的能力。
因为,makefile关系到了整个工程的编译规则。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定 义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个 Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的 make,Visual C++的nmake,Linux下GNU的make。
可见,makefile都成为了一种在工程方面的编译方法。
现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。
当然,不同产商的make各不相同,也有不同的语法,但其本质都是在 “文件依赖性”上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。
必竟,这个 make是应用最为广泛的,也是用得最多的。
而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。
在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。
linuxmakefile由浅入深剖析
linuxmakefile由浅入深剖析经过长时间学习linux Makefile,于是和大家分享一下,看完本文你肯定有不少收获,希望本文能教会你更多东西。
假设我们有一个程序由5个文件组成,源代码如下:/*main.c*/#include "mytool1.h"#include "mytool2.h"int main(){mytool1_print("hello mytool1!");mytool2_print("hello mytool2!");return 0;}/*mytool1.c*/#include "mytool1.h"#includevoid mytool1_print(char *print_str){printf("This is mytool1 print : %s ", print_str);}/*mytool1.h*/#ifndef _MYTOOL_1_H#define _MYTOOL_1_Hvoid mytool1_print(char *print_str);#endif/*mytool2.c*/#include "mytool2.h"#includevoid mytool2_print(char *print_str){printf("This is mytool2 print : %s ", print_str);}/*mytool2.h*/#ifndef _MYTOOL_2_H#define _MYTOOL_2_Hvoid mytool2_print(char *print_str);#endif首先了解一下make和linux Makefile。
GNU make是一个工程管理器,它可以管理较多的文件。
我所使用的RedHat 9.0的make版本为GNU Make version3.79.1。
Makefile总结文档
Makefile的书写规则1)如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。
2)如果这个工程的某几个C文件被修改,那么我们只编译被修改的C文件,并链接目标程序。
3)如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C 文件,并链接目标程序。
Makefile的规则target ... : prerequisites ...command......prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。
这就是Makefile的规则。
也就是Makefile中最核心的内容。
依赖关系的实质上就是说明了目标文件是由哪些文件生成的,换言之,目标文件是哪些文件更新的。
make是如何工作的1、make会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最终的目标文件。
3、如果edit文件不存在,或是edit所依赖的后面的.o 文件的文件修改时间要比edit这个文件新,那么,他就会执行后面所定义的命令来生成edit这个文件。
4、如果edit所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o文件的依赖性,如果找到则再根据那一个规则生成.o文件。
(这有点像一个堆栈的过程)5、当然,你的C文件和H文件是存在的啦,于是make会生成.o 文件,然后再用.o 文件生成make的终极任务,也就是执行文件edit了。
makefile中使用变量edit : main.o kbd.o command.o display.o \insert.o search.o files.o utils.occ -o edit main.o kbd.o command.o display.o \insert.o search.o files.o utils.o为了makefile的易维护,在makefile中我们可以使用变量。
Makefile入门
Makefile入门makefile很重要什么是makefile?或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。
这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。
特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。
因为,makefile关系到了整个工程的编译规则。
一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
makefile带来的好处就是——―自动化编译‖,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。
可见,makefile都成为了一种在工程方面的编译方法。
现在讲述如何写makefile的文章比较少,这是我想写这篇文章的原因。
当然,不同产商的make各不相同,也有不同的语法,但其本质都是在―文件依赖性‖上做文章,这里,我仅对GNU的make进行讲述,我的环境是RedHat Linux 8.0,make的版本是3.80。
必竟,这个make是应用最为广泛的,也是用得最多的。
而且其还是最遵循于IEEE 1003.2-1992 标准的(POSIX.2)。
在这篇文档中,将以C/C++的源码作为我们基础,所以必然涉及一些关于C/C++的编译的知识,相关于这方面的内容,还请各位查看相关的编译器的文档。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
在学习linux系统中认识到了makefile是必须要掌握的,一开始对于makefile(翻译:生成文件)不理解,经过几天的学习对makefile也有了一定的理解:
一、Makefile的作用:
makefile 关系到整个工程的编译规则,一个工程文件不计其数,其按类型,功能,模块分别放在不同的目录下,makefile定义了一些规则来指定,哪些文件需要先编译,哪些文件需要重新编译,甚至进行更复杂的功能操作,因为makefile就像一个shell脚本一样,其中也可以执行操作系统命令。
也就是通过makefile规则编写makefile文件来实现执行文件的生成,makefile对于多个文件生成的执行文件,若有某个发生改变后,makefile可以发现直接去编译,从而减少了从头开始编译的时间,提高编译效率,同时也可以很方便的修改文件,添加或者删去某些文件。
二、Makefile的规则:
1.隐晦规则:就是利用make 的自动推导的功能
2.显示规则:就是显示的在命令行中写出目标文件的依赖关系
3.变量的定义:就变量的宏替换
4.文件指示:其中包括三部分的内容,一个是在一个makefile中引
用另一个makefile,就像c语言中的include 一样;另一个是根据某些情况指定makefile中的有效部分,就像c语言的预编译#ifdef 一样;还有一个就是定义一个多行的命令。
5.注释:只有行注释用#号字符注释如果你的makefile中用到了# 你
可以用“\#“转义
一、把源代码编译成目标代码一般是一个规则。
二、把所有中间文件编译链接在一起也是一个规则。
编译需要一定的依赖文件,例如把一个.c文件编译为一个可执行文件,则一般是通过:先有.c再到.o然后到执行文件
例子:#要想生成hello.o目标,必须先有hello.c,
然后调用命令行gcc编译生成hello.o
依赖对象hello.c
hello.o:hello.c
gcc –c hello.c –o hello.o
要想生成执行程序hello,必须先执行规则hello.o,
然后调用命令行gcc链接生成hello
hello:hello.o
gcc hello.o –o hello
在例子中hello.o要依赖hello.c调用gcc编译器才能生成,执行文件hello要依赖hello.o
Makefile可以理解为由make程序进行解释的一种特殊脚本。
(备注:脚本通常可以由应用程序临时调用并执行。
各类脚本被广泛地
应用于网页设计中,因为脚本不仅可以减小网页的规模和提高网页浏览速度,而且可以丰富网页的表现,如动画、声音等。
举个最常见的例子,当点击网页上的Email地址时能自动调用Outlook Express或Foxmail这类邮箱软件,就是通过脚本功能来实现的)
首先make找到Makefile的入口规则,一般是all,或者是用户在命令行指定的target
顺着入口规则的依赖对象查找下去,检查一直查找到最终的目标,即只有被依赖而没有依赖其它对象的目标.即终目标
从最终目标顺着依赖关系依次执行到入口规则,中间只有运行命令出错,才停止执行.
如果是依赖文件,make会自动检测最后更新时间,只会去执行已经修改过的文件,以此来减少编译时间
三、在makefile也可以定义变量。
如赋值:定义变量可在规则中使用,Makefile 中使用变量
Makefile中的变量就像是c 语言的中宏一样
怎样定义变量呢?
我们在makefile最上面定义一个变量
OBJS = main.o func1.o func2.o func3.o func4.o func5.o
引用变量$(OBJS) 这就等价于main.o func1.o func2.o func3.o func4.o func5.o 就像宏一样的会被替换掉,等价后如果一个生成文件需要依赖main.o func1.o func2.o func3.o func4.o func5.o多个.o文件,则可用$(OBJS)代替。
Makefile还有自推导,判断源代码的依赖关系的功能,也就是不用我
们去为了.o文件而编写其他命令,例如:只要make看到一个*.o文件,它
就会自动的把*.c文件加到依赖关系中,如果make 找到一个func2.o 那么func2.c 就会使func2.o 的依赖文件。
并且gcc –c func2.c 也会被推导出来。
所以我们的makefile就会简单多了
在编写makefile是也有很多小细节值得注意,最为重要的一点就是命开头的空格是用tab键生成的,命令间空格也是tab键生成,还有赋值方式= 和:= 许多换行等许多应用需要注意,makefile的功能
很是强大,上述只是简单操作入门。