###############################################################################
# Linux kernel configuration overrides, useful for enabling a driver build 
# but not much else (can't turn on whole subsystems or change kernel options)
###############################################################################

configs := CONFIG_DCA
CONFIG_DCA := m

###############################################################################
# Sub-directories that need building
###############################################################################

###############################################################################
# Exported variables for recursive building
###############################################################################

KBUILD_EXTRA_CFLAGS += -include $(CURDIR)/kcompat.h
export KBUILD_EXTRA_CFLAGS

###############################################################################
# Everything below should be independent of the module being built
###############################################################################

# realpath is a useful function, but only exists in GNU make 3.81
# the $(call realpath,path) syntax works even for the built in function
# this uses the shell for older versions of make
ifneq ($(call realpath,/),/)
realpath = $(shell cd $(1) && pwd -P)
endif

KERNELRELEASE ?= $(shell uname -r)
KBUILD_SRC    ?= /lib/modules/$(KERNELRELEASE)/source
KBUILD_OUTPUT ?= /lib/modules/$(KERNELRELEASE)/build

SUBDIRS_CONFIGURE = $(addsuffix .configure, $(SUBDIRS))
SUBDIRS_DISTCLEAN = $(addsuffix .distclean, $(SUBDIRS))

# this flag is needed in kernels 2.6.24 and later
ifeq ($(findstring 2.6.1,$(KERNELRELEASE)),)
ifeq ($(findstring 2.6.20,$(KERNELRELEASE)),)
ifeq ($(findstring 2.6.21,$(KERNELRELEASE)),)
ifeq ($(findstring 2.6.22,$(KERNELRELEASE)),)
ifeq ($(findstring 2.6.23,$(KERNELRELEASE)),)
KBUILD_EXTRA_CFLAGS += -include $(CURDIR)/../include/linux/dca.h
endif
endif
endif
endif
endif

.PHONY: all help modules modules_install install clean distclean configure \
	$(SUBDIRS_CONFIGURE) $(SUBDIRS_DISTCLEAN)

.DEFAULT_GOAL := all
all: modules

$(SUBDIRS_CONFIGURE):
	$(MAKE) -C $(basename $@) configure

modules: configure

install: DEPMOD ?= /sbin/depmod
install: modules_install
	$(DEPMOD) -a $(KERNELRELEASE)

help modules modules_install clean:
ifeq ($(call realpath,$(KBUILD_SRC)),$(call realpath,$(KBUILD_OUTPUT)))
	$(MAKE) -C $(KBUILD_SRC) M=$(CURDIR) $@
else
	$(MAKE) -C $(KBUILD_SRC) O=$(KBUILD_OUTPUT) M=$(CURDIR) $@
endif

distclean:: clean $(SUBDIRS_DISTCLEAN)
	-rm -f config config.h Module.symvers Modules.symvers

$(SUBDIRS_DISTCLEAN):
	$(MAKE) -C $(basename $@) distclean

configure: $(SUBDIRS_CONFIGURE)
configure: $(if $(configs) $(KBUILD_EXTRA_CFLAGS),config) 
configure: $(if $(configs),config.h)

config config.h: CONFIG_STRINGS := $(foreach C, $(configs), $(C)=$($(C)))

config: $(MAKEFILE_LIST)
	@echo "  CHK     $(CURDIR)/$@"
	@( \
		if [ -n '$(CONFIG_STRINGS)' ]; then \
			for line in $(CONFIG_STRINGS); \
			do \
				symbol=$$(echo $$line | cut -f1 -d=); \
				value=$$(echo $$line | cut -f2 -d=); \
				case $$value in \
				y) \
					printf "override %s=y\n" $$symbol; \
					;; \
				m) \
					printf "override %s=m\n" $$symbol; \
					;; \
				n) \
					printf "# %s is not set\n" $$symbol; \
					printf "override %s=\n" $$symbol; \
					;; \
				esac \
			done; \
			printf 'EXTRA_CFLAGS += -include $$(src)/config.h\n'; \
		fi; \
		if [ -n '$(KBUILD_EXTRA_CFLAGS)' ]; then \
			printf 'EXTRA_CFLAGS += $(KBUILD_EXTRA_CFLAGS)\n'; \
		fi; \
	) > $@
	@[ -f $@ ]

config.h: $(MAKEFILE_LIST)
	@echo "  CHK     $(CURDIR)/$@"
	@( \
		printf "#include <linux/autoconf.h>\n\n"; \
		for line in $(CONFIG_STRINGS); \
		do \
			symbol=$$(echo $$line | cut -f1 -d=); \
			value=$$(echo $$line | cut -f2 -d=); \
			printf "#undef %s\n" $$symbol; \
			printf "#undef %s_MODULE\n" $$symbol; \
			case $$value in \
			y) \
				printf "#define %s 1\n" $$symbol; \
				;; \
			m) \
				printf "#define %s_MODULE 1\n" $$symbol; \
				;; \
			esac \
		done; \
	) > $@
	@[ -f $@ ]

