Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild

* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild: (40 commits)
  kbuild: trivial fixes in Makefile
  kbuild: adding symbols in Kconfig and defconfig to TAGS
  kbuild: replace abort() with exit(1)
  kbuild: support for %.symtypes files
  kbuild: fix silentoldconfig recursion
  kbuild: add option for stripping modules while installing them
  kbuild: kill some false positives from modpost
  kbuild: export-symbol usage report generator
  kbuild: fix make -rR breakage
  kbuild: append -dirty for updated but uncommited changes
  kbuild: append git revision for all untagged commits
  kbuild: fix module.symvers parsing in modpost
  kbuild: ignore make's built-in rules & variables
  kbuild: bugfix with initramfs
  kbuild: modpost build fix
  kbuild: check license compatibility when building modules
  kbuild: export-type enhancement to modpost.c
  kbuild: add dependency on kernel.release to the package targets
  kbuild: `make kernelrelease' speedup
  kconfig: KCONFIG_OVERWRITECONFIG
  ...
This commit is contained in:
Linus Torvalds 2006-06-26 11:05:15 -07:00
commit 2a2ed2db35
48 changed files with 2739 additions and 1658 deletions

View File

@ -1123,6 +1123,14 @@ The top Makefile exports the following variables:
$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may
override this value on the command line if desired. override this value on the command line if desired.
INSTALL_MOD_STRIP
If this variable is specified, will cause modules to be stripped
after they are installed. If INSTALL_MOD_STRIP is '1', then the
default option --strip-debug will be used. Otherwise,
INSTALL_MOD_STRIP will used as the option(s) to the strip command.
=== 8 Makefile language === 8 Makefile language
The kernel Makefiles are designed to run with GNU Make. The Makefiles The kernel Makefiles are designed to run with GNU Make. The Makefiles

213
Makefile
View File

@ -71,7 +71,7 @@ endif
# In both cases the working directory must be the root of the kernel src. # In both cases the working directory must be the root of the kernel src.
# 1) O= # 1) O=
# Use "make O=dir/to/store/output/files/" # Use "make O=dir/to/store/output/files/"
# #
# 2) Set KBUILD_OUTPUT # 2) Set KBUILD_OUTPUT
# Set the environment variable KBUILD_OUTPUT to point to the directory # Set the environment variable KBUILD_OUTPUT to point to the directory
# where the output files shall be placed. # where the output files shall be placed.
@ -178,18 +178,20 @@ CROSS_COMPILE ?=
# Architecture as present in compile.h # Architecture as present in compile.h
UTS_MACHINE := $(ARCH) UTS_MACHINE := $(ARCH)
KCONFIG_CONFIG ?= .config
# SHELL used by kbuild # SHELL used by kbuild
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
else if [ -x /bin/bash ]; then echo /bin/bash; \ else if [ -x /bin/bash ]; then echo /bin/bash; \
else echo sh; fi ; fi) else echo sh; fi ; fi)
HOSTCC = gcc HOSTCC = gcc
HOSTCXX = g++ HOSTCXX = g++
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
HOSTCXXFLAGS = -O2 HOSTCXXFLAGS = -O2
# Decide whether to build built-in, modular, or both. # Decide whether to build built-in, modular, or both.
# Normally, just do built-in. # Normally, just do built-in.
KBUILD_MODULES := KBUILD_MODULES :=
KBUILD_BUILTIN := 1 KBUILD_BUILTIN := 1
@ -197,7 +199,7 @@ KBUILD_BUILTIN := 1
# If we have only "make modules", don't compile built-in objects. # If we have only "make modules", don't compile built-in objects.
# When we're building modules with modversions, we need to consider # When we're building modules with modversions, we need to consider
# the built-in objects during the descend as well, in order to # the built-in objects during the descend as well, in order to
# make sure the checksums are uptodate before we record them. # make sure the checksums are up to date before we record them.
ifeq ($(MAKECMDGOALS),modules) ifeq ($(MAKECMDGOALS),modules)
KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1) KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
@ -230,7 +232,7 @@ export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
# #
# If $(quiet) is empty, the whole command will be printed. # If $(quiet) is empty, the whole command will be printed.
# If it is set to "quiet_", only the short version will be printed. # If it is set to "quiet_", only the short version will be printed.
# If it is set to "silent_", nothing wil be printed at all, since # If it is set to "silent_", nothing will be printed at all, since
# the variable $(silent_cmd_cc_o_c) doesn't exist. # the variable $(silent_cmd_cc_o_c) doesn't exist.
# #
# A simple variant is to prefix commands with $(Q) - that's useful # A simple variant is to prefix commands with $(Q) - that's useful
@ -265,10 +267,9 @@ MAKEFLAGS += --include-dir=$(srctree)
# We need some generic definitions # We need some generic definitions
include $(srctree)/scripts/Kbuild.include include $(srctree)/scripts/Kbuild.include
# For maximum performance (+ possibly random breakage, uncomment # Do not use make's built-in rules and variables
# the following) # This increases performance and avoid hard-to-debug behavour
MAKEFLAGS += -rR
#MAKEFLAGS += -rR
# Make variables (CC, etc...) # Make variables (CC, etc...)
@ -305,21 +306,21 @@ LINUXINCLUDE := -Iinclude \
CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE) CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-fno-strict-aliasing -fno-common -fno-strict-aliasing -fno-common
AFLAGS := -D__ASSEMBLY__ AFLAGS := -D__ASSEMBLY__
# Read KERNELRELEASE from .kernelrelease (if it exists) # Read KERNELRELEASE from include/config/kernel.release (if it exists)
KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null) KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION \ export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \ export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \ export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
# When compiling out-of-tree modules, put MODVERDIR in the module # When compiling out-of-tree modules, put MODVERDIR in the module
@ -357,12 +358,13 @@ endif
# catch them early, and hand them over to scripts/kconfig/Makefile # catch them early, and hand them over to scripts/kconfig/Makefile
# It is allowed to specify more targets when calling make, including # It is allowed to specify more targets when calling make, including
# mixing *config targets and build targets. # mixing *config targets and build targets.
# For example 'make oldconfig all'. # For example 'make oldconfig all'.
# Detect when mixed targets is specified, and make a second invocation # Detect when mixed targets is specified, and make a second invocation
# of make so .config is not included in this case either (for *config). # of make so .config is not included in this case either (for *config).
no-dot-config-targets := clean mrproper distclean \ no-dot-config-targets := clean mrproper distclean \
cscope TAGS tags help %docs check% cscope TAGS tags help %docs check% \
kernelrelease kernelversion
config-targets := 0 config-targets := 0
mixed-targets := 0 mixed-targets := 0
@ -404,9 +406,8 @@ include $(srctree)/arch/$(ARCH)/Makefile
export KBUILD_DEFCONFIG export KBUILD_DEFCONFIG
config %config: scripts_basic outputmakefile FORCE config %config: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux $(Q)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig $@ $(Q)$(MAKE) $(build)=scripts/kconfig $@
$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease
else else
# =========================================================================== # ===========================================================================
@ -416,13 +417,11 @@ else
ifeq ($(KBUILD_EXTMOD),) ifeq ($(KBUILD_EXTMOD),)
# Additional helpers built in scripts/ # Additional helpers built in scripts/
# Carefully list dependencies so we do not try to build scripts twice # Carefully list dependencies so we do not try to build scripts twice
# in parrallel # in parallel
PHONY += scripts PHONY += scripts
scripts: scripts_basic include/config/MARKER scripts: scripts_basic include/config/auto.conf
$(Q)$(MAKE) $(build)=$(@) $(Q)$(MAKE) $(build)=$(@)
scripts_basic: include/linux/autoconf.h
# Objects we will link into vmlinux / subdirs we need to visit # Objects we will link into vmlinux / subdirs we need to visit
init-y := init/ init-y := init/
drivers-y := drivers/ sound/ drivers-y := drivers/ sound/
@ -436,31 +435,32 @@ ifeq ($(dot-config),1)
# Read in dependencies to all Kconfig* files, make sure to run # Read in dependencies to all Kconfig* files, make sure to run
# oldconfig if changes are detected. # oldconfig if changes are detected.
-include .kconfig.d -include include/config/auto.conf.cmd
-include include/config/auto.conf
include .config
# If .config needs to be updated, it will be done via the dependency
# that autoconf has on .config.
# To avoid any implicit rule to kick in, define an empty command # To avoid any implicit rule to kick in, define an empty command
.config .kconfig.d: ; $(KCONFIG_CONFIG) include/config/auto.conf.cmd: ;
# If .config is newer than include/linux/autoconf.h, someone tinkered # If .config is newer than include/config/auto.conf, someone tinkered
# with it and forgot to run make oldconfig. # with it and forgot to run make oldconfig.
# If kconfig.d is missing then we are probarly in a cleaned tree so # 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 # we execute the config step to be sure to catch updated Kconfig files
include/linux/autoconf.h: .kconfig.d .config include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
$(Q)mkdir -p include/linux ifeq ($(KBUILD_EXTMOD),)
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig $(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
else
$(error kernel configuration not valid - run 'make prepare' in $(srctree) to update it)
endif
else else
# Dummy target needed, because used as prerequisite # Dummy target needed, because used as prerequisite
include/linux/autoconf.h: ; include/config/auto.conf: ;
endif endif
# The all: target is the default when no target is given on the # The all: target is the default when no target is given on the
# command line. # command line.
# This allow a user to issue only 'make' to build a kernel including modules # This allow a user to issue only 'make' to build a kernel including modules
# Defaults vmlinux but it is usually overriden in the arch makefile # Defaults vmlinux but it is usually overridden in the arch makefile
all: vmlinux all: vmlinux
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
@ -492,11 +492,11 @@ CHECKFLAGS += $(NOSTDINC_FLAGS)
# warn about C99 declaration after statement # warn about C99 declaration after statement
CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
# disable pointer signedness warnings in gcc 4.0 # disable pointer signed / unsigned warnings in gcc 4.0
CFLAGS += $(call cc-option,-Wno-pointer-sign,) CFLAGS += $(call cc-option,-Wno-pointer-sign,)
# Default kernel image to build when no specific target is given. # Default kernel image to build when no specific target is given.
# KBUILD_IMAGE may be overruled on the commandline or # KBUILD_IMAGE may be overruled on the command line or
# set in the environment # set in the environment
# Also any assignments in arch/$(ARCH)/Makefile take precedence over # Also any assignments in arch/$(ARCH)/Makefile take precedence over
# this default value # this default value
@ -510,12 +510,29 @@ export INSTALL_PATH ?= /boot
# #
# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
# relocations required by build roots. This is not defined in the # relocations required by build roots. This is not defined in the
# makefile but the arguement can be passed to make if needed. # makefile but the argument can be passed to make if needed.
# #
MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
export MODLIB export MODLIB
#
# INSTALL_MOD_STRIP, if defined, will cause modules to be
# stripped after they are installed. If INSTALL_MOD_STRIP is '1', then
# the default option --strip-debug will be used. Otherwise,
# INSTALL_MOD_STRIP will used as the options to the strip command.
ifdef INSTALL_MOD_STRIP
ifeq ($(INSTALL_MOD_STRIP),1)
mod_strip_cmd = $STRIP) --strip-debug
else
mod_strip_cmd = $(STRIP) $(INSTALL_MOD_STRIP)
endif # INSTALL_MOD_STRIP=1
else
mod_strip_cmd = true
endif # INSTALL_MOD_STRIP
export mod_strip_cmd
ifeq ($(KBUILD_EXTMOD),) ifeq ($(KBUILD_EXTMOD),)
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/ core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
@ -539,7 +556,7 @@ libs-y := $(libs-y1) $(libs-y2)
# Build vmlinux # Build vmlinux
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# vmlinux is build from the objects selected by $(vmlinux-init) and # vmlinux is built from the objects selected by $(vmlinux-init) and
# $(vmlinux-main). Most are built-in.o files from top-level directories # $(vmlinux-main). Most are built-in.o files from top-level directories
# in the kernel tree, others are specified in arch/$(ARCH)Makefile. # in the kernel tree, others are specified in arch/$(ARCH)Makefile.
# Ordering when linking is important, and $(vmlinux-init) must be first. # Ordering when linking is important, and $(vmlinux-init) must be first.
@ -590,7 +607,7 @@ quiet_cmd_vmlinux_version = GEN .version
$(MAKE) $(build)=init $(MAKE) $(build)=init
# Generate System.map # Generate System.map
quiet_cmd_sysmap = SYSMAP quiet_cmd_sysmap = SYSMAP
cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
# Link of vmlinux # Link of vmlinux
@ -719,7 +736,7 @@ $(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@ $(Q)$(MAKE) $(build)=$@
# Build the kernel release string # Build the kernel release string
# The KERNELRELEASE is stored in a file named .kernelrelease # The KERNELRELEASE is stored in a file named include/config/kernel.release
# to be used when executing for example make install or make modules_install # to be used when executing for example make install or make modules_install
# #
# Take the contents of any files called localversion* and the config # Take the contents of any files called localversion* and the config
@ -737,10 +754,10 @@ _localver = $(foreach f, $(__localver), $(if $(findstring ~, $(f)),,$(f)))
localver = $(subst $(space),, \ localver = $(subst $(space),, \
$(shell cat /dev/null $(_localver)) \ $(shell cat /dev/null $(_localver)) \
$(patsubst "%",%,$(CONFIG_LOCALVERSION))) $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called # If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called
# and if the SCM is know a tag from the SCM is appended. # and if the SCM is know a tag from the SCM is appended.
# The appended tag is determinded by the SCM used. # The appended tag is determined by the SCM used.
# #
# Currently, only git is supported. # Currently, only git is supported.
# Other SCMs can edit scripts/setlocalversion and add the appropriate # Other SCMs can edit scripts/setlocalversion and add the appropriate
@ -753,9 +770,9 @@ endif
localver-full = $(localver)$(localver-auto) localver-full = $(localver)$(localver-auto)
# Store (new) KERNELRELASE string in .kernelrelease # Store (new) KERNELRELASE string in include/config/kernel.release
kernelrelease = $(KERNELVERSION)$(localver-full) kernelrelease = $(KERNELVERSION)$(localver-full)
.kernelrelease: FORCE include/config/kernel.release: include/config/auto.conf FORCE
$(Q)rm -f $@ $(Q)rm -f $@
$(Q)echo $(kernelrelease) > $@ $(Q)echo $(kernelrelease) > $@
@ -776,10 +793,10 @@ PHONY += prepare-all
# and if so do: # and if so do:
# 1) Check that make has not been executed in the kernel src $(srctree) # 1) Check that make has not been executed in the kernel src $(srctree)
# 2) Create the include2 directory, used for the second asm symlink # 2) Create the include2 directory, used for the second asm symlink
prepare3: .kernelrelease prepare3: include/config/kernel.release
ifneq ($(KBUILD_SRC),) ifneq ($(KBUILD_SRC),)
@echo ' Using $(srctree) as source for kernel' @echo ' Using $(srctree) as source for kernel'
$(Q)if [ -f $(srctree)/.config ]; then \ $(Q)if [ -f $(srctree)/.config -o -d $(srctree)/include/config ]; then \
echo " $(srctree) is not clean, please run 'make mrproper'";\ echo " $(srctree) is not clean, please run 'make mrproper'";\
echo " in the '$(srctree)' directory.";\ echo " in the '$(srctree)' directory.";\
/bin/false; \ /bin/false; \
@ -792,7 +809,7 @@ endif
prepare2: prepare3 outputmakefile prepare2: prepare3 outputmakefile
prepare1: prepare2 include/linux/version.h include/asm \ prepare1: prepare2 include/linux/version.h include/asm \
include/config/MARKER include/config/auto.conf
ifneq ($(KBUILD_MODULES),) ifneq ($(KBUILD_MODULES),)
$(Q)mkdir -p $(MODVERDIR) $(Q)mkdir -p $(MODVERDIR)
$(Q)rm -f $(MODVERDIR)/* $(Q)rm -f $(MODVERDIR)/*
@ -806,27 +823,20 @@ prepare0: archprepare FORCE
# All the preparing.. # All the preparing..
prepare prepare-all: prepare0 prepare prepare-all: prepare0
# Leave this as default for preprocessing vmlinux.lds.S, which is now # Leave this as default for preprocessing vmlinux.lds.S, which is now
# done in arch/$(ARCH)/kernel/Makefile # done in arch/$(ARCH)/kernel/Makefile
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
# FIXME: The asm symlink changes when $(ARCH) changes. That's # FIXME: The asm symlink changes when $(ARCH) changes. That's
# hard to detect, but I suppose "make mrproper" is a good idea # hard to detect, but I suppose "make mrproper" is a good idea
# before switching between archs anyway. # before switching between archs anyway.
include/asm: include/asm:
@echo ' SYMLINK $@ -> include/asm-$(ARCH)' @echo ' SYMLINK $@ -> include/asm-$(ARCH)'
$(Q)if [ ! -d include ]; then mkdir -p include; fi; $(Q)if [ ! -d include ]; then mkdir -p include; fi;
@ln -fsn asm-$(ARCH) $@ @ln -fsn asm-$(ARCH) $@
# Split autoconf.h into include/linux/config/*
include/config/MARKER: scripts/basic/split-include include/linux/autoconf.h
@echo ' SPLIT include/linux/autoconf.h -> include/config/*'
@scripts/basic/split-include include/linux/autoconf.h include/config
@touch $@
# Generate some files # Generate some files
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -846,7 +856,7 @@ define filechk_version.h
) )
endef endef
include/linux/version.h: $(srctree)/Makefile .config .kernelrelease FORCE include/linux/version.h: $(srctree)/Makefile include/config/kernel.release FORCE
$(call filechk,version.h) $(call filechk,version.h)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -860,7 +870,7 @@ depend dep:
ifdef CONFIG_MODULES ifdef CONFIG_MODULES
# By default, build modules as well # By default, build modules as well
all: modules all: modules
@ -942,7 +952,7 @@ CLEAN_FILES += vmlinux System.map \
MRPROPER_DIRS += include/config include2 MRPROPER_DIRS += include/config include2
MRPROPER_FILES += .config .config.old include/asm .version .old_version \ MRPROPER_FILES += .config .config.old include/asm .version .old_version \
include/linux/autoconf.h include/linux/version.h \ include/linux/autoconf.h include/linux/version.h \
.kernelrelease Module.symvers tags TAGS cscope* Module.symvers tags TAGS cscope*
# clean - Delete most, but leave enough to build external modules # clean - Delete most, but leave enough to build external modules
# #
@ -958,8 +968,9 @@ clean: archclean $(clean-dirs)
$(call cmd,rmdirs) $(call cmd,rmdirs)
$(call cmd,rmfiles) $(call cmd,rmfiles)
@find . $(RCS_FIND_IGNORE) \ @find . $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
-o -name '*.symtypes' \) \
-type f -print | xargs rm -f -type f -print | xargs rm -f
# mrproper - Delete all generated files, including .config # mrproper - Delete all generated files, including .config
@ -982,9 +993,9 @@ PHONY += distclean
distclean: mrproper distclean: mrproper
@find $(srctree) $(RCS_FIND_IGNORE) \ @find $(srctree) $(RCS_FIND_IGNORE) \
\( -name '*.orig' -o -name '*.rej' -o -name '*~' \ \( -name '*.orig' -o -name '*.rej' -o -name '*~' \
-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \ -o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
-o -name '.*.rej' -o -size 0 \ -o -name '.*.rej' -o -size 0 \
-o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \ -o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
-type f -print | xargs rm -f -type f -print | xargs rm -f
@ -994,9 +1005,9 @@ distclean: mrproper
# rpm target kept for backward compatibility # rpm target kept for backward compatibility
package-dir := $(srctree)/scripts/package package-dir := $(srctree)/scripts/package
%pkg: FORCE %pkg: include/config/kernel.release FORCE
$(Q)$(MAKE) $(build)=$(package-dir) $@ $(Q)$(MAKE) $(build)=$(package-dir) $@
rpm: FORCE rpm: include/config/kernel.release FORCE
$(Q)$(MAKE) $(build)=$(package-dir) $@ $(Q)$(MAKE) $(build)=$(package-dir) $@
@ -1077,7 +1088,7 @@ else # KBUILD_EXTMOD
# make M=dir modules Make all modules in specified dir # make M=dir modules Make all modules in specified dir
# make M=dir Same as 'make M=dir modules' # make M=dir Same as 'make M=dir modules'
# make M=dir modules_install # make M=dir modules_install
# Install the modules build in the module directory # Install the modules built in the module directory
# Assumes install directory is already created # Assumes install directory is already created
# We are always building modules # We are always building modules
@ -1136,7 +1147,7 @@ clean: rm-dirs := $(MODVERDIR)
clean: $(clean-dirs) clean: $(clean-dirs)
$(call cmd,rmdirs) $(call cmd,rmdirs)
@find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \ @find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \ \( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
-type f -print | xargs rm -f -type f -print | xargs rm -f
@ -1175,31 +1186,41 @@ else
ALLINCLUDE_ARCHS := $(ARCH) ALLINCLUDE_ARCHS := $(ARCH)
endif endif
else else
#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour. #Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behavour.
ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS) ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
endif endif
ALLSOURCE_ARCHS := $(ARCH) ALLSOURCE_ARCHS := $(ARCH)
define all-sources define find-sources
( find $(__srctree) $(RCS_FIND_IGNORE) \ ( find $(__srctree) $(RCS_FIND_IGNORE) \
\( -name include -o -name arch \) -prune -o \ \( -name include -o -name arch \) -prune -o \
-name '*.[chS]' -print; \ -name $1 -print; \
for ARCH in $(ALLSOURCE_ARCHS) ; do \ for ARCH in $(ALLSOURCE_ARCHS) ; do \
find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \ find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print; \ -name $1 -print; \
done ; \ done ; \
find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \ find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print; \ -name $1 -print; \
find $(__srctree)include $(RCS_FIND_IGNORE) \ find $(__srctree)include $(RCS_FIND_IGNORE) \
\( -name config -o -name 'asm-*' \) -prune \ \( -name config -o -name 'asm-*' \) -prune \
-o -name '*.[chS]' -print; \ -o -name $1 -print; \
for ARCH in $(ALLINCLUDE_ARCHS) ; do \ for ARCH in $(ALLINCLUDE_ARCHS) ; do \
find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \ find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print; \ -name $1 -print; \
done ; \ done ; \
find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
-name '*.[chS]' -print ) -name $1 -print )
endef
define all-sources
$(call find-sources,'*.[chS]')
endef
define all-kconfigs
$(call find-sources,'Kconfig*')
endef
define all-defconfigs
$(call find-sources,'defconfig')
endef endef
quiet_cmd_cscope-file = FILELST cscope.files quiet_cmd_cscope-file = FILELST cscope.files
@ -1219,7 +1240,13 @@ define cmd_TAGS
echo "-I __initdata,__exitdata,__acquires,__releases \ echo "-I __initdata,__exitdata,__acquires,__releases \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
--extra=+f --c-kinds=+px"`; \ --extra=+f --c-kinds=+px"`; \
$(all-sources) | xargs etags $$ETAGSF -a $(all-sources) | xargs etags $$ETAGSF -a; \
if test "x$$ETAGSF" = x; then \
$(all-kconfigs) | xargs etags -a \
--regex='/^config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \
$(all-defconfigs) | xargs etags -a \
--regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \
fi
endef endef
TAGS: FORCE TAGS: FORCE
@ -1259,14 +1286,14 @@ namespacecheck:
endif #ifeq ($(config-targets),1) endif #ifeq ($(config-targets),1)
endif #ifeq ($(mixed-targets),1) endif #ifeq ($(mixed-targets),1)
PHONY += checkstack PHONY += checkstack kernelrelease kernelversion
checkstack: checkstack:
$(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \ $(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
$(PERL) $(src)/scripts/checkstack.pl $(ARCH) $(PERL) $(src)/scripts/checkstack.pl $(ARCH)
kernelrelease: kernelrelease:
$(if $(wildcard .kernelrelease), $(Q)echo $(KERNELRELEASE), \ $(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \
$(error kernelrelease not valid - run 'make *config' to update it)) $(error kernelrelease not valid - run 'make prepare' to update it))
kernelversion: kernelversion:
@echo $(KERNELVERSION) @echo $(KERNELVERSION)
@ -1301,6 +1328,8 @@ endif
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
%.o: %.S prepare scripts FORCE %.o: %.S prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
%.symtypes: %.c prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
# Modules # Modules
/ %/: prepare scripts FORCE / %/: prepare scripts FORCE

View File

@ -177,7 +177,7 @@ boot := arch/arm/boot
# them changed. We use .arch to indicate when they were updated # them changed. We use .arch to indicate when they were updated
# last, otherwise make uses the target directory mtime. # last, otherwise make uses the target directory mtime.
include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/MARKER include/asm-arm/.arch: $(wildcard include/config/arch/*.h) include/config/auto.conf
@echo ' SYMLINK include/asm-arm/arch -> include/asm-arm/$(INCDIR)' @echo ' SYMLINK include/asm-arm/arch -> include/asm-arm/$(INCDIR)'
ifneq ($(KBUILD_SRC),) ifneq ($(KBUILD_SRC),)
$(Q)mkdir -p include/asm-arm $(Q)mkdir -p include/asm-arm

View File

@ -147,7 +147,7 @@ endif
# them changed. We use .arch and .mach to indicate when they were # them changed. We use .arch and .mach to indicate when they were
# updated last, otherwise make uses the target directory mtime. # updated last, otherwise make uses the target directory mtime.
include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/auto.conf
@echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)' @echo ' SYMLINK include/asm-sh/cpu -> include/asm-sh/$(cpuincdir-y)'
$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
$(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu $(Q)ln -fsn $(incdir-prefix)$(cpuincdir-y) include/asm-sh/cpu
@ -157,7 +157,7 @@ include/asm-sh/.cpu: $(wildcard include/config/cpu/*.h) include/config/MARKER
# don't, just reference the parent directory so the semantics are # don't, just reference the parent directory so the semantics are
# kept roughly the same. # kept roughly the same.
include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/MARKER include/asm-sh/.mach: $(wildcard include/config/sh/*.h) include/config/auto.conf
@echo -n ' SYMLINK include/asm-sh/mach -> ' @echo -n ' SYMLINK include/asm-sh/mach -> '
$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi $(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
$(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \ $(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \

View File

@ -71,7 +71,7 @@ archprepare: $(archinc)/.platform
# Update machine cpu and platform symlinks if something which affects # Update machine cpu and platform symlinks if something which affects
# them changed. # them changed.
$(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/MARKER $(archinc)/.platform: $(wildcard include/config/arch/*.h) include/config/auto.conf
@echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)' @echo ' SYMLINK $(archinc)/xtensa/config -> $(archinc)/xtensa/config-$(CPU)'
$(Q)mkdir -p $(archinc) $(Q)mkdir -p $(archinc)
$(Q)mkdir -p $(archinc)/xtensa $(Q)mkdir -p $(archinc)/xtensa

View File

@ -86,14 +86,14 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
block and "-2" means the penultimate block. block and "-2" means the penultimate block.
config MTD_REDBOOT_PARTS_UNALLOCATED config MTD_REDBOOT_PARTS_UNALLOCATED
bool " Include unallocated flash regions" bool "Include unallocated flash regions"
depends on MTD_REDBOOT_PARTS depends on MTD_REDBOOT_PARTS
help help
If you need to register each unallocated flash region as a MTD If you need to register each unallocated flash region as a MTD
'partition', enable this option. 'partition', enable this option.
config MTD_REDBOOT_PARTS_READONLY config MTD_REDBOOT_PARTS_READONLY
bool " Force read-only for RedBoot system images" bool "Force read-only for RedBoot system images"
depends on MTD_REDBOOT_PARTS depends on MTD_REDBOOT_PARTS
help help
If you need to force read-only for 'RedBoot', 'RedBoot Config' and If you need to force read-only for 'RedBoot', 'RedBoot Config' and

View File

@ -212,7 +212,7 @@ config MTD_NETtel
Support for flash chips on NETtel/SecureEdge/SnapGear boards. Support for flash chips on NETtel/SecureEdge/SnapGear boards.
config MTD_ALCHEMY config MTD_ALCHEMY
tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support' tristate "AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support"
depends on SOC_AU1X00 depends on SOC_AU1X00
help help
Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards

View File

@ -1169,7 +1169,7 @@ config SCSI_NCR_Q720
you do not have this SCSI card, so say N. you do not have this SCSI card, so say N.
config SCSI_NCR53C8XX_DEFAULT_TAGS config SCSI_NCR53C8XX_DEFAULT_TAGS
int " default tagged command queue depth" int "default tagged command queue depth"
depends on SCSI_ZALON || SCSI_NCR_Q720 depends on SCSI_ZALON || SCSI_NCR_Q720
default "8" default "8"
---help--- ---help---
@ -1195,7 +1195,7 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS
There is no safe option other than using good SCSI devices. There is no safe option other than using good SCSI devices.
config SCSI_NCR53C8XX_MAX_TAGS config SCSI_NCR53C8XX_MAX_TAGS
int " maximum number of queued commands" int "maximum number of queued commands"
depends on SCSI_ZALON || SCSI_NCR_Q720 depends on SCSI_ZALON || SCSI_NCR_Q720
default "32" default "32"
---help--- ---help---
@ -1212,7 +1212,7 @@ config SCSI_NCR53C8XX_MAX_TAGS
There is no safe option and the default answer is recommended. There is no safe option and the default answer is recommended.
config SCSI_NCR53C8XX_SYNC config SCSI_NCR53C8XX_SYNC
int " synchronous transfers frequency in MHz" int "synchronous transfers frequency in MHz"
depends on SCSI_ZALON || SCSI_NCR_Q720 depends on SCSI_ZALON || SCSI_NCR_Q720
default "20" default "20"
---help--- ---help---
@ -1246,7 +1246,7 @@ config SCSI_NCR53C8XX_SYNC
terminations and SCSI conformant devices. terminations and SCSI conformant devices.
config SCSI_NCR53C8XX_PROFILE config SCSI_NCR53C8XX_PROFILE
bool " enable profiling" bool "enable profiling"
depends on SCSI_ZALON || SCSI_NCR_Q720 depends on SCSI_ZALON || SCSI_NCR_Q720
help help
This option allows you to enable profiling information gathering. This option allows you to enable profiling information gathering.
@ -1257,7 +1257,7 @@ config SCSI_NCR53C8XX_PROFILE
The normal answer therefore is N. The normal answer therefore is N.
config SCSI_NCR53C8XX_NO_DISCONNECT config SCSI_NCR53C8XX_NO_DISCONNECT
bool " not allow targets to disconnect" bool "not allow targets to disconnect"
depends on (SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0 depends on (SCSI_ZALON || SCSI_NCR_Q720) && SCSI_NCR53C8XX_DEFAULT_TAGS=0
help help
This option is only provided for safety if you suspect some SCSI This option is only provided for safety if you suspect some SCSI

14
include/linux/license.h Normal file
View File

@ -0,0 +1,14 @@
#ifndef __LICENSE_H
#define __LICENSE_H
static inline int license_is_gpl_compatible(const char *license)
{
return (strcmp(license, "GPL") == 0
|| strcmp(license, "GPL v2") == 0
|| strcmp(license, "GPL and additional rights") == 0
|| strcmp(license, "Dual BSD/GPL") == 0
|| strcmp(license, "Dual MIT/GPL") == 0
|| strcmp(license, "Dual MPL/GPL") == 0);
}
#endif

View File

@ -1,3 +1,11 @@
config DEFCONFIG_LIST
string
option defconfig_list
default "/lib/modules/$UNAME_RELEASE/.config"
default "/etc/kernel-config"
default "/boot/config-$UNAME_RELEASE"
default "arch/$ARCH/defconfig"
menu "Code maturity level options" menu "Code maturity level options"
config EXPERIMENTAL config EXPERIMENTAL

View File

@ -44,6 +44,7 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <linux/license.h>
#if 0 #if 0
#define DEBUGP printk #define DEBUGP printk
@ -1251,16 +1252,6 @@ static void layout_sections(struct module *mod,
} }
} }
static inline int license_is_gpl_compatible(const char *license)
{
return (strcmp(license, "GPL") == 0
|| strcmp(license, "GPL v2") == 0
|| strcmp(license, "GPL and additional rights") == 0
|| strcmp(license, "Dual BSD/GPL") == 0
|| strcmp(license, "Dual MIT/GPL") == 0
|| strcmp(license, "Dual MPL/GPL") == 0);
}
static void set_license(struct module *mod, const char *license) static void set_license(struct module *mod, const char *license)
{ {
if (!license) if (!license)

View File

@ -12,6 +12,11 @@ space := $(empty) $(empty)
# contain a comma # contain a comma
depfile = $(subst $(comma),_,$(@D)/.$(@F).d) depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
###
# basetarget equals the filename of the target with no extension.
# So 'foo/bar.o' becomes 'bar'
basetarget = $(basename $(notdir $@))
### ###
# Escape single quote for use in echo statements # Escape single quote for use in echo statements
escsq = $(subst $(squote),'\$(squote)',$1) escsq = $(subst $(squote),'\$(squote)',$1)

View File

@ -8,7 +8,7 @@ PHONY := __build
__build: __build:
# Read .config if it exist, otherwise ignore # Read .config if it exist, otherwise ignore
-include .config -include include/config/auto.conf
include scripts/Kbuild.include include scripts/Kbuild.include
@ -117,7 +117,7 @@ $(real-objs-m:.o=.lst): quiet_modtag := [M]
$(obj-m) : quiet_modtag := [M] $(obj-m) : quiet_modtag := [M]
# Default for not multi-part modules # Default for not multi-part modules
modname = $(*F) modname = $(basetarget)
$(multi-objs-m) : modname = $(modname-multi) $(multi-objs-m) : modname = $(modname-multi)
$(multi-objs-m:.o=.i) : modname = $(modname-multi) $(multi-objs-m:.o=.i) : modname = $(modname-multi)
@ -140,6 +140,15 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
%.i: %.c FORCE %.i: %.c FORCE
$(call if_changed_dep,cc_i_c) $(call if_changed_dep,cc_i_c)
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
cmd_cc_symtypes_c = \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \
| $(GENKSYMS) -T $@ >/dev/null; \
test -s $@ || rm -f $@
%.symtypes : %.c FORCE
$(call if_changed_dep,cc_symtypes_c)
# C (.c) files # C (.c) files
# The C file is compiled and updated dependency information is generated. # The C file is compiled and updated dependency information is generated.
# (See cmd_cc_o_c + relevant part of rule_cc_o_c) # (See cmd_cc_o_c + relevant part of rule_cc_o_c)
@ -166,7 +175,8 @@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
cmd_modversions = \ cmd_modversions = \
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
$(CPP) -D__GENKSYMS__ $(c_flags) $< \ $(CPP) -D__GENKSYMS__ $(c_flags) $< \
| $(GENKSYMS) -a $(ARCH) \ | $(GENKSYMS) $(if $(KBUILD_SYMTYPES), \
-T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \
> $(@D)/.tmp_$(@F:.o=.ver); \ > $(@D)/.tmp_$(@F:.o=.ver); \
\ \
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \

View File

@ -33,8 +33,8 @@
__hostprogs := $(sort $(hostprogs-y)$(hostprogs-m)) __hostprogs := $(sort $(hostprogs-y)$(hostprogs-m))
# hostprogs-y := tools/build may have been specified. Retreive directory # hostprogs-y := tools/build may have been specified. Retreive directory
obj-dirs += $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f)))) host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs)))) host-objdirs := $(strip $(sort $(filter-out ./,$(host-objdirs))))
# C code # C code
@ -73,13 +73,17 @@ host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs)) host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
host-cshlib := $(addprefix $(obj)/,$(host-cshlib)) host-cshlib := $(addprefix $(obj)/,$(host-cshlib))
host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs)) host-cshobjs := $(addprefix $(obj)/,$(host-cshobjs))
obj-dirs := $(addprefix $(obj)/,$(obj-dirs)) host-objdirs := $(addprefix $(obj)/,$(host-objdirs))
obj-dirs += $(host-objdirs)
##### #####
# Handle options to gcc. Support building with separate output directory # Handle options to gcc. Support building with separate output directory
_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o) _hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o) $(HOSTCFLAGS_$(basetarget).o)
_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
$(HOSTCXXFLAGS_$(basetarget).o)
ifeq ($(KBUILD_SRC),) ifeq ($(KBUILD_SRC),)
__hostc_flags = $(_hostc_flags) __hostc_flags = $(_hostc_flags)

View File

@ -82,12 +82,12 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
# than one module. In that case KBUILD_MODNAME will be set to foo_bar, # than one module. In that case KBUILD_MODNAME will be set to foo_bar,
# where foo and bar are the name of the modules. # where foo and bar are the name of the modules.
name-fix = $(subst $(comma),_,$(subst -,_,$1)) name-fix = $(subst $(comma),_,$(subst -,_,$1))
basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(*F)))" basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
modname_flags = $(if $(filter 1,$(words $(modname))),\ modname_flags = $(if $(filter 1,$(words $(modname))),\
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))") -D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) _c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(basetarget).o)
_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o) _a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
_cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F)) _cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F))
# If building the kernel in a separate objtree expand all occurrences # If building the kernel in a separate objtree expand all occurrences

View File

@ -17,7 +17,7 @@ __modinst: $(modules)
@: @:
quiet_cmd_modules_install = INSTALL $@ quiet_cmd_modules_install = INSTALL $@
cmd_modules_install = mkdir -p $(2); cp $@ $(2) cmd_modules_install = mkdir -p $(2); cp $@ $(2) ; $(mod_strip_cmd) $(2)/$(notdir $@)
# Modules built outside the kernel source tree go into extra by default # Modules built outside the kernel source tree go into extra by default
INSTALL_MOD_DIR ?= extra INSTALL_MOD_DIR ?= extra

View File

@ -35,7 +35,7 @@
PHONY := _modpost PHONY := _modpost
_modpost: __modpost _modpost: __modpost
include .config include include/config/auto.conf
include scripts/Kbuild.include include scripts/Kbuild.include
include scripts/Makefile.lib include scripts/Makefile.lib
@ -72,7 +72,7 @@ $(modules:.ko=.mod.c): __modpost ;
# Step 5), compile all *.mod.c files # Step 5), compile all *.mod.c files
# modname is set to make c_flags define KBUILD_MODNAME # modname is set to make c_flags define KBUILD_MODNAME
modname = $(*F) modname = $(basetarget)
quiet_cmd_cc_o_c = CC $@ quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \ cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \

View File

@ -1,17 +1,15 @@
### ###
# Makefile.basic list the most basic programs used during the build process. # Makefile.basic list the most basic programs used during the build process.
# The programs listed herein is what is needed to do the basic stuff, # The programs listed herein is what is needed to do the basic stuff,
# such as splitting .config and fix dependency file. # such as fix dependency file.
# This initial step is needed to avoid files to be recompiled # This initial step is needed to avoid files to be recompiled
# when kernel configuration changes (which is what happens when # when kernel configuration changes (which is what happens when
# .config is included by main Makefile. # .config is included by main Makefile.
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# fixdep: Used to generate dependency information during build process # fixdep: Used to generate dependency information during build process
# split-include: Divide all config symbols up in a number of files in
# include/config/...
# docproc: Used in Documentation/docbook # docproc: Used in Documentation/docbook
hostprogs-y := fixdep split-include docproc hostprogs-y := fixdep docproc
always := $(hostprogs-y) always := $(hostprogs-y)
# fixdep is needed to compile other host programs # fixdep is needed to compile other host programs

View File

@ -1,226 +0,0 @@
/*
* split-include.c
*
* Copyright abandoned, Michael Chastain, <mailto:mec@shout.net>.
* This is a C version of syncdep.pl by Werner Almesberger.
*
* This program takes autoconf.h as input and outputs a directory full
* of one-line include files, merging onto the old values.
*
* Think of the configuration options as key-value pairs. Then there
* are five cases:
*
* key old value new value action
*
* KEY-1 VALUE-1 VALUE-1 leave file alone
* KEY-2 VALUE-2A VALUE-2B write VALUE-2B into file
* KEY-3 - VALUE-3 write VALUE-3 into file
* KEY-4 VALUE-4 - write an empty file
* KEY-5 (empty) - leave old empty file alone
*/
#include <sys/stat.h>
#include <sys/types.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define ERROR_EXIT(strExit) \
{ \
const int errnoSave = errno; \
fprintf(stderr, "%s: ", str_my_name); \
errno = errnoSave; \
perror((strExit)); \
exit(1); \
}
int main(int argc, const char * argv [])
{
const char * str_my_name;
const char * str_file_autoconf;
const char * str_dir_config;
FILE * fp_config;
FILE * fp_target;
FILE * fp_find;
int buffer_size;
char * line;
char * old_line;
char * list_target;
char * ptarget;
struct stat stat_buf;
/* Check arg count. */
if (argc != 3)
{
fprintf(stderr, "%s: wrong number of arguments.\n", argv[0]);
exit(1);
}
str_my_name = argv[0];
str_file_autoconf = argv[1];
str_dir_config = argv[2];
/* Find a buffer size. */
if (stat(str_file_autoconf, &stat_buf) != 0)
ERROR_EXIT(str_file_autoconf);
buffer_size = 2 * stat_buf.st_size + 4096;
/* Allocate buffers. */
if ( (line = malloc(buffer_size)) == NULL
|| (old_line = malloc(buffer_size)) == NULL
|| (list_target = malloc(buffer_size)) == NULL )
ERROR_EXIT(str_file_autoconf);
/* Open autoconfig file. */
if ((fp_config = fopen(str_file_autoconf, "r")) == NULL)
ERROR_EXIT(str_file_autoconf);
/* Make output directory if needed. */
if (stat(str_dir_config, &stat_buf) != 0)
{
if (mkdir(str_dir_config, 0755) != 0)
ERROR_EXIT(str_dir_config);
}
/* Change to output directory. */
if (chdir(str_dir_config) != 0)
ERROR_EXIT(str_dir_config);
/* Put initial separator into target list. */
ptarget = list_target;
*ptarget++ = '\n';
/* Read config lines. */
while (fgets(line, buffer_size, fp_config))
{
const char * str_config;
int is_same;
int itarget;
if (line[0] != '#')
continue;
if ((str_config = strstr(line, "CONFIG_")) == NULL)
continue;
/* Make the output file name. */
str_config += sizeof("CONFIG_") - 1;
for (itarget = 0; !isspace(str_config[itarget]); itarget++)
{
int c = (unsigned char) str_config[itarget];
if (isupper(c)) c = tolower(c);
if (c == '_') c = '/';
ptarget[itarget] = c;
}
ptarget[itarget++] = '.';
ptarget[itarget++] = 'h';
ptarget[itarget++] = '\0';
/* Check for existing file. */
is_same = 0;
if ((fp_target = fopen(ptarget, "r")) != NULL)
{
fgets(old_line, buffer_size, fp_target);
if (fclose(fp_target) != 0)
ERROR_EXIT(ptarget);
if (!strcmp(line, old_line))
is_same = 1;
}
if (!is_same)
{
/* Auto-create directories. */
int islash;
for (islash = 0; islash < itarget; islash++)
{
if (ptarget[islash] == '/')
{
ptarget[islash] = '\0';
if (stat(ptarget, &stat_buf) != 0
&& mkdir(ptarget, 0755) != 0)
ERROR_EXIT( ptarget );
ptarget[islash] = '/';
}
}
/* Write the file. */
if ((fp_target = fopen(ptarget, "w" )) == NULL)
ERROR_EXIT(ptarget);
fputs(line, fp_target);
if (ferror(fp_target) || fclose(fp_target) != 0)
ERROR_EXIT(ptarget);
}
/* Update target list */
ptarget += itarget;
*(ptarget-1) = '\n';
}
/*
* Close autoconfig file.
* Terminate the target list.
*/
if (fclose(fp_config) != 0)
ERROR_EXIT(str_file_autoconf);
*ptarget = '\0';
/*
* Fix up existing files which have no new value.
* This is Case 4 and Case 5.
*
* I re-read the tree and filter it against list_target.
* This is crude. But it avoids data copies. Also, list_target
* is compact and contiguous, so it easily fits into cache.
*
* Notice that list_target contains strings separated by \n,
* with a \n before the first string and after the last.
* fgets gives the incoming names a terminating \n.
* So by having an initial \n, strstr will find exact matches.
*/
fp_find = popen("find * -type f -name \"*.h\" -print", "r");
if (fp_find == 0)
ERROR_EXIT( "find" );
line[0] = '\n';
while (fgets(line+1, buffer_size, fp_find))
{
if (strstr(list_target, line) == NULL)
{
/*
* This is an old file with no CONFIG_* flag in autoconf.h.
*/
/* First strip the \n. */
line[strlen(line)-1] = '\0';
/* Grab size. */
if (stat(line+1, &stat_buf) != 0)
ERROR_EXIT(line);
/* If file is not empty, make it empty and give it a fresh date. */
if (stat_buf.st_size != 0)
{
if ((fp_target = fopen(line+1, "w")) == NULL)
ERROR_EXIT(line);
if (fclose(fp_target) != 0)
ERROR_EXIT(line);
}
}
}
if (pclose(fp_find) != 0)
ERROR_EXIT("find");
return 0;
}

169
scripts/export_report.pl Normal file
View File

@ -0,0 +1,169 @@
#!/usr/bin/perl -w
#
# (C) Copyright IBM Corporation 2006.
# Released under GPL v2.
# Author : Ram Pai (linuxram@us.ibm.com)
#
# Usage: export_report.pl -k Module.symvers [-o report_file ] -f *.mod.c
#
use Getopt::Std;
use strict;
sub numerically {
my $no1 = (split /\s+/, $a)[1];
my $no2 = (split /\s+/, $b)[1];
return $no1 <=> $no2;
}
sub alphabetically {
my ($module1, $value1) = @{$a};
my ($module2, $value2) = @{$b};
return $value1 <=> $value2 || $module2 cmp $module1;
}
sub print_depends_on {
my ($href) = @_;
print "\n";
while (my ($mod, $list) = each %$href) {
print "\t$mod:\n";
foreach my $sym (sort numerically @{$list}) {
my ($symbol, $no) = split /\s+/, $sym;
printf("\t\t%-25s\t%-25d\n", $symbol, $no);
}
print "\n";
}
print "\n";
print "~"x80 , "\n";
}
sub usage {
print "Usage: @_ -h -k Module.symvers [ -o outputfile ] \n",
"\t-f: treat all the non-option argument as .mod.c files. ",
"Recommend using this as the last option\n",
"\t-h: print detailed help\n",
"\t-k: the path to Module.symvers file. By default uses ",
"the file from the current directory\n",
"\t-o outputfile: output the report to outputfile\n";
exit 0;
}
sub collectcfiles {
my @file = `cat .tmp_versions/*.mod | grep '.*\.ko\$'`;
@file = grep {s/\.ko/.mod.c/} @file;
chomp @file;
return @file;
}
my (%SYMBOL, %MODULE, %opt, @allcfiles);
if (not getopts('hk:o:f',\%opt) or defined $opt{'h'}) {
usage($0);
}
if (defined $opt{'f'}) {
@allcfiles = @ARGV;
} else {
@allcfiles = collectcfiles();
}
if (not defined $opt{'k'}) {
$opt{'k'} = "Module.symvers";
}
unless (open(MODULE_SYMVERS, $opt{'k'})) {
die "Sorry, cannot open $opt{'k'}: $!\n";
}
if (defined $opt{'o'}) {
unless (open(OUTPUT_HANDLE, ">$opt{'o'}")) {
die "Sorry, cannot open $opt{'o'} $!\n";
}
select OUTPUT_HANDLE;
}
#
# collect all the symbols and their attributes from the
# Module.symvers file
#
while ( <MODULE_SYMVERS> ) {
chomp;
my (undef, $symbol, $module, $gpl) = split;
$SYMBOL { $symbol } = [ $module , "0" , $symbol, $gpl];
}
close(MODULE_SYMVERS);
#
# collect the usage count of each symbol.
#
foreach my $thismod (@allcfiles) {
unless (open(MODULE_MODULE, $thismod)) {
print "Sorry, cannot open $thismod: $!\n";
next;
}
my $state=0;
while ( <MODULE_MODULE> ) {
chomp;
if ($state eq 0) {
$state = 1 if ($_ =~ /static const struct modversion_info/);
next;
}
if ($state eq 1) {
$state = 2 if ($_ =~ /__attribute__\(\(section\("__versions"\)\)\)/);
next;
}
if ($state eq 2) {
if ( $_ !~ /0x[0-9a-f]{7,8},/ ) {
next;
}
my $sym = (split /([,"])/,)[4];
my ($module, $value, $symbol, $gpl) = @{$SYMBOL{$sym}};
$SYMBOL{ $sym } = [ $module, $value+1, $symbol, $gpl];
push(@{$MODULE{$thismod}} , $sym);
}
}
if ($state ne 2) {
print "WARNING:$thismod is not built with CONFIG_MODVERSION enabled\n";
}
close(MODULE_MODULE);
}
print "\tThis file reports the exported symbols usage patterns by in-tree\n",
"\t\t\t\tmodules\n";
printf("%s\n\n\n","x"x80);
printf("\t\t\t\tINDEX\n\n\n");
printf("SECTION 1: Usage counts of all exported symbols\n");
printf("SECTION 2: List of modules and the exported symbols they use\n");
printf("%s\n\n\n","x"x80);
printf("SECTION 1:\tThe exported symbols and their usage count\n\n");
printf("%-25s\t%-25s\t%-5s\t%-25s\n", "Symbol", "Module", "Usage count",
"export type");
#
# print the list of unused exported symbols
#
foreach my $list (sort alphabetically values(%SYMBOL)) {
my ($module, $value, $symbol, $gpl) = @{$list};
printf("%-25s\t%-25s\t%-10s\t", $symbol, $module, $value);
if (defined $gpl) {
printf("%-25s\n",$gpl);
} else {
printf("\n");
}
}
printf("%s\n\n\n","x"x80);
printf("SECTION 2:\n\tThis section reports export-symbol-usage of in-kernel
modules. Each module lists the modules, and the symbols from that module that
it uses. Each listed symbol reports the number of modules using it\n");
print "~"x80 , "\n";
while (my ($thismod, $list) = each %MODULE) {
my %depends;
$thismod =~ s/\.mod\.c/.ko/;
print "\t\t\t$thismod\n";
foreach my $symbol (@{$list}) {
my ($module, $value, undef, $gpl) = @{$SYMBOL{$symbol}};
push (@{$depends{"$module"}}, "$symbol $value");
}
print_depends_on(\%depends);
}

View File

@ -42,7 +42,7 @@ static FILE *debugfile;
int cur_line = 1; int cur_line = 1;
char *cur_filename; char *cur_filename;
static int flag_debug, flag_dump_defs, flag_warnings; static int flag_debug, flag_dump_defs, flag_dump_types, flag_warnings;
static const char *arch = ""; static const char *arch = "";
static const char *mod_prefix = ""; static const char *mod_prefix = "";
@ -50,6 +50,7 @@ static int errors;
static int nsyms; static int nsyms;
static struct symbol *expansion_trail; static struct symbol *expansion_trail;
static struct symbol *visited_symbols;
static const char *const symbol_type_name[] = { static const char *const symbol_type_name[] = {
"normal", "typedef", "enum", "struct", "union" "normal", "typedef", "enum", "struct", "union"
@ -176,6 +177,7 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
sym->type = type; sym->type = type;
sym->defn = defn; sym->defn = defn;
sym->expansion_trail = NULL; sym->expansion_trail = NULL;
sym->visited = NULL;
sym->is_extern = is_extern; sym->is_extern = is_extern;
sym->hash_next = symtab[h]; sym->hash_next = symtab[h];
@ -236,26 +238,11 @@ static int equal_list(struct string_list *a, struct string_list *b)
static void print_node(FILE * f, struct string_list *list) static void print_node(FILE * f, struct string_list *list)
{ {
switch (list->tag) { if (list->tag != SYM_NORMAL) {
case SYM_STRUCT: putc(symbol_type_name[list->tag][0], f);
putc('s', f);
goto printit;
case SYM_UNION:
putc('u', f);
goto printit;
case SYM_ENUM:
putc('e', f);
goto printit;
case SYM_TYPEDEF:
putc('t', f);
goto printit;
printit:
putc('#', f); putc('#', f);
case SYM_NORMAL:
fputs(list->string, f);
break;
} }
fputs(list->string, f);
} }
static void print_list(FILE * f, struct string_list *list) static void print_list(FILE * f, struct string_list *list)
@ -287,9 +274,9 @@ static void print_list(FILE * f, struct string_list *list)
} }
} }
static unsigned long expand_and_crc_list(struct string_list *list, static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
unsigned long crc)
{ {
struct string_list *list = sym->defn;
struct string_list **e, **b; struct string_list **e, **b;
struct string_list *tmp, **tmp2; struct string_list *tmp, **tmp2;
int elem = 1; int elem = 1;
@ -332,7 +319,7 @@ static unsigned long expand_and_crc_list(struct string_list *list,
} else { } else {
subsym->expansion_trail = expansion_trail; subsym->expansion_trail = expansion_trail;
expansion_trail = subsym; expansion_trail = subsym;
crc = expand_and_crc_list(subsym->defn, crc); crc = expand_and_crc_sym(subsym, crc);
} }
break; break;
@ -382,12 +369,22 @@ static unsigned long expand_and_crc_list(struct string_list *list,
} else { } else {
subsym->expansion_trail = expansion_trail; subsym->expansion_trail = expansion_trail;
expansion_trail = subsym; expansion_trail = subsym;
crc = expand_and_crc_list(subsym->defn, crc); crc = expand_and_crc_sym(subsym, crc);
} }
break; break;
} }
} }
{
static struct symbol **end = &visited_symbols;
if (!sym->visited) {
*end = sym;
end = &sym->visited;
sym->visited = (struct symbol *)-1L;
}
}
return crc; return crc;
} }
@ -406,7 +403,7 @@ void export_symbol(const char *name)
expansion_trail = (struct symbol *)-1L; expansion_trail = (struct symbol *)-1L;
crc = expand_and_crc_list(sym->defn, 0xffffffff) ^ 0xffffffff; crc = expand_and_crc_sym(sym, 0xffffffff) ^ 0xffffffff;
sym = expansion_trail; sym = expansion_trail;
while (sym != (struct symbol *)-1L) { while (sym != (struct symbol *)-1L) {
@ -464,6 +461,7 @@ static void genksyms_usage(void)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
FILE *dumpfile = NULL;
int o; int o;
#ifdef __GNU_LIBRARY__ #ifdef __GNU_LIBRARY__
@ -473,15 +471,16 @@ int main(int argc, char **argv)
{"warnings", 0, 0, 'w'}, {"warnings", 0, 0, 'w'},
{"quiet", 0, 0, 'q'}, {"quiet", 0, 0, 'q'},
{"dump", 0, 0, 'D'}, {"dump", 0, 0, 'D'},
{"dump-types", 1, 0, 'T'},
{"version", 0, 0, 'V'}, {"version", 0, 0, 'V'},
{"help", 0, 0, 'h'}, {"help", 0, 0, 'h'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
while ((o = getopt_long(argc, argv, "a:dwqVDk:p:", while ((o = getopt_long(argc, argv, "a:dwqVDT:k:p:",
&long_opts[0], NULL)) != EOF) &long_opts[0], NULL)) != EOF)
#else /* __GNU_LIBRARY__ */ #else /* __GNU_LIBRARY__ */
while ((o = getopt(argc, argv, "a:dwqVDk:p:")) != EOF) while ((o = getopt(argc, argv, "a:dwqVDT:k:p:")) != EOF)
#endif /* __GNU_LIBRARY__ */ #endif /* __GNU_LIBRARY__ */
switch (o) { switch (o) {
case 'a': case 'a':
@ -502,6 +501,14 @@ int main(int argc, char **argv)
case 'D': case 'D':
flag_dump_defs = 1; flag_dump_defs = 1;
break; break;
case 'T':
flag_dump_types = 1;
dumpfile = fopen(optarg, "w");
if (!dumpfile) {
perror(optarg);
return 1;
}
break;
case 'h': case 'h':
genksyms_usage(); genksyms_usage();
return 0; return 0;
@ -524,6 +531,24 @@ int main(int argc, char **argv)
yyparse(); yyparse();
if (flag_dump_types && visited_symbols) {
while (visited_symbols != (struct symbol *)-1L) {
struct symbol *sym = visited_symbols;
if (sym->type != SYM_NORMAL) {
putc(symbol_type_name[sym->type][0], dumpfile);
putc('#', dumpfile);
}
fputs(sym->name, dumpfile);
putc(' ', dumpfile);
print_list(dumpfile, sym->defn);
putc('\n', dumpfile);
visited_symbols = sym->visited;
sym->visited = NULL;
}
}
if (flag_debug) { if (flag_debug) {
fprintf(debugfile, "Hash table occupancy %d/%d = %g\n", fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
nsyms, HASH_BUCKETS, nsyms, HASH_BUCKETS,

View File

@ -41,6 +41,7 @@ struct symbol {
enum symbol_type type; enum symbol_type type;
struct string_list *defn; struct string_list *defn;
struct symbol *expansion_trail; struct symbol *expansion_trail;
struct symbol *visited;
int is_extern; int is_extern;
}; };

View File

@ -2023,7 +2023,7 @@ repeat:
break; break;
default: default:
abort(); exit(1);
} }
fini: fini:

View File

@ -392,7 +392,7 @@ repeat:
break; break;
default: default:
abort(); exit(1);
} }
fini: fini:

View File

@ -539,6 +539,7 @@ int main(int ac, char **av)
name = av[i]; name = av[i];
if (!name) { if (!name) {
printf(_("%s: Kconfig file missing\n"), av[0]); printf(_("%s: Kconfig file missing\n"), av[0]);
exit(1);
} }
conf_parse(name); conf_parse(name);
//zconfdump(stdout); //zconfdump(stdout);
@ -573,7 +574,7 @@ int main(int ac, char **av)
case set_random: case set_random:
name = getenv("KCONFIG_ALLCONFIG"); name = getenv("KCONFIG_ALLCONFIG");
if (name && !stat(name, &tmpstat)) { if (name && !stat(name, &tmpstat)) {
conf_read_simple(name); conf_read_simple(name, S_DEF_USER);
break; break;
} }
switch (input_mode) { switch (input_mode) {
@ -584,9 +585,9 @@ int main(int ac, char **av)
default: break; default: break;
} }
if (!stat(name, &tmpstat)) if (!stat(name, &tmpstat))
conf_read_simple(name); conf_read_simple(name, S_DEF_USER);
else if (!stat("all.config", &tmpstat)) else if (!stat("all.config", &tmpstat))
conf_read_simple("all.config"); conf_read_simple("all.config", S_DEF_USER);
break; break;
default: default:
break; break;
@ -599,7 +600,15 @@ int main(int ac, char **av)
input_mode = ask_silent; input_mode = ask_silent;
valid_stdin = 1; valid_stdin = 1;
} }
} } else if (sym_change_count) {
name = getenv("KCONFIG_NOSILENTUPDATE");
if (name && *name) {
fprintf(stderr, _("\n*** Kernel configuration requires explicit update.\n\n"));
return 1;
}
} else
goto skip_check;
do { do {
conf_cnt = 0; conf_cnt = 0;
check_conf(&rootmenu); check_conf(&rootmenu);
@ -608,5 +617,11 @@ int main(int ac, char **av)
fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
return 1; return 1;
} }
skip_check:
if (input_mode == ask_silent && conf_write_autoconf()) {
fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n"));
return 1;
}
return 0; return 0;
} }

