Codebase list splix / 0051000e-0a7e-4ec5-b171-d2e010da7f32/main Makefile
0051000e-0a7e-4ec5-b171-d2e010da7f32/main

Tree @0051000e-0a7e-4ec5-b171-d2e010da7f32/main (Download .tar.gz)

Makefile @0051000e-0a7e-4ec5-b171-d2e010da7f32/mainraw · history · blame

#
#	Makefile		(C) 2006-2008, Aurélien Croc (AP²C)
#
# This project is under the GPL Licence
#
# Available MAKE options:
#      * V sets to 1 for verbose mode
# 
# Available variables in module.mk :
#      * SUBDIRS
#      * MODE = {default,debug,optimized}
#      * CFLAGS
#      * CXXFLAGS
#      * LDFLAGS
#      * DEBUG_CFLAGS
#      * DEBUG_CXXFLAGS
#      * OPTIMIZED_CFLAGS
#      * OPTIMIZED_CXXFLAGS
#      * TARGETS
#      * GENERIC_TARGETS
#      * PRE_GENERIC_TARGETS
#      * directory1_directory2_file_ext_FLAGS
#
# Each project must be listed in the TARGETS variable. Next:
#      * project1_SRC
#      * project1_LIB
#      * project1_CFLAGS
#      * project1_LDFLAGS
#      * project1_MODULES
#      * project1_CXXFLAGS
#      * ...
#
# This Makefile will generate:
#      * project1_TARGET
#      * project1_OBJ
#
#
# In the file rules.mk:
#
# You can add your own rules
# 
# To add a new target file support, please add the target extension in the
# TARGET_RULES variable and define the function targetDefinition_{extension}.
# This function will be called with one parameters: the target name
# Like the examples above, use $(value $(1)_TARGET) or _OBJ, .. to access
# to useful informations
#
#
# /!\ = Please do your modifications in the module.mk file = /!\
# 


# +--------------------------------------------------------------------------+
# |   SUPPORTED LANGUAGES, DIRECTORIES ARCHI AND TOOLS LOCATIONS & FLAGS     |
# +--------------------------------------------------------------------------+
LANGUAGES	:= cpp c

CC		:= gcc
CXX		:= g++
RM		:= rm -f
AR		:= ar crs
LEX		:= flex
YACC		:= bison
LINKER		:= $(CXX)

DEPDIR          := .deps
BUILDDIR        := .build
TARGETDIR       := .


empty           :=
space           := $(empty) $(empty)
comma           := ,

DEBUG_CFLAGS    := -O0 -g
DEBUG_CXXFLAGS  := -O0 -g
OPTIM_CFLAGS	:= -O2
OPTIM_CXXFLAGS	:= -O2

ARCHI           := $(shell uname -s)

ifeq ($(ARCHI),Darwin)
PLUGIN_EXT      := bundle
LIBRARY_EXT     := dylib
else
PLUGIN_EXT      := so
LIBRARY_EXT     := so
endif


# +--------------------------------------------------------------------------+
# |   DEFINITIONS VARIABLE LOADING                                           |
# +--------------------------------------------------------------------------+

MODE		:= default
DEFFILE		:= .defs.mk
-include $(DEFFILE)



# +--------------------------------------------------------------------------+
# |   SUBDIRS LOADING                                                        |
# +--------------------------------------------------------------------------+

include module.mk
ifeq ($(DEFLOADED),1)
include $(patsubst %, %/module.mk, $(_SUBDIRS))
endif # DEFLOADED == 1
ifeq ($(DEFDONE),1)




# +--------------------------------------------------------------------------+
# |   COMPILATION MODE INITIALIZATION                                        |
# +--------------------------------------------------------------------------+

ifeq ($(MAKECMDGOALS),debug)
MODE            := debug
endif #MAKECMDGOALS == debug
ifeq ($(MAKECMDGOALS),optimized)
MODE            := optimized
endif #MAKECMDGOALS == optimized
ifeq ($(MAKECMDGOALS),default)
MODE            := default
endif #MAKECMDGOALS == default

ifeq ($(MODE),debug)            # DEBUG
CFLAGS		+= $(DEBUG_CFLAGS)
CXXFLAGS	+= $(DEBUG_CXXFLAGS)
BUILDDIR	:= debug
TARGETDIR	:= debug
DEPDIR		:= debug
else
ifeq ($(MODE),optimized)        # OPTIMIZED
CFLAGS		+= $(OPTIM_CFLAGS)
CXXFLAGS	+= $(OPTIM_CXXFLAGS)
BUILDDIR	:= optimized
TARGETDIR	:= optimized
DEPDIR		:= optimized
endif # MODE == optimized
endif # MODE == debug



# +--------------------------------------------------------------------------+
# |   VERBOSE MODE AND INITIALIZATION                                        |
# +--------------------------------------------------------------------------+

V := 
ifeq ($(V),1) 
	Q := 
else
	Q := @
endif



