diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/Makefile.build | 479 | ||||
| -rw-r--r-- | scripts/Makefile.clean | 104 | ||||
| -rw-r--r-- | scripts/Makefile.host | 170 | ||||
| -rw-r--r-- | scripts/Makefile.lib | 373 | ||||
| -rw-r--r-- | scripts/basic/.gitignore | 1 | ||||
| -rw-r--r-- | scripts/basic/Makefile | 15 | ||||
| -rw-r--r-- | scripts/basic/fixdep.c | 462 | ||||
| -rw-r--r-- | scripts/mkmakefile | 59 | 
8 files changed, 1663 insertions, 0 deletions
| diff --git a/scripts/Makefile.build b/scripts/Makefile.build new file mode 100644 index 000000000..d5d859c80 --- /dev/null +++ b/scripts/Makefile.build @@ -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) diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean new file mode 100644 index 000000000..686cb0d31 --- /dev/null +++ b/scripts/Makefile.clean @@ -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) diff --git a/scripts/Makefile.host b/scripts/Makefile.host new file mode 100644 index 000000000..1ac414fd5 --- /dev/null +++ b/scripts/Makefile.host @@ -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)  + diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib new file mode 100644 index 000000000..49392ecbe --- /dev/null +++ b/scripts/Makefile.lib @@ -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:=" diff --git a/scripts/basic/.gitignore b/scripts/basic/.gitignore new file mode 100644 index 000000000..a776371a3 --- /dev/null +++ b/scripts/basic/.gitignore @@ -0,0 +1 @@ +fixdep diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile new file mode 100644 index 000000000..4fcef87bb --- /dev/null +++ b/scripts/basic/Makefile @@ -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 diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c new file mode 100644 index 000000000..078fe1d64 --- /dev/null +++ b/scripts/basic/fixdep.c @@ -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; +} diff --git a/scripts/mkmakefile b/scripts/mkmakefile new file mode 100644 index 000000000..0cc044260 --- /dev/null +++ b/scripts/mkmakefile @@ -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 |