This commit imports build scripts from Linux Kernel v3.13 as they are. I know they include some trailing spaces but I am intentionally keeping them untouched. Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>master
parent
ec626f1139
commit
22433fc54b
@ -0,0 +1,479 @@ |
|||||||
|
# ==========================================================================
|
||||||
|
# Building
|
||||||
|
# ==========================================================================
|
||||||
|
|
||||||
|
src := $(obj)
|
||||||
|
|
||||||
|
PHONY := __build
|
||||||
|
__build: |
||||||
|
|
||||||
|
# Init all relevant variables used in kbuild files so
|
||||||
|
# 1) they have correct type
|
||||||
|
# 2) they do not inherit any value from the environment
|
||||||
|
obj-y :=
|
||||||
|
obj-m :=
|
||||||
|
lib-y :=
|
||||||
|
lib-m :=
|
||||||
|
always :=
|
||||||
|
targets :=
|
||||||
|
subdir-y :=
|
||||||
|
subdir-m :=
|
||||||
|
EXTRA_AFLAGS :=
|
||||||
|
EXTRA_CFLAGS :=
|
||||||
|
EXTRA_CPPFLAGS :=
|
||||||
|
EXTRA_LDFLAGS :=
|
||||||
|
asflags-y :=
|
||||||
|
ccflags-y :=
|
||||||
|
cppflags-y :=
|
||||||
|
ldflags-y :=
|
||||||
|
|
||||||
|
subdir-asflags-y :=
|
||||||
|
subdir-ccflags-y :=
|
||||||
|
|
||||||
|
# Read auto.conf if it exists, otherwise ignore
|
||||||
|
-include include/config/auto.conf |
||||||
|
|
||||||
|
include scripts/Kbuild.include |
||||||
|
|
||||||
|
# For backward compatibility check that these variables do not change
|
||||||
|
save-cflags := $(CFLAGS)
|
||||||
|
|
||||||
|
# The filename Kbuild has precedence over Makefile
|
||||||
|
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
|
||||||
|
kbuild-file := $(if $(wildcard $(kbuild-dir)/Kbuild),$(kbuild-dir)/Kbuild,$(kbuild-dir)/Makefile)
|
||||||
|
include $(kbuild-file) |
||||||
|
|
||||||
|
# If the save-* variables changed error out
|
||||||
|
ifeq ($(KBUILD_NOPEDANTIC),) |
||||||
|
ifneq ("$(save-cflags)","$(CFLAGS)")
|
||||||
|
$(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y)
|
||||||
|
endif
|
||||||
|
endif |
||||||
|
|
||||||
|
#
|
||||||
|
# make W=... settings
|
||||||
|
#
|
||||||
|
# W=1 - warnings that may be relevant and does not occur too often
|
||||||
|
# W=2 - warnings that occur quite often but may still be relevant
|
||||||
|
# W=3 - the more obscure warnings, can most likely be ignored
|
||||||
|
#
|
||||||
|
# $(call cc-option, -W...) handles gcc -W.. options which
|
||||||
|
# are not supported by all versions of the compiler
|
||||||
|
ifdef KBUILD_ENABLE_EXTRA_GCC_CHECKS |
||||||
|
warning- := $(empty)
|
||||||
|
|
||||||
|
warning-1 := -Wextra -Wunused -Wno-unused-parameter
|
||||||
|
warning-1 += -Wmissing-declarations
|
||||||
|
warning-1 += -Wmissing-format-attribute
|
||||||
|
warning-1 += -Wmissing-prototypes
|
||||||
|
warning-1 += -Wold-style-definition
|
||||||
|
warning-1 += $(call cc-option, -Wmissing-include-dirs)
|
||||||
|
warning-1 += $(call cc-option, -Wunused-but-set-variable)
|
||||||
|
warning-1 += $(call cc-disable-warning, missing-field-initializers)
|
||||||
|
|
||||||
|
warning-2 := -Waggregate-return
|
||||||
|
warning-2 += -Wcast-align
|
||||||
|
warning-2 += -Wdisabled-optimization
|
||||||
|
warning-2 += -Wnested-externs
|
||||||
|
warning-2 += -Wshadow
|
||||||
|
warning-2 += $(call cc-option, -Wlogical-op)
|
||||||
|
warning-2 += $(call cc-option, -Wmissing-field-initializers)
|
||||||
|
|
||||||
|
warning-3 := -Wbad-function-cast
|
||||||
|
warning-3 += -Wcast-qual
|
||||||
|
warning-3 += -Wconversion
|
||||||
|
warning-3 += -Wpacked
|
||||||
|
warning-3 += -Wpadded
|
||||||
|
warning-3 += -Wpointer-arith
|
||||||
|
warning-3 += -Wredundant-decls
|
||||||
|
warning-3 += -Wswitch-default
|
||||||
|
warning-3 += $(call cc-option, -Wpacked-bitfield-compat)
|
||||||
|
warning-3 += $(call cc-option, -Wvla)
|
||||||
|
|
||||||
|
warning := $(warning-$(findstring 1, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
|
||||||
|
warning += $(warning-$(findstring 2, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
|
||||||
|
warning += $(warning-$(findstring 3, $(KBUILD_ENABLE_EXTRA_GCC_CHECKS)))
|
||||||
|
|
||||||
|
ifeq ("$(strip $(warning))","") |
||||||
|
$(error W=$(KBUILD_ENABLE_EXTRA_GCC_CHECKS) is unknown)
|
||||||
|
endif |
||||||
|
|
||||||
|
KBUILD_CFLAGS += $(warning)
|
||||||
|
endif |
||||||
|
|
||||||
|
include scripts/Makefile.lib |
||||||
|
|
||||||
|
ifdef host-progs |
||||||
|
ifneq ($(hostprogs-y),$(host-progs)) |
||||||
|
$(warning kbuild: $(obj)/Makefile - Usage of host-progs is deprecated. Please replace with hostprogs-y!) |
||||||
|
hostprogs-y += $(host-progs)
|
||||||
|
endif |
||||||
|
endif |
||||||
|
|
||||||
|
# Do not include host rules unless needed
|
||||||
|
ifneq ($(hostprogs-y)$(hostprogs-m),) |
||||||
|
include scripts/Makefile.host |
||||||
|
endif |
||||||
|
|
||||||
|
ifneq ($(KBUILD_SRC),) |
||||||
|
# Create output directory if not already present
|
||||||
|
_dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj))
|
||||||
|
|
||||||
|
# Create directories for object files if directory does not exist
|
||||||
|
# Needed when obj-y := dir/file.o syntax is used
|
||||||
|
_dummy := $(foreach d,$(obj-dirs), $(shell [ -d $(d) ] || mkdir -p $(d)))
|
||||||
|
endif |
||||||
|
|
||||||
|
ifndef obj |
||||||
|
$(warning kbuild: Makefile.build is included improperly) |
||||||
|
endif |
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
ifneq ($(strip $(lib-y) $(lib-m) $(lib-n) $(lib-)),) |
||||||
|
lib-target := $(obj)/lib.a
|
||||||
|
endif |
||||||
|
|
||||||
|
ifneq ($(strip $(obj-y) $(obj-m) $(obj-n) $(obj-) $(subdir-m) $(lib-target)),) |
||||||
|
builtin-target := $(obj)/built-in.o
|
||||||
|
endif |
||||||
|
|
||||||
|
modorder-target := $(obj)/modules.order
|
||||||
|
|
||||||
|
# We keep a list of all modules in $(MODVERDIR)
|
||||||
|
|
||||||
|
__build: $(if $(KBUILD_BUILTIN),$(builtin-target) $(lib-target) $(extra-y)) \
|
||||||
|
$(if $(KBUILD_MODULES),$(obj-m) $(modorder-target)) \
|
||||||
|
$(subdir-ym) $(always)
|
||||||
|
@:
|
||||||
|
|
||||||
|
# Linus' kernel sanity checking tool
|
||||||
|
ifneq ($(KBUILD_CHECKSRC),0) |
||||||
|
ifeq ($(KBUILD_CHECKSRC),2)
|
||||||
|
quiet_cmd_force_checksrc = CHECK $<
|
||||||
|
cmd_force_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
|
||||||
|
else
|
||||||
|
quiet_cmd_checksrc = CHECK $<
|
||||||
|
cmd_checksrc = $(CHECK) $(CHECKFLAGS) $(c_flags) $< ;
|
||||||
|
endif
|
||||||
|
endif |
||||||
|
|
||||||
|
# Do section mismatch analysis for each module/built-in.o
|
||||||
|
ifdef CONFIG_DEBUG_SECTION_MISMATCH |
||||||
|
cmd_secanalysis = ; scripts/mod/modpost $@
|
||||||
|
endif |
||||||
|
|
||||||
|
# Compile C sources (.c)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Default is built-in, unless we know otherwise
|
||||||
|
modkern_cflags = \
|
||||||
|
$(if $(part-of-module), \
|
||||||
|
$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
|
||||||
|
$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL))
|
||||||
|
quiet_modtag := $(empty) $(empty)
|
||||||
|
|
||||||
|
$(real-objs-m) : part-of-module := y |
||||||
|
$(real-objs-m:.o=.i) : part-of-module := y |
||||||
|
$(real-objs-m:.o=.s) : part-of-module := y |
||||||
|
$(real-objs-m:.o=.lst): part-of-module := y |
||||||
|
|
||||||
|
$(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] |
||||||
|
|
||||||
|
# Default for not multi-part modules
|
||||||
|
modname = $(basetarget)
|
||||||
|
|
||||||
|
$(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) -fverbose-asm -S -o $@ $<
|
||||||
|
|
||||||
|
$(obj)/%.s: $(src)/%.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 $@ $<
|
||||||
|
|
||||||
|
$(obj)/%.i: $(src)/%.c FORCE |
||||||
|
$(call if_changed_dep,cc_i_c)
|
||||||
|
|
||||||
|
cmd_gensymtypes = \
|
||||||
|
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
|
||||||
|
$(GENKSYMS) $(if $(1), -T $(2)) \
|
||||||
|
$(patsubst y,-s _,$(CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX)) \
|
||||||
|
$(if $(KBUILD_PRESERVE),-p) \
|
||||||
|
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
|
||||||
|
|
||||||
|
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
|
||||||
|
cmd_cc_symtypes_c = \
|
||||||
|
set -e; \
|
||||||
|
$(call cmd_gensymtypes,true,$@) >/dev/null; \
|
||||||
|
test -s $@ || rm -f $@
|
||||||
|
|
||||||
|
$(obj)/%.symtypes : $(src)/%.c FORCE |
||||||
|
$(call cmd,cc_symtypes_c)
|
||||||
|
|
||||||
|
# C (.c) files
|
||||||
|
# The C file is compiled and updated dependency information is generated.
|
||||||
|
# (See cmd_cc_o_c + relevant part of rule_cc_o_c)
|
||||||
|
|
||||||
|
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
|
||||||
|
|
||||||
|
ifndef CONFIG_MODVERSIONS |
||||||
|
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
|
||||||
|
|
||||||
|
else |
||||||
|
# When module versioning is enabled the following steps are executed:
|
||||||
|
# o compile a .tmp_<file>.o from <file>.c
|
||||||
|
# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
|
||||||
|
# not export symbols, we just rename .tmp_<file>.o to <file>.o and
|
||||||
|
# are done.
|
||||||
|
# o otherwise, we calculate symbol versions using the good old
|
||||||
|
# genksyms on the preprocessed source and postprocess them in a way
|
||||||
|
# that they are usable as a linker script
|
||||||
|
# o generate <file>.o from .tmp_<file>.o using the linker to
|
||||||
|
# replace the unresolved symbols __crc_exported_symbol with
|
||||||
|
# the actual value of the checksum generated by genksyms
|
||||||
|
|
||||||
|
cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
|
||||||
|
cmd_modversions = \
|
||||||
|
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
|
||||||
|
$(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
||||||
|
> $(@D)/.tmp_$(@F:.o=.ver); \
|
||||||
|
\
|
||||||
|
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
|
||||||
|
-T $(@D)/.tmp_$(@F:.o=.ver); \
|
||||||
|
rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
|
||||||
|
else \
|
||||||
|
mv -f $(@D)/.tmp_$(@F) $@; \
|
||||||
|
fi;
|
||||||
|
endif |
||||||
|
|
||||||
|
ifdef CONFIG_FTRACE_MCOUNT_RECORD |
||||||
|
ifdef BUILD_C_RECORDMCOUNT |
||||||
|
ifeq ("$(origin RECORDMCOUNT_WARN)", "command line") |
||||||
|
RECORDMCOUNT_FLAGS = -w
|
||||||
|
endif |
||||||
|
# Due to recursion, we must skip empty.o.
|
||||||
|
# The empty.o file is created in the make process in order to determine
|
||||||
|
# the target endianness and word size. It is made before all other C
|
||||||
|
# files, including recordmcount.
|
||||||
|
sub_cmd_record_mcount = \
|
||||||
|
if [ $(@) != "scripts/mod/empty.o" ]; then \
|
||||||
|
$(objtree)/scripts/recordmcount $(RECORDMCOUNT_FLAGS) "$(@)"; \
|
||||||
|
fi;
|
||||||
|
recordmcount_source := $(srctree)/scripts/recordmcount.c \
|
||||||
|
$(srctree)/scripts/recordmcount.h
|
||||||
|
else |
||||||
|
sub_cmd_record_mcount = set -e ; perl $(srctree)/scripts/recordmcount.pl "$(ARCH)" \
|
||||||
|
"$(if $(CONFIG_CPU_BIG_ENDIAN),big,little)" \
|
||||||
|
"$(if $(CONFIG_64BIT),64,32)" \
|
||||||
|
"$(OBJDUMP)" "$(OBJCOPY)" "$(CC) $(KBUILD_CFLAGS)" \
|
||||||
|
"$(LD)" "$(NM)" "$(RM)" "$(MV)" \
|
||||||
|
"$(if $(part-of-module),1,0)" "$(@)";
|
||||||
|
recordmcount_source := $(srctree)/scripts/recordmcount.pl
|
||||||
|
endif |
||||||
|
cmd_record_mcount = \
|
||||||
|
if [ "$(findstring -pg,$(_c_flags))" = "-pg" ]; then \
|
||||||
|
$(sub_cmd_record_mcount) \
|
||||||
|
fi;
|
||||||
|
endif |
||||||
|
|
||||||
|
define rule_cc_o_c |
||||||
|
$(call echo-cmd,checksrc) $(cmd_checksrc) \
|
||||||
|
$(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
|
||||||
|
$(cmd_modversions) \
|
||||||
|
$(call echo-cmd,record_mcount) \
|
||||||
|
$(cmd_record_mcount) \
|
||||||
|
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
|
||||||
|
$(dot-target).tmp; \
|
||||||
|
rm -f $(depfile); \
|
||||||
|
mv -f $(dot-target).tmp $(dot-target).cmd
|
||||||
|
endef |
||||||
|
|
||||||
|
# Built-in and composite module parts
|
||||||
|
$(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE |
||||||
|
$(call cmd,force_checksrc)
|
||||||
|
$(call if_changed_rule,cc_o_c)
|
||||||
|
|
||||||
|
# Single-part modules are special since we need to mark them in $(MODVERDIR)
|
||||||
|
|
||||||
|
$(single-used-m): $(obj)/%.o: $(src)/%.c $(recordmcount_source) FORCE |
||||||
|
$(call cmd,force_checksrc)
|
||||||
|
$(call if_changed_rule,cc_o_c)
|
||||||
|
@{ echo $(@:.o=.ko); echo $@; } > $(MODVERDIR)/$(@F:.o=.mod)
|
||||||
|
|
||||||
|
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) > $@
|
||||||
|
|
||||||
|
$(obj)/%.lst: $(src)/%.c FORCE |
||||||
|
$(call if_changed_dep,cc_lst_c)
|
||||||
|
|
||||||
|
# Compile assembler sources (.S)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
|
||||||
|
|
||||||
|
$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) |
||||||
|
$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE) |
||||||
|
|
||||||
|
quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
|
||||||
|
cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
|
||||||
|
|
||||||
|
$(obj)/%.s: $(src)/%.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 $@ $<
|
||||||
|
|
||||||
|
$(obj)/%.o: $(src)/%.S FORCE |
||||||
|
$(call if_changed_dep,as_o_S)
|
||||||
|
|
||||||
|
targets += $(real-objs-y) $(real-objs-m) $(lib-y)
|
||||||
|
targets += $(extra-y) $(MAKECMDGOALS) $(always)
|
||||||
|
|
||||||
|
# Linker scripts preprocessor (.lds.S -> .lds)
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
quiet_cmd_cpp_lds_S = LDS $@
|
||||||
|
cmd_cpp_lds_S = $(CPP) $(cpp_flags) -P -C -U$(ARCH) \
|
||||||
|
-D__ASSEMBLY__ -DLINKER_SCRIPT -o $@ $<
|
||||||
|
|
||||||
|
$(obj)/%.lds: $(src)/%.lds.S FORCE |
||||||
|
$(call if_changed_dep,cpp_lds_S)
|
||||||
|
|
||||||
|
# ASN.1 grammar
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
quiet_cmd_asn1_compiler = ASN.1 $@
|
||||||
|
cmd_asn1_compiler = $(objtree)/scripts/asn1_compiler $< \
|
||||||
|
$(subst .h,.c,$@) $(subst .c,.h,$@)
|
||||||
|
|
||||||
|
.PRECIOUS: $(objtree)/$(obj)/%-asn1.c $(objtree)/$(obj)/%-asn1.h |
||||||
|
|
||||||
|
$(obj)/%-asn1.c $(obj)/%-asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler |
||||||
|
$(call cmd,asn1_compiler)
|
||||||
|
|
||||||
|
# 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 builtin-target |
||||||
|
quiet_cmd_link_o_target = LD $@
|
||||||
|
# If the list of objects to link is empty, just create an empty built-in.o
|
||||||
|
cmd_link_o_target = $(if $(strip $(obj-y)),\
|
||||||
|
$(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \
|
||||||
|
$(cmd_secanalysis),\
|
||||||
|
rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@)
|
||||||
|
|
||||||
|
$(builtin-target): $(obj-y) FORCE |
||||||
|
$(call if_changed,link_o_target)
|
||||||
|
|
||||||
|
targets += $(builtin-target)
|
||||||
|
endif # builtin-target
|
||||||
|
|
||||||
|
#
|
||||||
|
# Rule to create modules.order file
|
||||||
|
#
|
||||||
|
# Create commands to either record .ko file or cat modules.order from
|
||||||
|
# a subdirectory
|
||||||
|
modorder-cmds = \
|
||||||
|
$(foreach m, $(modorder), \
|
||||||
|
$(if $(filter %/modules.order, $m), \
|
||||||
|
cat $m;, echo kernel/$m;))
|
||||||
|
|
||||||
|
$(modorder-target): $(subdir-ym) FORCE |
||||||
|
$(Q)(cat /dev/null; $(modorder-cmds)) > $@
|
||||||
|
|
||||||
|
#
|
||||||
|
# Rule to compile a set of .o files into one .a file
|
||||||
|
#
|
||||||
|
ifdef lib-target |
||||||
|
quiet_cmd_link_l_target = AR $@
|
||||||
|
cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y)
|
||||||
|
|
||||||
|
$(lib-target): $(lib-y) FORCE |
||||||
|
$(call if_changed,link_l_target)
|
||||||
|
|
||||||
|
targets += $(lib-target)
|
||||||
|
endif |
||||||
|
|
||||||
|
#
|
||||||
|
# Rule to link composite objects
|
||||||
|
#
|
||||||
|
# Composite objects are specified in kbuild makefile as follows:
|
||||||
|
# <composite-object>-objs := <list of .o files>
|
||||||
|
# or
|
||||||
|
# <composite-object>-y := <list of .o files>
|
||||||
|
link_multi_deps = \
|
||||||
|
$(filter $(addprefix $(obj)/, \
|
||||||
|
$($(subst $(obj)/,,$(@:.o=-objs))) \
|
||||||
|
$($(subst $(obj)/,,$(@:.o=-y)))), $^) |
||||||
|
|
||||||
|
quiet_cmd_link_multi-y = LD $@
|
||||||
|
cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis)
|
||||||
|
|
||||||
|
quiet_cmd_link_multi-m = LD [M] $@
|
||||||
|
cmd_link_multi-m = $(cmd_link_multi-y)
|
||||||
|
|
||||||
|
# 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: $(multi-objs-m) FORCE |
||||||
|
$(call if_changed,link_multi-m)
|
||||||
|
@{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod)
|
||||||
|
|
||||||
|
targets += $(multi-used-y) $(multi-used-m)
|
||||||
|
|
||||||
|
|
||||||
|
# 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 |
||||||
|
|
||||||
|
# Declare the contents of the .PHONY variable as phony. We keep that
|
||||||
|
# information in a variable se we can use it in if_changed and friends.
|
||||||
|
|
||||||
|
.PHONY: $(PHONY) |
@ -0,0 +1,104 @@ |
|||||||
|
# ==========================================================================
|
||||||
|
# Cleaning up
|
||||||
|
# ==========================================================================
|
||||||
|
|
||||||
|
src := $(obj)
|
||||||
|
|
||||||
|
PHONY := __clean
|
||||||
|
__clean: |
||||||
|
|
||||||
|
# Shorthand for $(Q)$(MAKE) scripts/Makefile.clean obj=dir
|
||||||
|
# Usage:
|
||||||
|
# $(Q)$(MAKE) $(clean)=dir
|
||||||
|
clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
|
||||||
|
|
||||||
|
# The filename Kbuild has precedence over Makefile
|
||||||
|
kbuild-dir := $(if $(filter /%,$(src)),$(src),$(srctree)/$(src))
|
||||||
|
include $(if $(wildcard $(kbuild-dir)/Kbuild), $(kbuild-dir)/Kbuild, $(kbuild-dir)/Makefile) |
||||||
|
|
||||||
|
# Figure out what we need to build from the various variables
|
||||||
|
# ==========================================================================
|
||||||
|
|
||||||
|
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
|
||||||
|
subdir-y += $(__subdir-y)
|
||||||
|
__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
|
||||||
|
subdir-m += $(__subdir-m)
|
||||||
|
__subdir-n := $(patsubst %/,%,$(filter %/, $(obj-n)))
|
||||||
|
subdir-n += $(__subdir-n)
|
||||||
|
__subdir- := $(patsubst %/,%,$(filter %/, $(obj-)))
|
||||||
|
subdir- += $(__subdir-)
|
||||||
|
|
||||||
|
# Subdirectories we need to descend into
|
||||||
|
|
||||||
|
subdir-ym := $(sort $(subdir-y) $(subdir-m))
|
||||||
|
subdir-ymn := $(sort $(subdir-ym) $(subdir-n) $(subdir-))
|
||||||
|
|
||||||
|
# Add subdir path
|
||||||
|
|
||||||
|
subdir-ymn := $(addprefix $(obj)/,$(subdir-ymn))
|
||||||
|
|
||||||
|
# build a list of files to remove, usually relative to the current
|
||||||
|
# directory
|
||||||
|
|
||||||
|
__clean-files := $(extra-y) $(always) \
|
||||||
|
$(targets) $(clean-files) \
|
||||||
|
$(host-progs) \
|
||||||
|
$(hostprogs-y) $(hostprogs-m) $(hostprogs-)
|
||||||
|
|
||||||
|
__clean-files := $(filter-out $(no-clean-files), $(__clean-files))
|
||||||
|
|
||||||
|
# as clean-files is given relative to the current directory, this adds
|
||||||
|
# a $(obj) prefix, except for absolute paths
|
||||||
|
|
||||||
|
__clean-files := $(wildcard \
|
||||||
|
$(addprefix $(obj)/, $(filter-out /%, $(__clean-files))) \
|
||||||
|
$(filter /%, $(__clean-files)))
|
||||||
|
|
||||||
|
# as clean-dirs is given relative to the current directory, this adds
|
||||||
|
# a $(obj) prefix, except for absolute paths
|
||||||
|
|
||||||
|
__clean-dirs := $(wildcard \
|
||||||
|
$(addprefix $(obj)/, $(filter-out /%, $(clean-dirs))) \
|
||||||
|
$(filter /%, $(clean-dirs)))
|
||||||
|
|
||||||
|
# ==========================================================================
|
||||||
|
|
||||||
|
quiet_cmd_clean = CLEAN $(obj)
|
||||||
|
cmd_clean = rm -f $(__clean-files)
|
||||||
|
quiet_cmd_cleandir = CLEAN $(__clean-dirs)
|
||||||
|
cmd_cleandir = rm -rf $(__clean-dirs)
|
||||||
|
|
||||||
|
|
||||||
|
__clean: $(subdir-ymn) |
||||||
|
ifneq ($(strip $(__clean-files)),) |
||||||
|
+$(call cmd,clean)
|
||||||
|
endif |
||||||
|
ifneq ($(strip $(__clean-dirs)),) |
||||||
|
+$(call cmd,cleandir)
|
||||||
|
endif |
||||||
|
ifneq ($(strip $(clean-rule)),) |
||||||
|
+$(clean-rule)
|
||||||
|
endif |
||||||
|
@:
|
||||||
|
|
||||||
|
|
||||||
|
# ===========================================================================
|
||||||
|
# Generic stuff
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
# Descending
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
PHONY += $(subdir-ymn)
|
||||||
|
$(subdir-ymn): |
||||||
|
$(Q)$(MAKE) $(clean)=$@
|
||||||
|
|
||||||
|
# If quiet is set, only print short version of command
|
||||||
|
|
||||||
|
cmd = @$(if $($(quiet)cmd_$(1)),echo ' $($(quiet)cmd_$(1))' &&) $(cmd_$(1))
|
||||||
|
|
||||||
|
|
||||||
|
# Declare the contents of the .PHONY variable as phony. We keep that
|
||||||
|
# information in a variable se we can use it in if_changed and friends.
|
||||||
|
|
||||||
|
.PHONY: $(PHONY) |
@ -0,0 +1,170 @@ |
|||||||
|
# ==========================================================================
|
||||||
|
# Building binaries on the host system
|
||||||
|
# Binaries are used during the compilation of the kernel, for example
|
||||||
|
# to preprocess a data file.
|
||||||
|
#
|
||||||
|
# Both C and C++ are supported, but preferred language is C for such utilities.
|
||||||
|
#
|
||||||
|
# Sample syntax (see Documentation/kbuild/makefiles.txt for reference)
|
||||||
|
# hostprogs-y := bin2hex
|
||||||
|
# Will compile bin2hex.c and create an executable named bin2hex
|
||||||
|
#
|
||||||
|
# hostprogs-y := 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
|
||||||
|
#
|
||||||
|
# hostprogs-y := 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
|
||||||
|
|
||||||
|
# hostprogs-y := conf
|
||||||
|
# conf-objs := conf.o libkconfig.so
|
||||||
|
# libkconfig-objs := expr.o type.o
|
||||||
|
# Will create a shared library named libkconfig.so that consists of
|
||||||
|
# expr.o and type.o (they are both compiled as C code and the object files
|
||||||
|
# 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
|
||||||
|
|
||||||
|
__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
|
||||||
|
|
||||||
|
# C code
|
||||||
|
# Executables compiled from a single .c file
|
||||||
|
host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m)))
|
||||||
|
|
||||||
|
# C executables linked based on several .o files
|
||||||
|
host-cmulti := $(foreach m,$(__hostprogs),\
|
||||||
|
$(if $($(m)-cxxobjs),,$(if $($(m)-objs),$(m))))
|
||||||
|
|
||||||
|
# Object (.o) files compiled from .c files
|
||||||
|
host-cobjs := $(sort $(foreach m,$(__hostprogs),$($(m)-objs)))
|
||||||
|
|
||||||
|
# C++ code
|
||||||
|
# C++ executables compiled from at least on .cc file
|
||||||
|
# and zero or more .c files
|
||||||
|
host-cxxmulti := $(foreach m,$(__hostprogs),$(if $($(m)-cxxobjs),$(m)))
|
||||||
|
|
||||||
|
# C++ Object (.o) files compiled from .cc files
|
||||||
|
host-cxxobjs := $(sort $(foreach m,$(host-cxxmulti),$($(m)-cxxobjs)))
|
||||||
|
|
||||||
|
# Shared libaries (only .c supported)
|
||||||
|
# Shared libraries (.so) - all .so files referenced in "xxx-objs"
|
||||||
|
host-cshlib := $(sort $(filter %.so, $(host-cobjs)))
|
||||||
|
# Remove .so files from "xxx-objs"
|
||||||
|
host-cobjs := $(filter-out %.so,$(host-cobjs))
|
||||||
|
|
||||||
|
#Object (.o) files used by the shared libaries
|
||||||
|
host-cshobjs := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs))))
|
||||||
|
|
||||||
|
# output directory for programs/.o files
|
||||||
|
# hostprogs-y := tools/build may have been specified. Retrieve directory
|
||||||
|
host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
|
||||||
|
# directory of .o files from prog-objs notation
|
||||||
|
host-objdirs += $(foreach f,$(host-cmulti), \
|
||||||
|
$(foreach m,$($(f)-objs), \
|
||||||
|
$(if $(dir $(m)),$(dir $(m)))))
|
||||||
|
# directory of .o files from prog-cxxobjs notation
|
||||||
|
host-objdirs += $(foreach f,$(host-cxxmulti), \
|
||||||
|
$(foreach m,$($(f)-cxxobjs), \
|
||||||
|
$(if $(dir $(m)),$(dir $(m)))))
|
||||||
|
|
||||||
|
host-objdirs := $(strip $(sort $(filter-out ./,$(host-objdirs))))
|
||||||
|
|
||||||
|
|
||||||
|
__hostprogs := $(addprefix $(obj)/,$(__hostprogs))
|
||||||
|
host-csingle := $(addprefix $(obj)/,$(host-csingle))
|
||||||
|
host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
|
||||||
|
host-cobjs := $(addprefix $(obj)/,$(host-cobjs))
|
||||||
|
host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
|
||||||
|
host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
|
||||||
|
host-cshlib := $(addprefix $(obj)/,$(host-cshlib))
|
||||||
|
host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs))
|
||||||
|
host-objdirs := $(addprefix $(obj)/,$(host-objdirs))
|
||||||
|
|
||||||
|
obj-dirs += $(host-objdirs)
|
||||||
|
|
||||||
|
#####
|
||||||
|
# Handle options to gcc. Support building with separate output directory
|
||||||
|
|
||||||
|
_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
|
||||||
|
$(HOSTCFLAGS_$(basetarget).o)
|
||||||
|
_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
|
||||||
|
$(HOSTCXXFLAGS_$(basetarget).o)
|
||||||
|
|
||||||
|
ifeq ($(KBUILD_SRC),) |
||||||
|
__hostc_flags = $(_hostc_flags)
|
||||||
|
__hostcxx_flags = $(_hostcxx_flags)
|
||||||
|
else |
||||||
|
__hostc_flags = -I$(obj) $(call flags,_hostc_flags)
|
||||||
|
__hostcxx_flags = -I$(obj) $(call flags,_hostcxx_flags)
|
||||||
|
endif |
||||||
|
|
||||||
|
hostc_flags = -Wp,-MD,$(depfile) $(__hostc_flags)
|
||||||
|
hostcxx_flags = -Wp,-MD,$(depfile) $(__hostcxx_flags)
|
||||||
|
|
||||||
|
#####
|
||||||
|
# Compile programs on the host
|
||||||
|
|
||||||
|
# Create executable from a single .c file
|
||||||
|
# host-csingle -> Executable
|
||||||
|
quiet_cmd_host-csingle = HOSTCC $@
|
||||||
|
cmd_host-csingle = $(HOSTCC) $(hostc_flags) -o $@ $< \
|
||||||
|
$(HOST_LOADLIBES) $(HOSTLOADLIBES_$(@F))
|
||||||
|
$(host-csingle): $(obj)/%: $(src)/%.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): $(obj)/%: $(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): $(obj)/%.o: $(src)/%.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): $(obj)/%: $(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): $(obj)/%.o: $(src)/%.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): $(obj)/%.o: $(src)/%.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): $(obj)/%: $(host-cshobjs) FORCE |
||||||
|
$(call if_changed,host-cshlib)
|
||||||
|
|
||||||
|
targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\
|
||||||
|
$(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs)
|
||||||
|
|
@ -0,0 +1,373 @@ |
|||||||
|
# Backward compatibility
|
||||||
|
asflags-y += $(EXTRA_AFLAGS)
|
||||||
|
ccflags-y += $(EXTRA_CFLAGS)
|
||||||
|
cppflags-y += $(EXTRA_CPPFLAGS)
|
||||||
|
ldflags-y += $(EXTRA_LDFLAGS)
|
||||||
|
|
||||||
|
#
|
||||||
|
# flags that take effect in sub directories
|
||||||
|
export KBUILD_SUBDIR_ASFLAGS := $(KBUILD_SUBDIR_ASFLAGS) $(subdir-asflags-y)
|
||||||
|
export KBUILD_SUBDIR_CCFLAGS := $(KBUILD_SUBDIR_CCFLAGS) $(subdir-ccflags-y)
|
||||||
|
|
||||||
|
# Figure out what we need to build from the various variables
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
# When an object is listed to be built compiled-in and modular,
|
||||||
|
# only build the compiled-in version
|
||||||
|
|
||||||
|
obj-m := $(filter-out $(obj-y),$(obj-m))
|
||||||
|
|
||||||
|
# Libraries are always collected in one lib file.
|
||||||
|
# Filter out objects already built-in
|
||||||
|
|
||||||
|
lib-y := $(filter-out $(obj-y), $(sort $(lib-y) $(lib-m)))
|
||||||
|
|
||||||
|
|
||||||
|
# Handle objects in subdirs
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# o if we encounter foo/ in $(obj-y), replace it by foo/built-in.o
|
||||||
|
# and add the directory to the list of dirs to descend into: $(subdir-y)
|
||||||
|
# o if we encounter foo/ in $(obj-m), remove it from $(obj-m)
|
||||||
|
# and add the directory to the list of dirs to descend into: $(subdir-m)
|
||||||
|
|
||||||
|
# Determine modorder.
|
||||||
|
# Unfortunately, we don't have information about ordering between -y
|
||||||
|
# and -m subdirs. Just put -y's first.
|
||||||
|
modorder := $(patsubst %/,%/modules.order, $(filter %/, $(obj-y)) $(obj-m:.o=.ko))
|
||||||
|
|
||||||
|
__subdir-y := $(patsubst %/,%,$(filter %/, $(obj-y)))
|
||||||
|
subdir-y += $(__subdir-y)
|
||||||
|
__subdir-m := $(patsubst %/,%,$(filter %/, $(obj-m)))
|
||||||
|
subdir-m += $(__subdir-m)
|
||||||
|
obj-y := $(patsubst %/, %/built-in.o, $(obj-y))
|
||||||
|
obj-m := $(filter-out %/, $(obj-m))
|
||||||
|
|
||||||
|
# Subdirectories we need to descend into
|
||||||
|
|
||||||
|
subdir-ym := $(sort $(subdir-y) $(subdir-m))
|
||||||
|
|
||||||
|
# if $(foo-objs) exists, foo.o is a composite object
|
||||||
|
multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
|
||||||
|
multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
|
||||||
|
multi-used := $(multi-used-y) $(multi-used-m)
|
||||||
|
single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
|
||||||
|
|
||||||
|
# Build list of the parts of our composite objects, our composite
|
||||||
|
# objects depend on those (obviously)
|
||||||
|
multi-objs-y := $(foreach m, $(multi-used-y), $($(m:.o=-objs)) $($(m:.o=-y)))
|
||||||
|
multi-objs-m := $(foreach m, $(multi-used-m), $($(m:.o=-objs)) $($(m:.o=-y)))
|
||||||
|
multi-objs := $(multi-objs-y) $(multi-objs-m)
|
||||||
|
|
||||||
|
# $(subdir-obj-y) is the list of objects in $(obj-y) which uses dir/ to
|
||||||
|
# tell kbuild to descend
|
||||||
|
subdir-obj-y := $(filter %/built-in.o, $(obj-y))
|
||||||
|
|
||||||
|
# $(obj-dirs) is a list of directories that contain object files
|
||||||
|
obj-dirs := $(dir $(multi-objs) $(obj-y))
|
||||||
|
|
||||||
|
# Replace multi-part objects by their individual parts, look at local dir only
|
||||||
|
real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(extra-y)
|
||||||
|
real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
|
||||||
|
|
||||||
|
# Add subdir path
|
||||||
|
|
||||||
|
extra-y := $(addprefix $(obj)/,$(extra-y))
|
||||||
|
always := $(addprefix $(obj)/,$(always))
|
||||||
|
targets := $(addprefix $(obj)/,$(targets))
|
||||||
|
modorder := $(addprefix $(obj)/,$(modorder))
|
||||||
|
obj-y := $(addprefix $(obj)/,$(obj-y))
|
||||||
|
obj-m := $(addprefix $(obj)/,$(obj-m))
|
||||||
|
lib-y := $(addprefix $(obj)/,$(lib-y))
|
||||||
|
subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y))
|
||||||
|
real-objs-y := $(addprefix $(obj)/,$(real-objs-y))
|
||||||
|
real-objs-m := $(addprefix $(obj)/,$(real-objs-m))
|
||||||
|
single-used-m := $(addprefix $(obj)/,$(single-used-m))
|
||||||
|
multi-used-y := $(addprefix $(obj)/,$(multi-used-y))
|
||||||
|
multi-used-m := $(addprefix $(obj)/,$(multi-used-m))
|
||||||
|
multi-objs-y := $(addprefix $(obj)/,$(multi-objs-y))
|
||||||
|
multi-objs-m := $(addprefix $(obj)/,$(multi-objs-m))
|
||||||
|
subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
|
||||||
|
obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
|
||||||
|
|
||||||
|
# These flags are needed for modversions and compiling, so we define them here
|
||||||
|
# already
|
||||||
|
# $(modname_flags) #defines KBUILD_MODNAME as the name of the module it will
|
||||||
|
# end up in (or would, if it gets compiled in)
|
||||||
|
# Note: Files that end up in two or more modules are compiled without the
|
||||||
|
# KBUILD_MODNAME definition. The reason is that any made-up name would
|
||||||
|
# differ in different configs.
|
||||||
|
name-fix = $(subst $(comma),_,$(subst -,_,$1))
|
||||||
|
basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
|
||||||
|
modname_flags = $(if $(filter 1,$(words $(modname))),\
|
||||||
|
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
|
||||||
|
|
||||||
|
orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \
|
||||||
|
$(ccflags-y) $(CFLAGS_$(basetarget).o)
|
||||||
|
_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
|
||||||
|
_a_flags = $(KBUILD_CPPFLAGS) $(KBUILD_AFLAGS) $(KBUILD_SUBDIR_ASFLAGS) \
|
||||||
|
$(asflags-y) $(AFLAGS_$(basetarget).o)
|
||||||
|
_cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(@F))
|
||||||
|
|
||||||
|
#
|
||||||
|
# Enable gcov profiling flags for a file, directory or for all files depending
|
||||||
|
# on variables GCOV_PROFILE_obj.o, GCOV_PROFILE and CONFIG_GCOV_PROFILE_ALL
|
||||||
|
# (in this order)
|
||||||
|
#
|
||||||
|
ifeq ($(CONFIG_GCOV_KERNEL),y) |
||||||
|
_c_flags += $(if $(patsubst n%,, \
|
||||||
|
$(GCOV_PROFILE_$(basetarget).o)$(GCOV_PROFILE)$(CONFIG_GCOV_PROFILE_ALL)), \
|
||||||
|
$(CFLAGS_GCOV))
|
||||||
|
endif |
||||||
|
|
||||||
|
# If building the kernel in a separate objtree expand all occurrences
|
||||||
|
# of -Idir to -I$(srctree)/dir except for absolute paths (starting with '/').
|
||||||
|
|
||||||
|
ifeq ($(KBUILD_SRC),) |
||||||
|
__c_flags = $(_c_flags)
|
||||||
|
__a_flags = $(_a_flags)
|
||||||
|
__cpp_flags = $(_cpp_flags)
|
||||||
|
else |
||||||
|
|
||||||
|
# -I$(obj) locates generated .h files
|
||||||
|
# $(call addtree,-I$(obj)) locates .h files in srctree, from generated .c files
|
||||||
|
# and locates generated .h files
|
||||||
|
# FIXME: Replace both with specific CFLAGS* statements in the makefiles
|
||||||
|
__c_flags = $(call addtree,-I$(obj)) $(call flags,_c_flags)
|
||||||
|
__a_flags = $(call flags,_a_flags)
|
||||||
|
__cpp_flags = $(call flags,_cpp_flags)
|
||||||
|
endif |
||||||
|
|
||||||
|
c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
|
||||||
|
$(__c_flags) $(modkern_cflags) \
|
||||||
|
-D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
|
||||||
|
|
||||||
|
a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
|
||||||
|
$(__a_flags) $(modkern_aflags)
|
||||||
|
|
||||||
|
cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) \
|
||||||
|
$(__cpp_flags)
|
||||||
|
|
||||||
|
ld_flags = $(LDFLAGS) $(ldflags-y)
|
||||||
|
|
||||||
|
dtc_cpp_flags = -Wp,-MD,$(depfile).pre.tmp -nostdinc \
|
||||||
|
-I$(srctree)/arch/$(SRCARCH)/boot/dts \
|
||||||
|
-I$(srctree)/arch/$(SRCARCH)/boot/dts/include \
|
||||||
|
-undef -D__DTS__
|
||||||
|
|
||||||
|
# Finds the multi-part object the current object will be linked into
|
||||||
|
modname-multi = $(sort $(foreach m,$(multi-used),\
|
||||||
|
$(if $(filter $(subst $(obj)/,,$*.o), $($(m:.o=-objs)) $($(m:.o=-y))),$(m:.o=))))
|
||||||
|
|
||||||
|
ifdef REGENERATE_PARSERS |
||||||
|
|
||||||
|
# GPERF
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
quiet_cmd_gperf = GPERF $@
|
||||||
|
cmd_gperf = gperf -t --output-file $@ -a -C -E -g -k 1,3,$$ -p -t $<
|
||||||
|
|
||||||
|
.PRECIOUS: $(src)/%.hash.c_shipped |
||||||
|
$(src)/%.hash.c_shipped: $(src)/%.gperf |
||||||
|
$(call cmd,gperf)
|
||||||
|
|
||||||
|
# LEX
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
LEX_PREFIX = $(if $(LEX_PREFIX_${baseprereq}),$(LEX_PREFIX_${baseprereq}),yy)
|
||||||
|
|
||||||
|
quiet_cmd_flex = LEX $@
|
||||||
|
cmd_flex = flex -o$@ -L -P $(LEX_PREFIX) $<
|
||||||
|
|
||||||
|
.PRECIOUS: $(src)/%.lex.c_shipped |
||||||
|
$(src)/%.lex.c_shipped: $(src)/%.l |
||||||
|
$(call cmd,flex)
|
||||||
|
|
||||||
|
# YACC
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
YACC_PREFIX = $(if $(YACC_PREFIX_${baseprereq}),$(YACC_PREFIX_${baseprereq}),yy)
|
||||||
|
|
||||||
|
quiet_cmd_bison = YACC $@
|
||||||
|
cmd_bison = bison -o$@ -t -l -p $(YACC_PREFIX) $<
|
||||||
|
|
||||||
|
.PRECIOUS: $(src)/%.tab.c_shipped |
||||||
|
$(src)/%.tab.c_shipped: $(src)/%.y |
||||||
|
$(call cmd,bison)
|
||||||
|
|
||||||
|
quiet_cmd_bison_h = YACC $@
|
||||||
|
cmd_bison_h = bison -o/dev/null --defines=$@ -t -l -p $(YACC_PREFIX) $<
|
||||||
|
|
||||||
|
.PRECIOUS: $(src)/%.tab.h_shipped |
||||||
|
$(src)/%.tab.h_shipped: $(src)/%.y |
||||||
|
$(call cmd,bison_h)
|
||||||
|
|
||||||
|
endif |
||||||
|
|
||||||
|
# Shipped files
|
||||||
|
# ===========================================================================
|
||||||
|
|
||||||
|
quiet_cmd_shipped = SHIPPED $@
|
||||||
|
cmd_shipped = cat $< > $@
|
||||||
|
|
||||||
|
$(obj)/%: $(src)/%_shipped |
||||||
|
$(call cmd,shipped)
|
||||||
|
|
||||||
|
# Commands useful for building a boot image
|
||||||
|
# ===========================================================================
|
||||||
|
#
|
||||||
|
# Use as following:
|
||||||
|
#
|
||||||
|
# target: source(s) FORCE
|
||||||
|
# $(if_changed,ld/objcopy/gzip)
|
||||||
|
#
|
||||||
|
# and add target to extra-y so that we know we have to
|
||||||
|
# read in the saved command line
|
||||||
|
|
||||||
|
# Linking
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
quiet_cmd_ld = LD $@
|
||||||
|
cmd_ld = $(LD) $(LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F)) \
|
||||||
|
$(filter-out FORCE,$^) -o $@
|
||||||
|
|
||||||
|
# Objcopy
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
quiet_cmd_objcopy = OBJCOPY $@
|
||||||
|
cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
|
||||||
|
|
||||||
|
# Gzip
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
quiet_cmd_gzip = GZIP $@
|
||||||
|
cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -n -f -9 > $@) || \
|
||||||
|
(rm -f $@ ; false)
|
||||||
|
|
||||||
|
# DTC
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Generate an assembly file to wrap the output of the device tree compiler
|
||||||
|
quiet_cmd_dt_S_dtb= DTB $@
|
||||||
|
cmd_dt_S_dtb= \
|
||||||
|
( \ |
||||||
|
echo '\#include <asm-generic/vmlinux.lds.h>'; \
|
||||||
|
echo '.section .dtb.init.rodata,"a"'; \
|
||||||
|
echo '.balign STRUCT_ALIGNMENT'; \
|
||||||
|
echo '.global __dtb_$(*F)_begin'; \
|
||||||
|
echo '__dtb_$(*F)_begin:'; \
|
||||||
|
echo '.incbin "$<" '; \
|
||||||
|
echo '__dtb_$(*F)_end:'; \
|
||||||
|
echo '.global __dtb_$(*F)_end'; \
|
||||||
|
echo '.balign STRUCT_ALIGNMENT'; \
|
||||||
|
) > $@ |
||||||
|
|
||||||
|
$(obj)/%.dtb.S: $(obj)/%.dtb |
||||||
|
$(call cmd,dt_S_dtb)
|
||||||
|
|
||||||
|
quiet_cmd_dtc = DTC $@
|
||||||
|
cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
|
||||||
|
$(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
|
||||||
|
-i $(dir $<) $(DTC_FLAGS) \
|
||||||
|
-d $(depfile).dtc.tmp $(dtc-tmp) ; \
|
||||||
|
cat $(depfile).pre.tmp $(depfile).dtc.tmp > $(depfile)
|
||||||
|
|
||||||
|
$(obj)/%.dtb: $(src)/%.dts FORCE |
||||||
|
$(call if_changed_dep,dtc)
|
||||||
|
|
||||||
|
dtc-tmp = $(subst $(comma),_,$(dot-target).dts.tmp)
|
||||||
|
|
||||||
|
# Bzip2
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Bzip2 and LZMA do not include size in file... so we have to fake that;
|
||||||
|
# append the size as a 32-bit littleendian number as gzip does.
|
||||||
|
size_append = printf $(shell \
|
||||||
|
dec_size=0; \
|
||||||
|
for F in $1; do \ |
||||||
|
fsize=$$(stat -c "%s" $$F); \
|
||||||
|
dec_size=$$(expr $$dec_size + $$fsize); \
|
||||||
|
done; \ |
||||||
|
printf "%08x\n" $$dec_size | \ |
||||||
|
sed 's/\(..\)/\1 /g' | { \
|
||||||
|
read ch0 ch1 ch2 ch3; \
|
||||||
|
for ch in $$ch3 $$ch2 $$ch1 $$ch0; do \
|
||||||
|
printf '%s%03o' '\\' $$((0x$$ch)); \
|
||||||
|
done; \
|
||||||
|
} \
|
||||||
|
) |
||||||
|
|
||||||
|
quiet_cmd_bzip2 = BZIP2 $@
|
||||||
|
cmd_bzip2 = (cat $(filter-out FORCE,$^) | \
|
||||||
|
bzip2 -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
|
||||||
|
(rm -f $@ ; false)
|
||||||
|
|
||||||
|
# Lzma
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
quiet_cmd_lzma = LZMA $@
|
||||||
|
cmd_lzma = (cat $(filter-out FORCE,$^) | \
|
||||||
|
lzma -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
|
||||||
|
(rm -f $@ ; false)
|
||||||
|
|
||||||
|
quiet_cmd_lzo = LZO $@
|
||||||
|
cmd_lzo = (cat $(filter-out FORCE,$^) | \
|
||||||
|
lzop -9 && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
|
||||||
|
(rm -f $@ ; false)
|
||||||
|
|
||||||
|
quiet_cmd_lz4 = LZ4 $@
|
||||||
|
cmd_lz4 = (cat $(filter-out FORCE,$^) | \
|
||||||
|
lz4c -l -c1 stdin stdout && $(call size_append, $(filter-out FORCE,$^))) > $@ || \
|
||||||
|
(rm -f $@ ; false)
|
||||||
|
|
||||||
|
# U-Boot mkimage
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
MKIMAGE := $(srctree)/scripts/mkuboot.sh
|
||||||
|
|
||||||
|
# SRCARCH just happens to match slightly more than ARCH (on sparc), so reduces
|
||||||
|
# the number of overrides in arch makefiles
|
||||||
|
UIMAGE_ARCH ?= $(SRCARCH)
|
||||||
|
UIMAGE_COMPRESSION ?= $(if $(2),$(2),none)
|
||||||
|
UIMAGE_OPTS-y ?=
|
||||||
|
UIMAGE_TYPE ?= kernel
|
||||||
|
UIMAGE_LOADADDR ?= arch_must_set_this
|
||||||
|
UIMAGE_ENTRYADDR ?= $(UIMAGE_LOADADDR)
|
||||||
|
UIMAGE_NAME ?= 'Linux-$(KERNELRELEASE)'
|
||||||
|
UIMAGE_IN ?= $<
|
||||||
|
UIMAGE_OUT ?= $@
|
||||||
|
|
||||||
|
quiet_cmd_uimage = UIMAGE $(UIMAGE_OUT)
|
||||||
|
cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A $(UIMAGE_ARCH) -O linux \
|
||||||
|
-C $(UIMAGE_COMPRESSION) $(UIMAGE_OPTS-y) \
|
||||||
|
-T $(UIMAGE_TYPE) \
|
||||||
|
-a $(UIMAGE_LOADADDR) -e $(UIMAGE_ENTRYADDR) \
|
||||||
|
-n $(UIMAGE_NAME) -d $(UIMAGE_IN) $(UIMAGE_OUT)
|
||||||
|
|
||||||
|
# XZ
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Use xzkern to compress the kernel image and xzmisc to compress other things.
|
||||||
|
#
|
||||||
|
# xzkern uses a big LZMA2 dictionary since it doesn't increase memory usage
|
||||||
|
# of the kernel decompressor. A BCJ filter is used if it is available for
|
||||||
|
# the target architecture. xzkern also appends uncompressed size of the data
|
||||||
|
# using size_append. The .xz format has the size information available at
|
||||||
|
# the end of the file too, but it's in more complex format and it's good to
|
||||||
|
# avoid changing the part of the boot code that reads the uncompressed size.
|
||||||
|
# Note that the bytes added by size_append will make the xz tool think that
|
||||||
|
# the file is corrupt. This is expected.
|
||||||
|
#
|
||||||
|
# xzmisc doesn't use size_append, so it can be used to create normal .xz
|
||||||
|
# files. xzmisc uses smaller LZMA2 dictionary than xzkern, because a very
|
||||||
|
# big dictionary would increase the memory usage too much in the multi-call
|
||||||
|
# decompression mode. A BCJ filter isn't used either.
|
||||||
|
quiet_cmd_xzkern = XZKERN $@
|
||||||
|
cmd_xzkern = (cat $(filter-out FORCE,$^) | \
|
||||||
|
sh $(srctree)/scripts/xz_wrap.sh && \
|
||||||
|
$(call size_append, $(filter-out FORCE,$^))) > $@ || \
|
||||||
|
(rm -f $@ ; false)
|
||||||
|
|
||||||
|
quiet_cmd_xzmisc = XZMISC $@
|
||||||
|
cmd_xzmisc = (cat $(filter-out FORCE,$^) | \
|
||||||
|
xz --check=crc32 --lzma2=dict=1MiB) > $@ || \
|
||||||
|
(rm -f $@ ; false)
|
||||||
|
|
||||||
|
# misc stuff
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
quote:="
|
@ -0,0 +1 @@ |
|||||||
|
fixdep |
@ -0,0 +1,15 @@ |
|||||||
|
###
|
||||||
|
# Makefile.basic lists the most basic programs used during the build process.
|
||||||
|
# The programs listed herein are what are needed to do the basic stuff,
|
||||||
|
# such as fix file dependencies.
|
||||||
|
# This initial step is needed to avoid files to be recompiled
|
||||||
|
# when kernel configuration changes (which is what happens when
|
||||||
|
# .config is included by main Makefile.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# fixdep: Used to generate dependency information during build process
|
||||||
|
|
||||||
|
hostprogs-y := fixdep
|
||||||
|
always := $(hostprogs-y)
|
||||||
|
|
||||||
|
# fixdep is needed to compile other host programs
|
||||||
|
$(addprefix $(obj)/,$(filter-out fixdep,$(always))): $(obj)/fixdep |
@ -0,0 +1,462 @@ |
|||||||
|
/*
|
||||||
|
* "Optimize" a list of dependencies as spit out by gcc -MD |
||||||
|
* for the kernel build |
||||||
|
* =========================================================================== |
||||||
|
* |
||||||
|
* Author Kai Germaschewski |
||||||
|
* Copyright 2002 by Kai Germaschewski <kai.germaschewski@gmx.de> |
||||||
|
* |
||||||
|
* This software may be used and distributed according to the terms |
||||||
|
* of the GNU General Public License, incorporated herein by reference. |
||||||
|
* |
||||||
|
* |
||||||
|
* Introduction: |
||||||
|
* |
||||||
|
* gcc produces a very nice and correct list of dependencies which |
||||||
|
* tells make when to remake a file. |
||||||
|
* |
||||||
|
* To use this list as-is however has the drawback that virtually |
||||||
|
* every file in the kernel includes autoconf.h. |
||||||
|
* |
||||||
|
* If the user re-runs make *config, autoconf.h will be |
||||||
|
* regenerated. make notices that and will rebuild every file which |
||||||
|
* includes autoconf.h, i.e. basically all files. This is extremely |
||||||
|
* annoying if the user just changed CONFIG_HIS_DRIVER from n to m. |
||||||
|
* |
||||||
|
* So we play the same trick that "mkdep" played before. We replace |
||||||
|
* the dependency on autoconf.h by a dependency on every config |
||||||
|
* option which is mentioned in any of the listed prequisites. |
||||||
|
* |
||||||
|
* kconfig populates a tree in include/config/ with an empty file |
||||||
|
* for each config symbol and when the configuration is updated |
||||||
|
* the files representing changed config options are touched |
||||||
|
* which then let make pick up the changes and the files that use |
||||||
|
* the config symbols are rebuilt. |
||||||
|
* |
||||||
|
* So if the user changes his CONFIG_HIS_DRIVER option, only the objects |
||||||
|
* which depend on "include/linux/config/his/driver.h" will be rebuilt, |
||||||
|
* so most likely only his driver ;-) |
||||||
|
* |
||||||
|
* The idea above dates, by the way, back to Michael E Chastain, AFAIK. |
||||||
|
* |
||||||
|
* So to get dependencies right, there are two issues: |
||||||
|
* o if any of the files the compiler read changed, we need to rebuild |
||||||
|
* o if the command line given to the compile the file changed, we |
||||||
|
* better rebuild as well. |
||||||
|
* |
||||||
|
* The former is handled by using the -MD output, the later by saving |
||||||
|
* the command line used to compile the old object and comparing it |
||||||
|
* to the one we would now use. |
||||||
|
* |
||||||
|
* Again, also this idea is pretty old and has been discussed on |
||||||
|
* kbuild-devel a long time ago. I don't have a sensibly working |
||||||
|
* internet connection right now, so I rather don't mention names |
||||||
|
* without double checking. |
||||||
|
* |
||||||
|
* This code here has been based partially based on mkdep.c, which |
||||||
|
* says the following about its history: |
||||||
|
* |
||||||
|
* Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>. |
||||||
|
* This is a C version of syncdep.pl by Werner Almesberger. |
||||||
|
* |
||||||
|
* |
||||||
|
* It is invoked as |
||||||
|
* |
||||||
|
* fixdep <depfile> <target> <cmdline> |
||||||
|
* |
||||||
|
* and will read the dependency file <depfile> |
||||||
|
* |
||||||
|
* The transformed dependency snipped is written to stdout. |
||||||
|
* |
||||||
|
* It first generates a line |
||||||
|
* |
||||||
|
* cmd_<target> = <cmdline> |
||||||
|
* |
||||||
|
* and then basically copies the .<target>.d file to stdout, in the |
||||||
|
* process filtering out the dependency on autoconf.h and adding |
||||||
|
* dependencies on include/config/my/option.h for every |
||||||
|
* CONFIG_MY_OPTION encountered in any of the prequisites. |
||||||
|
* |
||||||
|
* It will also filter out all the dependencies on *.ver. We need |
||||||
|
* to make sure that the generated version checksum are globally up |
||||||
|
* to date before even starting the recursive build, so it's too late |
||||||
|
* at this point anyway. |
||||||
|
* |
||||||
|
* The algorithm to grep for "CONFIG_..." is bit unusual, but should |
||||||
|
* be fast ;-) We don't even try to really parse the header files, but |
||||||
|
* merely grep, i.e. if CONFIG_FOO is mentioned in a comment, it will |
||||||
|
* be picked up as well. It's not a problem with respect to |
||||||
|
* correctness, since that can only give too many dependencies, thus |
||||||
|
* we cannot miss a rebuild. Since people tend to not mention totally |
||||||
|
* unrelated CONFIG_ options all over the place, it's not an |
||||||
|
* efficiency problem either. |
||||||
|
* |
||||||
|
* (Note: it'd be easy to port over the complete mkdep state machine, |
||||||
|
* but I don't think the added complexity is worth it) |
||||||
|
*/ |
||||||
|
/*
|
||||||
|
* Note 2: if somebody writes HELLO_CONFIG_BOOM in a file, it will depend onto |
||||||
|
* CONFIG_BOOM. This could seem a bug (not too hard to fix), but please do not |
||||||
|
* fix it! Some UserModeLinux files (look at arch/um/) call CONFIG_BOOM as |
||||||
|
* UML_CONFIG_BOOM, to avoid conflicts with /usr/include/linux/autoconf.h, |
||||||
|
* through arch/um/include/uml-config.h; this fixdep "bug" makes sure that |
||||||
|
* those files will have correct dependencies. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <sys/types.h> |
||||||
|
#include <sys/stat.h> |
||||||
|
#include <sys/mman.h> |
||||||
|
#include <unistd.h> |
||||||
|
#include <fcntl.h> |
||||||
|
#include <string.h> |
||||||
|
#include <stdlib.h> |
||||||
|
#include <stdio.h> |
||||||
|
#include <limits.h> |
||||||
|
#include <ctype.h> |
||||||
|
#include <arpa/inet.h> |
||||||
|
|
||||||
|
#define INT_CONF ntohl(0x434f4e46) |
||||||
|
#define INT_ONFI ntohl(0x4f4e4649) |
||||||
|
#define INT_NFIG ntohl(0x4e464947) |
||||||
|
#define INT_FIG_ ntohl(0x4649475f) |
||||||
|
|
||||||
|
char *target; |
||||||
|
char *depfile; |
||||||
|
char *cmdline; |
||||||
|
|
||||||
|
static void usage(void) |
||||||
|
{ |
||||||
|
fprintf(stderr, "Usage: fixdep <depfile> <target> <cmdline>\n"); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Print out the commandline prefixed with cmd_<target filename> := |
||||||
|
*/ |
||||||
|
static void print_cmdline(void) |
||||||
|
{ |
||||||
|
printf("cmd_%s := %s\n\n", target, cmdline); |
||||||
|
} |
||||||
|
|
||||||
|
struct item { |
||||||
|
struct item *next; |
||||||
|
unsigned int len; |
||||||
|
unsigned int hash; |
||||||
|
char name[0]; |
||||||
|
}; |
||||||
|
|
||||||
|
#define HASHSZ 256 |
||||||
|
static struct item *hashtab[HASHSZ]; |
||||||
|
|
||||||
|
static unsigned int strhash(const char *str, unsigned int sz) |
||||||
|
{ |
||||||
|
/* fnv32 hash */ |
||||||
|
unsigned int i, hash = 2166136261U; |
||||||
|
|
||||||
|
for (i = 0; i < sz; i++) |
||||||
|
hash = (hash ^ str[i]) * 0x01000193; |
||||||
|
return hash; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Lookup a value in the configuration string. |
||||||
|
*/ |
||||||
|
static int is_defined_config(const char *name, int len, unsigned int hash) |
||||||
|
{ |
||||||
|
struct item *aux; |
||||||
|
|
||||||
|
for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { |
||||||
|
if (aux->hash == hash && aux->len == len && |
||||||
|
memcmp(aux->name, name, len) == 0) |
||||||
|
return 1; |
||||||
|
} |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Add a new value to the configuration string. |
||||||
|
*/ |
||||||
|
static void define_config(const char *name, int len, unsigned int hash) |
||||||
|
{ |
||||||
|
struct item *aux = malloc(sizeof(*aux) + len); |
||||||
|
|
||||||
|
if (!aux) { |
||||||
|
perror("fixdep:malloc"); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
memcpy(aux->name, name, len); |
||||||
|
aux->len = len; |
||||||
|
aux->hash = hash; |
||||||
|
aux->next = hashtab[hash % HASHSZ]; |
||||||
|
hashtab[hash % HASHSZ] = aux; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear the set of configuration strings. |
||||||
|
*/ |
||||||
|
static void clear_config(void) |
||||||
|
{ |
||||||
|
struct item *aux, *next; |
||||||
|
unsigned int i; |
||||||
|
|
||||||
|
for (i = 0; i < HASHSZ; i++) { |
||||||
|
for (aux = hashtab[i]; aux; aux = next) { |
||||||
|
next = aux->next; |
||||||
|
free(aux); |
||||||
|
} |
||||||
|
hashtab[i] = NULL; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Record the use of a CONFIG_* word. |
||||||
|
*/ |
||||||
|
static void use_config(const char *m, int slen) |
||||||
|
{ |
||||||
|
unsigned int hash = strhash(m, slen); |
||||||
|
int c, i; |
||||||
|
|
||||||
|
if (is_defined_config(m, slen, hash)) |
||||||
|
return; |
||||||
|
|
||||||
|
define_config(m, slen, hash); |
||||||
|
|
||||||
|
printf(" $(wildcard include/config/"); |
||||||
|
for (i = 0; i < slen; i++) { |
||||||
|
c = m[i]; |
||||||
|
if (c == '_') |
||||||
|
c = '/'; |
||||||
|
else |
||||||
|
c = tolower(c); |
||||||
|
putchar(c); |
||||||
|
} |
||||||
|
printf(".h) \\\n"); |
||||||
|
} |
||||||
|
|
||||||
|
static void parse_config_file(const char *map, size_t len) |
||||||
|
{ |
||||||
|
const int *end = (const int *) (map + len); |
||||||
|
/* start at +1, so that p can never be < map */ |
||||||
|
const int *m = (const int *) map + 1; |
||||||
|
const char *p, *q; |
||||||
|
|
||||||
|
for (; m < end; m++) { |
||||||
|
if (*m == INT_CONF) { p = (char *) m ; goto conf; } |
||||||
|
if (*m == INT_ONFI) { p = (char *) m-1; goto conf; } |
||||||
|
if (*m == INT_NFIG) { p = (char *) m-2; goto conf; } |
||||||
|
if (*m == INT_FIG_) { p = (char *) m-3; goto conf; } |
||||||
|
continue; |
||||||
|
conf: |
||||||
|
if (p > map + len - 7) |
||||||
|
continue; |
||||||
|
if (memcmp(p, "CONFIG_", 7)) |
||||||
|
continue; |
||||||
|
for (q = p + 7; q < map + len; q++) { |
||||||
|
if (!(isalnum(*q) || *q == '_')) |
||||||
|
goto found; |
||||||
|
} |
||||||
|
continue; |
||||||
|
|
||||||
|
found: |
||||||
|
if (!memcmp(q - 7, "_MODULE", 7)) |
||||||
|
q -= 7; |
||||||
|
if( (q-p-7) < 0 ) |
||||||
|
continue; |
||||||
|
use_config(p+7, q-p-7); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* test is s ends in sub */ |
||||||
|
static int strrcmp(char *s, char *sub) |
||||||
|
{ |
||||||
|
int slen = strlen(s); |
||||||
|
int sublen = strlen(sub); |
||||||
|
|
||||||
|
if (sublen > slen) |
||||||
|
return 1; |
||||||
|
|
||||||
|
return memcmp(s + slen - sublen, sub, sublen); |
||||||
|
} |
||||||
|
|
||||||
|
static void do_config_file(const char *filename) |
||||||
|
{ |
||||||
|
struct stat st; |
||||||
|
int fd; |
||||||
|
void *map; |
||||||
|
|
||||||
|
fd = open(filename, O_RDONLY); |
||||||
|
if (fd < 0) { |
||||||
|
fprintf(stderr, "fixdep: error opening config file: "); |
||||||
|
perror(filename); |
||||||
|
exit(2); |
||||||
|
} |
||||||
|
fstat(fd, &st); |
||||||
|
if (st.st_size == 0) { |
||||||
|
close(fd); |
||||||
|
return; |
||||||
|
} |
||||||
|
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
||||||
|
if ((long) map == -1) { |
||||||
|
perror("fixdep: mmap"); |
||||||
|
close(fd); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
parse_config_file(map, st.st_size); |
||||||
|
|
||||||
|
munmap(map, st.st_size); |
||||||
|
|
||||||
|
close(fd); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Important: The below generated source_foo.o and deps_foo.o variable |
||||||
|
* assignments are parsed not only by make, but also by the rather simple |
||||||
|
* parser in scripts/mod/sumversion.c. |
||||||
|
*/ |
||||||
|
static void parse_dep_file(void *map, size_t len) |
||||||
|
{ |
||||||
|
char *m = map; |
||||||
|
char *end = m + len; |
||||||
|
char *p; |
||||||
|
char s[PATH_MAX]; |
||||||
|
int is_target; |
||||||
|
int saw_any_target = 0; |
||||||
|
int is_first_dep = 0; |
||||||
|
|
||||||
|
clear_config(); |
||||||
|
|
||||||
|
while (m < end) { |
||||||
|
/* Skip any "white space" */ |
||||||
|
while (m < end && (*m == ' ' || *m == '\\' || *m == '\n')) |
||||||
|
m++; |
||||||
|
/* Find next "white space" */ |
||||||
|
p = m; |
||||||
|
while (p < end && *p != ' ' && *p != '\\' && *p != '\n') |
||||||
|
p++; |
||||||
|
/* Is the token we found a target name? */ |
||||||
|
is_target = (*(p-1) == ':'); |
||||||
|
/* Don't write any target names into the dependency file */ |
||||||
|
if (is_target) { |
||||||
|
/* The /next/ file is the first dependency */ |
||||||
|
is_first_dep = 1; |
||||||
|
} else { |
||||||
|
/* Save this token/filename */ |
||||||
|
memcpy(s, m, p-m); |
||||||
|
s[p - m] = 0; |
||||||
|
|
||||||
|
/* Ignore certain dependencies */ |
||||||
|
if (strrcmp(s, "include/generated/autoconf.h") && |
||||||
|
strrcmp(s, "arch/um/include/uml-config.h") && |
||||||
|
strrcmp(s, "include/linux/kconfig.h") && |
||||||
|
strrcmp(s, ".ver")) { |
||||||
|
/*
|
||||||
|
* Do not list the source file as dependency, |
||||||
|
* so that kbuild is not confused if a .c file |
||||||
|
* is rewritten into .S or vice versa. Storing |
||||||
|
* it in source_* is needed for modpost to |
||||||
|
* compute srcversions. |
||||||
|
*/ |
||||||
|
if (is_first_dep) { |
||||||
|
/*
|
||||||
|
* If processing the concatenation of |
||||||
|
* multiple dependency files, only |
||||||
|
* process the first target name, which |
||||||
|
* will be the original source name, |
||||||
|
* and ignore any other target names, |
||||||
|
* which will be intermediate temporary |
||||||
|
* files. |
||||||
|
*/ |
||||||
|
if (!saw_any_target) { |
||||||
|
saw_any_target = 1; |
||||||
|
printf("source_%s := %s\n\n", |
||||||
|
target, s); |
||||||
|
printf("deps_%s := \\\n", |
||||||
|
target); |
||||||
|
} |
||||||
|
is_first_dep = 0; |
||||||
|
} else |
||||||
|
printf(" %s \\\n", s); |
||||||
|
do_config_file(s); |
||||||
|
} |
||||||
|
} |
||||||
|
/*
|
||||||
|
* Start searching for next token immediately after the first |
||||||
|
* "whitespace" character that follows this token. |
||||||
|
*/ |
||||||
|
m = p + 1; |
||||||
|
} |
||||||
|
|
||||||
|
if (!saw_any_target) { |
||||||
|
fprintf(stderr, "fixdep: parse error; no targets found\n"); |
||||||
|
exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
printf("\n%s: $(deps_%s)\n\n", target, target); |
||||||
|
printf("$(deps_%s):\n", target); |
||||||
|
} |
||||||
|
|
||||||
|
static void print_deps(void) |
||||||
|
{ |
||||||
|
struct stat st; |
||||||
|
int fd; |
||||||
|
void *map; |
||||||
|
|
||||||
|
fd = open(depfile, O_RDONLY); |
||||||
|
if (fd < 0) { |
||||||
|
fprintf(stderr, "fixdep: error opening depfile: "); |
||||||
|
perror(depfile); |
||||||
|
exit(2); |
||||||
|
} |
||||||
|
if (fstat(fd, &st) < 0) { |
||||||
|
fprintf(stderr, "fixdep: error fstat'ing depfile: "); |
||||||
|
perror(depfile); |
||||||
|
exit(2); |
||||||
|
} |
||||||
|
if (st.st_size == 0) { |
||||||
|
fprintf(stderr,"fixdep: %s is empty\n",depfile); |
||||||
|
close(fd); |
||||||
|
return; |
||||||
|
} |
||||||
|
map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); |
||||||
|
if ((long) map == -1) { |
||||||
|
perror("fixdep: mmap"); |
||||||
|
close(fd); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
parse_dep_file(map, st.st_size); |
||||||
|
|
||||||
|
munmap(map, st.st_size); |
||||||
|
|
||||||
|
close(fd); |
||||||
|
} |
||||||
|
|
||||||
|
static void traps(void) |
||||||
|
{ |
||||||
|
static char test[] __attribute__((aligned(sizeof(int)))) = "CONF"; |
||||||
|
int *p = (int *)test; |
||||||
|
|
||||||
|
if (*p != INT_CONF) { |
||||||
|
fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianness? %#x\n", |
||||||
|
*p); |
||||||
|
exit(2); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
int main(int argc, char *argv[]) |
||||||
|
{ |
||||||
|
traps(); |
||||||
|
|
||||||
|
if (argc != 4) |
||||||
|
usage(); |
||||||
|
|
||||||
|
depfile = argv[1]; |
||||||
|
target = argv[2]; |
||||||
|
cmdline = argv[3]; |
||||||
|
|
||||||
|
print_cmdline(); |
||||||
|
print_deps(); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
#!/bin/sh |
||||||
|
# Generates a small Makefile used in the root of the output |
||||||
|
# directory, to allow make to be started from there. |
||||||
|
# The Makefile also allow for more convinient build of external modules |
||||||
|
|
||||||
|
# Usage |
||||||
|
# $1 - Kernel src directory |
||||||
|
# $2 - Output directory |
||||||
|
# $3 - version |
||||||
|
# $4 - patchlevel |
||||||
|
|
||||||
|
|
||||||
|
test ! -r $2/Makefile -o -O $2/Makefile || exit 0 |
||||||
|
# Only overwrite automatically generated Makefiles |
||||||
|
# (so we do not overwrite kernel Makefile) |
||||||
|
if test -e $2/Makefile && ! grep -q Automatically $2/Makefile |
||||||
|
then |
||||||
|
exit 0 |
||||||
|
fi |
||||||
|
if [ "${quiet}" != "silent_" ]; then |
||||||
|
echo " GEN $2/Makefile" |
||||||
|
fi |
||||||
|
|
||||||
|
cat << EOF > $2/Makefile |
||||||
|
# Automatically generated by $0: don't edit |
||||||
|
|
||||||
|
VERSION = $3 |
||||||
|
PATCHLEVEL = $4 |
||||||
|
|
||||||
|
lastword = \$(word \$(words \$(1)),\$(1)) |
||||||
|
makedir := \$(dir \$(call lastword,\$(MAKEFILE_LIST))) |
||||||
|
|
||||||
|
ifeq ("\$(origin V)", "command line") |
||||||
|
VERBOSE := \$(V) |
||||||
|
endif |
||||||
|
ifneq (\$(VERBOSE),1) |
||||||
|
Q := @ |
||||||
|
endif |
||||||
|
|
||||||
|
MAKEARGS := -C $1 |
||||||
|
MAKEARGS += O=\$(if \$(patsubst /%,,\$(makedir)),\$(CURDIR)/)\$(patsubst %/,%,\$(makedir)) |
||||||
|
|
||||||
|
MAKEFLAGS += --no-print-directory |
||||||
|
|
||||||
|
.PHONY: all \$(MAKECMDGOALS) |
||||||
|
|
||||||
|
all := \$(filter-out all Makefile,\$(MAKECMDGOALS)) |
||||||
|
|
||||||
|
all: |
||||||
|
\$(Q)\$(MAKE) \$(MAKEARGS) \$(all) |
||||||
|
|
||||||
|
Makefile:; |
||||||
|
|
||||||
|
\$(all): all |
||||||
|
@: |
||||||
|
|
||||||
|
%/: all |
||||||
|
@: |
||||||
|
EOF |
Loading…
Reference in new issue