From 51148790f26e42ef1fd4a1a8d056bf0252539525 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Wed, 30 Jul 2014 14:08:17 +0900 Subject: [PATCH] kconfig: switch to Kconfig This commit enables Kconfig. Going forward, we use Kconfig for the board configuration. mkconfig will never be used. Nor will include/config.mk be generated. Kconfig must be adjusted for U-Boot because our situation is a little more complicated than Linux Kernel. We have to generate multiple boot images (Normal, SPL, TPL) from one source tree. Each image needs its own configuration input. Usage: Run "make _defconfig" to do the board configuration. It will create the .config file and additionally spl/.config, tpl/.config if SPL, TPL is enabled, respectively. You can use "make config", "make menuconfig" etc. to create a new .config or modify the existing one. Use "make spl/config", "make spl/menuconfig" etc. for spl/.config and do likewise for tpl/.config file. The generic syntax of configuration targets for SPL, TPL is: / Here, is either 'spl' or 'tpl' is 'config', 'menuconfig', 'xconfig', etc. When the configuration is done, run "make". (Or "make _defconfig all" will do the configuration and build in one time.) For futher information of how Kconfig works in U-Boot, please read the comment block of scripts/multiconfig.py. By the way, there is another item worth remarking here: coexistence of Kconfig and board herder files. Prior to Kconfig, we used C headers to define a set of configs. We expect a very long term to migrate from C headers to Kconfig. Two different infractructure must coexist in the interim. In our former configuration scheme, include/autoconf.mk was generated for use in makefiles. It is still generated under include/, spl/include/, tpl/include/ directory for the Normal, SPL, TPL image, respectively. Signed-off-by: Masahiro Yamada Acked-by: Simon Glass --- .gitignore | 2 - Makefile | 116 ++++----- arch/m68k/cpu/mcf52x2/config.mk | 16 +- arch/m68k/cpu/mcf532x/config.mk | 6 +- arch/m68k/cpu/mcf5445x/config.mk | 4 +- arch/powerpc/cpu/ppc4xx/config.mk | 4 +- config.mk | 10 + include/.gitignore | 1 - scripts/Makefile | 2 +- scripts/Makefile.autoconf | 100 ++++++++ scripts/Makefile.build | 31 +-- scripts/Makefile.spl | 31 +-- scripts/basic/fixdep.c | 6 +- scripts/kconfig/confdata.c | 8 + scripts/multiconfig.py | 410 ++++++++++++++++++++++++++++++ tools/Makefile | 2 +- tools/env/Makefile | 2 +- 17 files changed, 619 insertions(+), 132 deletions(-) create mode 100644 scripts/Makefile.autoconf create mode 100755 scripts/multiconfig.py diff --git a/.gitignore b/.gitignore index 0ace33bd61..5ac2e60d2b 100644 --- a/.gitignore +++ b/.gitignore @@ -53,8 +53,6 @@ # /include/config/ /include/generated/ -/include/spl-autoconf.mk -/include/tpl-autoconf.mk # stgit generated dirs patches-* diff --git a/Makefile b/Makefile index 80eb239d93..5e495451d8 100644 --- a/Makefile +++ b/Makefile @@ -166,9 +166,6 @@ VPATH := $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD)) export srctree objtree VPATH -MKCONFIG := $(srctree)/mkconfig -export MKCONFIG - # Make sure CDPATH settings don't interfere unexport CDPATH @@ -189,9 +186,6 @@ HOSTOS := $(shell uname -s | tr '[:upper:]' '[:lower:]' | \ export HOSTARCH HOSTOS -# Deal with colliding definitions from tcsh etc. -VENDOR= - ######################################################################### # set default to nothing for native builds @@ -199,6 +193,9 @@ ifeq ($(HOSTARCH),$(ARCH)) CROSS_COMPILE ?= endif +KCONFIG_CONFIG ?= .config +export KCONFIG_CONFIG + # SHELL used by kbuild CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ else if [ -x /bin/bash ]; then echo /bin/bash; \ @@ -341,6 +338,7 @@ OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump AWK = awk PERL = perl +PYTHON = python DTC = dtc CHECK = sparse @@ -362,7 +360,7 @@ export VERSION PATCHLEVEL SUBLEVEL UBOOTRELEASE UBOOTVERSION export ARCH CPU BOARD VENDOR SOC CPUDIR BOARDDIR export CONFIG_SHELL HOSTCC HOSTCFLAGS HOSTLDFLAGS CROSS_COMPILE AS LD CC export CPP AR NM LDR STRIP OBJCOPY OBJDUMP -export MAKE AWK PERL +export MAKE AWK PERL PYTHON export HOSTCXX HOSTCXXFLAGS DTC CHECK CHECKFLAGS export KBUILD_CPPFLAGS NOSTDINC_FLAGS UBOOTINCLUDE OBJCOPYFLAGS LDFLAGS @@ -460,31 +458,49 @@ ifeq ($(config-targets),1) # *config targets only - make sure prerequisites are updated, and descend # in scripts/kconfig to make the *config target -# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed. -# KBUILD_DEFCONFIG may point out an alternative default configuration -# used for 'make defconfig' +KBUILD_DEFCONFIG := sandbox_defconfig +export KBUILD_DEFCONFIG KBUILD_KCONFIG -%_config:: outputmakefile - @$(MKCONFIG) -A $(@:_config=) +config: scripts_basic outputmakefile FORCE + +$(Q)$(PYTHON) $(srctree)/scripts/multiconfig.py $@ + +%config: scripts_basic outputmakefile FORCE + +$(Q)$(PYTHON) $(srctree)/scripts/multiconfig.py $@ else # =========================================================================== # Build targets only - this includes vmlinux, arch specific targets, clean # targets and others. In general all targets except *config targets. -# load ARCH, BOARD, and CPU configuration --include include/config.mk - ifeq ($(dot-config),1) # Read in config +-include include/config/auto.conf + +# Read in dependencies to all Kconfig* files, make sure to run +# oldconfig if changes are detected. +-include include/config/auto.conf.cmd + +# To avoid any implicit rule to kick in, define an empty command +$(KCONFIG_CONFIG) include/config/auto.conf.cmd: ; + +# If .config is newer than include/config/auto.conf, someone tinkered +# with it and forgot to run make oldconfig. +# if auto.conf.cmd is missing then we are probably in a cleaned tree so +# we execute the config step to be sure to catch updated Kconfig files +include/config/%.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd + $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig + -include include/autoconf.mk -include include/autoconf.mk.dep -# load other configuration +# We want to include arch/$(ARCH)/config.mk only when include/config/auto.conf +# is up-to-date. When we switch to a different board configuration, old CONFIG +# macros are still remaining in include/config/auto.conf. Without the following +# gimmick, wrong config.mk would be included leading nasty warnings/errors. +autoconf_is_current := $(if $(wildcard $(KCONFIG_CONFIG)),$(shell find . \ + -path ./include/config/auto.conf -newer $(KCONFIG_CONFIG))) +ifneq ($(autoconf_is_current),) include $(srctree)/config.mk - -ifeq ($(wildcard include/config.mk),) -$(error "System not configured - see README") endif # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use @@ -513,8 +529,8 @@ ifndef LDSCRIPT endif else - - +# Dummy target needed, because used as prerequisite +include/config/auto.conf: ; endif # $(dot-config) KBUILD_CFLAGS += -Os #-fomit-frame-pointer @@ -563,7 +579,8 @@ KBUILD_CFLAGS += $(KCFLAGS) UBOOTINCLUDE := \ -Iinclude \ $(if $(KBUILD_SRC), -I$(srctree)/include) \ - -I$(srctree)/arch/$(ARCH)/include + -I$(srctree)/arch/$(ARCH)/include \ + -include $(srctree)/include/linux/kconfig.h NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) CHECKFLAGS += $(NOSTDINC_FLAGS) @@ -1024,7 +1041,7 @@ define filechk_uboot.release endef # Store (new) UBOOTRELEASE string in include/config/uboot.release -include/config/uboot.release: Makefile FORCE +include/config/uboot.release: include/config/auto.conf FORCE $(call filechk,uboot.release) @@ -1042,8 +1059,8 @@ PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3 # 1) Check that make has not been executed in the kernel src $(srctree) prepare3: include/config/uboot.release ifneq ($(KBUILD_SRC),) - @$(kecho) ' Using $(srctree) as source for u-boot' - $(Q)if [ -f $(srctree)/include/config.mk ]; then \ + @$(kecho) ' Using $(srctree) as source for U-Boot' + $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \ echo >&2 " $(srctree) is not clean, please run 'make mrproper'"; \ echo >&2 " in the '$(srctree)' directory.";\ /bin/false; \ @@ -1053,7 +1070,8 @@ endif # prepare2 creates a makefile if using a separate output directory prepare2: prepare3 outputmakefile -prepare1: prepare2 $(version_h) $(timestamp_h) +prepare1: prepare2 $(version_h) $(timestamp_h) \ + include/config/auto.conf ifeq ($(__HAVE_ARCH_GENERIC_BOARD),) ifeq ($(CONFIG_SYS_GENERIC_BOARD),y) @echo >&2 " Your architecture does not support generic board." @@ -1095,29 +1113,6 @@ $(version_h): include/config/uboot.release FORCE $(timestamp_h): $(srctree)/Makefile FORCE $(call filechk,timestamp.h) -# -# Auto-generate the autoconf.mk file (which is included by all makefiles) -# -# This target actually generates 2 files; autoconf.mk and autoconf.mk.dep. -# the dep file is only include in this top level makefile to determine when -# to regenerate the autoconf.mk file. - -quiet_cmd_autoconf_dep = GEN $@ - cmd_autoconf_dep = $(CC) -x c -DDO_DEPS_ONLY -M $(c_flags) \ - -MQ include/autoconf.mk $(srctree)/include/common.h > $@ || rm $@ - -include/autoconf.mk.dep: include/config.h include/common.h - $(call cmd,autoconf_dep) - -quiet_cmd_autoconf = GEN $@ - cmd_autoconf = \ - $(CPP) $(c_flags) -DDO_DEPS_ONLY -dM $(srctree)/include/common.h > $@.tmp && \ - sed -n -f $(srctree)/tools/scripts/define2mk.sed $@.tmp > $@; \ - rm $@.tmp - -include/autoconf.mk: include/config.h - $(call cmd,autoconf) - # --------------------------------------------------------------------------- PHONY += depend dep @@ -1141,7 +1136,7 @@ spl/sunxi-spl.bin: spl/u-boot-spl @: tpl/u-boot-tpl.bin: tools prepare - $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all CONFIG_TPL_BUILD=y + $(Q)$(MAKE) obj=tpl -f $(srctree)/scripts/Makefile.spl all TAG_SUBDIRS := $(patsubst %,$(srctree)/%,$(u-boot-dirs) include) @@ -1216,20 +1211,18 @@ include/license.h: tools/bin2header COPYING # Directories & files removed with 'make clean' CLEAN_DIRS += $(MODVERDIR) -CLEAN_FILES += u-boot.lds include/bmp_logo.h include/bmp_logo_data.h \ - include/autoconf.mk* include/spl-autoconf.mk \ - include/tpl-autoconf.mk +CLEAN_FILES += u-boot.lds include/bmp_logo.h include/bmp_logo_data.h # Directories & files removed with 'make clobber' -CLOBBER_DIRS += spl tpl +CLOBBER_DIRS += $(foreach d, spl tpl, $(patsubst %,$d/%, \ + $(filter-out include, $(shell ls -1 $d 2>/dev/null)))) CLOBBER_FILES += u-boot* MLO* SPL System.map # Directories & files removed with 'make mrproper' -MRPROPER_DIRS += include/config include/generated \ +MRPROPER_DIRS += include/config include/generated spl tpl \ .tmp_objdiff -MRPROPER_FILES += .config .config.old \ - ctags etags cscope* GPATH GTAGS GRTAGS GSYMS \ - include/config.h include/config.mk +MRPROPER_FILES += .config .config.old include/autoconf.mk* include/config.h \ + ctags etags TAGS cscope* GPATH GTAGS GRTAGS GSYMS # clean - Delete most, but leave enough to build external modules # @@ -1306,10 +1299,9 @@ help: @echo ' mrproper - Remove all generated files + config + various backup files' @echo ' distclean - mrproper + remove editor backup and patch files' @echo '' -# uncomment after adding Kconfig feature -# @echo 'Configuration targets:' -# @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help -# @echo '' + @echo 'Configuration targets:' + @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help + @echo '' @echo 'Other generic targets:' @echo ' all - Build all necessary images depending on configuration' @echo ' u-boot - Build the bare u-boot' diff --git a/arch/m68k/cpu/mcf52x2/config.mk b/arch/m68k/cpu/mcf52x2/config.mk index 34ad99e92c..f66000b331 100644 --- a/arch/m68k/cpu/mcf52x2/config.mk +++ b/arch/m68k/cpu/mcf52x2/config.mk @@ -7,14 +7,14 @@ # SPDX-License-Identifier: GPL-2.0+ # -cfg=$(shell grep configs $(objtree)/include/config.h | sed 's/.*<\(configs.*\)>/\1/') -is5208:=$(shell grep CONFIG_M5208 $(srctree)/include/$(cfg)) -is5249:=$(shell grep CONFIG_M5249 $(srctree)/include/$(cfg)) -is5253:=$(shell grep CONFIG_M5253 $(srctree)/include/$(cfg)) -is5271:=$(shell grep CONFIG_M5271 $(srctree)/include/$(cfg)) -is5272:=$(shell grep CONFIG_M5272 $(srctree)/include/$(cfg)) -is5275:=$(shell grep CONFIG_M5275 $(srctree)/include/$(cfg)) -is5282:=$(shell grep CONFIG_M5282 $(srctree)/include/$(cfg)) +cfg=$(srctree)/include/configs/$(CONFIG_SYS_CONFIG_NAME:"%"=%).h +is5208:=$(shell grep CONFIG_M5208 $(cfg)) +is5249:=$(shell grep CONFIG_M5249 $(cfg)) +is5253:=$(shell grep CONFIG_M5253 $(cfg)) +is5271:=$(shell grep CONFIG_M5271 $(cfg)) +is5272:=$(shell grep CONFIG_M5272 $(cfg)) +is5275:=$(shell grep CONFIG_M5275 $(cfg)) +is5282:=$(shell grep CONFIG_M5282 $(cfg)) ifneq (,$(findstring CONFIG_M5208,$(is5208))) PLATFORM_CPPFLAGS += -mcpu=5208 diff --git a/arch/m68k/cpu/mcf532x/config.mk b/arch/m68k/cpu/mcf532x/config.mk index af943543a2..2efb60f04a 100644 --- a/arch/m68k/cpu/mcf532x/config.mk +++ b/arch/m68k/cpu/mcf532x/config.mk @@ -7,9 +7,9 @@ # SPDX-License-Identifier: GPL-2.0+ # -cfg=$(shell grep configs $(objtree)/include/config.h | sed 's/.*<\(configs.*\)>/\1/') -is5301x:=$(shell grep CONFIG_MCF5301x $(srctree)/include/$(cfg)) -is532x:=$(shell grep CONFIG_MCF532x $(srctree)/include/$(cfg)) +cfg=$(srctree)/include/configs/$(CONFIG_SYS_CONFIG_NAME:"%"=%).h +is5301x:=$(shell grep CONFIG_MCF5301x $(cfg)) +is532x:=$(shell grep CONFIG_MCF532x $(cfg)) ifneq (,$(findstring CONFIG_MCF5301x,$(is5301x))) PLATFORM_CPPFLAGS += -mcpu=53015 -fPIC diff --git a/arch/m68k/cpu/mcf5445x/config.mk b/arch/m68k/cpu/mcf5445x/config.mk index 5fd0d4d0e2..13f8a9f57b 100644 --- a/arch/m68k/cpu/mcf5445x/config.mk +++ b/arch/m68k/cpu/mcf5445x/config.mk @@ -9,8 +9,8 @@ # SPDX-License-Identifier: GPL-2.0+ # -cfg=$(shell grep configs $(objtree)/include/config.h | sed 's/.*<\(configs.*\)>/\1/') -is5441x:=$(shell grep CONFIG_MCF5441x $(srctree)/include/$(cfg)) +cfg=$(srctree)/include/configs/$(CONFIG_SYS_CONFIG_NAME:"%"=%).h +is5441x:=$(shell grep CONFIG_MCF5441x $(cfg)) ifneq (,$(findstring CONFIG_MCF5441x,$(is5441x))) PLATFORM_CPPFLAGS += -mcpu=54418 -fPIC diff --git a/arch/powerpc/cpu/ppc4xx/config.mk b/arch/powerpc/cpu/ppc4xx/config.mk index 102f069f9e..a7253b2bb4 100644 --- a/arch/powerpc/cpu/ppc4xx/config.mk +++ b/arch/powerpc/cpu/ppc4xx/config.mk @@ -7,8 +7,8 @@ PLATFORM_CPPFLAGS += -DCONFIG_4xx -mstring -msoft-float -cfg=$(shell grep configs $(objtree)/include/config.h | sed 's/.*<\(configs.*\)>/\1/') -is440:=$(shell grep CONFIG_440 $(srctree)/include/$(cfg)) +cfg=$(srctree)/include/configs/$(CONFIG_SYS_CONFIG_NAME:"%"=%).h +is440:=$(shell grep CONFIG_440 $(cfg)) ifneq (,$(findstring CONFIG_440,$(is440))) PLATFORM_CPPFLAGS += -Wa,-m440 -mcpu=440 diff --git a/config.mk b/config.mk index bd74732d48..b4bf6f95d3 100644 --- a/config.mk +++ b/config.mk @@ -20,6 +20,16 @@ LDFLAGS_FINAL := OBJCOPYFLAGS := ######################################################################### +ARCH := $(CONFIG_SYS_ARCH:"%"=%) +CPU := $(CONFIG_SYS_CPU:"%"=%) +BOARD := $(CONFIG_SYS_BOARD:"%"=%) +ifneq ($(CONFIG_SYS_VENDOR),) +VENDOR := $(CONFIG_SYS_VENDOR:"%"=%) +endif +ifneq ($(CONFIG_SYS_SOC),) +SOC := $(CONFIG_SYS_SOC:"%"=%) +endif + # Some architecture config.mk files need to know what CPUDIR is set to, # so calculate CPUDIR before including ARCH/SOC/CPU config.mk files. # Check if arch/$ARCH/cpu/$CPU exists, otherwise assume arch/$ARCH/cpu contains diff --git a/include/.gitignore b/include/.gitignore index bf142fc2f9..8e41a9511d 100644 --- a/include/.gitignore +++ b/include/.gitignore @@ -2,4 +2,3 @@ /bmp_logo.h /bmp_logo_data.h /config.h -/config.mk diff --git a/scripts/Makefile b/scripts/Makefile index 68c998e588..efe25bfc6e 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -13,4 +13,4 @@ build_docproc: $(obj)/docproc @: # Let clean descend into subdirs -subdir- += basic +subdir- += basic kconfig diff --git a/scripts/Makefile.autoconf b/scripts/Makefile.autoconf new file mode 100644 index 0000000000..44c39970f3 --- /dev/null +++ b/scripts/Makefile.autoconf @@ -0,0 +1,100 @@ +# This helper makefile is used for creating +# - symbolic links (arch/$ARCH/include/asm/arch +# - include/autoconf.mk, {spl,tpl}/include/autoconf.mk +# - include/config.h +# +# When our migration to Kconfig is done +# (= When we move all CONFIGs from header files to Kconfig) +# this makefile can be deleted. + +# obj is "include" or "spl/include" or "tpl/include" +# for non-SPL, SPL, TPL, respectively +include $(obj)/config/auto.conf + +include scripts/Kbuild.include + +# Need to define CC and CPP again here in case the top Makefile did not +# include config.mk. Some architectures expect CROSS_COMPILE to be defined +# in arch/$(ARCH)/config.mk +CC = $(CROSS_COMPILE)gcc +CPP = $(CC) -E + +include config.mk + +UBOOTINCLUDE := \ + -I$(obj) \ + -Iinclude \ + $(if $(KBUILD_SRC), -I$(srctree)/include) \ + -I$(srctree)/arch/$(ARCH)/include \ + -include $(srctree)/include/linux/kconfig.h + +c_flags := $(KBUILD_CFLAGS) $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) \ + $(UBOOTINCLUDE) $(NOSTDINC_FLAGS) + +quiet_cmd_autoconf_dep = GEN $@ + cmd_autoconf_dep = $(CC) -x c -DDO_DEPS_ONLY -M -MP $(c_flags) \ + -MQ include/config/auto.conf $(srctree)/include/common.h > $@ || { \ + rm $@; false; \ + } +include/autoconf.mk.dep: FORCE + $(call cmd,autoconf_dep) + +# We are migrating from board headers to Kconfig little by little. +# In the interim, we use both of +# - include/config/auto.conf (generated by Kconfig) +# - include/autoconf.mk (used in the U-Boot conventional configuration) +# The following rule creates autoconf.mk +# include/config/auto.conf is grepped in order to avoid duplication of the +# same CONFIG macros +quiet_cmd_autoconf = GEN $@ + cmd_autoconf = \ + $(CPP) $(c_flags) -DDO_DEPS_ONLY -dM $(srctree)/include/common.h > $@.tmp && { \ + sed -n -f $(srctree)/tools/scripts/define2mk.sed $@.tmp | \ + while read line; do \ + if ! grep -q "$${line%=*}=" $(obj)/config/auto.conf; then \ + echo "$$line"; \ + fi \ + done > $@; \ + rm $@.tmp; \ + } || { \ + rm $@.tmp; false; \ + } + +$(obj)/autoconf.mk: FORCE + $(call cmd,autoconf) + +include/autoconf.mk include/autoconf.mk.dep: include/config.h + +# include/config.h +# Prior to Kconfig, it was generated by mkconfig. Now it is created here. +define filechk_config_h + (echo "/* Automatically generated - do not edit */"; \ + for i in $$(echo $(CONFIG_SYS_EXTRA_OPTIONS) | sed 's/,/ /g'); do \ + echo \#define CONFIG_$$i \ + | sed '/=/ {s/=/ /;q; } ; { s/$$/ 1/; }'; \ + done; \ + echo \#define CONFIG_BOARDDIR board/$(if $(VENDOR),$(VENDOR)/)$(BOARD);\ + echo \#include \; \ + echo \#include \; \ + echo \#include \; \ + echo \#include \; \ + echo \#include \; \ + echo \#include \; ) +endef + +include/config.h: scripts/Makefile.autoconf create_symlink FORCE + $(call filechk,config_h) + +# symbolic links +PHONY += create_symlink +create_symlink: +ifneq ($(KBUILD_SRC),) + $(Q)mkdir -p include/asm +endif + $(Q)ln -fsn $(srctree)/arch/$(ARCH)/include/asm/arch-$(if $(SOC),$(SOC),$(CPU)) \ + $(if $(KBUILD_SRC),,arch/$(ARCH)/)include/asm/arch + +PHONY += FORCE +FORCE: + +.PHONY: $(PHONY) diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 04c6f7d239..baeaabe310 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -3,14 +3,14 @@ # ========================================================================== # Modified for U-Boot -ifeq ($(CONFIG_TPL_BUILD),y) - src := $(patsubst tpl/%,%,$(obj)) -else - ifeq ($(CONFIG_SPL_BUILD),y) - src := $(patsubst spl/%,%,$(obj)) - else - src := $(obj) - endif +prefix := tpl +src := $(patsubst $(prefix)/%,%,$(obj)) +ifeq ($(obj),$(src)) +prefix := spl +src := $(patsubst $(prefix)/%,%,$(obj)) +ifeq ($(obj),$(src)) +prefix := . +endif endif PHONY := __build @@ -40,18 +40,9 @@ subdir-asflags-y := subdir-ccflags-y := # Read auto.conf if it exists, otherwise ignore --include include/config/auto.conf - -# Added for U-Boot: Load U-Boot configuration -ifeq ($(CONFIG_TPL_BUILD),y) - -include include/tpl-autoconf.mk -else - ifeq ($(CONFIG_SPL_BUILD),y) - -include include/spl-autoconf.mk - else - -include include/autoconf.mk - endif -endif +# Modified for U-Boot +-include $(prefix)/include/config/auto.conf +-include $(prefix)/include/autoconf.mk include scripts/Kbuild.include diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index bf677aa42a..88c01d18ec 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -21,13 +21,10 @@ _dummy := $(shell [ -d $(obj) ] || mkdir -p $(obj)) include $(srctree)/scripts/Kbuild.include -CONFIG_SPL_BUILD := y -export CONFIG_SPL_BUILD +UBOOTINCLUDE := -I$(obj)/include $(UBOOTINCLUDE) -KBUILD_CPPFLAGS += -DCONFIG_SPL_BUILD -ifeq ($(CONFIG_TPL_BUILD),y) -KBUILD_CPPFLAGS += -DCONFIG_TPL_BUILD -endif +-include $(obj)/include/config/auto.conf +-include $(obj)/include/autoconf.mk ifeq ($(CONFIG_TPL_BUILD),y) export CONFIG_TPL_BUILD @@ -36,14 +33,6 @@ else SPL_BIN := u-boot-spl endif -include include/config.mk - -ifeq ($(CONFIG_TPL_BUILD),y) - -include include/tpl-autoconf.mk -else - -include include/spl-autoconf.mk -endif - include $(srctree)/config.mk # Enable garbage collection of un-used sections for SPL @@ -53,20 +42,6 @@ LDFLAGS_FINAL += --gc-sections # FIX ME cpp_flags := $(KBUILD_CPPFLAGS) $(PLATFORM_CPPFLAGS) $(UBOOTINCLUDE) \ $(NOSTDINC_FLAGS) -c_flags := $(KBUILD_CFLAGS) $(cpp_flags) - -# Auto-generate the spl-autoconf.mk file (which is included by all makefiles for SPL) -quiet_cmd_autoconf = GEN $@ - cmd_autoconf = \ - $(CPP) $(c_flags) -DDO_DEPS_ONLY -dM $(srctree)/include/common.h > $@.tmp && \ - sed -n -f $(srctree)/tools/scripts/define2mk.sed $@.tmp > $@; \ - rm $@.tmp - -include/tpl-autoconf.mk: include/config.h - $(call cmd,autoconf) - -include/spl-autoconf.mk: include/config.h - $(call cmd,autoconf) HAVE_VENDOR_COMMON_LIB = $(if $(wildcard $(srctree)/board/$(VENDOR)/common/Makefile),y,n) diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index b30406860b..1a41723823 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -221,7 +221,11 @@ static void use_config(const char *m, int slen) define_config(m, slen, hash); - printf(" $(wildcard include/config/"); + /* printf(" $(wildcard include/config/"); */ + /* modified for U-Boot */ + printf(" $(wildcard %sinclude/config/", + strncmp(depfile, "spl/", 4) ? + (strncmp(depfile, "tpl/", 4) ? "" : "tpl/") : "spl/"); for (i = 0; i < slen; i++) { c = m[i]; if (c == '_') diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f88d90f202..ae6ce669e1 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -951,6 +951,14 @@ int conf_write_autoconf(void) FILE *out, *tristate, *out_h; int i; + /* + * Added for U-Boot SPL/TPL + */ + name = getenv("KCONFIG_OBJDIR"); + if (name && name[0]) + if (chdir(name)) + return 1; + sym_clear_all_valid(); file_write_dep("include/config/auto.conf.cmd"); diff --git a/scripts/multiconfig.py b/scripts/multiconfig.py new file mode 100755 index 0000000000..749abcb7a5 --- /dev/null +++ b/scripts/multiconfig.py @@ -0,0 +1,410 @@ +#!/usr/bin/env python +# +# Copyright (C) 2014, Masahiro Yamada +# +# SPDX-License-Identifier: GPL-2.0+ +# + +""" +A wrapper script to adjust Kconfig for U-Boot + +The biggest difference between Linux Kernel and U-Boot in terms of the +board configuration is that U-Boot has to configure multiple boot images +per board: Normal, SPL, TPL. +We need to expand the functions of Kconfig to handle multiple boot +images. + +Instead of touching various parts under the scripts/kconfig/ directory, +pushing necessary adjustments into this single script would be better +for code maintainance. All the make targets related to the configuration +(make %config) should be invoked via this script. + +Let's see what is different from the original Kconfig. + +- config, menuconfig, etc. + +The commands 'make config', 'make menuconfig', etc. are used to create +or modify the .config file, which stores configs for Normal boot image. + +The location of the one for SPL, TPL image is spl/.config, tpl/.config, +respectively. Use 'make spl/config', 'make spl/menuconfig', etc. +to create or modify the spl/.config file, which contains configs +for SPL image. +Do likewise for the tpl/.config file. +The generic syntax for SPL, TPL configuration is +'make /'. + +- silentoldconfig + +The command 'make silentoldconfig' updates .config, if necessary, and +additionally updates include/generated/autoconf.h and files under +include/configs/ directory. In U-Boot, it should do the same things for +SPL, TPL images for boards supporting them. +Depending on whether CONFIG_SPL, CONFIG_TPL is defined or not, +'make silentoldconfig' iterates three times at most changing the target +directory. + +To sum up, 'make silentoldconfig' possibly updates + - .config, include/generated/autoconf.h, include/config/* + - spl/.config, spl/include/generated/autoconf.h, spl/include/config/* + (in case CONFIG_SPL=y) + - tpl/.config, tpl/include/generated/autoconf.h, tpl/include/config/* + (in case CONFIG_TPL=y) + +- defconfig, _defconfig + +The command 'make _defconfig' creates a new .config based on the +file configs/_defconfig. The command 'make defconfig' is the same +but the difference is it uses the file specified with KBUILD_DEFCONFIG +environment. + +We need to create .config, spl/.config, tpl/.config for boards where SPL +and TPL images are supported. One possible solution for that is to have +multiple defconfig files per board, but it would produce duplication +among the defconfigs. +The approach chosen here is to expand the feature and support +conditional definition in defconfig, that is, each line in defconfig +files has the form of: +: + +The ':' prefix specifies which image the line is valid for. +The ':' is one of: + None - the line is valid only for Normal image + S: - the line is valid only for SPL image + T: - the line is valid only for TPL image + ST: - the line is valid for SPL and TPL images + +S: - the line is valid for Normal and SPL images + +T: - the line is valid for Normal and TPL images + +ST: - the line is valid for Normal, SPL and SPL images + +So, if neither CONFIG_SPL nor CONFIG_TPL is defined, the defconfig file +has no ':' part and therefore has the same form of that of +Linux Kernel. + +In U-Boot, for example, a defconfig file can be written like this: + + CONFIG_FOO=100 + S:CONFIG_FOO=200 + T:CONFIG_FOO=300 + ST:CONFIG_BAR=y + +S:CONFIG_BAZ=y + +T:CONFIG_QUX=y + +ST:CONFIG_QUUX=y + +The defconfig above is parsed by this script and internally divided into +three temporary defconfig files. + + - Temporary defconfig for Normal image + CONFIG_FOO=100 + CONFIG_BAZ=y + CONFIG_QUX=y + CONFIG_QUUX=y + + - Temporary defconfig for SPL image + CONFIG_FOO=200 + CONFIG_BAR=y + CONFIG_BAZ=y + CONFIG_QUUX=y + + - Temporary defconfig for TPL image + CONFIG_FOO=300 + CONFIG_BAR=y + CONFIG_QUX=y + CONFIG_QUUX=y + +They are passed to scripts/kconfig/conf, each is used for generating +.config, spl/.config, tpl/.config, respectively. + +- savedefconfig + +This is the reverse operation of 'make defconfig'. +If neither CONFIG_SPL nor CONFIG_TPL is defined in the .config file, +it works as 'make savedefconfig' in Linux Kernel: create the minimal set +of config based on the .config and save it into 'defconfig' file. + +If CONFIG_SPL or CONFIG_TPL is defined, the common lines among .config, +spl/.config, tpl/.config are coalesced together and output to the file +'defconfig' in the form like: + + CONFIG_FOO=100 + S:CONFIG_FOO=200 + T:CONFIG_FOO=300 + ST:CONFIG_BAR=y + +S:CONFIG_BAZ=y + +T:CONFIG_QUX=y + +ST:CONFIG_QUUX=y + +This can be used as an input of 'make _defconfig' command. +""" + +import errno +import os +import re +import subprocess +import sys + +# Constant variables +SUB_IMAGES = ('spl', 'tpl') +IMAGES = ('',) + SUB_IMAGES +SYMBOL_MAP = {'': '+', 'spl': 'S', 'tpl': 'T'} +PATTERN_SYMBOL = re.compile(r'(\+?)(S?)(T?):(.*)') + +# Environment variables (should be defined in the top Makefile) +# .get('key', 'default_value') method is useful for standalone testing. +MAKE = os.environ.get('MAKE', 'make') +srctree = os.environ.get('srctree', '.') +KCONFIG_CONFIG = os.environ.get('KCONFIG_CONFIG', '.config') + +# Useful shorthand +build = '%s -f %s/scripts/Makefile.build obj=scripts/kconfig %%s' % (MAKE, srctree) +autoconf = '%s -f %s/scripts/Makefile.autoconf obj=%%s %%s' % (MAKE, srctree) + +### helper functions ### +def mkdirs(*dirs): + """Make directories ignoring 'File exists' error.""" + for d in dirs: + try: + os.makedirs(d) + except OSError as exception: + # Ignore 'File exists' error + if exception.errno != errno.EEXIST: + raise + +def rmfiles(*files): + """Remove files ignoring 'No such file or directory' error.""" + for f in files: + try: + os.remove(f) + except OSError as exception: + # Ignore 'No such file or directory' error + if exception.errno != errno.ENOENT: + raise + +def rmdirs(*dirs): + """Remove directories ignoring 'No such file or directory' + and 'Directory not empty' error. + """ + for d in dirs: + try: + os.rmdir(d) + except OSError as exception: + # Ignore 'No such file or directory' + # and 'Directory not empty' error + if exception.errno != errno.ENOENT and \ + exception.errno != errno.ENOTEMPTY: + raise + +def error(msg): + """Output the given argument to stderr and exit with return code 1.""" + print >> sys.stderr, msg + sys.exit(1) + +def run_command(command, callback_on_error=None): + """Run the given command in a sub-shell (and exit if it fails). + + Arguments: + command: A string of the command + callback_on_error: Callback handler invoked just before exit + when the command fails (Default=None) + """ + retcode = subprocess.call(command, shell=True) + if retcode: + if callback_on_error: + callback_on_error() + error("'%s' Failed" % command) + +def run_make_config(cmd, objdir, callback_on_error=None): + """Run the make command in a sub-shell (and exit if it fails). + + Arguments: + cmd: Make target such as 'config', 'menuconfig', 'defconfig', etc. + objdir: Target directory where the make command is run. + Typically '', 'spl', 'tpl' for Normal, SPL, TPL image, + respectively. + callback_on_error: Callback handler invoked just before exit + when the command fails (Default=None) + """ + # Linux expects defconfig files in arch/$(SRCARCH)/configs/ directory, + # but U-Boot puts them in configs/ directory. + # Give SRCARCH=.. to fake scripts/kconfig/Makefile. + options = 'SRCARCH=.. KCONFIG_OBJDIR=%s' % objdir + if objdir: + options += ' KCONFIG_CONFIG=%s/%s' % (objdir, KCONFIG_CONFIG) + mkdirs(objdir) + run_command(build % cmd + ' ' + options, callback_on_error) + +def get_enabled_subimages(ignore_error=False): + """Parse .config file to detect if CONFIG_SPL, CONFIG_TPL is enabled + and return a tuple of enabled subimages. + + Arguments: + ignore_error: Specify the behavior when '.config' is not found; + Raise an exception if this flag is False. + Return a null tuple if this flag is True. + + Returns: + A tuple of enabled subimages as follows: + () if neither CONFIG_SPL nor CONFIG_TPL is defined + ('spl',) if CONFIG_SPL is defined but CONFIG_TPL is not + ('spl', 'tpl') if both CONFIG_SPL and CONFIG_TPL are defined + """ + enabled = () + match_patterns = [ (img, 'CONFIG_' + img.upper() + '=y\n') + for img in SUB_IMAGES ] + try: + f = open(KCONFIG_CONFIG) + except IOError as exception: + if not ignore_error or exception.errno != errno.ENOENT: + raise + return enabled + with f: + for line in f: + for img, pattern in match_patterns: + if line == pattern: + enabled += (img,) + return enabled + +def do_silentoldconfig(cmd): + """Run 'make silentoldconfig' for all the enabled images. + + Arguments: + cmd: should always be a string 'silentoldconfig' + """ + run_make_config(cmd, '') + subimages = get_enabled_subimages() + for obj in subimages: + mkdirs(os.path.join(obj, 'include', 'config'), + os.path.join(obj, 'include', 'generated')) + run_make_config(cmd, obj) + remove_auto_conf = lambda : rmfiles('include/config/auto.conf') + # If the following part failed, include/config/auto.conf should be deleted + # so 'make silentoldconfig' will be re-run on the next build. + run_command(autoconf % + ('include', 'include/autoconf.mk include/autoconf.mk.dep'), + remove_auto_conf) + # include/config.h has been updated after 'make silentoldconfig'. + # We need to touch include/config/auto.conf so it gets newer + # than include/config.h. + # Otherwise, 'make silentoldconfig' would be invoked twice. + os.utime('include/config/auto.conf', None) + for obj in subimages: + run_command(autoconf % (obj + '/include', + obj + '/include/autoconf.mk'), + remove_auto_conf) + +def do_tmp_defconfig(output_lines, img): + """Helper function for do_board_defconfig(). + + Write the defconfig contents into a file '.tmp_defconfig' and + invoke 'make .tmp_defconfig'. + + Arguments: + output_lines: A sequence of defconfig lines of each image + img: Target image. Typically '', 'spl', 'tpl' for + Normal, SPL, TPL images, respectively. + """ + TMP_DEFCONFIG = '.tmp_defconfig' + TMP_DIRS = ('arch', 'configs') + defconfig_path = os.path.join('configs', TMP_DEFCONFIG) + mkdirs(*TMP_DIRS) + with open(defconfig_path, 'w') as f: + f.write(''.join(output_lines[img])) + cleanup = lambda: (rmfiles(defconfig_path), rmdirs(*TMP_DIRS)) + run_make_config(TMP_DEFCONFIG, img, cleanup) + cleanup() + +def do_board_defconfig(cmd): + """Run 'make _defconfig'. + + Arguments: + cmd: should be a string '_defconfig' + """ + defconfig_path = os.path.join(srctree, 'configs', cmd) + output_lines = dict([ (img, []) for img in IMAGES ]) + with open(defconfig_path) as f: + for line in f: + m = PATTERN_SYMBOL.match(line) + if m: + for idx, img in enumerate(IMAGES): + if m.group(idx + 1): + output_lines[img].append(m.group(4) + '\n') + continue + output_lines[''].append(line) + do_tmp_defconfig(output_lines, '') + for img in get_enabled_subimages(): + do_tmp_defconfig(output_lines, img) + +def do_defconfig(cmd): + """Run 'make defconfig'. + + Arguments: + cmd: should always be a string 'defconfig' + """ + KBUILD_DEFCONFIG = os.environ['KBUILD_DEFCONFIG'] + print "*** Default configuration is based on '%s'" % KBUILD_DEFCONFIG + do_board_defconfig(KBUILD_DEFCONFIG) + +def do_savedefconfig(cmd): + """Run 'make savedefconfig'. + + Arguments: + cmd: should always be a string 'savedefconfig' + """ + DEFCONFIG = 'defconfig' + # Continue even if '.config' does not exist + subimages = get_enabled_subimages(True) + run_make_config(cmd, '') + output_lines = [] + prefix = {} + with open(DEFCONFIG) as f: + for line in f: + output_lines.append(line) + prefix[line] = '+' + for img in subimages: + run_make_config(cmd, img) + unmatched_lines = [] + with open(DEFCONFIG) as f: + for line in f: + if line in output_lines: + index = output_lines.index(line) + output_lines[index:index] = unmatched_lines + unmatched_lines = [] + prefix[line] += SYMBOL_MAP[img] + else: + ummatched_lines.append(line) + prefix[line] = SYMBOL_MAP[img] + with open(DEFCONFIG, 'w') as f: + for line in output_lines: + if prefix[line] == '+': + f.write(line) + else: + f.write(prefix[line] + ':' + line) + +def do_others(cmd): + """Run the make command other than 'silentoldconfig', 'defconfig', + '_defconfig' and 'savedefconfig'. + + Arguments: + cmd: Make target in the form of '/' + The field '/' is typically empty, 'spl/', 'tpl/' + for Normal, SPL, TPL images, respectively. + The field '' is make target such as 'config', + 'menuconfig', etc. + """ + objdir, _, cmd = cmd.rpartition('/') + run_make_config(cmd, objdir) + +cmd_list = {'silentoldconfig': do_silentoldconfig, + 'defconfig': do_defconfig, + 'savedefconfig': do_savedefconfig} + +def main(): + cmd = sys.argv[1] + if cmd.endswith('_defconfig'): + do_board_defconfig(cmd) + else: + func = cmd_list.get(cmd, do_others) + func(cmd) + +if __name__ == '__main__': + main() diff --git a/tools/Makefile b/tools/Makefile index 61b2048211..90e966d893 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -193,7 +193,7 @@ endif # !LOGO_BMP # Define _GNU_SOURCE to obtain the getline prototype from stdio.h # HOST_EXTRACFLAGS += -include $(srctree)/include/libfdt_env.h \ - $(patsubst -I%,-idirafter%, $(UBOOTINCLUDE)) \ + $(patsubst -I%,-idirafter%, $(filter -I%, $(UBOOTINCLUDE))) \ -I$(srctree)/lib/libfdt \ -I$(srctree)/tools \ -DCONFIG_SYS_TEXT_BASE=$(CONFIG_SYS_TEXT_BASE) \ diff --git a/tools/env/Makefile b/tools/env/Makefile index f5368bc4d0..4927489b16 100644 --- a/tools/env/Makefile +++ b/tools/env/Makefile @@ -11,7 +11,7 @@ HOSTCC = $(CC) # Compile for a hosted environment on the target -HOST_EXTRACFLAGS = $(patsubst -I%,-idirafter%, $(UBOOTINCLUDE)) \ +HOST_EXTRACFLAGS = $(patsubst -I%,-idirafter%, $(filter -I%, $(UBOOTINCLUDE))) \ -idirafter $(srctree)/tools/env \ -DUSE_HOSTCC \ -DTEXT_BASE=$(TEXT_BASE) -- 2.39.5