# +--------------------------------------------------------------------------+
# |   MAIN RULES AND TARGETS                                                 |
# +--------------------------------------------------------------------------+

_TARGETS	:= $(foreach target,$(TARGETS),$(TARGETDIR)/$(target))
_TARGETS	:= $(PRE_GENERIC_TARGETS) $(_TARGETS) $(GENERIC_TARGETS)

all: $(_TARGETS)
debug: $(_TARGETS)
optimized: $(_TARGETS)



# +--------------------------------------------------------------------------+
# |   MACRO DEFINITIONS                                                      |
# +--------------------------------------------------------------------------+

# Function to print smart messages
printCmd	= $(if $(filter $(V),1),,$(shell echo "@echo \"    $(1)\""))

# Get the target variable name
targetName	= $(subst .,_,$(subst /,_,$(1)))

# Specific flags definition
flags            = $(value $(subst /,_,$(subst .,_,$(1)))_FLAGS)
flag            = $(subst /,_,$(subst .,_,$(1)))_FLAGS



# +--------------------------------------------------------------------------+
# |   LOAD AND GENERATE DEPENDENCIES FILES                                   |
# +--------------------------------------------------------------------------+

# Get all the source files in ALLSRC
ALLSRC          := $(foreach target,$(call targetName,$(TARGETS)),$(value \
                        $(target)_SRC))

# Get the dependencies files
DEPENDENCIES    := $(foreach lang,$(LANGUAGES),$(patsubst %.$(lang), %.d, \
                   $(filter %.$(lang),$(ALLSRC))))

# Generate dependencies files for C++ source file
$(DEPDIR)/%.d: %.cpp
	@mkdir -p $(dir $@)
	@$(CXX) $(CXXFLAGS) -MM -MP -MG -MT "\$$(DEPDIR)/$(basename $<).d \
		\$$(BUILDDIR)/$(basename $<).o" -MG "$<" -MF $@

# Load dependencies files 
-include $(foreach dep,$(DEPENDENCIES),$(DEPDIR)/$(dep))



# +--------------------------------------------------------------------------+
# |   PREVENT LOADING RULES IF DEFFILE IS NOT COMPLET                        |
# +--------------------------------------------------------------------------+

else
TARGETS	:= $(empty)

endif # DEFDONE == 1



# +--------------------------------------------------------------------------+
# |   OBJECTS AND TARGETS DEFINITIONS                                        |
# +--------------------------------------------------------------------------+


# Define target variables
defineTarget	= $(call targetName,$(1))_TARGET  := $(TARGETDIR)/$(1)

# Define target object variables
define defineObject
$(1)_OBJ	:= $(foreach obj,$(foreach lang,$(LANGUAGES),$(patsubst \
			%.$(lang),%.o,$(filter %.$(lang),$(value $(1)_SRC)))), \
			$(BUILDDIR)/$(obj)) \
		   $(foreach module,$(value \
			$(1)_MODULES),$(TARGETDIR)/$(module)) \
		   $(foreach obj,$(patsubst %.l,%.l.o,$(filter %.l,$(value \
			$(1)_SRC))),$(BUILDDIR)/$(obj)) \
		   $(foreach obj,$(patsubst %.y,%.yy.o,$(filter %.y,$(value \
			$(1)_SRC))),$(BUILDDIR)/$(obj))
$(1)_CLEAN	:= $(foreach obj,$(patsubst %.y,%.yy.h,$(filter %.y,$(value \
			$(1)_SRC))),$(BUILDDIR)/$(obj))
endef

# Create these definitions
$(foreach target,$(TARGETS),$(eval $(call defineTarget,$(strip $(target)))) \
	$(eval $(call defineObject,$(strip $(call targetName,$(target))))))



# +--------------------------------------------------------------------------+
# |   SMART MESSAGE PRINTING                                                 |
# +--------------------------------------------------------------------------+


# Smart messages
cmd_ar_a_o	= AR                $@
cmd_cc_o_c	= CC                $<
cmd_cxx_o_cpp	= CXX               $<
cmd_yacc_h	= YACC [H]          $<
cmd_yacc_cpp	= YACC [CPP]        $<
cmd_lex_cpp	= LEX               $<
cmd_link	= LINK              $@
cmd_ln_so_o	= LINK [M]          $@
cmd_rm_clean	= RM                *.o
cmd_rm_distclean = RM                $(_TARGETS) *.d $(DEFFILE)



# +--------------------------------------------------------------------------+
# |   TARGET RULES                                                           |
# +--------------------------------------------------------------------------+

TARGET_RULES    := a so bundle

# Archives
define targetDefinition_a
$(value $(1)_TARGET): $(value $(1)_OBJ)
	$$(call printCmd, $$(cmd_ar_a_o))
	$$(Q)$$(AR) $$@ $$^
endef
-include rules.mk

