2012-01-13

Makefile example 2

#
# Introduction
#
# This is a Makefile example which can be used to build library or program from
# given directories. These directories could be at the same folder of the Makefile
# itself, or they could exist in other levels of the Makefile, sub-folders or
# parent-folders. 
#
# The Makefile searches all the .cpp files in the given folders and compile them
# into object files and link them into library or program. It generates dependency
# files automatically so that it can catch any change or the source files or 
# related header files.
#
# All the output of the make process is put in $(ODIR) folder. The default value
# is 'Build', but can be overriden with 'ODIR=xxx' when executing 'make'.   
#
# This makefile example contains a example to search folders and sub-folders for
# source file, and then collect all the folders.
#


PWD := $(abspath $(shell pwd))
TOP_DIR := $(abspath ../../..)
ODIR ?= Build


#
# The final targat. Should define only one of them: PROG or LIB
#
PROG := 
LIB := libapclient.a


#
# Find all the directories containing any generated CPP file.
#
GENERATED_TOP_DIR := $(TOP_DIR)/Dingo/Client/AccessPoint/GeneratedServices
GENERATED_CPP_FILES := $(shell find $(GENERATED_TOP_DIR) -name *.cpp)
GENERATED_CPP_DIRS := $(sort $(dir $(GENERATED_CPP_FILES)))


#
# The modules (directories) that need to be built. All the .cpp files in these
# directories will be built automatically.
#
MODULES   := \
  $(TOP_DIR)/Dingo/Client/AccessPoint/TinyXML \
    $(TOP_DIR)/Dingo/Gateway/Siemens.Gateway.Linux.Client \
    $(TOP_DIR)/Dingo/Gateway/PlatformSpecific/Linux \
  $(GENERATED_CPP_DIRS)

# CFLAGS for compiling
CFLAGS := -MD -MP -g \
-I. \
-I$(TOP_DIR)/Dingo/Client/AccessPoint/GatewayClient \
-I$(TOP_DIR)/Dingo/Client/AccessPoint/GatewayProxy \
-I$(TOP_DIR)/Dingo/Client/AccessPoint/GatewayProxy/gSoap \
-I$(TOP_DIR)/Dingo/Client/AccessPoint/TinyXML \
-I$(TOP_DIR)/Dingo/Gateway \
-I$(TOP_DIR)/Dingo/Gateway/PlatformSpecific/Linux \
-I$(TOP_DIR)/Dingo/Client/AccessPoint/GeneratedServices \


#
# -DDEBUG to enable logging of gSoap library
#
ifeq ($(DEBUG),yes)
CFLAGS += -DDEBUG
endif


ifeq ($(OPENSSL),yes)
CFLAGS += -DWITH_OPENSSL
endif


ifeq ($(ARM),yes)
CFLAGS += -I$(TOP_DIR)/../application/include
endif


#
# LDFLAGS for linking PROG
#
LDFLAGS :=


#
# Common Part
#
ifneq ($(ARM),yes)
CROSS_COMPILE
endif


SRC_DIRS  := $(MODULES)
INC_DIRS := $(MODULES)
BUILD_DIRS:= $(addprefix $(ODIR),$(subst $(TOP_DIR),,$(MODULES)))


SRCS      := $(foreach sdir,$(SRC_DIRS),$(wildcard $(sdir)/*.cpp))
OBJS := $(patsubst %.cpp,%.o,$(addprefix $(ODIR),$(subst $(TOP_DIR),,$(SRCS))))
DEPS      := $(OBJS:.o=.d)
INCLUDES  := $(addprefix -I,$(INC_DIRS))


CFLAGS += $(INCLUDES)


CC        := $(CROSS_COMPILE)g++
LD        := $(CROSS_COMPILE)g++
AR := $(CROSS_COMPILE)ar
ECHO := echo
MKDIR := mkdir -p
RM := rm -rf
LN := ln -sf


vpath %.cpp $(SRC_DIRS)


define make-goal
$1/%.o : %.cpp
@$(ECHO) "CC   $$<"
@$(CC) $(CFLAGS) -c $$< -o $$@


endef


.PHONY: all checkdirs clean 


all: checkdirs $(ODIR)/$(LIB) $(ODIR)/$(PROG) 


ifneq ($(PROG),)
$(ODIR)/$(PROG): $(OBJS)
@$(ECHO) "LD   $@"
@$(LD) -o $@ $(OBJS) $(LIBS) $(LDFLAGS)
endif


ifneq ($(LIB),)
$(ODIR)/$(LIB): $(OBJS)
@$(ECHO) "AR   $@"
@$(AR) crs $@ $(OBJS)
endif


checkdirs: $(BUILD_DIRS)

$(BUILD_DIRS):
@$(ECHO) "MKDIR  $@"
@$(MKDIR) -p $@


clean:
@$(RM) $(BUILD_DIRS) $(ODIR) $(TOP_DIR)/Dingo/Client/AccessPoint/TinyXML


$(foreach bdir,$(BUILD_DIRS),$(eval $(call make-goal,$(bdir))))


-include $(DEPS)


test:
@echo $(GENERATED_CPP_DIRS)

No comments:

Post a Comment