make工程管理器

2 篇文章 0 订阅

1 makefile 基本结构

makefile中通常包含如下内容:

  1. 需要由 make 工具创建的目标体(target),通常是目标文件或可执行文件;
  2. 要创建的目标体所依赖的文件(dependency_file);
  3. 创建每个目标体时需要运行的命令(command)
    ,这一行必须以制表符(tab 键)开头。
    格式为:
    target: dependency_files
    	command /* 该行必须以 TAB 开头 */

e.g.创建makefile文件。将通过两个文件hello.chello.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 中常见的预定义变量

预定义变量含义
AR库文件维护程序的名称,默认值为 ar
AS汇编程序的名称,默认值为 as
CCC 编译器的名称,默认值为 cc
CPPC 预编译器的名称,默认值为$(CC) –E
CXXC++编译器的名称,默认值为 g++
FCFortran 编译器的名称,默认值为 f77
RM文件删除程序的名称,默认值为 rm –f
ARFLAGS库文件维护程序的选项,无默认值
ASFLAGS汇编程序的选项,无默认值
CFLAGSC 编译器的选项,无默认值
CPPFLAGSC 预编译的选项,无默认值
CXXFLAGSC++编译器的选项,无默认值
FFLAGSFortran 编译器的选项,无默认值

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 中常见隐式规则目录

对应语言后缀名隐式规则
C 编译:.c 变为.o$(CC) –c $(CPPFLAGS) $(CFLAGS)
C++编译:.cc 或.C 变为.o$(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
Pascal 编译:.p 变为.o$(PC) -c $(PFLAGS)
Fortran 编译:.r 变为-o$(FC) -c $(FFLAGS)

通过隐式规则改写后的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 的命令行选项

命 令 格 式含义
-C dir读入指定目录下的 makefile
-f file读入当前目录下的 file 文件作为 makefile
-I忽略所有的命令执行错误
-I dir指定被包含的 makefile 所在目录
-n只打印要执行的命令,但不执行这些命令
-p显示 make 变量数据库和隐含规则
-s在执行命令时不显示命令
-w如果 make 在执行过程中改变目录,则打印当前目录名


参考:《嵌入式Linux应用程序开发标准教程》作者:华清远见

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值