# ==========================================================================
# Building
# ==========================================================================

src := $(obj)

.PHONY: __build
__build:

ifdef include_config
include .config
endif

include $(obj)/Makefile

include scripts/Makefile.lib

ifdef O_TARGET
$(error kbuild: $(obj)/Makefile - Usage of O_TARGET := $(O_TARGET) is obsolete in 2.5. Please fix!)
endif

ifdef L_TARGET
ifneq ($(L_TARGET),lib.a)
$(warning kbuild: $(obj)/Makefile - L_TARGET := $(L_TARGET) target shall be renamed to lib.a. Please fix!)
endif
endif

ifdef list-multi
$(warning kbuild: $(obj)/Makefile - list-multi := $(list-multi) is obsolete in 2.5. Please fix!)
endif

ifndef obj
$(warning kbuild: Makefile.build is included improperly)
endif

# ===========================================================================

# If a Makefile does not define a L_TARGET, link an object called "built-in.o"

ifdef L_TARGET
L_TARGET := $(obj)/$(L_TARGET)
else
ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-)),)
O_TARGET := $(obj)/built-in.o
endif
endif

__build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
	 $(if $(KBUILD_MODULES),$(obj-m:.o=.ko)) \
	 $(subdir-ym) $(build-targets)
	@:

# Compile C sources (.c)
# ---------------------------------------------------------------------------

# Default is built-in, unless we know otherwise
modkern_cflags := $(CFLAGS_KERNEL)
quiet_modtag := $(empty)   $(empty)

$(real-objs-m)        : modkern_cflags := $(CFLAGS_MODULE)
$(real-objs-m:.o=.i)  : modkern_cflags := $(CFLAGS_MODULE)
$(real-objs-m:.o=.s)  : modkern_cflags := $(CFLAGS_MODULE)
$(real-objs-m:.o=.lst): modkern_cflags := $(CFLAGS_MODULE)

$(real-objs-m)        : quiet_modtag := [M]
$(real-objs-m:.o=.i)  : quiet_modtag := [M]
$(real-objs-m:.o=.s)  : quiet_modtag := [M]
$(real-objs-m:.o=.lst): quiet_modtag := [M]

$(obj-m)              : quiet_modtag := [M]

$(export-objs)        : export_flags   := $(EXPORT_FLAGS)
$(export-objs:.o=.i)  : export_flags   := $(EXPORT_FLAGS)
$(export-objs:.o=.s)  : export_flags   := $(EXPORT_FLAGS)
$(export-objs:.o=.lst): export_flags   := $(EXPORT_FLAGS)

# Default for not multi-part modules
modname = $(*F)

$(multi-objs-m)         : modname = $(modname-multi)
$(multi-objs-m:.o=.i)   : modname = $(modname-multi)
$(multi-objs-m:.o=.s)   : modname = $(modname-multi)
$(multi-objs-m:.o=.lst) : modname = $(modname-multi)
$(multi-objs-y)         : modname = $(modname-multi)
$(multi-objs-y:.o=.i)   : modname = $(modname-multi)
$(multi-objs-y:.o=.s)   : modname = $(modname-multi)
$(multi-objs-y:.o=.lst) : modname = $(modname-multi)

quiet_cmd_cc_s_c = CC $(quiet_modtag)  $@
cmd_cc_s_c       = $(CC) $(c_flags) -S -o $@ $< 

%.s: %.c FORCE
	$(call if_changed_dep,cc_s_c)

quiet_cmd_cc_i_c = CPP $(quiet_modtag) $@
cmd_cc_i_c       = $(CPP) $(c_flags)   -o $@ $<

%.i: %.c FORCE
	$(call if_changed_dep,cc_i_c)

quiet_cmd_cc_o_c = CC $(quiet_modtag)  $@
cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<

%.o: %.c FORCE
	$(call if_changed_dep,cc_o_c)