View File

@ -5,6 +5,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <ctype.h> #include <ctype.h>
#include <fcntl.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -20,19 +21,8 @@ static void conf_warning(const char *fmt, ...)
static const char *conf_filename; static const char *conf_filename;
static int conf_lineno, conf_warnings, conf_unsaved; static int conf_lineno, conf_warnings, conf_unsaved;
const char conf_def_filename[] = ".config";
const char conf_defname[] = "arch/$ARCH/defconfig"; const char conf_defname[] = "arch/$ARCH/defconfig";
const char *conf_confnames[] = {
".config",
"/lib/modules/$UNAME_RELEASE/.config",
"/etc/kernel-config",
"/boot/config-$UNAME_RELEASE",
conf_defname,
NULL,
};
static void conf_warning(const char *fmt, ...) static void conf_warning(const char *fmt, ...)
{ {
va_list ap; va_list ap;
@ -44,6 +34,13 @@ static void conf_warning(const char *fmt, ...)
conf_warnings++; conf_warnings++;
} }
const char *conf_get_configname(void)
{
char *name = getenv("KCONFIG_CONFIG");
return name ? name : ".config";
}
static char *conf_expand_value(const char *in) static char *conf_expand_value(const char *in)
{ {
struct symbol *sym; struct symbol *sym;
@ -86,51 +83,65 @@ char *conf_get_default_confname(void)
return name; return name;
} }
int conf_read_simple(const char *name) int conf_read_simple(const char *name, int def)
{ {
FILE *in = NULL; FILE *in = NULL;
char line[1024]; char line[1024];
char *p, *p2; char *p, *p2;
struct symbol *sym; struct symbol *sym;
int i; int i, def_flags;
if (name) { if (name) {
in = zconf_fopen(name); in = zconf_fopen(name);
} else { } else {
const char **names = conf_confnames; struct property *prop;
while ((name = *names++)) {
name = conf_expand_value(name); name = conf_get_configname();
in = zconf_fopen(name);
if (in)
goto load;
sym_change_count++;
if (!sym_defconfig_list)
return 1;
for_all_defaults(sym_defconfig_list, prop) {
if (expr_calc_value(prop->visible.expr) == no ||
prop->expr->type != E_SYMBOL)
continue;
name = conf_expand_value(prop->expr->left.sym->name);
in = zconf_fopen(name); in = zconf_fopen(name);
if (in) { if (in) {
printf(_("#\n" printf(_("#\n"
"# using defaults found in %s\n" "# using defaults found in %s\n"
"#\n"), name); "#\n"), name);
break; goto load;
} }
} }
} }
if (!in) if (!in)
return 1; return 1;
load:
conf_filename = name; conf_filename = name;
conf_lineno = 0; conf_lineno = 0;
conf_warnings = 0; conf_warnings = 0;
conf_unsaved = 0; conf_unsaved = 0;
def_flags = SYMBOL_DEF << def;
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
sym->flags |= SYMBOL_NEW | SYMBOL_CHANGED; sym->flags |= SYMBOL_CHANGED;
sym->flags &= ~(def_flags|SYMBOL_VALID);
if (sym_is_choice(sym)) if (sym_is_choice(sym))
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
sym->flags &= ~SYMBOL_VALID;
switch (sym->type) { switch (sym->type) {
case S_INT: case S_INT:
case S_HEX: case S_HEX:
case S_STRING: case S_STRING:
if (sym->user.val) if (sym->def[def].val)
free(sym->user.val); free(sym->def[def].val);
default: default:
sym->user.val = NULL; sym->def[def].val = NULL;
sym->user.tri = no; sym->def[def].tri = no;
} }
} }
@ -147,19 +158,26 @@ int conf_read_simple(const char *name)
*p++ = 0; *p++ = 0;
if (strncmp(p, "is not set", 10)) if (strncmp(p, "is not set", 10))
continue; continue;
sym = sym_find(line + 9); if (def == S_DEF_USER) {
if (!sym) { sym = sym_find(line + 9);
conf_warning("trying to assign nonexistent symbol %s", line + 9); if (!sym) {
break; conf_warning("trying to assign nonexistent symbol %s", line + 9);
} else if (!(sym->flags & SYMBOL_NEW)) { break;
}
} else {
sym = sym_lookup(line + 9, 0);
if (sym->type == S_UNKNOWN)
sym->type = S_BOOLEAN;
}
if (sym->flags & def_flags) {
conf_warning("trying to reassign symbol %s", sym->name); conf_warning("trying to reassign symbol %s", sym->name);
break; break;
} }
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
case S_TRISTATE: case S_TRISTATE:
sym->user.tri = no; sym->def[def].tri = no;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
default: default:
; ;
@ -177,34 +195,48 @@ int conf_read_simple(const char *name)
p2 = strchr(p, '\n'); p2 = strchr(p, '\n');
if (p2) if (p2)
*p2 = 0; *p2 = 0;
sym = sym_find(line + 7); if (def == S_DEF_USER) {
if (!sym) { sym = sym_find(line + 7);
conf_warning("trying to assign nonexistent symbol %s", line + 7); if (!sym) {
break; conf_warning("trying to assign nonexistent symbol %s", line + 7);
} else if (!(sym->flags & SYMBOL_NEW)) { break;
}
} else {
sym = sym_lookup(line + 7, 0);
if (sym->type == S_UNKNOWN)
sym->type = S_OTHER;
}
if (sym->flags & def_flags) {
conf_warning("trying to reassign symbol %s", sym->name); conf_warning("trying to reassign symbol %s", sym->name);
break; break;
} }
switch (sym->type) { switch (sym->type) {
case S_TRISTATE: case S_TRISTATE:
if (p[0] == 'm') { if (p[0] == 'm') {
sym->user.tri = mod; sym->def[def].tri = mod;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
case S_BOOLEAN: case S_BOOLEAN:
if (p[0] == 'y') { if (p[0] == 'y') {
sym->user.tri = yes; sym->def[def].tri = yes;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
if (p[0] == 'n') { if (p[0] == 'n') {
sym->user.tri = no; sym->def[def].tri = no;
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
break; break;
} }
conf_warning("symbol value '%s' invalid for %s", p, sym->name); conf_warning("symbol value '%s' invalid for %s", p, sym->name);
break; break;
case S_OTHER:
if (*p != '"') {
for (p2 = p; *p2 && !isspace(*p2); p2++)
;
sym->type = S_STRING;
goto done;
}
case S_STRING: case S_STRING:
if (*p++ != '"') if (*p++ != '"')
break; break;
@ -221,9 +253,10 @@ int conf_read_simple(const char *name)
} }
case S_INT: case S_INT:
case S_HEX: case S_HEX:
done:
if (sym_string_valid(sym, p)) { if (sym_string_valid(sym, p)) {
sym->user.val = strdup(p); sym->def[def].val = strdup(p);
sym->flags &= ~SYMBOL_NEW; sym->flags |= def_flags;
} else { } else {
conf_warning("symbol value '%s' invalid for %s", p, sym->name); conf_warning("symbol value '%s' invalid for %s", p, sym->name);
continue; continue;
@ -241,24 +274,24 @@ int conf_read_simple(const char *name)
} }
if (sym && sym_is_choice_value(sym)) { if (sym && sym_is_choice_value(sym)) {
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym)); struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
switch (sym->user.tri) { switch (sym->def[def].tri) {
case no: case no:
break; break;
case mod: case mod:
if (cs->user.tri == yes) { if (cs->def[def].tri == yes) {
conf_warning("%s creates inconsistent choice state", sym->name); conf_warning("%s creates inconsistent choice state", sym->name);
cs->flags |= SYMBOL_NEW; cs->flags &= ~def_flags;
} }
break; break;
case yes: case yes:
if (cs->user.tri != no) { if (cs->def[def].tri != no) {
conf_warning("%s creates inconsistent choice state", sym->name); conf_warning("%s creates inconsistent choice state", sym->name);
cs->flags |= SYMBOL_NEW; cs->flags &= ~def_flags;
} else } else
cs->user.val = sym; cs->def[def].val = sym;
break; break;
} }
cs->user.tri = E_OR(cs->user.tri, sym->user.tri); cs->def[def].tri = E_OR(cs->def[def].tri, sym->def[def].tri);
} }
} }
fclose(in); fclose(in);
@ -273,9 +306,11 @@ int conf_read(const char *name)
struct symbol *sym; struct symbol *sym;
struct property *prop; struct property *prop;
struct expr *e; struct expr *e;
int i; int i, flags;
if (conf_read_simple(name)) sym_change_count = 0;
if (conf_read_simple(name, S_DEF_USER))
return 1; return 1;
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
@ -287,12 +322,12 @@ int conf_read(const char *name)
switch (sym->type) { switch (sym->type) {
case S_BOOLEAN: case S_BOOLEAN:
case S_TRISTATE: case S_TRISTATE:
if (sym->user.tri != sym_get_tristate_value(sym)) if (sym->def[S_DEF_USER].tri != sym_get_tristate_value(sym))
break; break;
if (!sym_is_choice(sym)) if (!sym_is_choice(sym))
goto sym_ok; goto sym_ok;
default: default:
if (!strcmp(sym->curr.val, sym->user.val)) if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
goto sym_ok; goto sym_ok;
break; break;
} }
@ -304,15 +339,13 @@ int conf_read(const char *name)
sym_ok: sym_ok:
if (sym_has_value(sym) && !sym_is_choice_value(sym)) { if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
if (sym->visible == no) if (sym->visible == no)
sym->flags |= SYMBOL_NEW; sym->flags &= ~SYMBOL_DEF_USER;
switch (sym->type) { switch (sym->type) {
case S_STRING: case S_STRING:
case S_INT: case S_INT:
case S_HEX: case S_HEX:
if (!sym_string_within_range(sym, sym->user.val)) { if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
sym->flags |= SYMBOL_NEW; sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
sym->flags &= ~SYMBOL_VALID;
}
default: default:
break; break;
} }
@ -320,19 +353,21 @@ int conf_read(const char *name)
if (!sym_is_choice(sym)) if (!sym_is_choice(sym))
continue; continue;
prop = sym_get_choice_prop(sym); prop = sym_get_choice_prop(sym);
flags = sym->flags;
for (e = prop->expr; e; e = e->left.expr) for (e = prop->expr; e; e = e->left.expr)
if (e->right.sym->visible != no) if (e->right.sym->visible != no)
sym->flags |= e->right.sym->flags & SYMBOL_NEW; flags &= e->right.sym->flags;
sym->flags |= flags & SYMBOL_DEF_USER;
} }
sym_change_count = conf_warnings || conf_unsaved; sym_change_count += conf_warnings || conf_unsaved;
return 0; return 0;
} }
int conf_write(const char *name) int conf_write(const char *name)
{ {
FILE *out, *out_h; FILE *out;
struct symbol *sym; struct symbol *sym;
struct menu *menu; struct menu *menu;
const char *basename; const char *basename;
@ -351,7 +386,7 @@ int conf_write(const char *name)
if (!stat(name, &st) && S_ISDIR(st.st_mode)) { if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
strcpy(dirname, name); strcpy(dirname, name);
strcat(dirname, "/"); strcat(dirname, "/");
basename = conf_def_filename; basename = conf_get_configname();
} else if ((slash = strrchr(name, '/'))) { } else if ((slash = strrchr(name, '/'))) {
int size = slash - name + 1; int size = slash - name + 1;
memcpy(dirname, name, size); memcpy(dirname, name, size);
@ -359,23 +394,24 @@ int conf_write(const char *name)
if (slash[1]) if (slash[1])
basename = slash + 1; basename = slash + 1;
else else
basename = conf_def_filename; basename = conf_get_configname();
} else } else
basename = name; basename = name;
} else } else
basename = conf_def_filename; basename = conf_get_configname();
sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid()); sprintf(newname, "%s%s", dirname, basename);
out = fopen(newname, "w"); env = getenv("KCONFIG_OVERWRITECONFIG");
if (!env || !*env) {
sprintf(tmpname, "%s.tmpconfig.%d", dirname, (int)getpid());
out = fopen(tmpname, "w");
} else {
*tmpname = 0;
out = fopen(newname, "w");
}
if (!out) if (!out)
return 1; return 1;
out_h = NULL;
if (!name) {
out_h = fopen(".tmpconfig.h", "w");
if (!out_h)
return 1;
file_write_dep(NULL);
}
sym = sym_lookup("KERNELVERSION", 0); sym = sym_lookup("KERNELVERSION", 0);
sym_calc_value(sym); sym_calc_value(sym);
time(&now); time(&now);
@ -391,16 +427,6 @@ int conf_write(const char *name)
sym_get_string_value(sym), sym_get_string_value(sym),
use_timestamp ? "# " : "", use_timestamp ? "# " : "",
use_timestamp ? ctime(&now) : ""); use_timestamp ? ctime(&now) : "");
if (out_h)
fprintf(out_h, "/*\n"
" * Automatically generated C config: don't edit\n"
" * Linux kernel version: %s\n"
"%s%s"
" */\n"
"#define AUTOCONF_INCLUDED\n",
sym_get_string_value(sym),
use_timestamp ? " * " : "",
use_timestamp ? ctime(&now) : "");
if (!sym_change_count) if (!sym_change_count)
sym_clear_all_valid(); sym_clear_all_valid();
@ -416,11 +442,6 @@ int conf_write(const char *name)
"#\n" "#\n"
"# %s\n" "# %s\n"
"#\n", str); "#\n", str);
if (out_h)
fprintf(out_h, "\n"
"/*\n"
" * %s\n"
" */\n", str);
} else if (!(sym->flags & SYMBOL_CHOICE)) { } else if (!(sym->flags & SYMBOL_CHOICE)) {
sym_calc_value(sym); sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE)) if (!(sym->flags & SYMBOL_WRITE))
@ -438,59 +459,39 @@ int conf_write(const char *name)
switch (sym_get_tristate_value(sym)) { switch (sym_get_tristate_value(sym)) {
case no: case no:
fprintf(out, "# CONFIG_%s is not set\n", sym->name); fprintf(out, "# CONFIG_%s is not set\n", sym->name);
if (out_h)
fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
break; break;
case mod: case mod:
fprintf(out, "CONFIG_%s=m\n", sym->name); fprintf(out, "CONFIG_%s=m\n", sym->name);
if (out_h)
fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
break; break;
case yes: case yes:
fprintf(out, "CONFIG_%s=y\n", sym->name); fprintf(out, "CONFIG_%s=y\n", sym->name);
if (out_h)
fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
break; break;
} }
break; break;
case S_STRING: case S_STRING:
// fix me
str = sym_get_string_value(sym); str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=\"", sym->name); fprintf(out, "CONFIG_%s=\"", sym->name);
if (out_h) while (1) {
fprintf(out_h, "#define CONFIG_%s \"", sym->name);
do {
l = strcspn(str, "\"\\"); l = strcspn(str, "\"\\");
if (l) { if (l) {
fwrite(str, l, 1, out); fwrite(str, l, 1, out);
if (out_h) str += l;
fwrite(str, l, 1, out_h);
} }
str += l; if (!*str)
while (*str == '\\' || *str == '"') { break;
fprintf(out, "\\%c", *str); fprintf(out, "\\%c", *str++);
if (out_h) }
fprintf(out_h, "\\%c", *str);
str++;
}
} while (*str);
fputs("\"\n", out); fputs("\"\n", out);
if (out_h)
fputs("\"\n", out_h);
break; break;
case S_HEX: case S_HEX:
str = sym_get_string_value(sym); str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) { if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
fprintf(out, "CONFIG_%s=%s\n", sym->name, str); fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
if (out_h)
fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
break; break;
} }
case S_INT: case S_INT:
str = sym_get_string_value(sym); str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=%s\n", sym->name, str); fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
if (out_h)
fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
break; break;
} }
} }
@ -510,21 +511,253 @@ int conf_write(const char *name)
} }
} }
fclose(out); fclose(out);
if (out_h) {
fclose(out_h); if (*tmpname) {
rename(".tmpconfig.h", "include/linux/autoconf.h"); strcat(dirname, name ? name : conf_get_configname());
strcat(dirname, ".old");
rename(newname, dirname);
if (rename(tmpname, newname))
return 1;
} }
if (!name || basename != conf_def_filename) {
if (!name) printf(_("#\n"
name = conf_def_filename; "# configuration written to %s\n"
sprintf(tmpname, "%s.old", name); "#\n"), newname);
rename(name, tmpname);
}
sprintf(tmpname, "%s%s", dirname, basename);
if (rename(newname, tmpname))
return 1;
sym_change_count = 0; sym_change_count = 0;
return 0; return 0;
} }
int conf_split_config(void)
{
char *name, path[128];
char *s, *d, c;
struct symbol *sym;
struct stat sb;
int res, i, fd;
name = getenv("KCONFIG_AUTOCONFIG");
if (!name)
name = "include/config/auto.conf";
conf_read_simple(name, S_DEF_AUTO);
if (chdir("include/config"))
return 1;
res = 0;
for_all_symbols(i, sym) {
sym_calc_value(sym);
if ((sym->flags & SYMBOL_AUTO) || !sym->name)
continue;
if (sym->flags & SYMBOL_WRITE) {
if (sym->flags & SYMBOL_DEF_AUTO) {
/*
* symbol has old and new value,
* so compare them...
*/
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
if (sym_get_tristate_value(sym) ==
sym->def[S_DEF_AUTO].tri)
continue;
break;
case S_STRING:
case S_HEX:
case S_INT:
if (!strcmp(sym_get_string_value(sym),
sym->def[S_DEF_AUTO].val))
continue;
break;
default:
break;
}
} else {
/*
* If there is no old value, only 'no' (unset)
* is allowed as new value.
*/
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
if (sym_get_tristate_value(sym) == no)
continue;
break;
default:
break;
}
}
} else if (!(sym->flags & SYMBOL_DEF_AUTO))
/* There is neither an old nor a new value. */
continue;
/* else
* There is an old value, but no new value ('no' (unset)
* isn't saved in auto.conf, so the old value is always
* different from 'no').
*/
/* Replace all '_' and append ".h" */
s = sym->name;
d = path;
while ((c = *s++)) {
c = tolower(c);
*d++ = (c == '_') ? '/' : c;
}
strcpy(d, ".h");
/* Assume directory path already exists. */
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
if (errno != ENOENT) {
res = 1;
break;
}
/*
* Create directory components,
* unless they exist already.
*/
d = path;
while ((d = strchr(d, '/'))) {
*d = 0;
if (stat(path, &sb) && mkdir(path, 0755)) {
res = 1;
goto out;
}
*d++ = '/';
}
/* Try it again. */
fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd == -1) {
res = 1;
break;
}
}
close(fd);
}
out:
if (chdir("../.."))
return 1;
return res;
}
int conf_write_autoconf(void)
{
struct symbol *sym;
const char *str;
char *name;
FILE *out, *out_h;
time_t now;
int i, l;
sym_clear_all_valid();
file_write_dep("include/config/auto.conf.cmd");
if (conf_split_config())
return 1;
out = fopen(".tmpconfig", "w");
if (!out)
return 1;
out_h = fopen(".tmpconfig.h", "w");
if (!out_h) {
fclose(out);
return 1;
}
sym = sym_lookup("KERNELVERSION", 0);
sym_calc_value(sym);
time(&now);
fprintf(out, "#\n"
"# Automatically generated make config: don't edit\n"
"# Linux kernel version: %s\n"
"# %s"
"#\n",
sym_get_string_value(sym), ctime(&now));
fprintf(out_h, "/*\n"
" * Automatically generated C config: don't edit\n"
" * Linux kernel version: %s\n"
" * %s"
" */\n"
"#define AUTOCONF_INCLUDED\n",
sym_get_string_value(sym), ctime(&now));
for_all_symbols(i, sym) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE) || !sym->name)
continue;
switch (sym->type) {
case S_BOOLEAN:
case S_TRISTATE:
switch (sym_get_tristate_value(sym)) {
case no:
break;
case mod:
fprintf(out, "CONFIG_%s=m\n", sym->name);
fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
break;
case yes:
fprintf(out, "CONFIG_%s=y\n", sym->name);
fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
break;
}
break;
case S_STRING:
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=\"", sym->name);
fprintf(out_h, "#define CONFIG_%s \"", sym->name);
while (1) {
l = strcspn(str, "\"\\");
if (l) {
fwrite(str, l, 1, out);
fwrite(str, l, 1, out_h);
str += l;
}
if (!*str)
break;
fprintf(out, "\\%c", *str);
fprintf(out_h, "\\%c", *str);
str++;
}
fputs("\"\n", out);
fputs("\"\n", out_h);
break;
case S_HEX:
str = sym_get_string_value(sym);
if (str[0] != '0' || (str[1] != 'x' && str[1] != 'X')) {
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
fprintf(out_h, "#define CONFIG_%s 0x%s\n", sym->name, str);
break;
}
case S_INT:
str = sym_get_string_value(sym);
fprintf(out, "CONFIG_%s=%s\n", sym->name, str);
fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
break;
default:
break;
}
}
fclose(out);
fclose(out_h);
name = getenv("KCONFIG_AUTOHEADER");
if (!name)
name = "include/linux/autoconf.h";
if (rename(".tmpconfig.h", name))
return 1;
name = getenv("KCONFIG_AUTOCONFIG");
if (!name)
name = "include/config/auto.conf";
/*
* This must be the last step, kbuild has a dependency on auto.conf
* and this marks the successful completion of the previous steps.
*/
if (rename(".tmpconfig", name))
return 1;
return 0;
}

