1 makefile 基本结构
makefile
中通常包含如下内容:
- 需要由
make
工具创建的目标体(target
),通常是目标文件或可执行文件; - 要创建的目标体所依赖的文件(
dependency_file
); - 创建每个目标体时需要运行的命令(
command
)
,这一行必须以制表符(tab
键)开头。
格式为:
target: dependency_files
command /* 该行必须以 TAB 开头 */
e.g.
创建makefile
文件。将通过两个文件hello.c
和hello.h
创建目标文件hello.o
。
#The simplest example
hello.o: hello.c hello.h
gcc –c hello.c –o hello.o
执行make
<linux> make hello.o
gcc -c hello.c -o hello.o
<linux> ls
hello.c hello.h hello.o makefile
2 makefile 变量
变量是在 makefile
中定义的名字,用来代替一个文本字符串,该文本字符串称为该变量的值。在具体要求下,这些值可以代替目标体、依赖文件、命令以及 makefile
文件中其他部分。在 makefile
中的变量定义有两种方式:一种是递归展开方式,另一种是简单方式。
递归展开方式定义的变量是在引用该变量时进行替换的,即如果该变量包含了对其他变量的引用,则在引用该变量时一次性将内嵌的变量全部展开,虽然这种类型的变量能够很好地完成用户的指令,但是它也有严重的缺点,如不能在变量后追加内容(因为语句:CFLAGS = $(CFLAGS) -O
在变量扩展过程中可能导致无穷循环)。
为了避免上述问题,简单扩展型变量的值在定义处展开,并且只展开一次,因此它不包含任何对其他变量的引用,从而消除变量的嵌套引用。
递归展开方式的定义格式为:VAR=var
。
简单扩展方式的定义格式为:VAR:=var
。make
中的变量使用均使用的格式为:$(VAR)
。e.g.
准备文件:
my.h
/* my.h */
#include <stdio.h>
#include <stdlib.h>
test.c
/*test.c*/
#include "my.h"
int main(int argc, char *argv[])
{
int x,i, n = 0;
sscanf(argv[1], "%d", &x);
sum(x);
for(i = 1; i<= x; i++)
{
n += i;
}
printf("The sum of 1-%d is %d \n", x, n);
}
sum.c
/* sum.c */
#include "my.h"
int sum(int m)
{
int i, n = 0;
for (i = 1; i <= m; i++)
{
n += i;
printf("The sum of 1-%d is %d\n", i, n);
}
}
makefile
CC = gcc
CFLAGS1 = -fPIC -Wall -c
CFLAGS2 = -shared -o
LIBSO = -lsum
LIBSONAME = libsum
OP1 = sum
MAIN = test
SODIR = /lib
all : $(MAIN).c $(LIBSONAME).so $(OP1).o
$(CC) -o $(MAIN) $(MAIN).c -L . $(LIBSO)
rm $(OP1).o
$(LIBSONAME).so : $(OP1).o
$(CC) $(CFLAGS2) $(LIBSONAME).so $(OP1).o
sudo mv $(LIBSONAME).so $(SODIR)
$(OP1).o : $(OP1).c
$(CC) $(CFLAGS1) $(OP1).c
clean:
sudo rm $(SODIR)/$(LIBSONAME).so
rm $(MAIN)
键入命令及终端反馈
<linux> ls
makefile my.h sum.c test.c
<linux> make all
gcc -fPIC -Wall -c sum.c
sum.c: In function ‘sum’:
sum.c:13:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
gcc -shared -o libsum.so sum.o
sudo mv libsum.so /lib
gcc -o test test.c -L . -lsum
test.c: In function ‘main’:
test.c:8:3: warning: implicit declaration of function ‘sum’ [-Wimplicit-function-declaration]
sum(x);
^~~
rm sum.o
<linux> ./test 5
The sum of 1-1 is 1
The sum of 1-2 is 3
The sum of 1-3 is 6
The sum of 1-4 is 10
The sum of 1-5 is 15
The sum of 1-5 is 15
<linux> make clean
sudo rm /lib/libsum.so
rm test
makefile 中常见的变量
makefile
中常见的预定义变量
makefile
中常见的自动变量
通过自动变量改写后的makefile
文件
CC = gcc
CFLAGS1 = -fPIC -Wall -c
CFLAGS2 = -shared -o
LIBSO = -lsum
LIBSONAME = libsum
OP1 = sum
MAIN = test
SODIR = /lib
all : $(MAIN).c $(LIBSONAME).so $(OP1).o
$(CC) -o $(MAIN) $< -L . $(LIBSO)
rm $(OP1).o
$(LIBSONAME).so : $(OP1).o
$(CC) $(CFLAGS2) $(LIBSONAME).so $<
sudo mv $(LIBSONAME).so $(SODIR)
$(OP1).o : $(OP1).c
$(CC) $(CFLAGS1) $<
clean:
sudo rm $(SODIR)/$(LIBSONAME).so
rm $(MAIN)
3 makefile 规则
3.1 隐式规则
makefile
中常见隐式规则目录
通过隐式规则改写后的makefile
文件
CC = gcc
CFLAGS1 = -fPIC -Wall -c
CFLAGS2 = -shared -o
LIBSO = -lsum
LIBSONAME = libsum
OP1 = sum
MAIN = test
SODIR = /lib
all : $(MAIN).c $(LIBSONAME).so $(OP1).o
$(CC) -o $(MAIN) $< -L . $(LIBSO)
rm $(OP1).o
$(LIBSONAME).so : $(OP1).o
$(CC) $(CFLAGS2) $(LIBSONAME).so $<
sudo mv $(LIBSONAME).so $(SODIR)
$(CC) $(CFLAGS1) $<
clean:
sudo rm $(SODIR)/$(LIBSONAME).so
rm $(MAIN)
3.2 模式规则
模式规则是用来定义相同处理规则的多个文件的。它不同于隐式规则,隐式规则仅仅能够用 make
默认的
变量来进行操作,而模式规则还能引入用户自定义变量,为多个文件建立相同的规则,从而简化 makefile
的编写。
通过模式规则改写后的makefile
文件
CC = gcc
CFLAGS1 = -fPIC -Wall -c
CFLAGS2 = -shared -o
LIBSO = -lsum
LIBSONAME = libsum
OP1 = sum
MAIN = test
SODIR = /lib
all : $(MAIN).c $(LIBSONAME).so $(OP1).o
$(CC) -o $(MAIN) $< -L . $(LIBSO)
rm $(OP1).o
$(LIBSONAME).so : $(OP1).o
$(CC) $(CFLAGS2) $(LIBSONAME).so $<
sudo mv $(LIBSONAME).so $(SODIR)
%.o : %.c
$(CC) $(CFLAGS1) $<
clean:
sudo rm $(SODIR)/$(LIBSONAME).so
rm $(MAIN)
4 make 管理器的使用
make
的命令行选项
文章目录
参考:《嵌入式Linux应用程序开发标准教程》作者:华清远见