quiet_cmd_cc_lst_c = MKLST   $@
      cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
		     $(CONFIG_SHELL) $(srctree)/scripts/makelst $*.o \
				     System.map $(OBJDUMP) > $@

%.lst: %.c FORCE
	$(call if_changed_dep,cc_lst_c)

# Compile assembler sources (.S)
# ---------------------------------------------------------------------------

modkern_aflags := $(AFLAGS_KERNEL)

$(real-objs-m)      : modkern_aflags := $(AFLAGS_MODULE)
$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)

quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
cmd_as_s_S       = $(CPP) $(a_flags)   -o $@ $< 

%.s: %.S FORCE
	$(call if_changed_dep,as_s_S)

quiet_cmd_as_o_S = AS $(quiet_modtag)  $@
cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<

%.o: %.S FORCE
	$(call if_changed_dep,as_o_S)

targets += $(real-objs-y) $(real-objs-m) $(EXTRA_TARGETS) $(MAKECMDGOALS)

# Build the compiled-in targets
# ---------------------------------------------------------------------------

# To build objects in subdirs, we need to descend into the directories
$(sort $(subdir-obj-y)): $(subdir-ym) ;

#
# Rule to compile a set of .o files into one .o file
#
ifdef O_TARGET
quiet_cmd_link_o_target = LD      $@
# If the list of objects to link is empty, just create an empty O_TARGET
cmd_link_o_target = $(if $(strip $(obj-y)),\
		      $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(obj-y), $^),\
		      rm -f $@; $(AR) rcs $@)

$(O_TARGET): $(obj-y) FORCE
	$(call if_changed,link_o_target)

targets += $(O_TARGET)
endif # O_TARGET

#
# Rule to compile a set of .o files into one .a file
#
ifdef L_TARGET
quiet_cmd_link_l_target = AR      $@
cmd_link_l_target = rm -f $@; $(AR) $(EXTRA_ARFLAGS) rcs $@ $(obj-y)

$(L_TARGET): $(obj-y) FORCE
	$(call if_changed,link_l_target)

targets += $(L_TARGET)
endif

#
# Rule to link composite objects
#
quiet_cmd_link_multi-y = LD      $@
cmd_link_multi-y = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^)

quiet_cmd_link_multi-m = LD [M]  $@
cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.ko=-objs))) $($(subst $(obj)/,,$(@:.ko=-y)))),$^) init/vermagic.o

quiet_cmd_link_single-m = LD [M]  $@
cmd_link_single-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o

# Don't rebuilt vermagic.o unless we actually are in the init/ dir
ifneq ($(obj),init)
init/vermagic.o: ;
endif

# We would rather have a list of rules like
# 	foo.o: $(foo-objs)
# but that's not so easy, so we rather make all composite objects depend
# on the set of all their parts
$(multi-used-y) : %.o: $(multi-objs-y) FORCE
	$(call if_changed,link_multi-y)

$(multi-used-m:.o=.ko) : %.ko: $(multi-objs-m) init/vermagic.o FORCE
	$(call if_changed,link_multi-m)

$(single-used-m:.o=.ko) : %.ko: %.o init/vermagic.o FORCE
	$(call if_changed,link_single-m)

targets += $(multi-used-y) $(multi-used-m:.o=.ko) $(single-used-m:.o=.ko)

# Compile programs on the host
# ===========================================================================
# host-progs := bin2hex
# Will compile bin2hex.c and create an executable named bin2hex
#
# host-progs    := lxdialog
# lxdialog-objs := checklist.o lxdialog.o
# Will compile lxdialog.c and checklist.c, and then link the executable
# lxdialog, based on checklist.o and lxdialog.o
#
# host-progs      := qconf
# qconf-cxxobjs   := qconf.o
# qconf-objs      := menu.o
# Will compile qconf as a C++ program, and menu as a C program.
# They are linked as C++ code to the executable qconf