View File

@ -145,7 +145,8 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
return; return;
} }
if (e1->type == E_SYMBOL && e2->type == E_SYMBOL && if (e1->type == E_SYMBOL && e2->type == E_SYMBOL &&
e1->left.sym == e2->left.sym && (e1->left.sym->flags & (SYMBOL_YES|SYMBOL_NO))) e1->left.sym == e2->left.sym &&
(e1->left.sym == &symbol_yes || e1->left.sym == &symbol_no))
return; return;
if (!expr_eq(e1, e2)) if (!expr_eq(e1, e2))
return; return;
@ -1012,73 +1013,73 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
#endif #endif
} }
void expr_print(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken) void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken)
{ {
if (!e) { if (!e) {
fn(data, "y"); fn(data, NULL, "y");
return; return;
} }
if (expr_compare_type(prevtoken, e->type) > 0) if (expr_compare_type(prevtoken, e->type) > 0)
fn(data, "("); fn(data, NULL, "(");
switch (e->type) { switch (e->type) {
case E_SYMBOL: case E_SYMBOL:
if (e->left.sym->name) if (e->left.sym->name)
fn(data, e->left.sym->name); fn(data, e->left.sym, e->left.sym->name);
else else
fn(data, "<choice>"); fn(data, NULL, "<choice>");
break; break;
case E_NOT: case E_NOT:
fn(data, "!"); fn(data, NULL, "!");
expr_print(e->left.expr, fn, data, E_NOT); expr_print(e->left.expr, fn, data, E_NOT);
break; break;
case E_EQUAL: case E_EQUAL:
fn(data, e->left.sym->name); fn(data, e->left.sym, e->left.sym->name);
fn(data, "="); fn(data, NULL, "=");
fn(data, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
break; break;
case E_UNEQUAL: case E_UNEQUAL:
fn(data, e->left.sym->name); fn(data, e->left.sym, e->left.sym->name);
fn(data, "!="); fn(data, NULL, "!=");
fn(data, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
break; break;
case E_OR: case E_OR:
expr_print(e->left.expr, fn, data, E_OR); expr_print(e->left.expr, fn, data, E_OR);
fn(data, " || "); fn(data, NULL, " || ");
expr_print(e->right.expr, fn, data, E_OR); expr_print(e->right.expr, fn, data, E_OR);
break; break;
case E_AND: case E_AND:
expr_print(e->left.expr, fn, data, E_AND); expr_print(e->left.expr, fn, data, E_AND);
fn(data, " && "); fn(data, NULL, " && ");
expr_print(e->right.expr, fn, data, E_AND); expr_print(e->right.expr, fn, data, E_AND);
break; break;
case E_CHOICE: case E_CHOICE:
fn(data, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
if (e->left.expr) { if (e->left.expr) {
fn(data, " ^ "); fn(data, NULL, " ^ ");
expr_print(e->left.expr, fn, data, E_CHOICE); expr_print(e->left.expr, fn, data, E_CHOICE);
} }
break; break;
case E_RANGE: case E_RANGE:
fn(data, "["); fn(data, NULL, "[");
fn(data, e->left.sym->name); fn(data, e->left.sym, e->left.sym->name);
fn(data, " "); fn(data, NULL, " ");
fn(data, e->right.sym->name); fn(data, e->right.sym, e->right.sym->name);
fn(data, "]"); fn(data, NULL, "]");
break; break;
default: default:
{ {
char buf[32]; char buf[32];
sprintf(buf, "<unknown type %d>", e->type); sprintf(buf, "<unknown type %d>", e->type);
fn(data, buf); fn(data, NULL, buf);
break; break;
} }
} }
if (expr_compare_type(prevtoken, e->type) > 0) if (expr_compare_type(prevtoken, e->type) > 0)
fn(data, ")"); fn(data, NULL, ")");
} }
static void expr_print_file_helper(void *data, const char *str) static void expr_print_file_helper(void *data, struct symbol *sym, const char *str)
{ {
fwrite(str, strlen(str), 1, data); fwrite(str, strlen(str), 1, data);
} }
@ -1088,7 +1089,7 @@ void expr_fprint(struct expr *e, FILE *out)
expr_print(e, expr_print_file_helper, out, E_NONE); expr_print(e, expr_print_file_helper, out, E_NONE);
} }
static void expr_print_gstr_helper(void *data, const char *str) static void expr_print_gstr_helper(void *data, struct symbol *sym, const char *str)
{ {
str_append((struct gstr*)data, str); str_append((struct gstr*)data, str);
} }

View File

@ -63,12 +63,18 @@ enum symbol_type {
S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER S_UNKNOWN, S_BOOLEAN, S_TRISTATE, S_INT, S_HEX, S_STRING, S_OTHER
}; };
enum {
S_DEF_USER, /* main user value */
S_DEF_AUTO,
};
struct symbol { struct symbol {
struct symbol *next; struct symbol *next;
char *name; char *name;
char *help; char *help;
enum symbol_type type; enum symbol_type type;
struct symbol_value curr, user; struct symbol_value curr;
struct symbol_value def[4];
tristate visible; tristate visible;
int flags; int flags;
struct property *prop; struct property *prop;
@ -78,10 +84,7 @@ struct symbol {
#define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER) #define for_all_symbols(i, sym) for (i = 0; i < 257; i++) for (sym = symbol_hash[i]; sym; sym = sym->next) if (sym->type != S_OTHER)
#define SYMBOL_YES 0x0001 #define SYMBOL_CONST 0x0001
#define SYMBOL_MOD 0x0002
#define SYMBOL_NO 0x0004
#define SYMBOL_CONST 0x0007
#define SYMBOL_CHECK 0x0008 #define SYMBOL_CHECK 0x0008
#define SYMBOL_CHOICE 0x0010 #define SYMBOL_CHOICE 0x0010
#define SYMBOL_CHOICEVAL 0x0020 #define SYMBOL_CHOICEVAL 0x0020
@ -90,10 +93,14 @@ struct symbol {
#define SYMBOL_OPTIONAL 0x0100 #define SYMBOL_OPTIONAL 0x0100
#define SYMBOL_WRITE 0x0200 #define SYMBOL_WRITE 0x0200
#define SYMBOL_CHANGED 0x0400 #define SYMBOL_CHANGED 0x0400
#define SYMBOL_NEW 0x0800
#define SYMBOL_AUTO 0x1000 #define SYMBOL_AUTO 0x1000
#define SYMBOL_CHECKED 0x2000 #define SYMBOL_CHECKED 0x2000
#define SYMBOL_WARNED 0x8000 #define SYMBOL_WARNED 0x8000
#define SYMBOL_DEF 0x10000
#define SYMBOL_DEF_USER 0x10000
#define SYMBOL_DEF_AUTO 0x20000
#define SYMBOL_DEF3 0x40000
#define SYMBOL_DEF4 0x80000
#define SYMBOL_MAXLENGTH 256 #define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 257 #define SYMBOL_HASHSIZE 257
@ -149,6 +156,7 @@ struct file *lookup_file(const char *name);
extern struct symbol symbol_yes, symbol_no, symbol_mod; extern struct symbol symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym; extern struct symbol *modules_sym;
extern struct symbol *sym_defconfig_list;
extern int cdebug; extern int cdebug;
struct expr *expr_alloc_symbol(struct symbol *sym); struct expr *expr_alloc_symbol(struct symbol *sym);
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce); struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);

View File

@ -114,12 +114,6 @@ const char *dbg_print_flags(int val)
bzero(buf, 256); bzero(buf, 256);
if (val & SYMBOL_YES)
strcat(buf, "yes/");
if (val & SYMBOL_MOD)
strcat(buf, "mod/");
if (val & SYMBOL_NO)
strcat(buf, "no/");
if (val & SYMBOL_CONST) if (val & SYMBOL_CONST)
strcat(buf, "const/"); strcat(buf, "const/");
if (val & SYMBOL_CHECK) if (val & SYMBOL_CHECK)
@ -138,8 +132,6 @@ const char *dbg_print_flags(int val)
strcat(buf, "write/"); strcat(buf, "write/");
if (val & SYMBOL_CHANGED) if (val & SYMBOL_CHANGED)
strcat(buf, "changed/"); strcat(buf, "changed/");
if (val & SYMBOL_NEW)
strcat(buf, "new/");
if (val & SYMBOL_AUTO) if (val & SYMBOL_AUTO)
strcat(buf, "auto/"); strcat(buf, "auto/");
@ -1192,9 +1184,7 @@ static gchar **fill_row(struct menu *menu)
row[COL_OPTION] = row[COL_OPTION] =
g_strdup_printf("%s %s", menu_get_prompt(menu), g_strdup_printf("%s %s", menu_get_prompt(menu),
sym ? (sym-> sym && sym_has_value(sym) ? "(NEW)" : "");
flags & SYMBOL_NEW ? "(NEW)" : "") :
"");
if (show_all && !menu_is_visible(menu)) if (show_all && !menu_is_visible(menu))
row[COL_COLOR] = g_strdup("DarkGray"); row[COL_COLOR] = g_strdup("DarkGray");

View File

@ -8,7 +8,7 @@
#define FLEX_SCANNER #define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2 #define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5 #define YY_FLEX_MINOR_VERSION 5
#define YY_FLEX_SUBMINOR_VERSION 31 #define YY_FLEX_SUBMINOR_VERSION 33
#if YY_FLEX_SUBMINOR_VERSION > 0 #if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA #define FLEX_BETA
#endif #endif
@ -30,7 +30,15 @@
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ /* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L #if __STDC_VERSION__ >= 199901L
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
* if you want the limit (max/min) macros for int types.
*/
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS 1
#endif
#include <inttypes.h> #include <inttypes.h>
typedef int8_t flex_int8_t; typedef int8_t flex_int8_t;
typedef uint8_t flex_uint8_t; typedef uint8_t flex_uint8_t;
@ -134,6 +142,10 @@ typedef unsigned int flex_uint32_t;
#define YY_BUF_SIZE 16384 #define YY_BUF_SIZE 16384
#endif #endif
/* The state buf must be large enough to hold one state per character in the main buffer.
*/
#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
#ifndef YY_TYPEDEF_YY_BUFFER_STATE #ifndef YY_TYPEDEF_YY_BUFFER_STATE
#define YY_TYPEDEF_YY_BUFFER_STATE #define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE; typedef struct yy_buffer_state *YY_BUFFER_STATE;
@ -267,7 +279,7 @@ int zconfleng;
/* Points to current character in buffer. */ /* Points to current character in buffer. */
static char *yy_c_buf_p = (char *) 0; static char *yy_c_buf_p = (char *) 0;
static int yy_init = 1; /* whether we need to initialize */ static int yy_init = 0; /* whether we need to initialize */
static int yy_start = 0; /* start state number */ static int yy_start = 0; /* start state number */
/* Flag which is used to allow zconfwrap()'s to do buffer switches /* Flag which is used to allow zconfwrap()'s to do buffer switches
@ -820,6 +832,8 @@ void alloc_string(const char *str, int size)
#define YY_EXTRA_TYPE void * #define YY_EXTRA_TYPE void *
#endif #endif
static int yy_init_globals (void );
/* Macros after this point can all be overridden by user definitions in /* Macros after this point can all be overridden by user definitions in
* section 1. * section 1.
*/ */
@ -942,9 +956,9 @@ YY_DECL
int str = 0; int str = 0;
int ts, i; int ts, i;
if ( (yy_init) ) if ( !(yy_init) )
{ {
(yy_init) = 0; (yy_init) = 1;
#ifdef YY_USER_INIT #ifdef YY_USER_INIT
YY_USER_INIT; YY_USER_INIT;
@ -1452,7 +1466,7 @@ static int yy_get_next_buffer (void)
else else
{ {
size_t num_to_read = int num_to_read =
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
while ( num_to_read <= 0 ) while ( num_to_read <= 0 )
@ -1969,16 +1983,16 @@ YY_BUFFER_STATE zconf_scan_buffer (char * base, yy_size_t size )
/** Setup the input buffer state to scan a string. The next call to zconflex() will /** Setup the input buffer state to scan a string. The next call to zconflex() will
* scan from a @e copy of @a str. * scan from a @e copy of @a str.
* @param yy_str a NUL-terminated string to scan * @param yystr a NUL-terminated string to scan
* *
* @return the newly allocated buffer state object. * @return the newly allocated buffer state object.
* @note If you want to scan bytes that may contain NUL values, then use * @note If you want to scan bytes that may contain NUL values, then use
* zconf_scan_bytes() instead. * zconf_scan_bytes() instead.
*/ */
YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str ) YY_BUFFER_STATE zconf_scan_string (yyconst char * yystr )
{ {
return zconf_scan_bytes(yy_str,strlen(yy_str) ); return zconf_scan_bytes(yystr,strlen(yystr) );
} }
/** Setup the input buffer state to scan the given bytes. The next call to zconflex() will /** Setup the input buffer state to scan the given bytes. The next call to zconflex() will
@ -1988,7 +2002,7 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str )
* *
* @return the newly allocated buffer state object. * @return the newly allocated buffer state object.
*/ */
YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len ) YY_BUFFER_STATE zconf_scan_bytes (yyconst char * yybytes, int _yybytes_len )
{ {
YY_BUFFER_STATE b; YY_BUFFER_STATE b;
char *buf; char *buf;
@ -1996,15 +2010,15 @@ YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len )
int i; int i;
/* Get memory for full buffer, including space for trailing EOB's. */ /* Get memory for full buffer, including space for trailing EOB's. */
n = len + 2; n = _yybytes_len + 2;
buf = (char *) zconfalloc(n ); buf = (char *) zconfalloc(n );
if ( ! buf ) if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" ); YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
for ( i = 0; i < len; ++i ) for ( i = 0; i < _yybytes_len; ++i )
buf[i] = bytes[i]; buf[i] = yybytes[i];
buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
b = zconf_scan_buffer(buf,n ); b = zconf_scan_buffer(buf,n );
if ( ! b ) if ( ! b )
@ -2125,6 +2139,34 @@ void zconfset_debug (int bdebug )
zconf_flex_debug = bdebug ; zconf_flex_debug = bdebug ;
} }
static int yy_init_globals (void)
{
/* Initialization is the same as for the non-reentrant scanner.
* This function is called from zconflex_destroy(), so don't allocate here.
*/
(yy_buffer_stack) = 0;
(yy_buffer_stack_top) = 0;
(yy_buffer_stack_max) = 0;
(yy_c_buf_p) = (char *) 0;
(yy_init) = 0;
(yy_start) = 0;
/* Defined in main.c */
#ifdef YY_STDINIT
zconfin = stdin;
zconfout = stdout;
#else
zconfin = (FILE *) 0;
zconfout = (FILE *) 0;
#endif
/* For future reference: Set errno on error, since we are called by
* zconflex_init()
*/
return 0;
}
/* zconflex_destroy is for both reentrant and non-reentrant scanners. */ /* zconflex_destroy is for both reentrant and non-reentrant scanners. */
int zconflex_destroy (void) int zconflex_destroy (void)
{ {
@ -2140,6 +2182,10 @@ int zconflex_destroy (void)
zconffree((yy_buffer_stack) ); zconffree((yy_buffer_stack) );
(yy_buffer_stack) = NULL; (yy_buffer_stack) = NULL;
/* Reset the globals. This is important in a non-reentrant scanner so the next time
* zconflex() is called, initialization will occur. */
yy_init_globals( );
return 0; return 0;
} }
@ -2151,7 +2197,7 @@ int zconflex_destroy (void)
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
{ {
register int i; register int i;
for ( i = 0; i < n; ++i ) for ( i = 0; i < n; ++i )
s1[i] = s2[i]; s1[i] = s2[i];
} }
#endif #endif
@ -2160,7 +2206,7 @@ static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
static int yy_flex_strlen (yyconst char * s ) static int yy_flex_strlen (yyconst char * s )
{ {
register int n; register int n;
for ( n = 0; s[n]; ++n ) for ( n = 0; s[n]; ++n )
; ;
return n; return n;
@ -2191,19 +2237,6 @@ void zconffree (void * ptr )
#define YYTABLES_NAME "yytables" #define YYTABLES_NAME "yytables"
#undef YY_NEW_FILE
#undef YY_FLUSH_BUFFER
#undef yy_set_bol
#undef yy_new_buffer
#undef yy_set_interactive
#undef yytext_ptr
#undef YY_DO_BEFORE_ACTION
#ifdef YY_DECL_IS_OURS
#undef YY_DECL_IS_OURS
#undef YY_DECL
#endif
void zconf_starthelp(void) void zconf_starthelp(void)
{ {
new_string(); new_string();

View File

@ -40,6 +40,10 @@ extern "C" {
#define TF_COMMAND 0x0001 #define TF_COMMAND 0x0001
#define TF_PARAM 0x0002 #define TF_PARAM 0x0002
#define TF_OPTION 0x0004
#define T_OPT_MODULES 1
#define T_OPT_DEFCONFIG_LIST 2
struct kconf_id { struct kconf_id {
int name; int name;
@ -60,8 +64,6 @@ int zconf_lineno(void);
char *zconf_curname(void); char *zconf_curname(void);
/* confdata.c */ /* confdata.c */
extern const char conf_def_filename[];
char *conf_get_default_confname(void); char *conf_get_default_confname(void);
/* kconfig_load.c */ /* kconfig_load.c */
@ -78,6 +80,7 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep); struct property *menu_add_prompt(enum prop_type type, char *prompt, struct expr *dep);
void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep); void menu_add_expr(enum prop_type type, struct expr *expr, struct expr *dep);
void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep); void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
void menu_add_option(int token, char *arg);
void menu_finalize(struct menu *parent); void menu_finalize(struct menu *parent);
void menu_set_type(int type); void menu_set_type(int type);
@ -99,6 +102,7 @@ const char *str_get(struct gstr *gs);
/* symbol.c */ /* symbol.c */
void sym_init(void); void sym_init(void);
void sym_clear_all_valid(void); void sym_clear_all_valid(void);
void sym_set_all_changed(void);
void sym_set_changed(struct symbol *sym); void sym_set_changed(struct symbol *sym);
struct symbol *sym_check_deps(struct symbol *sym); struct symbol *sym_check_deps(struct symbol *sym);
struct property *prop_alloc(enum prop_type type, struct symbol *sym); struct property *prop_alloc(enum prop_type type, struct symbol *sym);
@ -137,7 +141,7 @@ static inline bool sym_is_optional(struct symbol *sym)
static inline bool sym_has_value(struct symbol *sym) static inline bool sym_has_value(struct symbol *sym)
{ {
return sym->flags & SYMBOL_NEW ? false : true; return sym->flags & SYMBOL_DEF_USER ? true : false;
} }
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -2,8 +2,9 @@
/* confdata.c */ /* confdata.c */
P(conf_parse,void,(const char *name)); P(conf_parse,void,(const char *name));
P(conf_read,int,(const char *name)); P(conf_read,int,(const char *name));
P(conf_read_simple,int,(const char *name)); P(conf_read_simple,int,(const char *name, int));
P(conf_write,int,(const char *name)); P(conf_write,int,(const char *name));
P(conf_write_autoconf,int,(void));
/* menu.c */ /* menu.c */
P(rootmenu,struct menu,); P(rootmenu,struct menu,);
@ -38,4 +39,4 @@ P(prop_get_type_name,const char *,(enum prop_type type));
/* expr.c */ /* expr.c */
P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2)); P(expr_compare_type,int,(enum expr_type t1, enum expr_type t2));
P(expr_print,void,(struct expr *e, void (*fn)(void *, const char *), void *data, int prevtoken)); P(expr_print,void,(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken));

View File

@ -114,7 +114,7 @@ void menu_set_type(int type)
sym->type = type; sym->type = type;
return; return;
} }
menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'\n", menu_warn(current_entry, "type of '%s' redefined from '%s' to '%s'",
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
sym_type_name(sym->type), sym_type_name(type)); sym_type_name(sym->type), sym_type_name(type));
} }
@ -124,15 +124,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e
struct property *prop = prop_alloc(type, current_entry->sym); struct property *prop = prop_alloc(type, current_entry->sym);
prop->menu = current_entry; prop->menu = current_entry;
prop->text = prompt;
prop->expr = expr; prop->expr = expr;
prop->visible.expr = menu_check_dep(dep); prop->visible.expr = menu_check_dep(dep);
if (prompt) { if (prompt) {
if (isspace(*prompt)) {
prop_warn(prop, "leading whitespace ignored");
while (isspace(*prompt))
prompt++;
}
if (current_entry->prompt) if (current_entry->prompt)
menu_warn(current_entry, "prompt redefined\n"); prop_warn(prop, "prompt redefined");
current_entry->prompt = prop; current_entry->prompt = prop;
} }
prop->text = prompt;
return prop; return prop;
} }
@ -152,6 +157,24 @@ void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep)
menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep); menu_add_prop(type, NULL, expr_alloc_symbol(sym), dep);
} }
void menu_add_option(int token, char *arg)
{
struct property *prop;
switch (token) {
case T_OPT_MODULES:
prop = prop_alloc(P_DEFAULT, modules_sym);
prop->expr = expr_alloc_symbol(current_entry->sym);
break;
case T_OPT_DEFCONFIG_LIST:
if (!sym_defconfig_list)
sym_defconfig_list = current_entry->sym;
else if (sym_defconfig_list != current_entry->sym)
zconf_error("trying to redefine defconfig symbol");
break;
}
}
static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2)
{ {
return sym2->type == S_INT || sym2->type == S_HEX || return sym2->type == S_INT || sym2->type == S_HEX ||
@ -325,11 +348,10 @@ void menu_finalize(struct menu *parent)
if (sym && !(sym->flags & SYMBOL_WARNED)) { if (sym && !(sym->flags & SYMBOL_WARNED)) {
if (sym->type == S_UNKNOWN) if (sym->type == S_UNKNOWN)
menu_warn(parent, "config symbol defined " menu_warn(parent, "config symbol defined without type");
"without type\n");
if (sym_is_choice(sym) && !parent->prompt) if (sym_is_choice(sym) && !parent->prompt)
menu_warn(parent, "choice must have a prompt\n"); menu_warn(parent, "choice must have a prompt");
/* Check properties connected to this symbol */ /* Check properties connected to this symbol */
sym_check_prop(sym); sym_check_prop(sym);

File diff suppressed because it is too large Load Diff

View File

@ -7,9 +7,25 @@
#if QT_VERSION >= 300 #if QT_VERSION >= 300
#include <qsettings.h> #include <qsettings.h>
#else #else
class QSettings { }; class QSettings {
public:
void beginGroup(const QString& group) { }
void endGroup(void) { }
bool readBoolEntry(const QString& key, bool def = FALSE, bool* ok = 0) const
{ if (ok) *ok = FALSE; return def; }
int readNumEntry(const QString& key, int def = 0, bool* ok = 0) const
{ if (ok) *ok = FALSE; return def; }
QString readEntry(const QString& key, const QString& def = QString::null, bool* ok = 0) const
{ if (ok) *ok = FALSE; return def; }
QStringList readListEntry(const QString& key, bool* ok = 0) const
{ if (ok) *ok = FALSE; return QStringList(); }
template <class t>
bool writeEntry(const QString& key, t value)
{ return TRUE; }
};
#endif #endif
class ConfigView;
class ConfigList; class ConfigList;
class ConfigItem; class ConfigItem;
class ConfigLineEdit; class ConfigLineEdit;
@ -18,64 +34,38 @@ class ConfigMainWindow;
class ConfigSettings : public QSettings { class ConfigSettings : public QSettings {
public: public:
ConfigSettings();
#if QT_VERSION >= 300
void readListSettings();
QValueList<int> readSizes(const QString& key, bool *ok); QValueList<int> readSizes(const QString& key, bool *ok);
bool writeSizes(const QString& key, const QValueList<int>& value); bool writeSizes(const QString& key, const QValueList<int>& value);
#endif
bool showAll;
bool showName;
bool showRange;
bool showData;
};
class ConfigView : public QVBox {
Q_OBJECT
typedef class QVBox Parent;
public:
ConfigView(QWidget* parent, ConfigMainWindow* cview, ConfigSettings* configSettings);
~ConfigView(void);
static void updateList(ConfigItem* item);
static void updateListAll(void);
public:
ConfigList* list;
ConfigLineEdit* lineEdit;
static ConfigView* viewList;
ConfigView* nextView;
}; };
enum colIdx { enum colIdx {
promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
}; };
enum listMode { enum listMode {
singleMode, menuMode, symbolMode, fullMode singleMode, menuMode, symbolMode, fullMode, listMode
}; };
class ConfigList : public QListView { class ConfigList : public QListView {
Q_OBJECT Q_OBJECT
typedef class QListView Parent; typedef class QListView Parent;
public: public:
ConfigList(ConfigView* p, ConfigMainWindow* cview, ConfigSettings *configSettings); ConfigList(ConfigView* p, const char *name = 0);
void reinit(void); void reinit(void);
ConfigView* parent(void) const ConfigView* parent(void) const
{ {
return (ConfigView*)Parent::parent(); return (ConfigView*)Parent::parent();
} }
ConfigItem* findConfigItem(struct menu *);
protected: protected:
ConfigMainWindow* cview;
void keyPressEvent(QKeyEvent *e); void keyPressEvent(QKeyEvent *e);
void contentsMousePressEvent(QMouseEvent *e); void contentsMousePressEvent(QMouseEvent *e);
void contentsMouseReleaseEvent(QMouseEvent *e); void contentsMouseReleaseEvent(QMouseEvent *e);
void contentsMouseMoveEvent(QMouseEvent *e); void contentsMouseMoveEvent(QMouseEvent *e);
void contentsMouseDoubleClickEvent(QMouseEvent *e); void contentsMouseDoubleClickEvent(QMouseEvent *e);
void focusInEvent(QFocusEvent *e); void focusInEvent(QFocusEvent *e);
void contextMenuEvent(QContextMenuEvent *e);
public slots: public slots:
void setRootMenu(struct menu *menu); void setRootMenu(struct menu *menu);
@ -83,10 +73,12 @@ public slots:
void setValue(ConfigItem* item, tristate val); void setValue(ConfigItem* item, tristate val);
void changeValue(ConfigItem* item); void changeValue(ConfigItem* item);
void updateSelection(void); void updateSelection(void);
void saveSettings(void);
signals: signals:
void menuChanged(struct menu *menu);
void menuSelected(struct menu *menu); void menuSelected(struct menu *menu);
void parentSelected(void); void parentSelected(void);
void gotFocus(void); void gotFocus(struct menu *);
public: public:
void updateListAll(void) void updateListAll(void)
@ -137,6 +129,7 @@ public:
struct menu *rootEntry; struct menu *rootEntry;
QColorGroup disabledColorGroup; QColorGroup disabledColorGroup;
QColorGroup inactivedColorGroup; QColorGroup inactivedColorGroup;
QPopupMenu* headerPopup;
private: private:
int colMap[colNr]; int colMap[colNr];
@ -208,9 +201,7 @@ class ConfigLineEdit : public QLineEdit {
Q_OBJECT Q_OBJECT
typedef class QLineEdit Parent; typedef class QLineEdit Parent;
public: public:
ConfigLineEdit(ConfigView* parent) ConfigLineEdit(ConfigView* parent);
: Parent(parent)
{ }
ConfigView* parent(void) const ConfigView* parent(void) const
{ {
return (ConfigView*)Parent::parent(); return (ConfigView*)Parent::parent();
@ -222,26 +213,104 @@ public:
ConfigItem *item; ConfigItem *item;
}; };
class ConfigView : public QVBox {
Q_OBJECT
typedef class QVBox Parent;
public:
ConfigView(QWidget* parent, const char *name = 0);
~ConfigView(void);
static void updateList(ConfigItem* item);
static void updateListAll(void);
bool showAll(void) const { return list->showAll; }
bool showName(void) const { return list->showName; }
bool showRange(void) const { return list->showRange; }
bool showData(void) const { return list->showData; }
public slots:
void setShowAll(bool);
void setShowName(bool);
void setShowRange(bool);
void setShowData(bool);
signals:
void showAllChanged(bool);
void showNameChanged(bool);
void showRangeChanged(bool);
void showDataChanged(bool);
public:
ConfigList* list;
ConfigLineEdit* lineEdit;
static ConfigView* viewList;
ConfigView* nextView;
};
class ConfigInfoView : public QTextBrowser {
Q_OBJECT
typedef class QTextBrowser Parent;
public:
ConfigInfoView(QWidget* parent, const char *name = 0);
bool showDebug(void) const { return _showDebug; }
public slots:
void setInfo(struct menu *menu);
void saveSettings(void);
void setSource(const QString& name);
void setShowDebug(bool);
signals:
void showDebugChanged(bool);
void menuSelected(struct menu *);
protected:
void symbolInfo(void);
void menuInfo(void);
QString debug_info(struct symbol *sym);
static QString print_filter(const QString &str);
static void expr_print_help(void *data, struct symbol *sym, const char *str);
QPopupMenu* createPopupMenu(const QPoint& pos);
void contentsContextMenuEvent(QContextMenuEvent *e);
struct symbol *sym;
struct menu *menu;
bool _showDebug;
};
class ConfigSearchWindow : public QDialog {
Q_OBJECT
typedef class QDialog Parent;
public:
ConfigSearchWindow(QWidget* parent, const char *name = 0);
public slots:
void saveSettings(void);
void search(void);
protected:
QLineEdit* editField;
QPushButton* searchButton;
QSplitter* split;
ConfigView* list;
ConfigInfoView* info;
struct symbol **result;
};
class ConfigMainWindow : public QMainWindow { class ConfigMainWindow : public QMainWindow {
Q_OBJECT Q_OBJECT
public: public:
ConfigMainWindow(void); ConfigMainWindow(void);
public slots: public slots:
void setHelp(QListViewItem* item);
void changeMenu(struct menu *); void changeMenu(struct menu *);
void setMenuLink(struct menu *);
void listFocusChanged(void); void listFocusChanged(void);
void goBack(void); void goBack(void);
void loadConfig(void); void loadConfig(void);
void saveConfig(void); void saveConfig(void);
void saveConfigAs(void); void saveConfigAs(void);
void searchConfig(void);
void showSingleView(void); void showSingleView(void);
void showSplitView(void); void showSplitView(void);
void showFullView(void); void showFullView(void);
void setShowAll(bool);
void setShowDebug(bool);
void setShowRange(bool);
void setShowName(bool);
void setShowData(bool);
void showIntro(void); void showIntro(void);
void showAbout(void); void showAbout(void);
void saveSettings(void); void saveSettings(void);
@ -249,15 +318,14 @@ public slots:
protected: protected:
void closeEvent(QCloseEvent *e); void closeEvent(QCloseEvent *e);
ConfigSearchWindow *searchWindow;
ConfigView *menuView; ConfigView *menuView;
ConfigList *menuList; ConfigList *menuList;
ConfigView *configView; ConfigView *configView;
ConfigList *configList; ConfigList *configList;
QTextView *helpText; ConfigInfoView *helpText;
QToolBar *toolBar; QToolBar *toolBar;
QAction *backAction; QAction *backAction;
QSplitter* split1; QSplitter* split1;
QSplitter* split2; QSplitter* split2;
bool showDebug;
}; };

View File

@ -15,15 +15,15 @@
struct symbol symbol_yes = { struct symbol symbol_yes = {
.name = "y", .name = "y",
.curr = { "y", yes }, .curr = { "y", yes },
.flags = SYMBOL_YES|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_mod = { }, symbol_mod = {
.name = "m", .name = "m",
.curr = { "m", mod }, .curr = { "m", mod },
.flags = SYMBOL_MOD|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_no = { }, symbol_no = {
.name = "n", .name = "n",
.curr = { "n", no }, .curr = { "n", no },
.flags = SYMBOL_NO|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}, symbol_empty = { }, symbol_empty = {
.name = "", .name = "",
.curr = { "", no }, .curr = { "", no },
@ -31,6 +31,7 @@ struct symbol symbol_yes = {
}; };
int sym_change_count; int sym_change_count;
struct symbol *sym_defconfig_list;
struct symbol *modules_sym; struct symbol *modules_sym;
tristate modules_val; tristate modules_val;
@ -227,7 +228,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
struct expr *e; struct expr *e;
/* is the user choice visible? */ /* is the user choice visible? */
def_sym = sym->user.val; def_sym = sym->def[S_DEF_USER].val;
if (def_sym) { if (def_sym) {
sym_calc_visibility(def_sym); sym_calc_visibility(def_sym);
if (def_sym->visible != no) if (def_sym->visible != no)
@ -306,7 +307,7 @@ void sym_calc_value(struct symbol *sym)
} else if (E_OR(sym->visible, sym->rev_dep.tri) != no) { } else if (E_OR(sym->visible, sym->rev_dep.tri) != no) {
sym->flags |= SYMBOL_WRITE; sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) if (sym_has_value(sym))
newval.tri = sym->user.tri; newval.tri = sym->def[S_DEF_USER].tri;
else if (!sym_is_choice(sym)) { else if (!sym_is_choice(sym)) {
prop = sym_get_default_prop(sym); prop = sym_get_default_prop(sym);
if (prop) if (prop)
@ -329,7 +330,7 @@ void sym_calc_value(struct symbol *sym)
if (sym->visible != no) { if (sym->visible != no) {
sym->flags |= SYMBOL_WRITE; sym->flags |= SYMBOL_WRITE;
if (sym_has_value(sym)) { if (sym_has_value(sym)) {
newval.val = sym->user.val; newval.val = sym->def[S_DEF_USER].val;
break; break;
} }
} }
@ -352,10 +353,13 @@ void sym_calc_value(struct symbol *sym)
sym->curr.val = sym_calc_choice(sym); sym->curr.val = sym_calc_choice(sym);
sym_validate_range(sym); sym_validate_range(sym);
if (memcmp(&oldval, &sym->curr, sizeof(oldval))) if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
sym_set_changed(sym); sym_set_changed(sym);
if (modules_sym == sym) if (modules_sym == sym) {
modules_val = modules_sym->curr.tri; sym_set_all_changed();
modules_val = modules_sym->curr.tri;
}
}
if (sym_is_choice(sym)) { if (sym_is_choice(sym)) {
int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE); int flags = sym->flags & (SYMBOL_CHANGED | SYMBOL_WRITE);
@ -426,8 +430,8 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
if (oldval != val && !sym_tristate_within_range(sym, val)) if (oldval != val && !sym_tristate_within_range(sym, val))
return false; return false;
if (sym->flags & SYMBOL_NEW) { if (!(sym->flags & SYMBOL_DEF_USER)) {
sym->flags &= ~SYMBOL_NEW; sym->flags |= SYMBOL_DEF_USER;
sym_set_changed(sym); sym_set_changed(sym);
} }
/* /*
@ -439,21 +443,18 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
struct property *prop; struct property *prop;
struct expr *e; struct expr *e;
cs->user.val = sym; cs->def[S_DEF_USER].val = sym;
cs->flags &= ~SYMBOL_NEW; cs->flags |= SYMBOL_DEF_USER;
prop = sym_get_choice_prop(cs); prop = sym_get_choice_prop(cs);
for (e = prop->expr; e; e = e->left.expr) { for (e = prop->expr; e; e = e->left.expr) {
if (e->right.sym->visible != no) if (e->right.sym->visible != no)
e->right.sym->flags &= ~SYMBOL_NEW; e->right.sym->flags |= SYMBOL_DEF_USER;
} }
} }
sym->user.tri = val; sym->def[S_DEF_USER].tri = val;
if (oldval != val) { if (oldval != val)
sym_clear_all_valid(); sym_clear_all_valid();
if (sym == modules_sym)
sym_set_all_changed();
}
return true; return true;
} }
@ -591,20 +592,20 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
if (!sym_string_within_range(sym, newval)) if (!sym_string_within_range(sym, newval))
return false; return false;
if (sym->flags & SYMBOL_NEW) { if (!(sym->flags & SYMBOL_DEF_USER)) {
sym->flags &= ~SYMBOL_NEW; sym->flags |= SYMBOL_DEF_USER;
sym_set_changed(sym); sym_set_changed(sym);
} }
oldval = sym->user.val; oldval = sym->def[S_DEF_USER].val;
size = strlen(newval) + 1; size = strlen(newval) + 1;
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) { if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
size += 2; size += 2;
sym->user.val = val = malloc(size); sym->def[S_DEF_USER].val = val = malloc(size);
*val++ = '0'; *val++ = '0';
*val++ = 'x'; *val++ = 'x';
} else if (!oldval || strcmp(oldval, newval)) } else if (!oldval || strcmp(oldval, newval))
sym->user.val = val = malloc(size); sym->def[S_DEF_USER].val = val = malloc(size);
else else
return true; return true;
@ -679,7 +680,6 @@ struct symbol *sym_lookup(const char *name, int isconst)
memset(symbol, 0, sizeof(*symbol)); memset(symbol, 0, sizeof(*symbol));
symbol->name = new_name; symbol->name = new_name;
symbol->type = S_UNKNOWN; symbol->type = S_UNKNOWN;
symbol->flags = SYMBOL_NEW;
if (isconst) if (isconst)
symbol->flags |= SYMBOL_CONST; symbol->flags |= SYMBOL_CONST;

View File

@ -44,7 +44,9 @@ int file_write_dep(const char *name)
else else
fprintf(out, "\t%s\n", file->name); fprintf(out, "\t%s\n", file->name);
} }
fprintf(out, "\n.config include/linux/autoconf.h: $(deps_config)\n\n$(deps_config):\n"); fprintf(out, "\ninclude/config/auto.conf: \\\n"
"\t$(deps_config)\n\n"
"$(deps_config): ;\n");
fclose(out); fclose(out);
rename("..config.tmp", name); rename("..config.tmp", name);
return 0; return 0;

View File

@ -39,5 +39,8 @@ string, T_TYPE, TF_COMMAND, S_STRING
select, T_SELECT, TF_COMMAND select, T_SELECT, TF_COMMAND
enable, T_SELECT, TF_COMMAND enable, T_SELECT, TF_COMMAND
range, T_RANGE, TF_COMMAND range, T_RANGE, TF_COMMAND
option, T_OPTION, TF_COMMAND
on, T_ON, TF_PARAM on, T_ON, TF_PARAM
modules, T_OPT_MODULES, TF_OPTION
defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION
%% %%

View File

@ -53,10 +53,10 @@ kconf_id_hash (register const char *str, register unsigned int len)
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 25, 10, 15, 47, 47, 47, 47, 47, 47, 47, 25, 30, 15,
0, 0, 5, 47, 0, 0, 47, 47, 0, 10, 0, 15, 0, 47, 5, 15, 47, 47, 30, 20,
0, 20, 20, 20, 5, 0, 0, 20, 47, 47, 5, 0, 25, 15, 0, 0, 10, 35, 47, 47,
20, 47, 47, 47, 47, 47, 47, 47, 47, 47, 5, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47, 47,
@ -88,69 +88,75 @@ kconf_id_hash (register const char *str, register unsigned int len)
struct kconf_id_strings_t struct kconf_id_strings_t
{ {
char kconf_id_strings_str2[sizeof("if")]; char kconf_id_strings_str2[sizeof("on")];
char kconf_id_strings_str3[sizeof("int")]; char kconf_id_strings_str6[sizeof("string")];
char kconf_id_strings_str4[sizeof("help")]; char kconf_id_strings_str7[sizeof("default")];
char kconf_id_strings_str5[sizeof("endif")]; char kconf_id_strings_str8[sizeof("def_bool")];
char kconf_id_strings_str6[sizeof("select")];
char kconf_id_strings_str7[sizeof("endmenu")];
char kconf_id_strings_str8[sizeof("tristate")];
char kconf_id_strings_str9[sizeof("endchoice")];
char kconf_id_strings_str10[sizeof("range")]; char kconf_id_strings_str10[sizeof("range")];
char kconf_id_strings_str11[sizeof("string")]; char kconf_id_strings_str11[sizeof("def_boolean")];
char kconf_id_strings_str12[sizeof("default")]; char kconf_id_strings_str12[sizeof("def_tristate")];
char kconf_id_strings_str13[sizeof("def_bool")]; char kconf_id_strings_str13[sizeof("hex")];
char kconf_id_strings_str14[sizeof("menu")]; char kconf_id_strings_str14[sizeof("defconfig_list")];
char kconf_id_strings_str16[sizeof("def_boolean")]; char kconf_id_strings_str16[sizeof("option")];
char kconf_id_strings_str17[sizeof("def_tristate")]; char kconf_id_strings_str17[sizeof("if")];
char kconf_id_strings_str18[sizeof("mainmenu")]; char kconf_id_strings_str18[sizeof("optional")];
char kconf_id_strings_str20[sizeof("menuconfig")]; char kconf_id_strings_str20[sizeof("endif")];
char kconf_id_strings_str21[sizeof("config")]; char kconf_id_strings_str21[sizeof("choice")];
char kconf_id_strings_str22[sizeof("on")]; char kconf_id_strings_str22[sizeof("endmenu")];
char kconf_id_strings_str23[sizeof("hex")]; char kconf_id_strings_str23[sizeof("requires")];
char kconf_id_strings_str26[sizeof("source")]; char kconf_id_strings_str24[sizeof("endchoice")];
char kconf_id_strings_str27[sizeof("depends")]; char kconf_id_strings_str26[sizeof("config")];
char kconf_id_strings_str28[sizeof("optional")]; char kconf_id_strings_str27[sizeof("modules")];
char kconf_id_strings_str31[sizeof("enable")]; char kconf_id_strings_str28[sizeof("int")];
char kconf_id_strings_str32[sizeof("comment")]; char kconf_id_strings_str29[sizeof("menu")];
char kconf_id_strings_str33[sizeof("requires")]; char kconf_id_strings_str31[sizeof("prompt")];
char kconf_id_strings_str32[sizeof("depends")];
char kconf_id_strings_str33[sizeof("tristate")];
char kconf_id_strings_str34[sizeof("bool")]; char kconf_id_strings_str34[sizeof("bool")];
char kconf_id_strings_str35[sizeof("menuconfig")];
char kconf_id_strings_str36[sizeof("select")];
char kconf_id_strings_str37[sizeof("boolean")]; char kconf_id_strings_str37[sizeof("boolean")];
char kconf_id_strings_str41[sizeof("choice")]; char kconf_id_strings_str39[sizeof("help")];
char kconf_id_strings_str46[sizeof("prompt")]; char kconf_id_strings_str41[sizeof("source")];
char kconf_id_strings_str42[sizeof("comment")];
char kconf_id_strings_str43[sizeof("mainmenu")];
char kconf_id_strings_str46[sizeof("enable")];
}; };
static struct kconf_id_strings_t kconf_id_strings_contents = static struct kconf_id_strings_t kconf_id_strings_contents =
{ {
"if", "on",
"int",
"help",
"endif",
"select",
"endmenu",
"tristate",
"endchoice",
"range",
"string", "string",
"default", "default",
"def_bool", "def_bool",
"menu", "range",
"def_boolean", "def_boolean",
"def_tristate", "def_tristate",
"mainmenu",
"menuconfig",
"config",
"on",
"hex", "hex",
"source", "defconfig_list",
"depends", "option",
"if",
"optional", "optional",
"enable", "endif",
"comment",
"requires",
"bool",
"boolean",
"choice", "choice",
"prompt" "endmenu",
"requires",
"endchoice",
"config",
"modules",
"int",
"menu",
"prompt",
"depends",
"tristate",
"bool",
"menuconfig",
"select",
"boolean",
"help",
"source",
"comment",
"mainmenu",
"enable"
}; };
#define kconf_id_strings ((const char *) &kconf_id_strings_contents) #define kconf_id_strings ((const char *) &kconf_id_strings_contents)
#ifdef __GNUC__ #ifdef __GNUC__
@ -161,9 +167,9 @@ kconf_id_lookup (register const char *str, register unsigned int len)
{ {
enum enum
{ {
TOTAL_KEYWORDS = 30, TOTAL_KEYWORDS = 33,
MIN_WORD_LENGTH = 2, MIN_WORD_LENGTH = 2,
MAX_WORD_LENGTH = 12, MAX_WORD_LENGTH = 14,
MIN_HASH_VALUE = 2, MIN_HASH_VALUE = 2,
MAX_HASH_VALUE = 46 MAX_HASH_VALUE = 46
}; };
@ -171,43 +177,48 @@ kconf_id_lookup (register const char *str, register unsigned int len)
static struct kconf_id wordlist[] = static struct kconf_id wordlist[] =
{ {
{-1}, {-1}, {-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_IF, TF_COMMAND|TF_PARAM}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str3, T_TYPE, TF_COMMAND, S_INT},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str4, T_HELP, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str5, T_ENDIF, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_SELECT, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_ENDMENU, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_TYPE, TF_COMMAND, S_TRISTATE},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str9, T_ENDCHOICE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_TYPE, TF_COMMAND, S_STRING},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_MENU, TF_COMMAND},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_DEFAULT, TF_COMMAND, S_TRISTATE},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_MAINMENU, TF_COMMAND},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_MENUCONFIG, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CONFIG, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ON, TF_PARAM},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_TYPE, TF_COMMAND, S_HEX},
{-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_SOURCE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_DEPENDS, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_OPTIONAL, TF_COMMAND},
{-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_SELECT, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_COMMENT, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_REQUIRES, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN},
{-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN},
{-1}, {-1}, {-1}, {-1}, {-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str6, T_TYPE, TF_COMMAND, S_STRING},
{-1}, {-1}, {-1}, {-1}, {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str7, T_DEFAULT, TF_COMMAND, S_UNKNOWN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_PROMPT, TF_COMMAND} {(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str8, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str10, T_RANGE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str11, T_DEFAULT, TF_COMMAND, S_BOOLEAN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str12, T_DEFAULT, TF_COMMAND, S_TRISTATE},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str13, T_TYPE, TF_COMMAND, S_HEX},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str14, T_OPT_DEFCONFIG_LIST,TF_OPTION},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str16, T_OPTION, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str17, T_IF, TF_COMMAND|TF_PARAM},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str18, T_OPTIONAL, TF_COMMAND},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str20, T_ENDIF, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str21, T_CHOICE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str22, T_ENDMENU, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str23, T_REQUIRES, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str24, T_ENDCHOICE, TF_COMMAND},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str26, T_CONFIG, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str27, T_OPT_MODULES, TF_OPTION},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str28, T_TYPE, TF_COMMAND, S_INT},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str29, T_MENU, TF_COMMAND},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str31, T_PROMPT, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str32, T_DEPENDS, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str33, T_TYPE, TF_COMMAND, S_TRISTATE},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str34, T_TYPE, TF_COMMAND, S_BOOLEAN},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str35, T_MENUCONFIG, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str36, T_SELECT, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str37, T_TYPE, TF_COMMAND, S_BOOLEAN},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str39, T_HELP, TF_COMMAND},
{-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_SOURCE, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str42, T_COMMENT, TF_COMMAND},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str43, T_MAINMENU, TF_COMMAND},
{-1}, {-1},
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str46, T_SELECT, TF_COMMAND}
}; };
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)

File diff suppressed because it is too large Load Diff

View File

@ -71,6 +71,7 @@ static struct menu *current_menu, *current_entry;
%token <id>T_DEFAULT %token <id>T_DEFAULT
%token <id>T_SELECT %token <id>T_SELECT
%token <id>T_RANGE %token <id>T_RANGE
%token <id>T_OPTION
%token <id>T_ON %token <id>T_ON
%token <string> T_WORD %token <string> T_WORD
%token <string> T_WORD_QUOTE %token <string> T_WORD_QUOTE
@ -91,6 +92,7 @@ static struct menu *current_menu, *current_entry;
%type <id> end %type <id> end
%type <id> option_name %type <id> option_name
%type <menu> if_entry menu_entry choice_entry %type <menu> if_entry menu_entry choice_entry
%type <string> symbol_option_arg
%destructor { %destructor {
fprintf(stderr, "%s:%d: missing end statement for this entry\n", fprintf(stderr, "%s:%d: missing end statement for this entry\n",
@ -173,6 +175,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
config_option_list: config_option_list:
/* empty */ /* empty */
| config_option_list config_option | config_option_list config_option
| config_option_list symbol_option
| config_option_list depends | config_option_list depends
| config_option_list help | config_option_list help
| config_option_list option_error | config_option_list option_error
@ -215,6 +218,26 @@ config_option: T_RANGE symbol symbol if_expr T_EOL
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
}; };
symbol_option: T_OPTION symbol_option_list T_EOL
;
symbol_option_list:
/* empty */
| symbol_option_list T_WORD symbol_option_arg
{
struct kconf_id *id = kconf_id_lookup($2, strlen($2));
if (id && id->flags & TF_OPTION)
menu_add_option(id->token, $3);
else
zconfprint("warning: ignoring unknown option %s", $2);
free($2);
};
symbol_option_arg:
/* empty */ { $$ = NULL; }
| T_EQUAL prompt { $$ = $2; }
;
/* choice entry */ /* choice entry */
choice: T_CHOICE T_EOL choice: T_CHOICE T_EOL
@ -458,7 +481,9 @@ void conf_parse(const char *name)
sym_init(); sym_init();
menu_init(); menu_init();
modules_sym = sym_lookup("MODULES", 0); modules_sym = sym_lookup(NULL, 0);
modules_sym->type = S_BOOLEAN;
modules_sym->flags |= SYMBOL_AUTO;
rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL); rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
#if YYDEBUG #if YYDEBUG
@ -468,6 +493,12 @@ void conf_parse(const char *name)
zconfparse(); zconfparse();
if (zconfnerrs) if (zconfnerrs)
exit(1); exit(1);
if (!modules_sym->prop) {
struct property *prop;
prop = prop_alloc(P_DEFAULT, modules_sym);
prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
}
menu_finalize(&rootmenu); menu_finalize(&rootmenu);
for_all_symbols(i, sym) { for_all_symbols(i, sym) {
sym_check_deps(sym); sym_check_deps(sym);

View File

@ -28,7 +28,7 @@ main(int argc, char **argv)
printf("#define KERNEL_ELFCLASS ELFCLASS64\n"); printf("#define KERNEL_ELFCLASS ELFCLASS64\n");
break; break;
default: default:
abort(); exit(1);
} }
switch (ei[EI_DATA]) { switch (ei[EI_DATA]) {
case ELFDATA2LSB: case ELFDATA2LSB:
@ -38,7 +38,7 @@ main(int argc, char **argv)
printf("#define KERNEL_ELFDATA ELFDATA2MSB\n"); printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
break; break;
default: default:
abort(); exit(1);
} }
if (sizeof(unsigned long) == 4) { if (sizeof(unsigned long) == 4) {
@ -53,7 +53,7 @@ main(int argc, char **argv)
else if (memcmp(endian_test.c, "\x02\x01", 2) == 0) else if (memcmp(endian_test.c, "\x02\x01", 2) == 0)
printf("#define HOST_ELFDATA ELFDATA2LSB\n"); printf("#define HOST_ELFDATA ELFDATA2LSB\n");
else else
abort(); exit(1);
if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0))
printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");

View File

@ -13,6 +13,7 @@
#include <ctype.h> #include <ctype.h>
#include "modpost.h" #include "modpost.h"
#include "../../include/linux/license.h"
/* Are we using CONFIG_MODVERSIONS? */ /* Are we using CONFIG_MODVERSIONS? */
int modversions = 0; int modversions = 0;
@ -22,6 +23,8 @@ int have_vmlinux = 0;
static int all_versions = 0; static int all_versions = 0;
/* If we are modposting external module set to 1 */ /* If we are modposting external module set to 1 */
static int external_module = 0; static int external_module = 0;
/* How a symbol is exported */
enum export {export_plain, export_gpl, export_gpl_future, export_unknown};
void fatal(const char *fmt, ...) void fatal(const char *fmt, ...)
{ {
@ -97,6 +100,7 @@ static struct module *new_module(char *modname)
/* add to list */ /* add to list */
mod->name = p; mod->name = p;
mod->gpl_compatible = -1;
mod->next = modules; mod->next = modules;
modules = mod; modules = mod;
@ -118,6 +122,7 @@ struct symbol {
unsigned int kernel:1; /* 1 if symbol is from kernel unsigned int kernel:1; /* 1 if symbol is from kernel
* (only for external modules) **/ * (only for external modules) **/
unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
enum export export; /* Type of export */
char name[0]; char name[0];
}; };
@ -153,7 +158,8 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak,
} }
/* For the hash of exported symbols */ /* For the hash of exported symbols */
static struct symbol *new_symbol(const char *name, struct module *module) static struct symbol *new_symbol(const char *name, struct module *module,
enum export export)
{ {
unsigned int hash; unsigned int hash;
struct symbol *new; struct symbol *new;
@ -161,6 +167,7 @@ static struct symbol *new_symbol(const char *name, struct module *module)
hash = tdb_hash(name) % SYMBOL_HASH_SIZE; hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
new->module = module; new->module = module;
new->export = export;
return new; return new;
} }
@ -179,16 +186,55 @@ static struct symbol *find_symbol(const char *name)
return NULL; return NULL;
} }
static struct {
const char *str;
enum export export;
} export_list[] = {
{ .str = "EXPORT_SYMBOL", .export = export_plain },
{ .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
{ .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
{ .str = "(unknown)", .export = export_unknown },
};
static const char *export_str(enum export ex)
{
return export_list[ex].str;
}
static enum export export_no(const char * s)
{
int i;
for (i = 0; export_list[i].export != export_unknown; i++) {
if (strcmp(export_list[i].str, s) == 0)
return export_list[i].export;
}
return export_unknown;
}
static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
{
if (sec == elf->export_sec)
return export_plain;
else if (sec == elf->export_gpl_sec)
return export_gpl;
else if (sec == elf->export_gpl_future_sec)
return export_gpl_future;
else
return export_unknown;
}
/** /**
* Add an exported symbol - it may have already been added without a * Add an exported symbol - it may have already been added without a
* CRC, in this case just update the CRC * CRC, in this case just update the CRC
**/ **/
static struct symbol *sym_add_exported(const char *name, struct module *mod) static struct symbol *sym_add_exported(const char *name, struct module *mod,
enum export export)
{ {
struct symbol *s = find_symbol(name); struct symbol *s = find_symbol(name);
if (!s) { if (!s) {
s = new_symbol(name, mod); s = new_symbol(name, mod, export);
} else { } else {
if (!s->preloaded) { if (!s->preloaded) {
warn("%s: '%s' exported twice. Previous export " warn("%s: '%s' exported twice. Previous export "
@ -200,16 +246,17 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod)
s->preloaded = 0; s->preloaded = 0;
s->vmlinux = is_vmlinux(mod->name); s->vmlinux = is_vmlinux(mod->name);
s->kernel = 0; s->kernel = 0;
s->export = export;
return s; return s;
} }
static void sym_update_crc(const char *name, struct module *mod, static void sym_update_crc(const char *name, struct module *mod,
unsigned int crc) unsigned int crc, enum export export)
{ {
struct symbol *s = find_symbol(name); struct symbol *s = find_symbol(name);
if (!s) if (!s)
s = new_symbol(name, mod); s = new_symbol(name, mod, export);
s->crc = crc; s->crc = crc;
s->crc_valid = 1; s->crc_valid = 1;
} }
@ -283,7 +330,7 @@ static void parse_elf(struct elf_info *info, const char *filename)
hdr = grab_file(filename, &info->size); hdr = grab_file(filename, &info->size);
if (!hdr) { if (!hdr) {
perror(filename); perror(filename);
abort(); exit(1);
} }
info->hdr = hdr; info->hdr = hdr;
if (info->size < sizeof(*hdr)) if (info->size < sizeof(*hdr))
@ -309,13 +356,21 @@ static void parse_elf(struct elf_info *info, const char *filename)
for (i = 1; i < hdr->e_shnum; i++) { for (i = 1; i < hdr->e_shnum; i++) {
const char *secstrings const char *secstrings
= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
const char *secname;
if (sechdrs[i].sh_offset > info->size) if (sechdrs[i].sh_offset > info->size)
goto truncated; goto truncated;
if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) { secname = secstrings + sechdrs[i].sh_name;
if (strcmp(secname, ".modinfo") == 0) {
info->modinfo = (void *)hdr + sechdrs[i].sh_offset; info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
info->modinfo_len = sechdrs[i].sh_size; info->modinfo_len = sechdrs[i].sh_size;
} } else if (strcmp(secname, "__ksymtab") == 0)
info->export_sec = i;
else if (strcmp(secname, "__ksymtab_gpl") == 0)
info->export_gpl_sec = i;
else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
info->export_gpl_future_sec = i;
if (sechdrs[i].sh_type != SHT_SYMTAB) if (sechdrs[i].sh_type != SHT_SYMTAB)
continue; continue;
@ -353,6 +408,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname) Elf_Sym *sym, const char *symname)
{ {
unsigned int crc; unsigned int crc;
enum export export = export_from_sec(info, sym->st_shndx);
switch (sym->st_shndx) { switch (sym->st_shndx) {
case SHN_COMMON: case SHN_COMMON:
@ -362,7 +418,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
/* CRC'd symbol */ /* CRC'd symbol */
if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
crc = (unsigned int) sym->st_value; crc = (unsigned int) sym->st_value;
sym_update_crc(symname + strlen(CRC_PFX), mod, crc); sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
export);
} }
break; break;
case SHN_UNDEF: case SHN_UNDEF:
@ -406,7 +463,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
default: default:
/* All exported symbols */ /* All exported symbols */
if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
sym_add_exported(symname + strlen(KSYMTAB_PFX), mod); sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
export);
} }
if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
mod->has_init = 1; mod->has_init = 1;
@ -437,13 +495,18 @@ static char *next_string(char *string, unsigned long *secsize)
return string; return string;
} }
static char *get_modinfo(void *modinfo, unsigned long modinfo_len, static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
const char *tag) const char *tag, char *info)
{ {
char *p; char *p;
unsigned int taglen = strlen(tag); unsigned int taglen = strlen(tag);
unsigned long size = modinfo_len; unsigned long size = modinfo_len;
if (info) {
size -= info - (char *)modinfo;
modinfo = next_string(info, &size);
}
for (p = modinfo; p; p = next_string(p, &size)) { for (p = modinfo; p; p = next_string(p, &size)) {
if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
return p + taglen + 1; return p + taglen + 1;
@ -451,6 +514,13 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
return NULL; return NULL;
} }
static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
const char *tag)
{
return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
}
/** /**
* Test if string s ends in string sub * Test if string s ends in string sub
* return 0 if match * return 0 if match
@ -821,6 +891,10 @@ static int init_section_ref_ok(const char *name)
".pci_fixup_final", ".pci_fixup_final",
".pdr", ".pdr",
"__param", "__param",
"__ex_table",
".fixup",
".smp_locks",
".plt", /* seen on ARCH=um build on x86_64. Harmless */
NULL NULL
}; };
/* Start of section names */ /* Start of section names */
@ -846,6 +920,8 @@ static int init_section_ref_ok(const char *name)
for (s = namelist3; *s; s++) for (s = namelist3; *s; s++)
if (strstr(name, *s) != NULL) if (strstr(name, *s) != NULL)
return 1; return 1;
if (strrcmp(name, ".init") == 0)
return 1;
return 0; return 0;
} }
@ -892,6 +968,10 @@ static int exit_section_ref_ok(const char *name)
".exitcall.exit", ".exitcall.exit",
".eh_frame", ".eh_frame",
".stab", ".stab",
"__ex_table",
".fixup",
".smp_locks",
".plt", /* seen on ARCH=um build on x86_64. Harmless */
NULL NULL
}; };
/* Start of section names */ /* Start of section names */
@ -921,6 +1001,7 @@ static void read_symbols(char *modname)
{ {
const char *symname; const char *symname;
char *version; char *version;
char *license;
struct module *mod; struct module *mod;
struct elf_info info = { }; struct elf_info info = { };
Elf_Sym *sym; Elf_Sym *sym;
@ -936,6 +1017,18 @@ static void read_symbols(char *modname)
mod->skip = 1; mod->skip = 1;
} }
license = get_modinfo(info.modinfo, info.modinfo_len, "license");
while (license) {
if (license_is_gpl_compatible(license))
mod->gpl_compatible = 1;
else {
mod->gpl_compatible = 0;
break;
}
license = get_next_modinfo(info.modinfo, info.modinfo_len,
"license", license);
}
for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
symname = info.strtab + sym->st_name; symname = info.strtab + sym->st_name;
@ -992,6 +1085,41 @@ void buf_write(struct buffer *buf, const char *s, int len)
buf->pos += len; buf->pos += len;
} }
void check_license(struct module *mod)
{
struct symbol *s, *exp;
for (s = mod->unres; s; s = s->next) {
const char *basename;
if (mod->gpl_compatible == 1) {
/* GPL-compatible modules may use all symbols */
continue;
}
exp = find_symbol(s->name);
if (!exp || exp->module == mod)
continue;
basename = strrchr(mod->name, '/');
if (basename)
basename++;
switch (exp->export) {
case export_gpl:
fatal("modpost: GPL-incompatible module %s "
"uses GPL-only symbol '%s'\n",
basename ? basename : mod->name,
exp->name);
break;
case export_gpl_future:
warn("modpost: GPL-incompatible module %s "
"uses future GPL-only symbol '%s'\n",
basename ? basename : mod->name,
exp->name);
break;
case export_plain: /* ignore */ break;
case export_unknown: /* ignore */ break;
}
}
}
/** /**
* Header for the generated file * Header for the generated file
**/ **/
@ -1142,6 +1270,9 @@ static void write_if_changed(struct buffer *b, const char *fname)
fclose(file); fclose(file);
} }
/* parse Module.symvers file. line format:
* 0x12345678<tab>symbol<tab>module[<tab>export]
**/
static void read_dump(const char *fname, unsigned int kernel) static void read_dump(const char *fname, unsigned int kernel)
{ {
unsigned long size, pos = 0; unsigned long size, pos = 0;
@ -1153,7 +1284,7 @@ static void read_dump(const char *fname, unsigned int kernel)
return; return;
while ((line = get_next_line(&pos, file, size))) { while ((line = get_next_line(&pos, file, size))) {
char *symname, *modname, *d; char *symname, *modname, *d, *export;
unsigned int crc; unsigned int crc;
struct module *mod; struct module *mod;
struct symbol *s; struct symbol *s;
@ -1164,8 +1295,9 @@ static void read_dump(const char *fname, unsigned int kernel)
if (!(modname = strchr(symname, '\t'))) if (!(modname = strchr(symname, '\t')))
goto fail; goto fail;
*modname++ = '\0'; *modname++ = '\0';
if (strchr(modname, '\t')) if ((export = strchr(modname, '\t')) != NULL)
goto fail; *export++ = '\0';
crc = strtoul(line, &d, 16); crc = strtoul(line, &d, 16);
if (*symname == '\0' || *modname == '\0' || *d != '\0') if (*symname == '\0' || *modname == '\0' || *d != '\0')
goto fail; goto fail;
@ -1177,10 +1309,10 @@ static void read_dump(const char *fname, unsigned int kernel)
mod = new_module(NOFAIL(strdup(modname))); mod = new_module(NOFAIL(strdup(modname)));
mod->skip = 1; mod->skip = 1;
} }
s = sym_add_exported(symname, mod); s = sym_add_exported(symname, mod, export_no(export));
s->kernel = kernel; s->kernel = kernel;
s->preloaded = 1; s->preloaded = 1;
sym_update_crc(symname, mod, crc); sym_update_crc(symname, mod, crc, export_no(export));
} }
return; return;
fail: fail:
@ -1210,9 +1342,10 @@ static void write_dump(const char *fname)
symbol = symbolhash[n]; symbol = symbolhash[n];
while (symbol) { while (symbol) {
if (dump_sym(symbol)) if (dump_sym(symbol))
buf_printf(&buf, "0x%08x\t%s\t%s\n", buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
symbol->crc, symbol->name, symbol->crc, symbol->name,
symbol->module->name); symbol->module->name,
export_str(symbol->export));
symbol = symbol->next; symbol = symbol->next;
} }
} }
@ -1260,6 +1393,12 @@ int main(int argc, char **argv)
read_symbols(argv[optind++]); read_symbols(argv[optind++]);
} }
for (mod = modules; mod; mod = mod->next) {
if (mod->skip)
continue;
check_license(mod);
}
for (mod = modules; mod; mod = mod->next) { for (mod = modules; mod; mod = mod->next) {
if (mod->skip) if (mod->skip)
continue; continue;

View File

@ -100,6 +100,7 @@ buf_write(struct buffer *buf, const char *s, int len);
struct module { struct module {
struct module *next; struct module *next;
const char *name; const char *name;
int gpl_compatible;
struct symbol *unres; struct symbol *unres;
int seen; int seen;
int skip; int skip;
@ -115,6 +116,9 @@ struct elf_info {
Elf_Shdr *sechdrs; Elf_Shdr *sechdrs;
Elf_Sym *symtab_start; Elf_Sym *symtab_start;
Elf_Sym *symtab_stop; Elf_Sym *symtab_stop;
Elf_Section export_sec;
Elf_Section export_gpl_sec;
Elf_Section export_gpl_future_sec;
const char *strtab; const char *strtab;
char *modinfo; char *modinfo;
unsigned int modinfo_len; unsigned int modinfo_len;

View File

@ -73,8 +73,13 @@ echo "%ifarch ia64"
echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE" echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/" echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
echo "%else" echo "%else"
echo "%ifarch ppc64"
echo "cp vmlinux arch/powerpc/boot"
echo "cp arch/powerpc/boot/"'$KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE"
echo "%else"
echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE" echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE"
echo "%endif" echo "%endif"
echo "%endif"
echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE" echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE"

View File

@ -11,12 +11,12 @@ cd "${1:-.}" || usage
# Check for git and a git repo. # Check for git and a git repo.
if head=`git rev-parse --verify HEAD 2>/dev/null`; then if head=`git rev-parse --verify HEAD 2>/dev/null`; then
# Do we have an untagged version? # Do we have an untagged version?
if [ "`git name-rev --tags HEAD`" = "HEAD undefined" ]; then if git name-rev --tags HEAD | grep -E '^HEAD[[:space:]]+(.*~[0-9]*|undefined)$' > /dev/null; then
printf '%s%s' -g `echo "$head" | cut -c1-8` printf '%s%s' -g `echo "$head" | cut -c1-8`
fi fi
# Are there uncommitted changes? # Are there uncommitted changes?
if git diff-files | read dummy; then if git diff-index HEAD | read dummy; then
printf '%s' -dirty printf '%s' -dirty
fi fi
fi fi

View File

@ -839,6 +839,6 @@ config SOUND_SH_DAC_AUDIO
depends on SOUND_PRIME && CPU_SH3 depends on SOUND_PRIME && CPU_SH3
config SOUND_SH_DAC_AUDIO_CHANNEL config SOUND_SH_DAC_AUDIO_CHANNEL
int " DAC channel" int "DAC channel"
default "1" default "1"
depends on SOUND_SH_DAC_AUDIO depends on SOUND_SH_DAC_AUDIO

View File

@ -21,8 +21,7 @@ ramfs-input := $(if $(filter-out "",$(CONFIG_INITRAMFS_SOURCE)), \
$(CONFIG_INITRAMFS_SOURCE),-d) $(CONFIG_INITRAMFS_SOURCE),-d)
ramfs-args := \ ramfs-args := \
$(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \ $(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
$(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID)) \ $(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))
$(ramfs-input)
# .initramfs_data.cpio.gz.d is used to identify all files included # .initramfs_data.cpio.gz.d is used to identify all files included
# in initramfs and to detect if any files are added/removed. # in initramfs and to detect if any files are added/removed.