First define directory variables, you specifies this to tell `make' where is your project?
PROJECT_ROOT_DIR = /devel/src/foo
Second, specify the common compiler settings, most of my time is build for embedded target, so here is the code:
export ARCH :=arm
export CROSS_COMPILE := arm-linux-
#
# Include make variables (CC, etc...)
#
ASM := $(CROSS_COMPILE)as
LD := $(CROSS_COMPILE)ld
CC := $(CROSS_COMPILE)gcc
CXX := $(CROSS_COMPILE)g++
AR := $(CROSS_COMPILE)ar
3rd, specifies the source code compileing rules, how you compile c++ or c code. The rules will make the later life easier
%.o : %.cpp
$(CXX) $(CXXFLAGS) -c -o $@ $<
%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<
Fourth, is more specific compiling setting, you define CFLAGS, CXXFLAGS, or LDFLAGS, so you specify what header directory to include, you specify what library to link, you also specify "-g" for debug, and how you want the compiler post warning message etc.
CFLAGS += -I$(PROJECT_ROOT_DIR)/include
CFLAGS += -I$(INCLS) -D_FOO_=1 -g
Fiveth, now you can provide the basic feature you want in the Makefile. Here is the sample:
compile: libfoo foo_bin
You want the user use "make compile" for build foo.
Sixth, specifiy all source code you build in seperate directories.
SRCS_FOO_DIR = $(PROJECT_ROOT_DIR)/src
SRCS_FOO = $(SRCS_FOO_DIR)/util_arm.s \
$(SRCS_FOO_DIR)/foo_info.c \
$(SRCS_FOO_DIR)/foo_main.c $(FOO_SRC_DIR)/foo_help.c
OBJS_FOO = $(patsubst %.s,%.o, $(patsubst %.c,%.o, $(SRCS_FOO)))
$(OBJS_FOO) : INCLS=-I$(SRCS_FOO_DIR)
SRCS_GST_DIR = $(PROJECT_ROOT_DIR)/gst
SRCS_GST = $(SRCS_GST_DIR)/gst.c
OBJS_GST = $(SRCS_GST:.c=.o)
$(OBJS_GST) : INCLS=-I$(SRCS_GST_DIR)
Seventh, now weave them together.
libfoo : $(OBJS_FOO) $(OBJS_GST)
$(CC) $(CFLAGS) -shared -o $@.so $^
For now, the Makefile is done, to add "clean" feature, is quite simple based the content from here.