欢迎大家加我的群:460952208
主要是写的Makefile如何书写
先来个简单的Makefile试试吧:
在工程中,就一个test.c文件
#include <stdio.h>
int main()
{
printf("test makefile!!!\n");
return 0;
}
那么我们的Makefile文件可以这么写,很简单,一句话
Makefile文件
test:test.o
对,你没看错,就这么一句话。
我们make一下
生成了可执行的文件test
这个是最简单的
接下来我们还是这个,简单的变化一下我们的Makefile
同时make一下
可以看到gcc分成了两步,第一步生成test.o
第二步生成了目标文件test。
在上面的Makefile中,test依赖test.o生成,test.o依赖test.c生成的这个关系是由生成的目标文件一步步的往上推,如果将test.o与test的位置换一下,结果如下:
这次只生成了test.o,而没有生成test的可执行文件。
所以这个依赖的关系不能弄错,要有里面一步步的往外推。
中间加个-g是生成了可调试的文件。
.PYTHON是表示 目标是伪目标,并不生成相应的文件。.PYTHON标志的文件总是执行的。
这个Makefile我们继续变型一下:
这里主要是宏替换了原来的文件,这样也很方便了,我们不需要改下面的了,只需要修改宏中就可以了。
make 一下
接下来我们的Makefile继续修改:
让我们先熟系一下这三个:$@、$^、$<
$@ --代表目标文件(target)
$^ --代表所有的依赖文件(components)
$< --代表第一个依赖文件(components中最左边的那个)。
所以咱们的Makefile可以进一步简写:
make一下
没什么问题的。
现在我们在当前的路径下建几个文件夹:
include obj bin src
include 放头文件的,src存放源代码,obj方生成的中间文件(.o文件),bin放我们生成的可执行文件。
咱们的Makefile就是这样的
再来个大点的例子,这样一个的话太少了:
实例:
include/print.h
#ifndef PRINT_H_
#define PRINT_H_
void print();
#endif
src/print.c
#include <stdio.h>
#include "printf.h"
void print()
{
printf("测试Makefile多文件\n");
}
include/common.h
#ifndef COMMOND_H_
#define COMMOND_H_
#define TEST_NUM_MAX 10
int gnLen = 100;
#endif
src/main.c
#include <stdio.h>
#include "print.h"
#include "common.h"
int main()
{
print();
printf("%d\n",gnLen);
print();
return 0;
}
Makefile
main_OBJ=obj/main.o
print_OBJ=obj/print.o
main_SOURCE=src/main.c
print_SOURCE=src/print.c
BIN=bin/main
INCLUDE=include
CC=gcc -g
$(BIN):$(main_OBJ) $(print_OBJ)
$(CC) -o $@ $^
$(main_OBJ):$(main_SOURCE)
$(CC) -o $@ -c $< -I$(INCLUDE)
$(print_OBJ):$(print_SOURCE)
$(CC) -o $@ -c $< -I$(INCLUDE)
rebuild:clean $(BIN)
.PHONY:clean
clean:
rm -rf $(print_OBJ) $(main_OBJ) $(BIN)
~
PWD=$(shell pwd)
main_OBJ=$(PWD)/obj/main.o
print_OBJ=$(PWD)/obj/print.o
main_SOURCE=$(PWD)/src/main.c
print_SOURCE=$(PWD)/src/print.c
BIN=$(PWD)/bin/main
INCLUDE=$(PWD)/include
CC=gcc -g
$(BIN):$(main_OBJ) $(print_OBJ)
$(CC) -o $@ $^
$(main_OBJ):$(main_SOURCE)
$(CC) -o $@ -c $< -I$(INCLUDE)
$(print_OBJ):$(print_SOURCE)
$(CC) -o $@ -c $< -I$(INCLUDE)
rebuild:clean $(BIN)
.PHONY:clean
clean:
rm -rf $(print_OBJ) $(main_OBJ) $(BIN)
上面的PWD中得加shell ,不然会报错
这里没有直接将include加入进来,直接用的是-Iinlcude 来
make一下,没什么问题
运行结果:
摘抄的别人的博客:
Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。
- 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。
- 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。
- 变量的定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。
- 文件指示。其包括了三个部分,一个是在一个Makefile中引用另一个Makefile,就像C语言中的include一样;另一个是指根据某些情况指定Makefile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。
- 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“\#”。
最后,还值得一提的是,在Makefile中的命令,必须要以[Tab]键缩进。
下一篇《 教你玩Makefile(二)》主要是记录下自己的理解,自己以后方便记忆。