makefile学习笔记

linux下开发c/c++程序需要写makefile,makefile是用来组织和构建工程的。其实不只编写c/c++程序要写makefile,所有语言的开发都可以写makefile,甚至所有的事情都可以。本篇就简要记录下写makefile常用操作。

make命令

执行命令make时会在当前目录下寻找名称为makefileMakefile的文件去执行,要指定执行哪个文件,需要执行如下命令:

1
$ make -f Makefile.1

可以在运行make命令时定义变量,如:make CFLAGS=-O2

编写规则

基本规则

makefile由一组规则组成,每条规则的格式是:

1
2
3
target ...: prerequisites ...
command
...

例如:

1
2
3
目标: 条件1 条件2
命令1
命令2

目标和条件之间的关系是:要更新目标必须先更新它所有的条件。有一个条件更新则目标也要被更新。

命令列表每行必须以tab开头。

常用的目标名:

  • all #执行主要的编译工作,通常为缺省目标;
  • install #执行编译后的安装工作;
  • clean #清理编译结构;

隐含规则

如果一个目标分开写多条规则,则只有其中一条规则允许有命令列表,否则以最后一条规则的命令列表执行。

隐含规则可以用make -p命令查看,例如省略了命令列表的规则就利用了隐含规则。

我们写makefile时不利用隐含规则也能完成相应工作,只不过就多写些罢了。

特殊变量

  • $@ #表示规则中的目标;
  • $< #表示规则中的第一个条件;
  • $^ #表示规则中的所有条件;
  • $? #表示规则中所有比目标新的条件;

实例

源码

设有如下源码文件:

a.h

1
2
3
4
#ifndef _A_H_
#define _A_H_
void hello_a();
#endif

b.h

1
2
3
4
#ifndef _B_H_
#define _B_H_
void hello_b();
#endif

a.c

1
2
3
4
5
6
#include "a.h"
#include <stdio.h>
void hello_a()
{
printf("hello,a\n");
}

b.c

1
2
3
4
5
6
#include "b.h"
#include <stdio.h>
void hello_b()
{
printf("hello,b\n");
}

main.c

1
2
3
4
5
6
7
8
#include "a.h"
#include "b.h"
int main(void)
{
hello_a();
hello_b();
return 0;
}

写makefile

上面的源码如何通过makefile组织并构建工程呢?下面是普通写法:

1
2
3
4
5
6
main: main.o a.o b.o
gcc -o $@ $^
.c.o:
gcc -c $<
clean:
rm -f *.o main

上面的写法对c++代码一样有效,就是把gcc换成g++,把.c.o换成.cpp.o就可以。

高级一些的写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
CC=gcc
CFLAGS = -Wall -O2
CFLAGS += -I./ -L./
LFLAGS = -lpthread -lm
SRCS = a.c \
b.c \
main.c
OBJS=$(SRCS:.c=.o)
EXEC=test
all:$(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(EXEC) $(LFLAGS)
clean:
rm -f $(EXEC) $(OBJS)

总结

以上记录的这些作为入门已经够了,要想更深入学习可以网上搜索跟我一起写Makefile,跟高手学习更好。