# host-progs := conf
# conf-objs  := conf.o libkconfig.so
# libkconfig-objs := expr.o type.o
# Will create a shared library named libkconfig.so that consist of
# expr.o and type.o (they are both compiled as C code and the object file
# are made as position independent code).
# conf.c is compiled as a c program, and conf.o is linked together with
# libkconfig.so as the executable conf.
# Note: Shared libraries consisting of C++ files are not supported  
#

# Create executable from a single .c file
# host-csingle -> Executable
quiet_cmd_host-csingle 	= HOSTCC  $@
      cmd_host-csingle	= $(HOSTCC) $(hostc_flags) $(HOST_LOADLIBES) -o $@ $<
$(host-csingle): %: %.c FORCE
	$(call if_changed_dep,host-csingle)

# Link an executable based on list of .o files, all plain c
# host-cmulti -> executable
quiet_cmd_host-cmulti	= HOSTLD  $@
      cmd_host-cmulti	= $(HOSTCC) $(HOSTLDFLAGS) -o $@ \
			  $(addprefix $(obj)/,$($(@F)-objs)) \
			  $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
$(host-cmulti): %: $(host-cobjs) $(host-cshlib) FORCE
	$(call if_changed,host-cmulti)

# Create .o file from a single .c file
# host-cobjs -> .o
quiet_cmd_host-cobjs	= HOSTCC  $@
      cmd_host-cobjs	= $(HOSTCC) $(hostc_flags) -c -o $@ $<
$(host-cobjs): %.o: %.c FORCE
	$(call if_changed_dep,host-cobjs)

# Link an executable based on list of .o files, a mixture of .c and .cc
# host-cxxmulti -> executable
quiet_cmd_host-cxxmulti	= HOSTLD  $@
      cmd_host-cxxmulti	= $(HOSTCXX) $(HOSTLDFLAGS) -o $@ \
			  $(foreach o,objs cxxobjs,\
			  $(addprefix $(obj)/,$($(@F)-$(o)))) \
			  $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
$(host-cxxmulti): %: $(host-cobjs) $(host-cxxobjs) $(host-cshlib) FORCE
	$(call if_changed,host-cxxmulti)

# Create .o file from a single .cc (C++) file
quiet_cmd_host-cxxobjs	= HOSTCXX $@
      cmd_host-cxxobjs	= $(HOSTCXX) $(hostcxx_flags) -c -o $@ $<
$(host-cxxobjs): %.o: %.cc FORCE
	$(call if_changed_dep,host-cxxobjs)

# Compile .c file, create position independent .o file
# host-cshobjs -> .o
quiet_cmd_host-cshobjs	= HOSTCC  -fPIC $@
      cmd_host-cshobjs	= $(HOSTCC) $(hostc_flags) -fPIC -c -o $@ $<
$(host-cshobjs): %.o: %.c FORCE
	$(call if_changed_dep,host-cshobjs)

# Link a shared library, based on position independent .o files
# *.o -> .so shared library (host-cshlib)
quiet_cmd_host-cshlib	= HOSTLLD -shared $@
      cmd_host-cshlib	= $(HOSTCC) $(HOSTLDFLAGS) -shared -o $@ \
			  $(addprefix $(obj)/,$($(@F:.so=-objs))) \
			  $(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
$(host-cshlib): %: $(host-cshobjs) FORCE
	$(call if_changed,host-cshlib)

targets += $(host-csingle)  $(host-cmulti) $(host-cobjs)\
	   $(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs) 

# Descending
# ---------------------------------------------------------------------------

.PHONY: $(subdir-ym)
$(subdir-ym):
	$(Q)$(MAKE) $(build)=$@

# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------

.PHONY: FORCE

FORCE:

# Read all saved command lines and dependencies for the $(targets) we
# may be building above, using $(if_changed{,_dep}). As an
# optimization, we don't need to read them if the target does not
# exist, we will rebuild anyway in that case.

targets := $(wildcard $(sort $(targets)))
cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))

ifneq ($(cmd_files),)
  include $(cmd_files)
endif