makefile文件编写,编写一个简单的 makefile 文件
makefile文件编写,编写一个简单的 makefile 文件详细介绍
本文目录一览: makefile怎么用?
是要先./configure一下,再make,再make install。
源码安装的方法是:
step1 ./configure
step2 make
step3 make install
如果仔细看,会发现,解压之后的软件源码包的目录下没有Makefile,然后在执行了./configure
会生成了很多奇怪名字的文件(./configure命令就是执行软件源码根目录下的名为configure的脚本),就包括了Makefile文件,在./configure的时候,Makefile.in是入口。
扩展资料:
Make工具最主要也是最基本的功能就是通过makefile文件来描述源程序之间的相互关系并自动维护编译工作。
而makefile 文件需要按照某种语法进行编写,文件中需要说明如何编译各个源文件并连接生成可执行文件,并要求定义源文件之间的依赖关系。
makefile 文件是许多编译器--包括 Windows NT 下的编译器--维护编译信息的常用方法,只是在集成开发环境中,用户通过友好的界面修改 makefile 文件而已。
在 UNIX 系统中,习惯使用 Makefile 作为 makefile 文件。如果要使用其他文件作为 makefile,则可利用类似下面的 make 命令选项指定 makefile 文件:
参考资料来源:百度百科-Makefile
Makefile详解
make 命令执行时,需要根据一些规则来决定按照怎么样的方式去 编译和链接程序 ,这些规则就由 makefile 文件所指定。如果我们 makefile 文件写的足够好,make 命令会自动地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。
首先,本文将给出一个makefile文件的示例,以便大家能有一个直观感受,这个例子来源于 GNU的make使用手册 。在这个例子中,我们的工程有8个c文件,和3个头文件,我们要写一个makefile来告诉make命令如何编译和链接这几个文件。例子如下:
这个例子里 make 的编码规则如下:
a. 如果这个工程没有编译过,那么我们的所有c文件都要编译并被链接。 b. 如果这个工程的某几个c文件被修改,那么我们只编译被修改的c文件,并链接目标程序。 c. 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的c文件,并链接目标程序。
在详细拆解上一节的 Makefile 之前,先来看下 Makefile 的基本范式。
target可以是一个 1) object file(可执行文件) ,2) 可执行文件 ,还可以是个3) label(标签) ,关于标签这个特性,在后面的 伪目标 章节还会有叙述。
prerequisites 就是,要生成那个target所需要的文件或是目标。 command 也就是 make 需要执行的命令,可以是任意的 shell 命令。
这是一个文件的依赖关系,也就是说,target 这一个或多个的目标文件依赖于 prerequisites 中的文件,其生成规则定义在 command 中。同时, prerequisites 中如果有一个以上的文件比target文件要新的话, command 所定义的命令就会被执行。这就是 Makefile 的规则,也是 Makefile 中 最核心 的内容。
有了这些规则后,再来分析上面的例子。在这个 makefile 中,目标文件(target)包含:
依赖文件(prerequisites)就是冒号后面的那些 .c 文件和 .h 文件。每一个 .o 文件都有一组依赖文件,而这些 .o 文件又是执行文件 edit 的依赖文件。
在定义好依赖关系后,后续的那一行定义了如何生成目标文件的系统命令, 一定要以一个tab键作为开头 。 make 会比较 targets 文件和 prerequisites 文件的修改日期,如果 prerequisites 文件的日期要比targets文件的日期要新,或者 target 不存在的话,那么,make就会执行后续定义的命令。
我们可以把这个内容保存在名字为 makefile 或 Makefile 的文件中,然后在该目录下直接输入命令 make 就可以生成可执行文件edit。如果要删除执行文件和所有的中间目标文件,那么,只要简单地执行一下 make clean 就可以了。 注:反斜线(\)是换行符的意思,这样比较便于阅读。
这里要说明一点的是, clean 不是一个文件,它只不过是一个动作名字,有点像C语言中的 lable 一样,其冒号后什么也没有,那么,make就不会去找它的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令(不仅用于 clean,其他 lable 同样适用),就要在 make 命令后显式指出这个 lable 的名字。这样的方法非常有用, 我们可以在一个 makefile 中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份 ,等等。
在默认的方式下,也就是我们只输入make命令。那么,
这就是整个 make 的依赖性,make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,如果出现错误,比如最后被依赖的文件找不到,那么make就会直接退出,并报错,而对于所定义的命令的错误,或是编译不成功,这些都不在 make 职责范围内。
通过上述分析,我们知道,像 clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,不过,我们可以显示要 make 执行。即命令 make clean ,以此来清除所有的目标文件,以便重编译。
在上面的例子中可以看到,后缀为 .o 的一大串文件名写了两次,这样比较费时费力,而且如果文件有所增减,要修改的地方也非常多,对以后的维护造成困难。在这种情形下,我们可以在Makefile里使用变量代替这一大串依赖文件,这里变量的使用方式基本类似于shell脚本里变量的使用方法。
我们可以在makefile一开始就这样定义:
那么接下来我们就可以很方便地在我们的Makefile中以 $(objects) 的方式来使用这个变量了,于是如果有新的 .o 文件加入,我们只需简单地修改一下 objects 变量就可以了。
GNU 的 make 很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个 .o 文件后都写上类似的命令。因为,我们的make会自动识别,并自己推导命令。
只要make看到一个 .o 文件,它就会自动的把 .c 文件加在依赖关系中,如果make找到一个 FILENAME.o ,那么 FILENAME.c ,就会是 FILENAME.o 的依赖文件。并且 cc -c FILENAME.c 也会被推导出来,于是,我们的makefile 再也不用写得这么复杂。我们的新makefile就可以这么写了。
这种方法,也就是make的**。上面文件内容中,“.PHONY”表示,clean是个伪目标文件。
编写一个makefile文件主要包含哪些内容
一、Makefile里有什么?
Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
1、显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
2、隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
3、变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
4、文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
5、注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“\#”。
最后,还值得一提的是,在Makefile中的命令,必须要以[Tab]键开始。
编写一个简单的 makefile 文件
obj=main.o iodata.o run.o io.s
example: $(obj)
cc -o example $(obj)
#下面的可有可无
main.o:main.c
cc -c main.o
iodata.0:iodata.c
cc -c iodata.c
run.o:run.c
cc -c run.c
#io.s 我不敢确定啊
makefile文件里面主要有三种内容:
1.变量声明:
变量声明就是一种基本的严格字符替换的操作。
比如在前面声明了:objects=program.o foo.o utils.o
那么在后面出现的所有$(objects)或者${objects}都会被自动替换成上面的那个字符序列,而且是严格替换,即不带空格的。
2.映射法则
3.命令:
映射法则和命令通常都是联合起来组成这样的结构形式:
target... : prerequisites..
command
可以简单地理解为通过prerequisites,也就是先决的依赖文件,采取后面描述的相应的命令(这里的命令都是linux里的shell命令)command之后(一般是)生成了文件target。命令的前面都要按以下tab建留一段空白来表示它是命令。
有的target后面并没有先决条件,也就是后面的命令是无条件执行的。
makefile 文件c语言程序:
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
makefile:
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
使用linux编程怎么写makefile
Makefile语法基础
在Linux下,自动化编译工具是通过make命令来完成的(一些工具厂商也提供了它们自己的make命令,如gmake等),make命令的基本格式如下:
make
[-f
makefile]
[label]
它可以通过-f参数指定输入文件,当省略-f参数时,默认输入文件名为Makefile,由于我们通常不用这个-f参数,往往就用默认的Makefile文件名。
Makefile是一个文本文件,它是基于一定的语法规则的,它的基本执行规则定义如下:
target
:
[prerequisites]
command
target
标签,用于标志当前构建的规则,它也可以是文件。
prerequisites
依赖项,在构建该标签的时候先执行的规则
command
make需要执行的命令。(任意的Shell命令)
注意:Makefile的target是顶格写的,而Command需要加一个Tab键。我这里为了排版看起来舒服点,每一行都多加了一个Tab键,如果要使用本文的Makefile示例,请去掉各行的第一个Tab键,否则make的时候报错。
例如,我们编写一个简单的Makefile:
clean:
@echo
"clean"
all:
@echo
"all"
当我们直接执行make命令的时候,输出如下:
tianfang
>
make
clean
tianfang
>
make
all
all
tianfang
>
make
clean
clean
从中我们可以看到:默认情况下构建第一个标签。可以通过在命令行参数中通过参数构建指定标签。
linux如何编写并使用makefile
1、先写Makefile编译出***.ko文件
模板如下,保存到命名为Makefile文件里,放到你代码的同级目录下
TARGET=my_proc.ko
LINUXDIR=/lib/modules/$(shell uname -r)/build
PWD=$(shell pwd)
obj-m :=
obj-m += my_proc.o
all: $(TARGET)
$(TARGET): $(OBJS)
make -C $(LINUXDIR) SUBDIRS=$(PWD) modules
clean:
rm -f modules.order Module.symvers $(TARGET) *.mod.c *.o
rm -rf .tmp_versions .mod* Module.markers
2、make
3、root权限下用命令插入模块
insmod my_proc.ko
4、可以用你写的应用程序打开、操作模块了
5、查看模块命令
lsmod
cat /proc/modules
modinfo my_proc.ko
6、root下卸载模块
rmmod
如何自己编写Makefile
相信很多朋友都有过这样的经历,看着开源项目中好几页的makefile文件,不知所云。在日常学习和工作中,也有意无意的去回避makefile,能改就不写,能用ide就用ide。其实makefile并没有想象的那么难写,只要你明白了其中的原理,自己实践几次。你也可以自己写makefile,让别人对你头来羡慕的目光。
下面本人介绍一下自己的学习成果,初学阶段,欢迎大家多多指正。
简单的说,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至可以在makefile中执行shell脚本。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。
关于程序的编译和链接
一般来说,无论是C还是C++,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o
文件,即 Object File,这个动作叫做编译(compile),一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。然后再把大量的Object
File合成执行文件,这个动作叫作链接(link)。
编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。
链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object
File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给中间目标文件打个包,在Windows下这种包叫“库文件”(Library
File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。
下面我们开始看看如何自己写出makefile。
Makefile的规则
目标 :
需要的条件 (注意冒号两边有空格)
命令 (注意前面用tab键开头)
解释一下:
1
目标可以是一个或多个,可以是Object File,也可以是执行文件,甚至可以是一个标签。
2
需要的条件就是生成目标所需要的文件或目标
3
命令就是生成目标所需要执行的脚本
总结一下,就是说一条makefile规则规定了编译的依赖关系,也就是目标文件依赖于条件,生成规则用命令来描述。在编译时,如果需要的条件的文件比目标更新的话,就会执行生成命令来更新目标。
下面举个简单的例子说明。如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。
edit : main.o kbd.o command.o display.o
/
insert.o search.o files.o utils.o
cc -o edit
main.o kbd.o command.o display.o /
insert.o search.o
files.o utils.o
main.o : main.c
defs.h
cc -c main.c
kbd.o : kbd.c defs.h
command.h
cc -c kbd.c
command.o : command.c defs.h
command.h
cc -c command.c
display.o : display.c defs.h
buffer.h
cc -c display.c
insert.o : insert.c defs.h
buffer.h
cc -c insert.c
search.o : search.c defs.h
buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h
command.h
cc -c files.c
utils.o : utils.c
defs.h
cc -c utils.c
clean :
rm edit main.o
kbd.o command.o display.o /
insert.o search.o files.o
utils.o
将上面的内容写入到Makefile文件中,然后执行make就可以进行编译,执行make
clean就可以删除所有目标文件。解释一下,也就是说生成最终的目标文件edit,依赖于一系列的.o目标文件,而这些.o文件又是需要用源文件来编译生成的。
需要注意的是,clean后面没有条件,而clean本身也不是文件,它只不过是一个动作名字,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。
make是如何工作的
在默认的方式下,也就是我们只输入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中使用变量
前面的知识已经足以让你自己完成一个简单的makefile了,不过makefile的精妙之处远不止如此,下面来看看如何在makefile中使用变量吧。
在上面的例子中,先让我们看看edit的规则:
edit : main.o kbd.o command.o
display.o /
insert.o search.o files.o
utils.o
cc -o edit main.o kbd.o command.o display.o
/
insert.o search.o files.o utils.o
我们可以看到[.o]文件的字符串被重复了两次,如果我们的工程需要加入一个新的[.o]文件,那么我们需要在两个地方加(应该是三个地方,还有一个地方在clean中)。当然,我们的makefile并不复杂,所以在两个地方加也不累,但如果
makefile变得复杂,那么我们就有可能会忘掉一个需要加入的地方,而导致编译失败。所以,为了makefile的易维护,在makefile中我们可以使用变量。makefile的变量也就是一个字符串,理解成C语言中的宏可能会更好。
于是,我们使用变量objects
objects = main.o kbd.o command.o display.o
/
insert.o search.o files.o utils.o
这样一来,原来的makefile变成如下的样子:
objects = main.o kbd.o command.o display.o
/
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c
main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o
: files.c defs.h buffer.h command.h
cc -c files.c
utils.o
: utils.c defs.h
cc -c utils.c
clean :
rm
edit $(objects)
这样看起来方便多了吧,也更加省事了。如果有新的.o文件怎么办?当然是在objects里面添加了,这样只需要一处改变,很方便吧。
让make自动推导
GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。
只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且
cc -c whatever.c
也会被推导出来,于是,我们的makefile再也不用写得这么复杂。我们的是新的makefile又出炉了。
objects = main.o kbd.o command.o display.o
/
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : defs.h
kbd.o :
defs.h command.h
command.o : defs.h command.h
display.o : defs.h
buffer.h
insert.o : defs.h buffer.h
search.o : defs.h
buffer.h
files.o : defs.h buffer.h command.h
utils.o :
defs.h
clean :
rm edit
$(objects)
当然,如果你觉得那么多[.o]和[.h]的依赖有点不爽的话,好吧,没有问题,这个对于make来说很容易,谁叫它提供了自动推导命令和文件的功能呢?来看看最新风格的makefile吧。
objects = main.o kbd.o command.o display.o
/
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
$(objects) : defs.h
kbd.o
command.o files.o : command.h
display.o insert.o search.o files.o :
buffer.h
clean :
rm edit $(objects)
如何编写makefile
makefile其实就是shell基本,把我们在编译一个程序中所有的步骤(命令)都写进去,然后执行make命令时系统自动运行makefile文件内的指令,接着就是自动编译了,其实和手工编译原理相同,只是makefile实现了自动化编译而已。至于怎么写?不同类型的程序有各自的编译器和编译指令,不是很复杂的编译过程不用makefile最好,gtk+编程最喜欢使用makefile了,你去看看gtk+编程例子里的makefile吧,QT自动创建的makefile非常恐怖,内容相当复杂
如果你想写
Makefile
的话,那么你只要用一个不将制表符过滤掉的文本编辑器就可以了,用
vi/vim
可以,用
emacs
可以,用其它的
geditor
也是可以的,只要是文本编辑器就可以了。你在
win
下也可以用记事本写
Makefile
,当然要确保你的系统已经安装了
make
了(最好了
GNU
make)。Makefile
是不需要后缀的,也就是说
Makefile
的文件名就是
Makefile。
下面我给出一个我写的一个简单的
Makefile
给你参考一下吧:
#
Makefile
for
'kmp'
CC=gcc
CFLAGS=-g
1 # To build modules outside of the kernel tree, we run "make"
2 # in the kernel source tree; the Makefile these then includes this
3 # Makefile once again.
4 # This conditional selects whether we are being included from the
5 # kernel Makefile or not.
6 ifeq ($(KERNELRELEASE),)
7
8 # Assume the source tree is where the running kernel was built
9 # You should set KERNELDIR in the environment if it's elsewhere
10 KERNELDIR ?= /lib/modules/$(shell uname -r)/build
11 # The current directory is passed to sub-makes as argument
12 PWD := $(shell pwd)
13
14 modules:
15 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
16
17 modules_install:
18 $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install
19
20 clean:
21 rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
22
23 .PHONY: modules modules_install clean
24
25 else
26 # called from kernel build system: just declare what our modules are
27 obj-m := hello.o
28 endif
在lwn上可以找到这个例子,你可以把以上两个文件放在你的某个目录下,然后执行make,也许你不一定能成功,因为linux kernel 2.6要求你编译模块之前,必须先在内核源代码目录下执行make,换言之,你必须先配置过内核,执行过make,然后才能make你自己的模块.原因我就不细说了,你按着她要求的这么去做就行了.
另外注意命令前面必须是tab
什么是命令?
类似于这种
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
http://wiki.netbsd.se/index.php/Basic_Unix_programming#Using_BSD_Make
去看看,也许有帮助
你先用gcc把它给编译出来。然后再想用makefile
gcc最一般的用法就是:
gcc -o 要生成的可执行文件名 源代码文件名
如:gcc -o hello.x hello.c
如果一些头文件要指明的话,可以这样:
gcc -o hello.x -I头文件所在的文件夹 -l一些库名 hello.c
最通常,我们用到一些数学库。gcc -o hello.x -lm hello.c
makefile的话,你可以基于上述的语句进行修改:建议你看点资料,或一些典型的例子。但是注意的是规则那一行,得用Tab键打头。
hello.x : hello.o
gcc -o hello.x hello.o (这一行,得用Tab打头)
hello.o : hello.c 头文件
gcc -c hello.o hello.c -I头文件所在目录 -lm (这一行,得用Tab打头)
[Linux]编写一个简单的C语言程序,编写Makefile文件。
c语言程序:
#include
#include
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
makefile:
# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
这个已经通过调试了!
//calculate.h
#ifndef DEFCALCULATE_H
#define DEFCALCULATE_H
#include
#include