blob: 4c06f5e565c2821df527f51efe310c0499775a69 [file] [log] [blame]
#-----------------------------------------------------------------------------------------------
# Generic makefile for executable/library
# All options:
# IN_TARGET
# IN_TARGET_DIR
# IN_BUILD_DIR
# IN_TARGET_PLATFORM
# IN_INCDIRS
# IN_SRCDIRS_REC
# IN_SOURCES
# IN_CFLAGS
# IN_DEFS
# IN_LDFLAGS
# IN_LDLIBS
# IN_PREREQS
# Note: avoid trailing spaces !
# Note: Variables from environment or cmd are unmodifiable.
# E.g. use additional variables:
# IN_SRCDIRS_REC += ${APP_SRCDIRS_REC}
# IN_SRCDIRS_REC += ...
#-----------------------------------------------------------------------------------------------
# relative to basedir or absolute if not possible
define CANONICAL_PATH
$(patsubst ${CURDIR}/%,%,$(abspath ${1}))
endef
# $1 = path, should end with '/' to avoid wildcard matching of directories
# $2 = file (extension)
define REC_FILE_SEARCH
$(wildcard $(addsuffix $2, $1)) $(foreach d,$(wildcard $(addsuffix *, $1)),$(call REC_FILE_SEARCH,$d/,$2))
endef
# USE WITH EVAL
define TARGET_RULE
ifeq "$$(suffix $${M_TARGET})" ".a"
# static library
$${M_TARGET}: $${M_OBJS}
@mkdir -p $$(dir $$@)
$$(strip $${AR} $${ARFLAGS} $${M_TARGET_DIR}/$$@ $${M_OBJS})
else
# executable
$${M_TARGET}: $${M_OBJS} $${M_PREREQS}
@mkdir -p $$(dir $$@)
$$(strip $${CC} -o $${M_TARGET_DIR}/$$@ $${M_LDFLAGS} $${M_OBJS} $${M_LDLIBS} )
endif
endef
ifeq ($(strip ${IN_BUILD_DIR}),)
# TODO: TARGET_BUILD_DIR should not be here
IN_BUILD_DIR := ${TARGET_BUILD_DIR}
endif
ifeq ($(strip ${IN_TARGET_DIR}),)
IN_TARGET_DIR := ${IN_BUILD_DIR}
endif
# Locals, no override from 'outside'
M_TARGET := ${IN_TARGET}
M_TARGET_DIR := ${IN_TARGET_DIR}
M_BUILD_DIR := ${IN_BUILD_DIR}
M_INCDIRS := ${IN_INCDIRS}
M_SRCDIRS_REC := ${IN_SRCDIRS_REC}
M_SOURCES := ${IN_SOURCES}
M_CFLAGS := ${IN_CFLAGS}
M_DEFS := ${IN_DEFS}
M_LDFLAGS := ${IN_LDFLAGS}
M_LDLIBS := ${IN_LDLIBS}
M_PREREQS := ${IN_PREREQS}
M_OBJS :=
M_SOURCES := $(call CANONICAL_PATH, ${M_SOURCES})
M_SOURCES += $(call CANONICAL_PATH,$(foreach DIR,${IN_SRCDIRS_REC},$(call REC_FILE_SEARCH,${DIR}/,*.c)))
M_SOURCES += $(call CANONICAL_PATH,$(foreach DIR,${IN_SRCDIRS_REC},$(call REC_FILE_SEARCH,${DIR}/,*.cpp)))
M_OBJS += $(addprefix ${M_BUILD_DIR}/,$(addsuffix .o,$(basename ${M_SOURCES})))
M_DEFS := $(addprefix -D,${M_DEFS})
M_INCDIRS := $(addprefix -I,$(call CANONICAL_PATH,${M_INCDIRS}))
#-----------------------------------------------------------------------------------------------
${M_BUILD_DIR}/%.o: %.c
@mkdir -p $(dir $@)
$(strip ${CC} -o $@ -c ${M_CFLAGS} ${M_SRC_CFLAGS} ${M_INCDIRS} \
${M_SRC_INCDIRS} ${M_SRC_DEFS} ${M_DEFS} $<)
${M_BUILD_DIR}/%.o: %.cpp
@mkdir -p $(dir $@)
$(strip ${CXX} -o $@ -c ${M_CFLAGS} ${M_SRC_CFLAGS} ${M_INCDIRS} \
${M_SRC_INCDIRS} ${M_SRC_DEFS} ${M_DEFS} $<)
.PHONY: build clean-all
all: clean build # CDT default
build: ${M_TARGET} # see M_PREREQS in target rule
$(eval $(call TARGET_RULE))
clean: clean_${M_TARGET}
clean_${M_TARGET}:
$(strip rm -f ${M_TARGET_DIR}/${M_TARGET} ${M_OBJS:%.o=%.[doP]})
# special clean: delete all mains
clean_build: clean
rm -rf ${M_BUILD_DIR}
clean-all: clean $(foreach REQ, ${M_PREREQS}, clean_${REQ})