(Makefile Tutorial)
http://mrbook.org/tutorials/make/
(Write Makefile with me)
http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=408225
Makefile 特殊变量:VPATH
告诉 make
在当前目录找不到的情况下,到所指定的目录中去找寻文件,目录用冒号隔开
include
类似 C
语言当中的 #include
@echo
加上“@”号之后隐藏运行时显示命令
命令执行
如果希望第二条命令在第一条命令的基础上执行,加冒号分隔
命令前加“-”忽略出错
-rm -rf *.o
export LD_LIB_DIR
传递变量到下级 Makefile
自动化变量
$@ 目标文件集
$< 符合模式的一系列文件集
$^ 所有的依赖目标的集合,如果有重复的则去除重复目标
后缀规则
.SUFFIXES: # 删除默认的后缀
.SUFFIXES: .c .o .h # 定义自己的后缀
Makefile
伪目标
.PHONY: clean
clean:
-rm -rf *.o
Examples
Makefile-1
all:
g++ main.cpp hello.cpp factorial.cpp -o hello
Makefile-2
all: hello
hello: main.o factorial.o hello.o
g++ main.o factorial.o hello.o -o hello
main.o: main.cpp
g++ -c main.cpp
factorial.o: factorial.cpp
g++ -c factorial.cpp
hello.o: hello.cpp
g++ -c hello.cpp
clean:
rm -rf *o hello
Makefile-3
# I am a comment, and I want to say that the variable CC will be
# the compiler to use.
CC=g++
# Hey!, I am comment number 2. I want to say that CFLAGS will be the
# options I'll pass to the compiler.
CFLAGS=-c -Wall
all: hello
hello: main.o factorial.o hello.o
$(CC) main.o factorial.o hello.o -o hello
main.o: main.cpp
$(CC) $(CFLAGS) main.cpp
factorial.o: factorial.cpp
$(CC) $(CFLAGS) factorial.cpp
hello.o: hello.cpp
$(CC) $(CFLAGS) hello.cpp
clean:
rm -rf *o hello
看完这些,我想说的是,以上全部都是理论知识,仅仅也就用在测试项目中可以稍微用上,在实际项目中极少机会需要自己手动来编写 Makefile 文件.因为有autoconf, automake
这些强大的工具,比如 sqlite 源代码项目的 Makefile 头两句就是
# Makefile.in generated by automake 1.9.6 from Makfile.am.
# Makefile. Generated from Makefile.in by configure.
所以最后真正需要编写的文件是
Makefile.am
或者是
Makefile.in
文件,然后通过
automake
工具或者项目
configure
可执行文件自动生成
Makefile
,另外
configure
文件也是通过
autoconf
工具自动生成的。
So in the end, let's take a look at the Makefile
of subversion project.
#
# Makefile.in: template Makefile for Subversion
#
...
VPATH = ../subversion
...
CC = gcc
CXX = g++
...
INCLUDES = -I$(top_srcdir)/subversion/include -I$(top_builddir)/subversion \
-I/usr/include/apr-1.0 -I/usr/include/apr-1.0 \
\
\
\
CFLAGS = -g3 -fno-omit-frame-pointer -fno-inline -pthread -DSVN_DEBUG -DAP_DEBUG $(EXTRA_CFLAGS)
CXXFLAGS = -g3 -fno-omit-frame-pointer -fno-inline -DSVN_DEBUG -DAP_DEBUG $(EXTRA_CXXFLAGS)
CMODEFLAGS = -std=c90
CPPFLAGS = -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE $(EXTRA_CPPFLAGS)
CMAINTAINERFLAGS = -Wall -Wpointer-arith -Wwrite-strings -Wshadow -Wformat=2 -Wunused -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wno-multichar -Wredundant-decls -Wnested-externs -Winline -Wno-long-long -Wno-string-plus-int -Wno-format-nonliteral -Wno-system-headers -Wold-style-definition -Werror=declaration-after-statement -Werror=implicit-function-declaration
COMPILE = $(CC) $(CMODEFLAGS) $(CPPFLAGS) $(CMAINTAINERFLAGS) $(CFLAGS) $(INCLUDES)
...
all: mkdir-init local-all
clean: local-clean
distclean: local-distclean
extraclean: local-extraclean
install: local-install revision-install
include $(top_srcdir)/build-outputs.mk
local-all: fsmod-lib ramod-lib lib bin test sub-test tools
...
#
# Implicit rules for creating outputs from input files
#
.SUFFIXES:
.SUFFIXES: .c .cpp .lo .o .la-a .la \
.po .spo .mo .rnc .rng .dtd .xsd .sql .h
.sql.h:
$(PYTHON) $(top_srcdir)/build/transform_sql.py $< $(top_srcdir)/$@
.c.o:
$(COMPILE) -o $@ -c $<
.cpp.o:
$(COMPILE_CXX) -o $@ -c $<
.c.lo:
$(LT_COMPILE) -o $@ -c $<
.cpp.lo:
$(LT_COMPILE_CXX) -o $@ -c $<
.la.la-a:
sed "/library_names/s/'.*'/''/" $< > $@
...
clean-swig: clean-swig-headers clean-swig-py clean-swig-rb clean-swig-pl
@rm -f .swig_checked
...