# Plugins (for MacOS X)
define targetDefinition_bundle
$(value $(1)_TARGET): $(value $(1)_OBJ) $(value $(1)_LOADER)
	$$(call printCmd, $$(cmd_ln_so_o))
	$$(Q)$$(LINKER) $$(MODULE_FLAGS) $$(LDFLAGS) -o $$@ $$(value $(1)_OBJ) \
		-bundle -bundle_loader $$(value $(1)_LOADER) \
		$$(value $(1)_LIBS) $$(value $(1)_FLAGS) $$(LIBS)
endef

# Plugins and libaries (for UNIXes)
define targetDefinition_so
$(value $(1)_TARGET): $(value $(1)_OBJ)
	$$(call printCmd, $$(cmd_ln_so_o))
	$$(Q)$$(LINKER) $$(MODULE_FLAGS) $$(LDFLAGS) -o $$@ $$(value $(1)_OBJ) \
		-rdynamic -shared $$(value $(1)_LIBS) $$(value $(1)_FLAGS) \
		$$(LIBS)
endef

rulesTarget	:= $(foreach rules,$(TARGET_RULES),$(filter \
			%.$(rules),$(TARGETS)))
$(foreach target,$(rulesTarget),$(eval $(call targetDefinition_$(subst \
	.,,$(suffix $(target))),$(call targetName,$(target)))))



# +--------------------------------------------------------------------------+
# |   COMPILATION RULES                                                      |
# +--------------------------------------------------------------------------+

# C Files
$(BUILDDIR)/%.o: $(BUILDDIR)/%.c
	$(call printCmd, $(cmd_cc_o_c))
	@mkdir -p $(dir $@)
	$(Q)$(CC) $(CFLAGS) $(call flags,$<) -o $@ -c $<
$(BUILDDIR)/%.o: %.c
	$(call printCmd, $(cmd_cc_o_c))
	@mkdir -p $(dir $@)
	$(Q)$(CC) $(CFLAGS) $(call flags,$<) -o $@ -c $<

# C++ Files
$(BUILDDIR)/%.o: $(BUILDDIR)/%.cpp
	$(call printCmd, $(cmd_cxx_o_cpp))
	@mkdir -p $(dir $@)
	$(Q)$(CXX) $(CXXFLAGS) $(call flags,$<) -o $@ -c $<
$(BUILDDIR)/%.o: %.cpp
	$(call printCmd, $(cmd_cxx_o_cpp))
	@mkdir -p $(dir $@)
	$(Q)$(CXX) $(CXXFLAGS) $(call flags,$<) -o $@ -c $<

# Yacc compilation
$(BUILDDIR)/%.yy.h: %.y
	$(call printCmd, $(cmd_yacc_h))
	@mkdir -p $(dir $@)
	$(Q)$(YACC) $(call flags,$<) -d -b $(basename $(basename $@)) \
		-p $(basename $(notdir $<)) $<
	$(Q)rm $(basename $(basename $@)).tab.c
	$(Q)mv $(basename $(basename $@)).tab.h $(basename $@).h
$(BUILDDIR)/%.yy.cpp: %.y
	$(call printCmd, $(cmd_yacc_cpp))
	@mkdir -p $(dir $@)
	$(Q)$(YACC) $(call flags,$<) -b $(basename $(basename $@)) \
		-p $(basename $(notdir $<)) -o $@ $<

# Lex compilation
$(BUILDDIR)/%.l.cpp: %.l $(BUILDDIR)/%.yy.h
	$(call printCmd, $(cmd_lex_cpp))
	$(Q)$(LEX) $(call flags,$<) -P$(basename $(notdir $<)) -t $< > $@



# +--------------------------------------------------------------------------+
# |   CLEAN RULES                                                            |
# +--------------------------------------------------------------------------+

.PHONY: clean distclean
clean:
	$(call printCmd, $(cmd_rm_clean))
	$(Q)$(RM) $(foreach target,$(TARGETS),$(value $(call \
		targetName,$(target))_OBJ) $(value $(target)_CLEAN))

distclean: clean
	$(call printCmd, $(cmd_rm_distclean))
	$(Q)$(RM) $(foreach dep,$(DEPENDENCIES),$(DEPDIR)/$(dep))
	$(Q)$(RM) $(_TARGETS)
	$(Q)$(RM) $(DEFFILE)



# +--------------------------------------------------------------------------+
# |   GET ALL SUBDIRS TO EXPLORE                                             |
# +--------------------------------------------------------------------------+

# Generate the defs.mk file which contains sub directories
$(DEFFILE): Makefile $(patsubst %, %/module.mk, $(SUBDIRS)) module.mk
	@echo -n "     GEN               $(DEFFILE)"
	@echo "" > $@
	@make -s -C ./ _depsreload

.PHONY: _depsreload
_depsreload:
	@echo -n "."
	@echo "DEFLOADED := 1" > $(DEFFILE)
	@echo "_SUBDIRS := $(SUBDIRS)" >> $(DEFFILE)
	@if [ "$(SUBDIRS)" != "$(_SUBDIRS)" ]; then make -j 1 -s -C ./ _depsreload; \
		else echo "DEFDONE := 1" >> $(DEFFILE); echo ""; fi