makefile文件采用依赖倒推的模式进行编译。
主要由以下几步构成:
1 申明
2 default 默认生成的对象
3 TARGET 链接过程
4 cpp 编译过程
5 生成一个version.h文件
6 一个空force过程
附上一个测试文件
.PHONY: default
SYSNAME=$(shell uname -s)
ifeq ($(SYSNAME),Darwin)
ECHO=echo
else
ECHO=echo -e
endif
CXX = g++
CFLAGS = -pg -Wall -std=c++0x
PRO_HOME=~/build-env/build-system
LDFLAGS = -L $(PRO_HOME)/3rd-soft/lib/
CLINC = -I $(PRO_HOME)/3rd-soft/include/
LDLIBS = -ljsoncpp -lsybdb -lgcrypt -lcurl -luuid -lglog -ljsoncpp
SOURCES = $(wildcard *.cpp ./common/*.cpp)
OBJECTS = $(patsubst %.cpp,%.o,$(SOURCES))
TARGET=program_name
# TODO: 这里加入所有默认需要编译的目标
default: version.h $(TARGET)
@echo Generation default ...
# 链接过程
${TARGET}: $(OBJECTS)
@echo Generation TARGET ...
$(CXX) $(OBJECTS) $(CLINC) $(LDFLAGS) $(LDLIBS) -o $(TARGET)
cp -f $(TARGET) ../bin/$(TARGET)
# 编译过程
%.o : %.cpp
@echo Generation cpp ...
$(CXX) -c $(CFLAGS) $(CLINC) $(LDFLAGS) $(LDLIBS) $< -o $@
# 下面是每个目标的生成过程
TEST_PROGRAM_NAME=AS
TEST_PROGRAM_NAME_CN=模块名简介
MAIN_VERSION_STRING="1.0.0"
VERSION_STRING:=$(shell LANG=C git log --oneline -1 2>/dev/null |cut -c1-7)
version.h: force
@echo Generation version.h ...
@$(ECHO) "# ifndef __TEST_SERVICE_VERSION_H__\n\
# define __TEST_SERVICE_VERSION_H__\n\
# define SERVICE_VERSION_STRING \"$(MAIN_VERSION_STRING).$(VERSION_STRING)\"\n\
# define TEST_PROGRAM_NAME \"$(TEST_PROGRAM_NAME)\"\n\
# define TEST_PROGRAM_NAME_CN \"$(TEST_PROGRAM_NAME_CN)\"\n\
# endif" > version.h
force:
@echo Generation force ...
# 程序的生成过程 {{{
# }}}
运行以后打印整理如下:
Generation force ...
Generation version.h ...
Generation cpp ...
Generation targets ...
Generation default ...
由此可见,实际运行时程序由下往上,按各自的依赖关系,先执行被依赖的部分。