make 是 UNIX 中的一个方便程序编译的工具程序。
当我们有多个 C 或 FORTRAN subroutines 分散在不同的
档案时,如果我们写一个叫做 Makefile 的档案,再使用
make
这个指令,则 UNIX 系统会根据 Makefile 内容将所有档案
个别 compile,并且在最后连结成可执行档。
使用 make 跟 Makefile 的另一个优点,是如果我们在稍后
修改了其中一个档案,再重新 make,则系统会「只」compile
那个修改过的档案,重新连结成新的可执行档。
如何使用make?
在shell的提示符号下,若键入 "make",则它会到目前的目录下找寻 Makefile
这个档案。然后依照Makefile中所记录的步骤一步一步的来执行。
在我们写程序的时候,如果事先就把compiler程序所需要的步骤
先写在Makefile中的话,想要compiler程序的时候就只要打入make的指令。
只要程序无误的话,就可以获得所需要的结果了!
Makefile的格式:
(1)批注:
在Makefile中,任何以"#"为开头的的文字皆为批注,make
在解译Makefile的时候会忽略它。
(2)续接下行:
在Makefile中,若一行不足以容纳该命令的时候。可于该行尾端
加一反斜线 (/)表示下一行为本行之延续,两行应视为一行来处理。
(3)宏(macro, 也就是 make 语言所用的文字变量)
宏的格式为: <string> = <value>
例如:
CFLAGS = -O -systype bsd43
其实make本身已有许多的default的macro,如果要查看
这些macro的话,可以下 make -p 的命令。
(4)法则(Rules)
格式如下:
<Target 1>: <depend>
<command 1>
<command 2>
....
<Target 2>: <depend>
<command 3>
<command 4>
....
(5)一个非常简单的Makefile
假设我们有一个程序,共分为下面的部份:
menu.c 主要的程序代码部份
menu.h menu.c的include file
utils.c 提供menu.c呼叫的一些function calls
utils.h utils.c的include file
同时本程序亦叫用了ncurses的function calls。
而menu.c和utils.c皆放在/usr/src/menu下。
但menu.h和utils.h却放在/usr/src/menu/include下。
而程序做完之后,执行文件名为menu且要放在/usr/bin下面。
----------------------------------- (Makefile begin:不含此行)
# This is the Makefile of menu
CC = gcc
CFLAGS = -DDEBUG -c
LIBS = -lncurses
INCLUDE = -I/usr/src/menu/include
#以上 CC, CFLAGS,LIBS,跟 INCLUDE 是四个我们自己定义的 macro
all: clean install
install: menu
chmod 750 menu
cp menu /usr/bin
menu: menu.o
$(CC) -o $@ $? $(LIBS)
menu.o:
$(CC) $(CFLAGS) -o $@ menu.c $(INCLUDE)
utils.o:
$(CC) $(CFLAGS) -o $@ utils.c $(INCLUDE)
clean:
-rm *.o
-rm *~
------------------------------------ (Makefile end:不含此行)
★★★★★★★★★★★★★★★★★★★★★★★★★★★
注意:上例 Makefile 中,某些行前面有一大段空格,
那是使用 vi 编辑器「按一次」<Tab> 「键」空出来的,
如果你用 ve ,因为 ve 将 <Tab> 当空格处理,
make 时就会发生错误。
★★★★★★★★★★★★★★★★★★★★★★★★★★★
在上述的 Makefile中,若要使用某个已经定义的 macro,
可用 $(macro_name) 如此的形式。make会自动的加以展开。
注:$@ 为该rule的Target,而 $? 则为该 rule 的 depend。
若在 command 的前面加一个"-",表示若此 command 发生错误则不予理会,
继续执行下去。
上述的Makefile的关系可以表示如下:
all
/ /
clean install
/
menu
/ /
menu.o utils.o
若只想清除 source 以外的档案,可以打 make clean。
若只想做出 menu.o 可以打 make menu.o。
若想一次全部做完,可以打 make all 或是 make。
以下是另一个 FORTRAN 程序使用 Makefile 的例子:
------------------------------ (Makefile begin:不含此行)
# 定义 SUBS 这个 macro (名字可以任取,习惯上用大写),
# 用来包含所有个别档案的 object file
# 例如, add.o 是 add.f 被编译后的 object file name
SUBS = add.o adjusth.o augment.o bfgs.o compar.o con_eval.o /
conmin.o eq.o eval.o form.o cost.o geteps.o grad.o /
inith.o inverth.o invrt2.o
# 你可以用 "make all", "make conmin", 或 "make" 指令
# 来得到最后的可执行档
#
# 以下这一行是说,"make all" 或 "make", make 程序就会
# 先把以下 "conmin: $(SUBS)" 部分先完成
all: conmin
# 以下这个部分是说,要将可执行档(-o conmin) conmin 编译出来前,
# make 程序得先将上面定义的 "SUBS = ..." 的所有 *.o 档先编译出来
# 然后才执行 f77 -o conmin $(SUBS) -llapack -lblas -lm
#
# "-llapack -lblas -lm" 表示在最后编译阶段
# 连结 lapack, blas, 及 math library
conmin: $(SUBS)
f77 -o conmin $(SUBS) -llapack -lblas -lm
# you can type "make clean" to delete all *.o object files
clean:
rm -f *.o
# 凡是碰到 .f 檔,就叫 make 用 f77 -c file_name.f
# 编译产生 file_name.o Object file
.f.o:
f77 -c $<
------------------------------------ (Makefile end:不含此行)
★★★★★★★★★★★★★★★★★★★★★★★★★★★
注意:上例 Makefile 中,某些行前面有一大段空格,
那是使用 vi 编辑器「按一次」<Tab> 「键」空出来的,
如果你用 ve ,因为 ve 将 <Tab> 当空格处理,
make 时就会发生错误。
★★★★★★★★★★★★★★★★★★★★★★★★★★★