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:
commit
2a2ed2db35
@ -1123,6 +1123,14 @@ The top Makefile exports the following variables:
|
||||
$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE). The user may
|
||||
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
|
||||
|
||||
The kernel Makefiles are designed to run with GNU Make. The Makefiles
|
||||
|
213
Makefile
213
Makefile
@ -71,7 +71,7 @@ endif
|
||||
# In both cases the working directory must be the root of the kernel src.
|
||||
# 1) O=
|
||||
# Use "make O=dir/to/store/output/files/"
|
||||
#
|
||||
#
|
||||
# 2) Set KBUILD_OUTPUT
|
||||
# Set the environment variable KBUILD_OUTPUT to point to the directory
|
||||
# where the output files shall be placed.
|
||||
@ -178,18 +178,20 @@ CROSS_COMPILE ?=
|
||||
# Architecture as present in compile.h
|
||||
UTS_MACHINE := $(ARCH)
|
||||
|
||||
KCONFIG_CONFIG ?= .config
|
||||
|
||||
# SHELL used by kbuild
|
||||
CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
|
||||
else if [ -x /bin/bash ]; then echo /bin/bash; \
|
||||
else echo sh; fi ; fi)
|
||||
|
||||
HOSTCC = gcc
|
||||
HOSTCXX = g++
|
||||
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
|
||||
HOSTCXXFLAGS = -O2
|
||||
HOSTCC = gcc
|
||||
HOSTCXX = g++
|
||||
HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
|
||||
HOSTCXXFLAGS = -O2
|
||||
|
||||
# Decide whether to build built-in, modular, or both.
|
||||
# Normally, just do built-in.
|
||||
# Decide whether to build built-in, modular, or both.
|
||||
# Normally, just do built-in.
|
||||
|
||||
KBUILD_MODULES :=
|
||||
KBUILD_BUILTIN := 1
|
||||
@ -197,7 +199,7 @@ KBUILD_BUILTIN := 1
|
||||
# If we have only "make modules", don't compile built-in objects.
|
||||
# When we're building modules with modversions, we need to consider
|
||||
# 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)
|
||||
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 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.
|
||||
#
|
||||
# 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
|
||||
include $(srctree)/scripts/Kbuild.include
|
||||
|
||||
# For maximum performance (+ possibly random breakage, uncomment
|
||||
# the following)
|
||||
|
||||
#MAKEFLAGS += -rR
|
||||
# Do not use make's built-in rules and variables
|
||||
# This increases performance and avoid hard-to-debug behavour
|
||||
MAKEFLAGS += -rR
|
||||
|
||||
# Make variables (CC, etc...)
|
||||
|
||||
@ -305,21 +306,21 @@ LINUXINCLUDE := -Iinclude \
|
||||
|
||||
CPPFLAGS := -D__KERNEL__ $(LINUXINCLUDE)
|
||||
|
||||
CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
||||
-fno-strict-aliasing -fno-common
|
||||
AFLAGS := -D__ASSEMBLY__
|
||||
CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
|
||||
-fno-strict-aliasing -fno-common
|
||||
AFLAGS := -D__ASSEMBLY__
|
||||
|
||||
# Read KERNELRELEASE from .kernelrelease (if it exists)
|
||||
KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null)
|
||||
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
|
||||
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
|
||||
KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
|
||||
|
||||
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION \
|
||||
ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
|
||||
CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
|
||||
HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
|
||||
export VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION
|
||||
export ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC
|
||||
export CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE
|
||||
export HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
# It is allowed to specify more targets when calling make, including
|
||||
# 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
|
||||
# of make so .config is not included in this case either (for *config).
|
||||
|
||||
no-dot-config-targets := clean mrproper distclean \
|
||||
cscope TAGS tags help %docs check%
|
||||
cscope TAGS tags help %docs check% \
|
||||
kernelrelease kernelversion
|
||||
|
||||
config-targets := 0
|
||||
mixed-targets := 0
|
||||
@ -404,9 +406,8 @@ include $(srctree)/arch/$(ARCH)/Makefile
|
||||
export KBUILD_DEFCONFIG
|
||||
|
||||
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) -C $(srctree) KBUILD_SRC= .kernelrelease
|
||||
|
||||
else
|
||||
# ===========================================================================
|
||||
@ -416,13 +417,11 @@ else
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
# Additional helpers built in scripts/
|
||||
# Carefully list dependencies so we do not try to build scripts twice
|
||||
# in parrallel
|
||||
# in parallel
|
||||
PHONY += scripts
|
||||
scripts: scripts_basic include/config/MARKER
|
||||
scripts: scripts_basic include/config/auto.conf
|
||||
$(Q)$(MAKE) $(build)=$(@)
|
||||
|
||||
scripts_basic: include/linux/autoconf.h
|
||||
|
||||
# Objects we will link into vmlinux / subdirs we need to visit
|
||||
init-y := init/
|
||||
drivers-y := drivers/ sound/
|
||||
@ -436,31 +435,32 @@ ifeq ($(dot-config),1)
|
||||
|
||||
# Read in dependencies to all Kconfig* files, make sure to run
|
||||
# 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
|
||||
.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.
|
||||
# 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
|
||||
include/linux/autoconf.h: .kconfig.d .config
|
||||
$(Q)mkdir -p include/linux
|
||||
include/config/auto.conf: $(KCONFIG_CONFIG) include/config/auto.conf.cmd
|
||||
ifeq ($(KBUILD_EXTMOD),)
|
||||
$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
|
||||
else
|
||||
$(error kernel configuration not valid - run 'make prepare' in $(srctree) to update it)
|
||||
endif
|
||||
|
||||
else
|
||||
# Dummy target needed, because used as prerequisite
|
||||
include/linux/autoconf.h: ;
|
||||
include/config/auto.conf: ;
|
||||
endif
|
||||
|
||||
# The all: target is the default when no target is given on the
|
||||
# command line.
|
||||
# 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
|
||||
|
||||
ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
|
||||
@ -492,11 +492,11 @@ CHECKFLAGS += $(NOSTDINC_FLAGS)
|
||||
# warn about C99 declaration 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,)
|
||||
|
||||
# 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
|
||||
# Also any assignments in arch/$(ARCH)/Makefile take precedence over
|
||||
# this default value
|
||||
@ -510,12 +510,29 @@ export INSTALL_PATH ?= /boot
|
||||
#
|
||||
# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
|
||||
# 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)
|
||||
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),)
|
||||
core-y += kernel/ mm/ fs/ ipc/ security/ crypto/ block/
|
||||
@ -539,7 +556,7 @@ libs-y := $(libs-y1) $(libs-y2)
|
||||
|
||||
# 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
|
||||
# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
|
||||
# Ordering when linking is important, and $(vmlinux-init) must be first.
|
||||
@ -590,7 +607,7 @@ quiet_cmd_vmlinux_version = GEN .version
|
||||
$(MAKE) $(build)=init
|
||||
|
||||
# Generate System.map
|
||||
quiet_cmd_sysmap = SYSMAP
|
||||
quiet_cmd_sysmap = SYSMAP
|
||||
cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
|
||||
|
||||
# Link of vmlinux
|
||||
@ -719,7 +736,7 @@ $(vmlinux-dirs): prepare scripts
|
||||
$(Q)$(MAKE) $(build)=$@
|
||||
|
||||
# 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
|
||||
#
|
||||
# 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),, \
|
||||
$(shell cat /dev/null $(_localver)) \
|
||||
$(patsubst "%",%,$(CONFIG_LOCALVERSION)))
|
||||
|
||||
|
||||
# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called
|
||||
# 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.
|
||||
# Other SCMs can edit scripts/setlocalversion and add the appropriate
|
||||
@ -753,9 +770,9 @@ endif
|
||||
|
||||
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: FORCE
|
||||
include/config/kernel.release: include/config/auto.conf FORCE
|
||||
$(Q)rm -f $@
|
||||
$(Q)echo $(kernelrelease) > $@
|
||||
|
||||
@ -776,10 +793,10 @@ PHONY += prepare-all
|
||||
# and if so do:
|
||||
# 1) Check that make has not been executed in the kernel src $(srctree)
|
||||
# 2) Create the include2 directory, used for the second asm symlink
|
||||
prepare3: .kernelrelease
|
||||
prepare3: include/config/kernel.release
|
||||
ifneq ($(KBUILD_SRC),)
|
||||
@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 " in the '$(srctree)' directory.";\
|
||||
/bin/false; \
|
||||
@ -792,7 +809,7 @@ endif
|
||||
prepare2: prepare3 outputmakefile
|
||||
|
||||
prepare1: prepare2 include/linux/version.h include/asm \
|
||||
include/config/MARKER
|
||||
include/config/auto.conf
|
||||
ifneq ($(KBUILD_MODULES),)
|
||||
$(Q)mkdir -p $(MODVERDIR)
|
||||
$(Q)rm -f $(MODVERDIR)/*
|
||||
@ -806,27 +823,20 @@ prepare0: archprepare FORCE
|
||||
# All the preparing..
|
||||
prepare prepare-all: prepare0
|
||||
|
||||
# Leave this as default for preprocessing vmlinux.lds.S, which is now
|
||||
# done in arch/$(ARCH)/kernel/Makefile
|
||||
# Leave this as default for preprocessing vmlinux.lds.S, which is now
|
||||
# done in arch/$(ARCH)/kernel/Makefile
|
||||
|
||||
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
|
||||
|
||||
# FIXME: The asm symlink changes when $(ARCH) changes. That's
|
||||
# hard to detect, but I suppose "make mrproper" is a good idea
|
||||
# before switching between archs anyway.
|
||||
# FIXME: The asm symlink changes when $(ARCH) changes. That's
|
||||
# hard to detect, but I suppose "make mrproper" is a good idea
|
||||
# before switching between archs anyway.
|
||||
|
||||
include/asm:
|
||||
@echo ' SYMLINK $@ -> include/asm-$(ARCH)'
|
||||
$(Q)if [ ! -d include ]; then mkdir -p include; fi;
|
||||
@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
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@ -846,7 +856,7 @@ define filechk_version.h
|
||||
)
|
||||
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)
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
@ -860,7 +870,7 @@ depend dep:
|
||||
|
||||
ifdef CONFIG_MODULES
|
||||
|
||||
# By default, build modules as well
|
||||
# By default, build modules as well
|
||||
|
||||
all: modules
|
||||
|
||||
@ -942,7 +952,7 @@ CLEAN_FILES += vmlinux System.map \
|
||||
MRPROPER_DIRS += include/config include2
|
||||
MRPROPER_FILES += .config .config.old include/asm .version .old_version \
|
||||
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
|
||||
#
|
||||
@ -958,8 +968,9 @@ clean: archclean $(clean-dirs)
|
||||
$(call cmd,rmdirs)
|
||||
$(call cmd,rmfiles)
|
||||
@find . $(RCS_FIND_IGNORE) \
|
||||
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
|
||||
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
|
||||
\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
|
||||
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
|
||||
-o -name '*.symtypes' \) \
|
||||
-type f -print | xargs rm -f
|
||||
|
||||
# mrproper - Delete all generated files, including .config
|
||||
@ -982,9 +993,9 @@ PHONY += distclean
|
||||
|
||||
distclean: mrproper
|
||||
@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 '.*.rej' -o -size 0 \
|
||||
-o -name '.*.rej' -o -size 0 \
|
||||
-o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
|
||||
-type f -print | xargs rm -f
|
||||
|
||||
@ -994,9 +1005,9 @@ distclean: mrproper
|
||||
# rpm target kept for backward compatibility
|
||||
package-dir := $(srctree)/scripts/package
|
||||
|
||||
%pkg: FORCE
|
||||
%pkg: include/config/kernel.release FORCE
|
||||
$(Q)$(MAKE) $(build)=$(package-dir) $@
|
||||
rpm: FORCE
|
||||
rpm: include/config/kernel.release FORCE
|
||||
$(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 Same as 'make M=dir modules'
|
||||
# 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
|
||||
|
||||
# We are always building modules
|
||||
@ -1136,7 +1147,7 @@ clean: rm-dirs := $(MODVERDIR)
|
||||
clean: $(clean-dirs)
|
||||
$(call cmd,rmdirs)
|
||||
@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' \) \
|
||||
-type f -print | xargs rm -f
|
||||
|
||||
@ -1175,31 +1186,41 @@ else
|
||||
ALLINCLUDE_ARCHS := $(ARCH)
|
||||
endif
|
||||
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)
|
||||
endif
|
||||
|
||||
ALLSOURCE_ARCHS := $(ARCH)
|
||||
|
||||
define all-sources
|
||||
( find $(__srctree) $(RCS_FIND_IGNORE) \
|
||||
define find-sources
|
||||
( find $(__srctree) $(RCS_FIND_IGNORE) \
|
||||
\( -name include -o -name arch \) -prune -o \
|
||||
-name '*.[chS]' -print; \
|
||||
-name $1 -print; \
|
||||
for ARCH in $(ALLSOURCE_ARCHS) ; do \
|
||||
find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print; \
|
||||
-name $1 -print; \
|
||||
done ; \
|
||||
find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print; \
|
||||
-name $1 -print; \
|
||||
find $(__srctree)include $(RCS_FIND_IGNORE) \
|
||||
\( -name config -o -name 'asm-*' \) -prune \
|
||||
-o -name '*.[chS]' -print; \
|
||||
-o -name $1 -print; \
|
||||
for ARCH in $(ALLINCLUDE_ARCHS) ; do \
|
||||
find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
|
||||
-name '*.[chS]' -print; \
|
||||
-name $1 -print; \
|
||||
done ; \
|
||||
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
|
||||
|
||||
quiet_cmd_cscope-file = FILELST cscope.files
|
||||
@ -1219,7 +1240,13 @@ define cmd_TAGS
|
||||
echo "-I __initdata,__exitdata,__acquires,__releases \
|
||||
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
|
||||
--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
|
||||
|
||||
TAGS: FORCE
|
||||
@ -1259,14 +1286,14 @@ namespacecheck:
|
||||
endif #ifeq ($(config-targets),1)
|
||||
endif #ifeq ($(mixed-targets),1)
|
||||
|
||||
PHONY += checkstack
|
||||
PHONY += checkstack kernelrelease kernelversion
|
||||
checkstack:
|
||||
$(OBJDUMP) -d vmlinux $$(find . -name '*.ko') | \
|
||||
$(PERL) $(src)/scripts/checkstack.pl $(ARCH)
|
||||
|
||||
kernelrelease:
|
||||
$(if $(wildcard .kernelrelease), $(Q)echo $(KERNELRELEASE), \
|
||||
$(error kernelrelease not valid - run 'make *config' to update it))
|
||||
$(if $(wildcard include/config/kernel.release), $(Q)echo $(KERNELRELEASE), \
|
||||
$(error kernelrelease not valid - run 'make prepare' to update it))
|
||||
kernelversion:
|
||||
@echo $(KERNELVERSION)
|
||||
|
||||
@ -1301,6 +1328,8 @@ endif
|
||||
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
|
||||
%.o: %.S prepare scripts FORCE
|
||||
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
|
||||
%.symtypes: %.c prepare scripts FORCE
|
||||
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
|
||||
|
||||
# Modules
|
||||
/ %/: prepare scripts FORCE
|
||||
|
@ -177,7 +177,7 @@ boot := arch/arm/boot
|
||||
# them changed. We use .arch to indicate when they were updated
|
||||
# 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)'
|
||||
ifneq ($(KBUILD_SRC),)
|
||||
$(Q)mkdir -p include/asm-arm
|
||||
|
@ -147,7 +147,7 @@ endif
|
||||
# them changed. We use .arch and .mach to indicate when they were
|
||||
# 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)'
|
||||
$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
|
||||
$(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
|
||||
# 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 -> '
|
||||
$(Q)if [ ! -d include/asm-sh ]; then mkdir -p include/asm-sh; fi
|
||||
$(Q)if [ -d $(incdir-prefix)$(incdir-y) ]; then \
|
||||
|
@ -71,7 +71,7 @@ archprepare: $(archinc)/.platform
|
||||
# Update machine cpu and platform symlinks if something which affects
|
||||
# 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)'
|
||||
$(Q)mkdir -p $(archinc)
|
||||
$(Q)mkdir -p $(archinc)/xtensa
|
||||
|
@ -86,14 +86,14 @@ config MTD_REDBOOT_DIRECTORY_BLOCK
|
||||
block and "-2" means the penultimate block.
|
||||
|
||||
config MTD_REDBOOT_PARTS_UNALLOCATED
|
||||
bool " Include unallocated flash regions"
|
||||
bool "Include unallocated flash regions"
|
||||
depends on MTD_REDBOOT_PARTS
|
||||
help
|
||||
If you need to register each unallocated flash region as a MTD
|
||||
'partition', enable this option.
|
||||
|
||||
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
|
||||
help
|
||||
If you need to force read-only for 'RedBoot', 'RedBoot Config' and
|
||||
|
@ -212,7 +212,7 @@ config MTD_NETtel
|
||||
Support for flash chips on NETtel/SecureEdge/SnapGear boards.
|
||||
|
||||
config MTD_ALCHEMY
|
||||
tristate ' AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support'
|
||||
tristate "AMD Alchemy Pb1xxx/Db1xxx/RDK MTD support"
|
||||
depends on SOC_AU1X00
|
||||
help
|
||||
Flash memory access on AMD Alchemy Pb/Db/RDK Reference Boards
|
||||
|
@ -1169,7 +1169,7 @@ config SCSI_NCR_Q720
|
||||
you do not have this SCSI card, so say N.
|
||||
|
||||
config SCSI_NCR53C8XX_DEFAULT_TAGS
|
||||
int " default tagged command queue depth"
|
||||
int "default tagged command queue depth"
|
||||
depends on SCSI_ZALON || SCSI_NCR_Q720
|
||||
default "8"
|
||||
---help---
|
||||
@ -1195,7 +1195,7 @@ config SCSI_NCR53C8XX_DEFAULT_TAGS
|
||||
There is no safe option other than using good SCSI devices.
|
||||
|
||||
config SCSI_NCR53C8XX_MAX_TAGS
|
||||
int " maximum number of queued commands"
|
||||
int "maximum number of queued commands"
|
||||
depends on SCSI_ZALON || SCSI_NCR_Q720
|
||||
default "32"
|
||||
---help---
|
||||
@ -1212,7 +1212,7 @@ config SCSI_NCR53C8XX_MAX_TAGS
|
||||
There is no safe option and the default answer is recommended.
|
||||
|
||||
config SCSI_NCR53C8XX_SYNC
|
||||
int " synchronous transfers frequency in MHz"
|
||||
int "synchronous transfers frequency in MHz"
|
||||
depends on SCSI_ZALON || SCSI_NCR_Q720
|
||||
default "20"
|
||||
---help---
|
||||
@ -1246,7 +1246,7 @@ config SCSI_NCR53C8XX_SYNC
|
||||
terminations and SCSI conformant devices.
|
||||
|
||||
config SCSI_NCR53C8XX_PROFILE
|
||||
bool " enable profiling"
|
||||
bool "enable profiling"
|
||||
depends on SCSI_ZALON || SCSI_NCR_Q720
|
||||
help
|
||||
This option allows you to enable profiling information gathering.
|
||||
@ -1257,7 +1257,7 @@ config SCSI_NCR53C8XX_PROFILE
|
||||
The normal answer therefore is N.
|
||||
|
||||
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
|
||||
help
|
||||
This option is only provided for safety if you suspect some SCSI
|
||||
|
14
include/linux/license.h
Normal file
14
include/linux/license.h
Normal 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
|
@ -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"
|
||||
|
||||
config EXPERIMENTAL
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/semaphore.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <linux/license.h>
|
||||
|
||||
#if 0
|
||||
#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)
|
||||
{
|
||||
if (!license)
|
||||
|
@ -12,6 +12,11 @@ space := $(empty) $(empty)
|
||||
# contain a comma
|
||||
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
|
||||
escsq = $(subst $(squote),'\$(squote)',$1)
|
||||
|
@ -8,7 +8,7 @@ PHONY := __build
|
||||
__build:
|
||||
|
||||
# Read .config if it exist, otherwise ignore
|
||||
-include .config
|
||||
-include include/config/auto.conf
|
||||
|
||||
include scripts/Kbuild.include
|
||||
|
||||
@ -117,7 +117,7 @@ $(real-objs-m:.o=.lst): quiet_modtag := [M]
|
||||
$(obj-m) : quiet_modtag := [M]
|
||||
|
||||
# Default for not multi-part modules
|
||||
modname = $(*F)
|
||||
modname = $(basetarget)
|
||||
|
||||
$(multi-objs-m) : 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
|
||||
$(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
|
||||
# The C file is compiled and updated dependency information is generated.
|
||||
# (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 = \
|
||||
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
|
||||
$(CPP) -D__GENKSYMS__ $(c_flags) $< \
|
||||
| $(GENKSYMS) -a $(ARCH) \
|
||||
| $(GENKSYMS) $(if $(KBUILD_SYMTYPES), \
|
||||
-T $(@D)/$(@F:.o=.symtypes)) -a $(ARCH) \
|
||||
> $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
\
|
||||
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
|
||||
|
@ -33,8 +33,8 @@
|
||||
__hostprogs := $(sort $(hostprogs-y)$(hostprogs-m))
|
||||
|
||||
# hostprogs-y := tools/build may have been specified. Retreive directory
|
||||
obj-dirs += $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
|
||||
obj-dirs := $(strip $(sort $(filter-out ./,$(obj-dirs))))
|
||||
host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
|
||||
host-objdirs := $(strip $(sort $(filter-out ./,$(host-objdirs))))
|
||||
|
||||
|
||||
# C code
|
||||
@ -73,13 +73,17 @@ host-cxxmulti := $(addprefix $(obj)/,$(host-cxxmulti))
|
||||
host-cxxobjs := $(addprefix $(obj)/,$(host-cxxobjs))
|
||||
host-cshlib := $(addprefix $(obj)/,$(host-cshlib))
|
||||
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
|
||||
|
||||
_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) $(HOSTCFLAGS_$(*F).o)
|
||||
_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) $(HOSTCXXFLAGS_$(*F).o)
|
||||
_hostc_flags = $(HOSTCFLAGS) $(HOST_EXTRACFLAGS) \
|
||||
$(HOSTCFLAGS_$(basetarget).o)
|
||||
_hostcxx_flags = $(HOSTCXXFLAGS) $(HOST_EXTRACXXFLAGS) \
|
||||
$(HOSTCXXFLAGS_$(basetarget).o)
|
||||
|
||||
ifeq ($(KBUILD_SRC),)
|
||||
__hostc_flags = $(_hostc_flags)
|
||||
|
@ -82,12 +82,12 @@ obj-dirs := $(addprefix $(obj)/,$(obj-dirs))
|
||||
# than one module. In that case KBUILD_MODNAME will be set to foo_bar,
|
||||
# where foo and bar are the name of the modules.
|
||||
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))),\
|
||||
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
|
||||
|
||||
_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o)
|
||||
_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
|
||||
_c_flags = $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$(basetarget).o)
|
||||
_a_flags = $(AFLAGS) $(EXTRA_AFLAGS) $(AFLAGS_$(basetarget).o)
|
||||
_cpp_flags = $(CPPFLAGS) $(EXTRA_CPPFLAGS) $(CPPFLAGS_$(@F))
|
||||
|
||||
# If building the kernel in a separate objtree expand all occurrences
|
||||
|
@ -17,7 +17,7 @@ __modinst: $(modules)
|
||||
@:
|
||||
|
||||
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
|
||||
INSTALL_MOD_DIR ?= extra
|
||||
|
@ -35,7 +35,7 @@
|
||||
PHONY := _modpost
|
||||
_modpost: __modpost
|
||||
|
||||
include .config
|
||||
include include/config/auto.conf
|
||||
include scripts/Kbuild.include
|
||||
include scripts/Makefile.lib
|
||||
|
||||
@ -72,7 +72,7 @@ $(modules:.ko=.mod.c): __modpost ;
|
||||
# Step 5), compile all *.mod.c files
|
||||
|
||||
# modname is set to make c_flags define KBUILD_MODNAME
|
||||
modname = $(*F)
|
||||
modname = $(basetarget)
|
||||
|
||||
quiet_cmd_cc_o_c = CC $@
|
||||
cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \
|
||||
|
@ -1,17 +1,15 @@
|
||||
###
|
||||
# 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,
|
||||
# such as splitting .config and fix dependency file.
|
||||
# such as fix dependency file.
|
||||
# This initial step is needed to avoid files to be recompiled
|
||||
# when kernel configuration changes (which is what happens when
|
||||
# .config is included by main Makefile.
|
||||
# ---------------------------------------------------------------------------
|
||||
# fixdep: Used to generate dependency information during build process
|
||||
# split-include: Divide all config symbols up in a number of files in
|
||||
# include/config/...
|
||||
# docproc: Used in Documentation/docbook
|
||||
|
||||
hostprogs-y := fixdep split-include docproc
|
||||
hostprogs-y := fixdep docproc
|
||||
always := $(hostprogs-y)
|
||||
|
||||
# fixdep is needed to compile other host programs
|
||||
|
@ -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
169
scripts/export_report.pl
Normal 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);
|
||||
}
|
@ -42,7 +42,7 @@ static FILE *debugfile;
|
||||
int cur_line = 1;
|
||||
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 *mod_prefix = "";
|
||||
|
||||
@ -50,6 +50,7 @@ static int errors;
|
||||
static int nsyms;
|
||||
|
||||
static struct symbol *expansion_trail;
|
||||
static struct symbol *visited_symbols;
|
||||
|
||||
static const char *const symbol_type_name[] = {
|
||||
"normal", "typedef", "enum", "struct", "union"
|
||||
@ -176,6 +177,7 @@ struct symbol *add_symbol(const char *name, enum symbol_type type,
|
||||
sym->type = type;
|
||||
sym->defn = defn;
|
||||
sym->expansion_trail = NULL;
|
||||
sym->visited = NULL;
|
||||
sym->is_extern = is_extern;
|
||||
|
||||
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)
|
||||
{
|
||||
switch (list->tag) {
|
||||
case SYM_STRUCT:
|
||||
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:
|
||||
if (list->tag != SYM_NORMAL) {
|
||||
putc(symbol_type_name[list->tag][0], 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)
|
||||
@ -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,
|
||||
unsigned long crc)
|
||||
static unsigned long expand_and_crc_sym(struct symbol *sym, unsigned long crc)
|
||||
{
|
||||
struct string_list *list = sym->defn;
|
||||
struct string_list **e, **b;
|
||||
struct string_list *tmp, **tmp2;
|
||||
int elem = 1;
|
||||
@ -332,7 +319,7 @@ static unsigned long expand_and_crc_list(struct string_list *list,
|
||||
} else {
|
||||
subsym->expansion_trail = expansion_trail;
|
||||
expansion_trail = subsym;
|
||||
crc = expand_and_crc_list(subsym->defn, crc);
|
||||
crc = expand_and_crc_sym(subsym, crc);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -382,12 +369,22 @@ static unsigned long expand_and_crc_list(struct string_list *list,
|
||||
} else {
|
||||
subsym->expansion_trail = expansion_trail;
|
||||
expansion_trail = subsym;
|
||||
crc = expand_and_crc_list(subsym->defn, crc);
|
||||
crc = expand_and_crc_sym(subsym, crc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
static struct symbol **end = &visited_symbols;
|
||||
|
||||
if (!sym->visited) {
|
||||
*end = sym;
|
||||
end = &sym->visited;
|
||||
sym->visited = (struct symbol *)-1L;
|
||||
}
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
@ -406,7 +403,7 @@ void export_symbol(const char *name)
|
||||
|
||||
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;
|
||||
while (sym != (struct symbol *)-1L) {
|
||||
@ -464,6 +461,7 @@ static void genksyms_usage(void)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *dumpfile = NULL;
|
||||
int o;
|
||||
|
||||
#ifdef __GNU_LIBRARY__
|
||||
@ -473,15 +471,16 @@ int main(int argc, char **argv)
|
||||
{"warnings", 0, 0, 'w'},
|
||||
{"quiet", 0, 0, 'q'},
|
||||
{"dump", 0, 0, 'D'},
|
||||
{"dump-types", 1, 0, 'T'},
|
||||
{"version", 0, 0, 'V'},
|
||||
{"help", 0, 0, 'h'},
|
||||
{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)
|
||||
#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__ */
|
||||
switch (o) {
|
||||
case 'a':
|
||||
@ -502,6 +501,14 @@ int main(int argc, char **argv)
|
||||
case 'D':
|
||||
flag_dump_defs = 1;
|
||||
break;
|
||||
case 'T':
|
||||
flag_dump_types = 1;
|
||||
dumpfile = fopen(optarg, "w");
|
||||
if (!dumpfile) {
|
||||
perror(optarg);
|
||||
return 1;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
genksyms_usage();
|
||||
return 0;
|
||||
@ -524,6 +531,24 @@ int main(int argc, char **argv)
|
||||
|
||||
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) {
|
||||
fprintf(debugfile, "Hash table occupancy %d/%d = %g\n",
|
||||
nsyms, HASH_BUCKETS,
|
||||
|
@ -41,6 +41,7 @@ struct symbol {
|
||||
enum symbol_type type;
|
||||
struct string_list *defn;
|
||||
struct symbol *expansion_trail;
|
||||
struct symbol *visited;
|
||||
int is_extern;
|
||||
};
|
||||
|
||||
|
@ -2023,7 +2023,7 @@ repeat:
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
exit(1);
|
||||
}
|
||||
fini:
|
||||
|
||||
|
@ -392,7 +392,7 @@ repeat:
|
||||
break;
|
||||
|
||||
default:
|
||||
abort();
|
||||
exit(1);
|
||||
}
|
||||
fini:
|
||||
|
||||
|
@ -539,6 +539,7 @@ int main(int ac, char **av)
|
||||
name = av[i];
|
||||
if (!name) {
|
||||
printf(_("%s: Kconfig file missing\n"), av[0]);
|
||||
exit(1);
|
||||
}
|
||||
conf_parse(name);
|
||||
//zconfdump(stdout);
|
||||
@ -573,7 +574,7 @@ int main(int ac, char **av)
|
||||
case set_random:
|
||||
name = getenv("KCONFIG_ALLCONFIG");
|
||||
if (name && !stat(name, &tmpstat)) {
|
||||
conf_read_simple(name);
|
||||
conf_read_simple(name, S_DEF_USER);
|
||||
break;
|
||||
}
|
||||
switch (input_mode) {
|
||||
@ -584,9 +585,9 @@ int main(int ac, char **av)
|
||||
default: break;
|
||||
}
|
||||
if (!stat(name, &tmpstat))
|
||||
conf_read_simple(name);
|
||||
conf_read_simple(name, S_DEF_USER);
|
||||
else if (!stat("all.config", &tmpstat))
|
||||
conf_read_simple("all.config");
|
||||
conf_read_simple("all.config", S_DEF_USER);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -599,7 +600,15 @@ int main(int ac, char **av)
|
||||
input_mode = ask_silent;
|
||||
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 {
|
||||
conf_cnt = 0;
|
||||
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"));
|
||||
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;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -20,19 +21,8 @@ static void conf_warning(const char *fmt, ...)
|
||||
static const char *conf_filename;
|
||||
static int conf_lineno, conf_warnings, conf_unsaved;
|
||||
|
||||
const char conf_def_filename[] = ".config";
|
||||
|
||||
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, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@ -44,6 +34,13 @@ static void conf_warning(const char *fmt, ...)
|
||||
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)
|
||||
{
|
||||
struct symbol *sym;
|
||||
@ -86,51 +83,65 @@ char *conf_get_default_confname(void)
|
||||
return name;
|
||||
}
|
||||
|
||||
int conf_read_simple(const char *name)
|
||||
int conf_read_simple(const char *name, int def)
|
||||
{
|
||||
FILE *in = NULL;
|
||||
char line[1024];
|
||||
char *p, *p2;
|
||||
struct symbol *sym;
|
||||
int i;
|
||||
int i, def_flags;
|
||||
|
||||
if (name) {
|
||||
in = zconf_fopen(name);
|
||||
} else {
|
||||
const char **names = conf_confnames;
|
||||
while ((name = *names++)) {
|
||||
name = conf_expand_value(name);
|
||||
struct property *prop;
|
||||
|
||||
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);
|
||||
if (in) {
|
||||
printf(_("#\n"
|
||||
"# using defaults found in %s\n"
|
||||
"#\n"), name);
|
||||
break;
|
||||
"# using defaults found in %s\n"
|
||||
"#\n"), name);
|
||||
goto load;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!in)
|
||||
return 1;
|
||||
|
||||
load:
|
||||
conf_filename = name;
|
||||
conf_lineno = 0;
|
||||
conf_warnings = 0;
|
||||
conf_unsaved = 0;
|
||||
|
||||
def_flags = SYMBOL_DEF << def;
|
||||
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))
|
||||
sym->flags &= ~SYMBOL_NEW;
|
||||
sym->flags &= ~SYMBOL_VALID;
|
||||
sym->flags |= def_flags;
|
||||
switch (sym->type) {
|
||||
case S_INT:
|
||||
case S_HEX:
|
||||
case S_STRING:
|
||||
if (sym->user.val)
|
||||
free(sym->user.val);
|
||||
if (sym->def[def].val)
|
||||
free(sym->def[def].val);
|
||||
default:
|
||||
sym->user.val = NULL;
|
||||
sym->user.tri = no;
|
||||
sym->def[def].val = NULL;
|
||||
sym->def[def].tri = no;
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,19 +158,26 @@ int conf_read_simple(const char *name)
|
||||
*p++ = 0;
|
||||
if (strncmp(p, "is not set", 10))
|
||||
continue;
|
||||
sym = sym_find(line + 9);
|
||||
if (!sym) {
|
||||
conf_warning("trying to assign nonexistent symbol %s", line + 9);
|
||||
break;
|
||||
} else if (!(sym->flags & SYMBOL_NEW)) {
|
||||
if (def == S_DEF_USER) {
|
||||
sym = sym_find(line + 9);
|
||||
if (!sym) {
|
||||
conf_warning("trying to assign nonexistent symbol %s", line + 9);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
switch (sym->type) {
|
||||
case S_BOOLEAN:
|
||||
case S_TRISTATE:
|
||||
sym->user.tri = no;
|
||||
sym->flags &= ~SYMBOL_NEW;
|
||||
sym->def[def].tri = no;
|
||||
sym->flags |= def_flags;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
@ -177,34 +195,48 @@ int conf_read_simple(const char *name)
|
||||
p2 = strchr(p, '\n');
|
||||
if (p2)
|
||||
*p2 = 0;
|
||||
sym = sym_find(line + 7);
|
||||
if (!sym) {
|
||||
conf_warning("trying to assign nonexistent symbol %s", line + 7);
|
||||
break;
|
||||
} else if (!(sym->flags & SYMBOL_NEW)) {
|
||||
if (def == S_DEF_USER) {
|
||||
sym = sym_find(line + 7);
|
||||
if (!sym) {
|
||||
conf_warning("trying to assign nonexistent symbol %s", line + 7);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
switch (sym->type) {
|
||||
case S_TRISTATE:
|
||||
if (p[0] == 'm') {
|
||||
sym->user.tri = mod;
|
||||
sym->flags &= ~SYMBOL_NEW;
|
||||
sym->def[def].tri = mod;
|
||||
sym->flags |= def_flags;
|
||||
break;
|
||||
}
|
||||
case S_BOOLEAN:
|
||||
if (p[0] == 'y') {
|
||||
sym->user.tri = yes;
|
||||
sym->flags &= ~SYMBOL_NEW;
|
||||
sym->def[def].tri = yes;
|
||||
sym->flags |= def_flags;
|
||||
break;
|
||||
}
|
||||
if (p[0] == 'n') {
|
||||
sym->user.tri = no;
|
||||
sym->flags &= ~SYMBOL_NEW;
|
||||
sym->def[def].tri = no;
|
||||
sym->flags |= def_flags;
|
||||
break;
|
||||
}
|
||||
conf_warning("symbol value '%s' invalid for %s", p, sym->name);
|
||||
break;
|
||||
case S_OTHER:
|
||||
if (*p != '"') {
|
||||
for (p2 = p; *p2 && !isspace(*p2); p2++)
|
||||
;
|
||||
sym->type = S_STRING;
|
||||
goto done;
|
||||
}
|
||||
case S_STRING:
|
||||
if (*p++ != '"')
|
||||
break;
|
||||
@ -221,9 +253,10 @@ int conf_read_simple(const char *name)
|
||||
}
|
||||
case S_INT:
|
||||
case S_HEX:
|
||||
done:
|
||||
if (sym_string_valid(sym, p)) {
|
||||
sym->user.val = strdup(p);
|
||||
sym->flags &= ~SYMBOL_NEW;
|
||||
sym->def[def].val = strdup(p);
|
||||
sym->flags |= def_flags;
|
||||
} else {
|
||||
conf_warning("symbol value '%s' invalid for %s", p, sym->name);
|
||||
continue;
|
||||
@ -241,24 +274,24 @@ int conf_read_simple(const char *name)
|
||||
}
|
||||
if (sym && sym_is_choice_value(sym)) {
|
||||
struct symbol *cs = prop_get_symbol(sym_get_choice_prop(sym));
|
||||
switch (sym->user.tri) {
|
||||
switch (sym->def[def].tri) {
|
||||
case no:
|
||||
break;
|
||||
case mod:
|
||||
if (cs->user.tri == yes) {
|
||||
if (cs->def[def].tri == yes) {
|
||||
conf_warning("%s creates inconsistent choice state", sym->name);
|
||||
cs->flags |= SYMBOL_NEW;
|
||||
cs->flags &= ~def_flags;
|
||||
}
|
||||
break;
|
||||
case yes:
|
||||
if (cs->user.tri != no) {
|
||||
if (cs->def[def].tri != no) {
|
||||
conf_warning("%s creates inconsistent choice state", sym->name);
|
||||
cs->flags |= SYMBOL_NEW;
|
||||
cs->flags &= ~def_flags;
|
||||
} else
|
||||
cs->user.val = sym;
|
||||
cs->def[def].val = sym;
|
||||
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);
|
||||
@ -273,9 +306,11 @@ int conf_read(const char *name)
|
||||
struct symbol *sym;
|
||||
struct property *prop;
|
||||
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;
|
||||
|
||||
for_all_symbols(i, sym) {
|
||||
@ -287,12 +322,12 @@ int conf_read(const char *name)
|
||||
switch (sym->type) {
|
||||
case S_BOOLEAN:
|
||||
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;
|
||||
if (!sym_is_choice(sym))
|
||||
goto sym_ok;
|
||||
default:
|
||||
if (!strcmp(sym->curr.val, sym->user.val))
|
||||
if (!strcmp(sym->curr.val, sym->def[S_DEF_USER].val))
|
||||
goto sym_ok;
|
||||
break;
|
||||
}
|
||||
@ -304,15 +339,13 @@ int conf_read(const char *name)
|
||||
sym_ok:
|
||||
if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
|
||||
if (sym->visible == no)
|
||||
sym->flags |= SYMBOL_NEW;
|
||||
sym->flags &= ~SYMBOL_DEF_USER;
|
||||
switch (sym->type) {
|
||||
case S_STRING:
|
||||
case S_INT:
|
||||
case S_HEX:
|
||||
if (!sym_string_within_range(sym, sym->user.val)) {
|
||||
sym->flags |= SYMBOL_NEW;
|
||||
sym->flags &= ~SYMBOL_VALID;
|
||||
}
|
||||
if (!sym_string_within_range(sym, sym->def[S_DEF_USER].val))
|
||||
sym->flags &= ~(SYMBOL_VALID|SYMBOL_DEF_USER);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -320,19 +353,21 @@ int conf_read(const char *name)
|
||||
if (!sym_is_choice(sym))
|
||||
continue;
|
||||
prop = sym_get_choice_prop(sym);
|
||||
flags = sym->flags;
|
||||
for (e = prop->expr; e; e = e->left.expr)
|
||||
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;
|
||||
}
|
||||
|
||||
int conf_write(const char *name)
|
||||
{
|
||||
FILE *out, *out_h;
|
||||
FILE *out;
|
||||
struct symbol *sym;
|
||||
struct menu *menu;
|
||||
const char *basename;
|
||||
@ -351,7 +386,7 @@ int conf_write(const char *name)
|
||||
if (!stat(name, &st) && S_ISDIR(st.st_mode)) {
|
||||
strcpy(dirname, name);
|
||||
strcat(dirname, "/");
|
||||
basename = conf_def_filename;
|
||||
basename = conf_get_configname();
|
||||
} else if ((slash = strrchr(name, '/'))) {
|
||||
int size = slash - name + 1;
|
||||
memcpy(dirname, name, size);
|
||||
@ -359,23 +394,24 @@ int conf_write(const char *name)
|
||||
if (slash[1])
|
||||
basename = slash + 1;
|
||||
else
|
||||
basename = conf_def_filename;
|
||||
basename = conf_get_configname();
|
||||
} else
|
||||
basename = name;
|
||||
} else
|
||||
basename = conf_def_filename;
|
||||
basename = conf_get_configname();
|
||||
|
||||
sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
|
||||
out = fopen(newname, "w");
|
||||
sprintf(newname, "%s%s", dirname, basename);
|
||||
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)
|
||||
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_calc_value(sym);
|
||||
time(&now);
|
||||
@ -391,16 +427,6 @@ int conf_write(const char *name)
|
||||
sym_get_string_value(sym),
|
||||
use_timestamp ? "# " : "",
|
||||
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)
|
||||
sym_clear_all_valid();
|
||||
@ -416,11 +442,6 @@ int conf_write(const char *name)
|
||||
"#\n"
|
||||
"# %s\n"
|
||||
"#\n", str);
|
||||
if (out_h)
|
||||
fprintf(out_h, "\n"
|
||||
"/*\n"
|
||||
" * %s\n"
|
||||
" */\n", str);
|
||||
} else if (!(sym->flags & SYMBOL_CHOICE)) {
|
||||
sym_calc_value(sym);
|
||||
if (!(sym->flags & SYMBOL_WRITE))
|
||||
@ -438,59 +459,39 @@ int conf_write(const char *name)
|
||||
switch (sym_get_tristate_value(sym)) {
|
||||
case no:
|
||||
fprintf(out, "# CONFIG_%s is not set\n", sym->name);
|
||||
if (out_h)
|
||||
fprintf(out_h, "#undef CONFIG_%s\n", sym->name);
|
||||
break;
|
||||
case mod:
|
||||
fprintf(out, "CONFIG_%s=m\n", sym->name);
|
||||
if (out_h)
|
||||
fprintf(out_h, "#define CONFIG_%s_MODULE 1\n", sym->name);
|
||||
break;
|
||||
case yes:
|
||||
fprintf(out, "CONFIG_%s=y\n", sym->name);
|
||||
if (out_h)
|
||||
fprintf(out_h, "#define CONFIG_%s 1\n", sym->name);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case S_STRING:
|
||||
// fix me
|
||||
str = sym_get_string_value(sym);
|
||||
fprintf(out, "CONFIG_%s=\"", sym->name);
|
||||
if (out_h)
|
||||
fprintf(out_h, "#define CONFIG_%s \"", sym->name);
|
||||
do {
|
||||
while (1) {
|
||||
l = strcspn(str, "\"\\");
|
||||
if (l) {
|
||||
fwrite(str, l, 1, out);
|
||||
if (out_h)
|
||||
fwrite(str, l, 1, out_h);
|
||||
str += l;
|
||||
}
|
||||
str += l;
|
||||
while (*str == '\\' || *str == '"') {
|
||||
fprintf(out, "\\%c", *str);
|
||||
if (out_h)
|
||||
fprintf(out_h, "\\%c", *str);
|
||||
str++;
|
||||
}
|
||||
} while (*str);
|
||||
if (!*str)
|
||||
break;
|
||||
fprintf(out, "\\%c", *str++);
|
||||
}
|
||||
fputs("\"\n", out);
|
||||
if (out_h)
|
||||
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);
|
||||
if (out_h)
|
||||
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);
|
||||
if (out_h)
|
||||
fprintf(out_h, "#define CONFIG_%s %s\n", sym->name, str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -510,21 +511,253 @@ int conf_write(const char *name)
|
||||
}
|
||||
}
|
||||
fclose(out);
|
||||
if (out_h) {
|
||||
fclose(out_h);
|
||||
rename(".tmpconfig.h", "include/linux/autoconf.h");
|
||||
|
||||
if (*tmpname) {
|
||||
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)
|
||||
name = conf_def_filename;
|
||||
sprintf(tmpname, "%s.old", name);
|
||||
rename(name, tmpname);
|
||||
}
|
||||
sprintf(tmpname, "%s%s", dirname, basename);
|
||||
if (rename(newname, tmpname))
|
||||
return 1;
|
||||
|
||||
printf(_("#\n"
|
||||
"# configuration written to %s\n"
|
||||
"#\n"), newname);
|
||||
|
||||
sym_change_count = 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;
|
||||
}
|
||||
|
@ -145,7 +145,8 @@ static void __expr_eliminate_eq(enum expr_type type, struct expr **ep1, struct e
|
||||
return;
|
||||
}
|
||||
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;
|
||||
if (!expr_eq(e1, e2))
|
||||
return;
|
||||
@ -1012,73 +1013,73 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2)
|
||||
#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) {
|
||||
fn(data, "y");
|
||||
fn(data, NULL, "y");
|
||||
return;
|
||||
}
|
||||
|
||||
if (expr_compare_type(prevtoken, e->type) > 0)
|
||||
fn(data, "(");
|
||||
fn(data, NULL, "(");
|
||||
switch (e->type) {
|
||||
case E_SYMBOL:
|
||||
if (e->left.sym->name)
|
||||
fn(data, e->left.sym->name);
|
||||
fn(data, e->left.sym, e->left.sym->name);
|
||||
else
|
||||
fn(data, "<choice>");
|
||||
fn(data, NULL, "<choice>");
|
||||
break;
|
||||
case E_NOT:
|
||||
fn(data, "!");
|
||||
fn(data, NULL, "!");
|
||||
expr_print(e->left.expr, fn, data, E_NOT);
|
||||
break;
|
||||
case E_EQUAL:
|
||||
fn(data, e->left.sym->name);
|
||||
fn(data, "=");
|
||||
fn(data, e->right.sym->name);
|
||||
fn(data, e->left.sym, e->left.sym->name);
|
||||
fn(data, NULL, "=");
|
||||
fn(data, e->right.sym, e->right.sym->name);
|
||||
break;
|
||||
case E_UNEQUAL:
|
||||
fn(data, e->left.sym->name);
|
||||
fn(data, "!=");
|
||||
fn(data, e->right.sym->name);
|
||||
fn(data, e->left.sym, e->left.sym->name);
|
||||
fn(data, NULL, "!=");
|
||||
fn(data, e->right.sym, e->right.sym->name);
|
||||
break;
|
||||
case 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);
|
||||
break;
|
||||
case 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);
|
||||
break;
|
||||
case E_CHOICE:
|
||||
fn(data, e->right.sym->name);
|
||||
fn(data, e->right.sym, e->right.sym->name);
|
||||
if (e->left.expr) {
|
||||
fn(data, " ^ ");
|
||||
fn(data, NULL, " ^ ");
|
||||
expr_print(e->left.expr, fn, data, E_CHOICE);
|
||||
}
|
||||
break;
|
||||
case E_RANGE:
|
||||
fn(data, "[");
|
||||
fn(data, e->left.sym->name);
|
||||
fn(data, " ");
|
||||
fn(data, e->right.sym->name);
|
||||
fn(data, "]");
|
||||
fn(data, NULL, "[");
|
||||
fn(data, e->left.sym, e->left.sym->name);
|
||||
fn(data, NULL, " ");
|
||||
fn(data, e->right.sym, e->right.sym->name);
|
||||
fn(data, NULL, "]");
|
||||
break;
|
||||
default:
|
||||
{
|
||||
char buf[32];
|
||||
sprintf(buf, "<unknown type %d>", e->type);
|
||||
fn(data, buf);
|
||||
fn(data, NULL, buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
@ -1088,7 +1089,7 @@ void expr_fprint(struct expr *e, FILE *out)
|
||||
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);
|
||||
}
|
||||
|
@ -63,12 +63,18 @@ enum symbol_type {
|
||||
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 *next;
|
||||
char *name;
|
||||
char *help;
|
||||
enum symbol_type type;
|
||||
struct symbol_value curr, user;
|
||||
struct symbol_value curr;
|
||||
struct symbol_value def[4];
|
||||
tristate visible;
|
||||
int flags;
|
||||
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 SYMBOL_YES 0x0001
|
||||
#define SYMBOL_MOD 0x0002
|
||||
#define SYMBOL_NO 0x0004
|
||||
#define SYMBOL_CONST 0x0007
|
||||
#define SYMBOL_CONST 0x0001
|
||||
#define SYMBOL_CHECK 0x0008
|
||||
#define SYMBOL_CHOICE 0x0010
|
||||
#define SYMBOL_CHOICEVAL 0x0020
|
||||
@ -90,10 +93,14 @@ struct symbol {
|
||||
#define SYMBOL_OPTIONAL 0x0100
|
||||
#define SYMBOL_WRITE 0x0200
|
||||
#define SYMBOL_CHANGED 0x0400
|
||||
#define SYMBOL_NEW 0x0800
|
||||
#define SYMBOL_AUTO 0x1000
|
||||
#define SYMBOL_CHECKED 0x2000
|
||||
#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_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 *modules_sym;
|
||||
extern struct symbol *sym_defconfig_list;
|
||||
extern int cdebug;
|
||||
struct expr *expr_alloc_symbol(struct symbol *sym);
|
||||
struct expr *expr_alloc_one(enum expr_type type, struct expr *ce);
|
||||
|
@ -114,12 +114,6 @@ const char *dbg_print_flags(int val)
|
||||
|
||||
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)
|
||||
strcat(buf, "const/");
|
||||
if (val & SYMBOL_CHECK)
|
||||
@ -138,8 +132,6 @@ const char *dbg_print_flags(int val)
|
||||
strcat(buf, "write/");
|
||||
if (val & SYMBOL_CHANGED)
|
||||
strcat(buf, "changed/");
|
||||
if (val & SYMBOL_NEW)
|
||||
strcat(buf, "new/");
|
||||
if (val & SYMBOL_AUTO)
|
||||
strcat(buf, "auto/");
|
||||
|
||||
@ -1192,9 +1184,7 @@ static gchar **fill_row(struct menu *menu)
|
||||
|
||||
row[COL_OPTION] =
|
||||
g_strdup_printf("%s %s", menu_get_prompt(menu),
|
||||
sym ? (sym->
|
||||
flags & SYMBOL_NEW ? "(NEW)" : "") :
|
||||
"");
|
||||
sym && sym_has_value(sym) ? "(NEW)" : "");
|
||||
|
||||
if (show_all && !menu_is_visible(menu))
|
||||
row[COL_COLOR] = g_strdup("DarkGray");
|
||||
|
@ -8,7 +8,7 @@
|
||||
#define FLEX_SCANNER
|
||||
#define YY_FLEX_MAJOR_VERSION 2
|
||||
#define YY_FLEX_MINOR_VERSION 5
|
||||
#define YY_FLEX_SUBMINOR_VERSION 31
|
||||
#define YY_FLEX_SUBMINOR_VERSION 33
|
||||
#if YY_FLEX_SUBMINOR_VERSION > 0
|
||||
#define FLEX_BETA
|
||||
#endif
|
||||
@ -30,7 +30,15 @@
|
||||
|
||||
/* 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>
|
||||
typedef int8_t flex_int8_t;
|
||||
typedef uint8_t flex_uint8_t;
|
||||
@ -134,6 +142,10 @@ typedef unsigned int flex_uint32_t;
|
||||
#define YY_BUF_SIZE 16384
|
||||
#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
|
||||
#define YY_TYPEDEF_YY_BUFFER_STATE
|
||||
typedef struct yy_buffer_state *YY_BUFFER_STATE;
|
||||
@ -267,7 +279,7 @@ int zconfleng;
|
||||
|
||||
/* Points to current character in buffer. */
|
||||
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 */
|
||||
|
||||
/* 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 *
|
||||
#endif
|
||||
|
||||
static int yy_init_globals (void );
|
||||
|
||||
/* Macros after this point can all be overridden by user definitions in
|
||||
* section 1.
|
||||
*/
|
||||
@ -942,9 +956,9 @@ YY_DECL
|
||||
int str = 0;
|
||||
int ts, i;
|
||||
|
||||
if ( (yy_init) )
|
||||
if ( !(yy_init) )
|
||||
{
|
||||
(yy_init) = 0;
|
||||
(yy_init) = 1;
|
||||
|
||||
#ifdef YY_USER_INIT
|
||||
YY_USER_INIT;
|
||||
@ -1452,7 +1466,7 @@ static int yy_get_next_buffer (void)
|
||||
|
||||
else
|
||||
{
|
||||
size_t num_to_read =
|
||||
int num_to_read =
|
||||
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
|
||||
|
||||
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
|
||||
* 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.
|
||||
* @note If you want to scan bytes that may contain NUL values, then use
|
||||
* 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
|
||||
@ -1988,7 +2002,7 @@ YY_BUFFER_STATE zconf_scan_string (yyconst char * yy_str )
|
||||
*
|
||||
* @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;
|
||||
char *buf;
|
||||
@ -1996,15 +2010,15 @@ YY_BUFFER_STATE zconf_scan_bytes (yyconst char * bytes, int len )
|
||||
int i;
|
||||
|
||||
/* Get memory for full buffer, including space for trailing EOB's. */
|
||||
n = len + 2;
|
||||
n = _yybytes_len + 2;
|
||||
buf = (char *) zconfalloc(n );
|
||||
if ( ! buf )
|
||||
YY_FATAL_ERROR( "out of dynamic memory in zconf_scan_bytes()" );
|
||||
|
||||
for ( i = 0; i < len; ++i )
|
||||
buf[i] = bytes[i];
|
||||
for ( i = 0; i < _yybytes_len; ++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 );
|
||||
if ( ! b )
|
||||
@ -2125,6 +2139,34 @@ void zconfset_debug (int 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. */
|
||||
int zconflex_destroy (void)
|
||||
{
|
||||
@ -2140,6 +2182,10 @@ int zconflex_destroy (void)
|
||||
zconffree((yy_buffer_stack) );
|
||||
(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;
|
||||
}
|
||||
|
||||
@ -2151,7 +2197,7 @@ int zconflex_destroy (void)
|
||||
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
|
||||
{
|
||||
register int i;
|
||||
for ( i = 0; i < n; ++i )
|
||||
for ( i = 0; i < n; ++i )
|
||||
s1[i] = s2[i];
|
||||
}
|
||||
#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 )
|
||||
{
|
||||
register int n;
|
||||
for ( n = 0; s[n]; ++n )
|
||||
for ( n = 0; s[n]; ++n )
|
||||
;
|
||||
|
||||
return n;
|
||||
@ -2191,19 +2237,6 @@ void zconffree (void * ptr )
|
||||
|
||||
#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)
|
||||
{
|
||||
new_string();
|
||||
|
@ -40,6 +40,10 @@ extern "C" {
|
||||
|
||||
#define TF_COMMAND 0x0001
|
||||
#define TF_PARAM 0x0002
|
||||
#define TF_OPTION 0x0004
|
||||
|
||||
#define T_OPT_MODULES 1
|
||||
#define T_OPT_DEFCONFIG_LIST 2
|
||||
|
||||
struct kconf_id {
|
||||
int name;
|
||||
@ -60,8 +64,6 @@ int zconf_lineno(void);
|
||||
char *zconf_curname(void);
|
||||
|
||||
/* confdata.c */
|
||||
extern const char conf_def_filename[];
|
||||
|
||||
char *conf_get_default_confname(void);
|
||||
|
||||
/* 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);
|
||||
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_option(int token, char *arg);
|
||||
void menu_finalize(struct menu *parent);
|
||||
void menu_set_type(int type);
|
||||
|
||||
@ -99,6 +102,7 @@ const char *str_get(struct gstr *gs);
|
||||
/* symbol.c */
|
||||
void sym_init(void);
|
||||
void sym_clear_all_valid(void);
|
||||
void sym_set_all_changed(void);
|
||||
void sym_set_changed(struct symbol *sym);
|
||||
struct symbol *sym_check_deps(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)
|
||||
{
|
||||
return sym->flags & SYMBOL_NEW ? false : true;
|
||||
return sym->flags & SYMBOL_DEF_USER ? true : false;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -2,8 +2,9 @@
|
||||
/* confdata.c */
|
||||
P(conf_parse,void,(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_autoconf,int,(void));
|
||||
|
||||
/* menu.c */
|
||||
P(rootmenu,struct menu,);
|
||||
@ -38,4 +39,4 @@ P(prop_get_type_name,const char *,(enum prop_type type));
|
||||
|
||||
/* expr.c */
|
||||
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));
|
||||
|
@ -114,7 +114,7 @@ void menu_set_type(int type)
|
||||
sym->type = type;
|
||||
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_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);
|
||||
|
||||
prop->menu = current_entry;
|
||||
prop->text = prompt;
|
||||
prop->expr = expr;
|
||||
prop->visible.expr = menu_check_dep(dep);
|
||||
|
||||
if (prompt) {
|
||||
if (isspace(*prompt)) {
|
||||
prop_warn(prop, "leading whitespace ignored");
|
||||
while (isspace(*prompt))
|
||||
prompt++;
|
||||
}
|
||||
if (current_entry->prompt)
|
||||
menu_warn(current_entry, "prompt redefined\n");
|
||||
prop_warn(prop, "prompt redefined");
|
||||
current_entry->prompt = prop;
|
||||
}
|
||||
prop->text = prompt;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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->type == S_UNKNOWN)
|
||||
menu_warn(parent, "config symbol defined "
|
||||
"without type\n");
|
||||
menu_warn(parent, "config symbol defined without type");
|
||||
|
||||
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 */
|
||||
sym_check_prop(sym);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -7,9 +7,25 @@
|
||||
#if QT_VERSION >= 300
|
||||
#include <qsettings.h>
|
||||
#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
|
||||
|
||||
class ConfigView;
|
||||
class ConfigList;
|
||||
class ConfigItem;
|
||||
class ConfigLineEdit;
|
||||
@ -18,64 +34,38 @@ class ConfigMainWindow;
|
||||
|
||||
class ConfigSettings : public QSettings {
|
||||
public:
|
||||
ConfigSettings();
|
||||
|
||||
#if QT_VERSION >= 300
|
||||
void readListSettings();
|
||||
QValueList<int> readSizes(const QString& key, bool *ok);
|
||||
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 {
|
||||
promptColIdx, nameColIdx, noColIdx, modColIdx, yesColIdx, dataColIdx, colNr
|
||||
};
|
||||
enum listMode {
|
||||
singleMode, menuMode, symbolMode, fullMode
|
||||
singleMode, menuMode, symbolMode, fullMode, listMode
|
||||
};
|
||||
|
||||
class ConfigList : public QListView {
|
||||
Q_OBJECT
|
||||
typedef class QListView Parent;
|
||||
public:
|
||||
ConfigList(ConfigView* p, ConfigMainWindow* cview, ConfigSettings *configSettings);
|
||||
ConfigList(ConfigView* p, const char *name = 0);
|
||||
void reinit(void);
|
||||
ConfigView* parent(void) const
|
||||
{
|
||||
return (ConfigView*)Parent::parent();
|
||||
}
|
||||
ConfigItem* findConfigItem(struct menu *);
|
||||
|
||||
protected:
|
||||
ConfigMainWindow* cview;
|
||||
|
||||
void keyPressEvent(QKeyEvent *e);
|
||||
void contentsMousePressEvent(QMouseEvent *e);
|
||||
void contentsMouseReleaseEvent(QMouseEvent *e);
|
||||
void contentsMouseMoveEvent(QMouseEvent *e);
|
||||
void contentsMouseDoubleClickEvent(QMouseEvent *e);
|
||||
void focusInEvent(QFocusEvent *e);
|
||||
void contextMenuEvent(QContextMenuEvent *e);
|
||||
|
||||
public slots:
|
||||
void setRootMenu(struct menu *menu);
|
||||
|
||||
@ -83,10 +73,12 @@ public slots:
|
||||
void setValue(ConfigItem* item, tristate val);
|
||||
void changeValue(ConfigItem* item);
|
||||
void updateSelection(void);
|
||||
void saveSettings(void);
|
||||
signals:
|
||||
void menuChanged(struct menu *menu);
|
||||
void menuSelected(struct menu *menu);
|
||||
void parentSelected(void);
|
||||
void gotFocus(void);
|
||||
void gotFocus(struct menu *);
|
||||
|
||||
public:
|
||||
void updateListAll(void)
|
||||
@ -137,6 +129,7 @@ public:
|
||||
struct menu *rootEntry;
|
||||
QColorGroup disabledColorGroup;
|
||||
QColorGroup inactivedColorGroup;
|
||||
QPopupMenu* headerPopup;
|
||||
|
||||
private:
|
||||
int colMap[colNr];
|
||||
@ -208,9 +201,7 @@ class ConfigLineEdit : public QLineEdit {
|
||||
Q_OBJECT
|
||||
typedef class QLineEdit Parent;
|
||||
public:
|
||||
ConfigLineEdit(ConfigView* parent)
|
||||
: Parent(parent)
|
||||
{ }
|
||||
ConfigLineEdit(ConfigView* parent);
|
||||
ConfigView* parent(void) const
|
||||
{
|
||||
return (ConfigView*)Parent::parent();
|
||||
@ -222,26 +213,104 @@ public:
|
||||
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 {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ConfigMainWindow(void);
|
||||
public slots:
|
||||
void setHelp(QListViewItem* item);
|
||||
void changeMenu(struct menu *);
|
||||
void setMenuLink(struct menu *);
|
||||
void listFocusChanged(void);
|
||||
void goBack(void);
|
||||
void loadConfig(void);
|
||||
void saveConfig(void);
|
||||
void saveConfigAs(void);
|
||||
void searchConfig(void);
|
||||
void showSingleView(void);
|
||||
void showSplitView(void);
|
||||
void showFullView(void);
|
||||
void setShowAll(bool);
|
||||
void setShowDebug(bool);
|
||||
void setShowRange(bool);
|
||||
void setShowName(bool);
|
||||
void setShowData(bool);
|
||||
void showIntro(void);
|
||||
void showAbout(void);
|
||||
void saveSettings(void);
|
||||
@ -249,15 +318,14 @@ public slots:
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *e);
|
||||
|
||||
ConfigSearchWindow *searchWindow;
|
||||
ConfigView *menuView;
|
||||
ConfigList *menuList;
|
||||
ConfigView *configView;
|
||||
ConfigList *configList;
|
||||
QTextView *helpText;
|
||||
ConfigInfoView *helpText;
|
||||
QToolBar *toolBar;
|
||||
QAction *backAction;
|
||||
QSplitter* split1;
|
||||
QSplitter* split2;
|
||||
|
||||
bool showDebug;
|
||||
};
|
||||
|
@ -15,15 +15,15 @@
|
||||
struct symbol symbol_yes = {
|
||||
.name = "y",
|
||||
.curr = { "y", yes },
|
||||
.flags = SYMBOL_YES|SYMBOL_VALID,
|
||||
.flags = SYMBOL_CONST|SYMBOL_VALID,
|
||||
}, symbol_mod = {
|
||||
.name = "m",
|
||||
.curr = { "m", mod },
|
||||
.flags = SYMBOL_MOD|SYMBOL_VALID,
|
||||
.flags = SYMBOL_CONST|SYMBOL_VALID,
|
||||
}, symbol_no = {
|
||||
.name = "n",
|
||||
.curr = { "n", no },
|
||||
.flags = SYMBOL_NO|SYMBOL_VALID,
|
||||
.flags = SYMBOL_CONST|SYMBOL_VALID,
|
||||
}, symbol_empty = {
|
||||
.name = "",
|
||||
.curr = { "", no },
|
||||
@ -31,6 +31,7 @@ struct symbol symbol_yes = {
|
||||
};
|
||||
|
||||
int sym_change_count;
|
||||
struct symbol *sym_defconfig_list;
|
||||
struct symbol *modules_sym;
|
||||
tristate modules_val;
|
||||
|
||||
@ -227,7 +228,7 @@ static struct symbol *sym_calc_choice(struct symbol *sym)
|
||||
struct expr *e;
|
||||
|
||||
/* is the user choice visible? */
|
||||
def_sym = sym->user.val;
|
||||
def_sym = sym->def[S_DEF_USER].val;
|
||||
if (def_sym) {
|
||||
sym_calc_visibility(def_sym);
|
||||
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) {
|
||||
sym->flags |= SYMBOL_WRITE;
|
||||
if (sym_has_value(sym))
|
||||
newval.tri = sym->user.tri;
|
||||
newval.tri = sym->def[S_DEF_USER].tri;
|
||||
else if (!sym_is_choice(sym)) {
|
||||
prop = sym_get_default_prop(sym);
|
||||
if (prop)
|
||||
@ -329,7 +330,7 @@ void sym_calc_value(struct symbol *sym)
|
||||
if (sym->visible != no) {
|
||||
sym->flags |= SYMBOL_WRITE;
|
||||
if (sym_has_value(sym)) {
|
||||
newval.val = sym->user.val;
|
||||
newval.val = sym->def[S_DEF_USER].val;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -352,10 +353,13 @@ void sym_calc_value(struct symbol *sym)
|
||||
sym->curr.val = sym_calc_choice(sym);
|
||||
sym_validate_range(sym);
|
||||
|
||||
if (memcmp(&oldval, &sym->curr, sizeof(oldval)))
|
||||
if (memcmp(&oldval, &sym->curr, sizeof(oldval))) {
|
||||
sym_set_changed(sym);
|
||||
if (modules_sym == sym)
|
||||
modules_val = modules_sym->curr.tri;
|
||||
if (modules_sym == sym) {
|
||||
sym_set_all_changed();
|
||||
modules_val = modules_sym->curr.tri;
|
||||
}
|
||||
}
|
||||
|
||||
if (sym_is_choice(sym)) {
|
||||
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))
|
||||
return false;
|
||||
|
||||
if (sym->flags & SYMBOL_NEW) {
|
||||
sym->flags &= ~SYMBOL_NEW;
|
||||
if (!(sym->flags & SYMBOL_DEF_USER)) {
|
||||
sym->flags |= SYMBOL_DEF_USER;
|
||||
sym_set_changed(sym);
|
||||
}
|
||||
/*
|
||||
@ -439,21 +443,18 @@ bool sym_set_tristate_value(struct symbol *sym, tristate val)
|
||||
struct property *prop;
|
||||
struct expr *e;
|
||||
|
||||
cs->user.val = sym;
|
||||
cs->flags &= ~SYMBOL_NEW;
|
||||
cs->def[S_DEF_USER].val = sym;
|
||||
cs->flags |= SYMBOL_DEF_USER;
|
||||
prop = sym_get_choice_prop(cs);
|
||||
for (e = prop->expr; e; e = e->left.expr) {
|
||||
if (e->right.sym->visible != no)
|
||||
e->right.sym->flags &= ~SYMBOL_NEW;
|
||||
e->right.sym->flags |= SYMBOL_DEF_USER;
|
||||
}
|
||||
}
|
||||
|
||||
sym->user.tri = val;
|
||||
if (oldval != val) {
|
||||
sym->def[S_DEF_USER].tri = val;
|
||||
if (oldval != val)
|
||||
sym_clear_all_valid();
|
||||
if (sym == modules_sym)
|
||||
sym_set_all_changed();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -591,20 +592,20 @@ bool sym_set_string_value(struct symbol *sym, const char *newval)
|
||||
if (!sym_string_within_range(sym, newval))
|
||||
return false;
|
||||
|
||||
if (sym->flags & SYMBOL_NEW) {
|
||||
sym->flags &= ~SYMBOL_NEW;
|
||||
if (!(sym->flags & SYMBOL_DEF_USER)) {
|
||||
sym->flags |= SYMBOL_DEF_USER;
|
||||
sym_set_changed(sym);
|
||||
}
|
||||
|
||||
oldval = sym->user.val;
|
||||
oldval = sym->def[S_DEF_USER].val;
|
||||
size = strlen(newval) + 1;
|
||||
if (sym->type == S_HEX && (newval[0] != '0' || (newval[1] != 'x' && newval[1] != 'X'))) {
|
||||
size += 2;
|
||||
sym->user.val = val = malloc(size);
|
||||
sym->def[S_DEF_USER].val = val = malloc(size);
|
||||
*val++ = '0';
|
||||
*val++ = 'x';
|
||||
} else if (!oldval || strcmp(oldval, newval))
|
||||
sym->user.val = val = malloc(size);
|
||||
sym->def[S_DEF_USER].val = val = malloc(size);
|
||||
else
|
||||
return true;
|
||||
|
||||
@ -679,7 +680,6 @@ struct symbol *sym_lookup(const char *name, int isconst)
|
||||
memset(symbol, 0, sizeof(*symbol));
|
||||
symbol->name = new_name;
|
||||
symbol->type = S_UNKNOWN;
|
||||
symbol->flags = SYMBOL_NEW;
|
||||
if (isconst)
|
||||
symbol->flags |= SYMBOL_CONST;
|
||||
|
||||
|
@ -44,7 +44,9 @@ int file_write_dep(const char *name)
|
||||
else
|
||||
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);
|
||||
rename("..config.tmp", name);
|
||||
return 0;
|
||||
|
@ -39,5 +39,8 @@ string, T_TYPE, TF_COMMAND, S_STRING
|
||||
select, T_SELECT, TF_COMMAND
|
||||
enable, T_SELECT, TF_COMMAND
|
||||
range, T_RANGE, TF_COMMAND
|
||||
option, T_OPTION, TF_COMMAND
|
||||
on, T_ON, TF_PARAM
|
||||
modules, T_OPT_MODULES, TF_OPTION
|
||||
defconfig_list, T_OPT_DEFCONFIG_LIST,TF_OPTION
|
||||
%%
|
||||
|
@ -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, 25, 10, 15,
|
||||
0, 0, 5, 47, 0, 0, 47, 47, 0, 10,
|
||||
0, 20, 20, 20, 5, 0, 0, 20, 47, 47,
|
||||
20, 47, 47, 47, 47, 47, 47, 47, 47, 47,
|
||||
47, 47, 47, 47, 47, 47, 47, 25, 30, 15,
|
||||
0, 15, 0, 47, 5, 15, 47, 47, 30, 20,
|
||||
5, 0, 25, 15, 0, 0, 10, 35, 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,
|
||||
@ -88,69 +88,75 @@ kconf_id_hash (register const char *str, register unsigned int len)
|
||||
|
||||
struct kconf_id_strings_t
|
||||
{
|
||||
char kconf_id_strings_str2[sizeof("if")];
|
||||
char kconf_id_strings_str3[sizeof("int")];
|
||||
char kconf_id_strings_str4[sizeof("help")];
|
||||
char kconf_id_strings_str5[sizeof("endif")];
|
||||
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_str2[sizeof("on")];
|
||||
char kconf_id_strings_str6[sizeof("string")];
|
||||
char kconf_id_strings_str7[sizeof("default")];
|
||||
char kconf_id_strings_str8[sizeof("def_bool")];
|
||||
char kconf_id_strings_str10[sizeof("range")];
|
||||
char kconf_id_strings_str11[sizeof("string")];
|
||||
char kconf_id_strings_str12[sizeof("default")];
|
||||
char kconf_id_strings_str13[sizeof("def_bool")];
|
||||
char kconf_id_strings_str14[sizeof("menu")];
|
||||
char kconf_id_strings_str16[sizeof("def_boolean")];
|
||||
char kconf_id_strings_str17[sizeof("def_tristate")];
|
||||
char kconf_id_strings_str18[sizeof("mainmenu")];
|
||||
char kconf_id_strings_str20[sizeof("menuconfig")];
|
||||
char kconf_id_strings_str21[sizeof("config")];
|
||||
char kconf_id_strings_str22[sizeof("on")];
|
||||
char kconf_id_strings_str23[sizeof("hex")];
|
||||
char kconf_id_strings_str26[sizeof("source")];
|
||||
char kconf_id_strings_str27[sizeof("depends")];
|
||||
char kconf_id_strings_str28[sizeof("optional")];
|
||||
char kconf_id_strings_str31[sizeof("enable")];
|
||||
char kconf_id_strings_str32[sizeof("comment")];
|
||||
char kconf_id_strings_str33[sizeof("requires")];
|
||||
char kconf_id_strings_str11[sizeof("def_boolean")];
|
||||
char kconf_id_strings_str12[sizeof("def_tristate")];
|
||||
char kconf_id_strings_str13[sizeof("hex")];
|
||||
char kconf_id_strings_str14[sizeof("defconfig_list")];
|
||||
char kconf_id_strings_str16[sizeof("option")];
|
||||
char kconf_id_strings_str17[sizeof("if")];
|
||||
char kconf_id_strings_str18[sizeof("optional")];
|
||||
char kconf_id_strings_str20[sizeof("endif")];
|
||||
char kconf_id_strings_str21[sizeof("choice")];
|
||||
char kconf_id_strings_str22[sizeof("endmenu")];
|
||||
char kconf_id_strings_str23[sizeof("requires")];
|
||||
char kconf_id_strings_str24[sizeof("endchoice")];
|
||||
char kconf_id_strings_str26[sizeof("config")];
|
||||
char kconf_id_strings_str27[sizeof("modules")];
|
||||
char kconf_id_strings_str28[sizeof("int")];
|
||||
char kconf_id_strings_str29[sizeof("menu")];
|
||||
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_str35[sizeof("menuconfig")];
|
||||
char kconf_id_strings_str36[sizeof("select")];
|
||||
char kconf_id_strings_str37[sizeof("boolean")];
|
||||
char kconf_id_strings_str41[sizeof("choice")];
|
||||
char kconf_id_strings_str46[sizeof("prompt")];
|
||||
char kconf_id_strings_str39[sizeof("help")];
|
||||
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 =
|
||||
{
|
||||
"if",
|
||||
"int",
|
||||
"help",
|
||||
"endif",
|
||||
"select",
|
||||
"endmenu",
|
||||
"tristate",
|
||||
"endchoice",
|
||||
"range",
|
||||
"on",
|
||||
"string",
|
||||
"default",
|
||||
"def_bool",
|
||||
"menu",
|
||||
"range",
|
||||
"def_boolean",
|
||||
"def_tristate",
|
||||
"mainmenu",
|
||||
"menuconfig",
|
||||
"config",
|
||||
"on",
|
||||
"hex",
|
||||
"source",
|
||||
"depends",
|
||||
"defconfig_list",
|
||||
"option",
|
||||
"if",
|
||||
"optional",
|
||||
"enable",
|
||||
"comment",
|
||||
"requires",
|
||||
"bool",
|
||||
"boolean",
|
||||
"endif",
|
||||
"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)
|
||||
#ifdef __GNUC__
|
||||
@ -161,9 +167,9 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
{
|
||||
enum
|
||||
{
|
||||
TOTAL_KEYWORDS = 30,
|
||||
TOTAL_KEYWORDS = 33,
|
||||
MIN_WORD_LENGTH = 2,
|
||||
MAX_WORD_LENGTH = 12,
|
||||
MAX_WORD_LENGTH = 14,
|
||||
MIN_HASH_VALUE = 2,
|
||||
MAX_HASH_VALUE = 46
|
||||
};
|
||||
@ -171,43 +177,48 @@ kconf_id_lookup (register const char *str, register unsigned int len)
|
||||
static struct kconf_id wordlist[] =
|
||||
{
|
||||
{-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_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},
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str2, T_ON, TF_PARAM},
|
||||
{-1}, {-1}, {-1},
|
||||
{(int)(long)&((struct kconf_id_strings_t *)0)->kconf_id_strings_str41, T_CHOICE, TF_COMMAND},
|
||||
{-1}, {-1}, {-1}, {-1},
|
||||
{(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_str6, T_TYPE, TF_COMMAND, S_STRING},
|
||||
{(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_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)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -71,6 +71,7 @@ static struct menu *current_menu, *current_entry;
|
||||
%token <id>T_DEFAULT
|
||||
%token <id>T_SELECT
|
||||
%token <id>T_RANGE
|
||||
%token <id>T_OPTION
|
||||
%token <id>T_ON
|
||||
%token <string> T_WORD
|
||||
%token <string> T_WORD_QUOTE
|
||||
@ -91,6 +92,7 @@ static struct menu *current_menu, *current_entry;
|
||||
%type <id> end
|
||||
%type <id> option_name
|
||||
%type <menu> if_entry menu_entry choice_entry
|
||||
%type <string> symbol_option_arg
|
||||
|
||||
%destructor {
|
||||
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:
|
||||
/* empty */
|
||||
| config_option_list config_option
|
||||
| config_option_list symbol_option
|
||||
| config_option_list depends
|
||||
| config_option_list help
|
||||
| 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());
|
||||
};
|
||||
|
||||
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: T_CHOICE T_EOL
|
||||
@ -458,7 +481,9 @@ void conf_parse(const char *name)
|
||||
|
||||
sym_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);
|
||||
|
||||
#if YYDEBUG
|
||||
@ -468,6 +493,12 @@ void conf_parse(const char *name)
|
||||
zconfparse();
|
||||
if (zconfnerrs)
|
||||
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);
|
||||
for_all_symbols(i, sym) {
|
||||
sym_check_deps(sym);
|
||||
|
@ -28,7 +28,7 @@ main(int argc, char **argv)
|
||||
printf("#define KERNEL_ELFCLASS ELFCLASS64\n");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
exit(1);
|
||||
}
|
||||
switch (ei[EI_DATA]) {
|
||||
case ELFDATA2LSB:
|
||||
@ -38,7 +38,7 @@ main(int argc, char **argv)
|
||||
printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sizeof(unsigned long) == 4) {
|
||||
@ -53,7 +53,7 @@ main(int argc, char **argv)
|
||||
else if (memcmp(endian_test.c, "\x02\x01", 2) == 0)
|
||||
printf("#define HOST_ELFDATA ELFDATA2LSB\n");
|
||||
else
|
||||
abort();
|
||||
exit(1);
|
||||
|
||||
if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0))
|
||||
printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <ctype.h>
|
||||
#include "modpost.h"
|
||||
#include "../../include/linux/license.h"
|
||||
|
||||
/* Are we using CONFIG_MODVERSIONS? */
|
||||
int modversions = 0;
|
||||
@ -22,6 +23,8 @@ int have_vmlinux = 0;
|
||||
static int all_versions = 0;
|
||||
/* If we are modposting external module set to 1 */
|
||||
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, ...)
|
||||
{
|
||||
@ -97,6 +100,7 @@ static struct module *new_module(char *modname)
|
||||
|
||||
/* add to list */
|
||||
mod->name = p;
|
||||
mod->gpl_compatible = -1;
|
||||
mod->next = modules;
|
||||
modules = mod;
|
||||
|
||||
@ -118,6 +122,7 @@ struct symbol {
|
||||
unsigned int kernel:1; /* 1 if symbol is from kernel
|
||||
* (only for external modules) **/
|
||||
unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
|
||||
enum export export; /* Type of export */
|
||||
char name[0];
|
||||
};
|
||||
|
||||
@ -153,7 +158,8 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak,
|
||||
}
|
||||
|
||||
/* 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;
|
||||
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;
|
||||
new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
|
||||
new->module = module;
|
||||
new->export = export;
|
||||
return new;
|
||||
}
|
||||
|
||||
@ -179,16 +186,55 @@ static struct symbol *find_symbol(const char *name)
|
||||
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
|
||||
* 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);
|
||||
|
||||
if (!s) {
|
||||
s = new_symbol(name, mod);
|
||||
s = new_symbol(name, mod, export);
|
||||
} else {
|
||||
if (!s->preloaded) {
|
||||
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->vmlinux = is_vmlinux(mod->name);
|
||||
s->kernel = 0;
|
||||
s->export = export;
|
||||
return s;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!s)
|
||||
s = new_symbol(name, mod);
|
||||
s = new_symbol(name, mod, export);
|
||||
s->crc = crc;
|
||||
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);
|
||||
if (!hdr) {
|
||||
perror(filename);
|
||||
abort();
|
||||
exit(1);
|
||||
}
|
||||
info->hdr = 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++) {
|
||||
const char *secstrings
|
||||
= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
|
||||
const char *secname;
|
||||
|
||||
if (sechdrs[i].sh_offset > info->size)
|
||||
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_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)
|
||||
continue;
|
||||
|
||||
@ -353,6 +408,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
|
||||
Elf_Sym *sym, const char *symname)
|
||||
{
|
||||
unsigned int crc;
|
||||
enum export export = export_from_sec(info, sym->st_shndx);
|
||||
|
||||
switch (sym->st_shndx) {
|
||||
case SHN_COMMON:
|
||||
@ -362,7 +418,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
|
||||
/* CRC'd symbol */
|
||||
if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
|
||||
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;
|
||||
case SHN_UNDEF:
|
||||
@ -406,7 +463,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
|
||||
default:
|
||||
/* All exported symbols */
|
||||
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)
|
||||
mod->has_init = 1;
|
||||
@ -437,13 +495,18 @@ static char *next_string(char *string, unsigned long *secsize)
|
||||
return string;
|
||||
}
|
||||
|
||||
static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
|
||||
const char *tag)
|
||||
static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
|
||||
const char *tag, char *info)
|
||||
{
|
||||
char *p;
|
||||
unsigned int taglen = strlen(tag);
|
||||
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)) {
|
||||
if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
|
||||
return p + taglen + 1;
|
||||
@ -451,6 +514,13 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
|
||||
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
|
||||
* return 0 if match
|
||||
@ -821,6 +891,10 @@ static int init_section_ref_ok(const char *name)
|
||||
".pci_fixup_final",
|
||||
".pdr",
|
||||
"__param",
|
||||
"__ex_table",
|
||||
".fixup",
|
||||
".smp_locks",
|
||||
".plt", /* seen on ARCH=um build on x86_64. Harmless */
|
||||
NULL
|
||||
};
|
||||
/* Start of section names */
|
||||
@ -846,6 +920,8 @@ static int init_section_ref_ok(const char *name)
|
||||
for (s = namelist3; *s; s++)
|
||||
if (strstr(name, *s) != NULL)
|
||||
return 1;
|
||||
if (strrcmp(name, ".init") == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -892,6 +968,10 @@ static int exit_section_ref_ok(const char *name)
|
||||
".exitcall.exit",
|
||||
".eh_frame",
|
||||
".stab",
|
||||
"__ex_table",
|
||||
".fixup",
|
||||
".smp_locks",
|
||||
".plt", /* seen on ARCH=um build on x86_64. Harmless */
|
||||
NULL
|
||||
};
|
||||
/* Start of section names */
|
||||
@ -921,6 +1001,7 @@ static void read_symbols(char *modname)
|
||||
{
|
||||
const char *symname;
|
||||
char *version;
|
||||
char *license;
|
||||
struct module *mod;
|
||||
struct elf_info info = { };
|
||||
Elf_Sym *sym;
|
||||
@ -936,6 +1017,18 @@ static void read_symbols(char *modname)
|
||||
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++) {
|
||||
symname = info.strtab + sym->st_name;
|
||||
|
||||
@ -992,6 +1085,41 @@ void buf_write(struct buffer *buf, const char *s, int 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
|
||||
**/
|
||||
@ -1142,6 +1270,9 @@ static void write_if_changed(struct buffer *b, const char *fname)
|
||||
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)
|
||||
{
|
||||
unsigned long size, pos = 0;
|
||||
@ -1153,7 +1284,7 @@ static void read_dump(const char *fname, unsigned int kernel)
|
||||
return;
|
||||
|
||||
while ((line = get_next_line(&pos, file, size))) {
|
||||
char *symname, *modname, *d;
|
||||
char *symname, *modname, *d, *export;
|
||||
unsigned int crc;
|
||||
struct module *mod;
|
||||
struct symbol *s;
|
||||
@ -1164,8 +1295,9 @@ static void read_dump(const char *fname, unsigned int kernel)
|
||||
if (!(modname = strchr(symname, '\t')))
|
||||
goto fail;
|
||||
*modname++ = '\0';
|
||||
if (strchr(modname, '\t'))
|
||||
goto fail;
|
||||
if ((export = strchr(modname, '\t')) != NULL)
|
||||
*export++ = '\0';
|
||||
|
||||
crc = strtoul(line, &d, 16);
|
||||
if (*symname == '\0' || *modname == '\0' || *d != '\0')
|
||||
goto fail;
|
||||
@ -1177,10 +1309,10 @@ static void read_dump(const char *fname, unsigned int kernel)
|
||||
mod = new_module(NOFAIL(strdup(modname)));
|
||||
mod->skip = 1;
|
||||
}
|
||||
s = sym_add_exported(symname, mod);
|
||||
s = sym_add_exported(symname, mod, export_no(export));
|
||||
s->kernel = kernel;
|
||||
s->preloaded = 1;
|
||||
sym_update_crc(symname, mod, crc);
|
||||
sym_update_crc(symname, mod, crc, export_no(export));
|
||||
}
|
||||
return;
|
||||
fail:
|
||||
@ -1210,9 +1342,10 @@ static void write_dump(const char *fname)
|
||||
symbol = symbolhash[n];
|
||||
while (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->module->name);
|
||||
symbol->module->name,
|
||||
export_str(symbol->export));
|
||||
symbol = symbol->next;
|
||||
}
|
||||
}
|
||||
@ -1260,6 +1393,12 @@ int main(int argc, char **argv)
|
||||
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) {
|
||||
if (mod->skip)
|
||||
continue;
|
||||
|
@ -100,6 +100,7 @@ buf_write(struct buffer *buf, const char *s, int len);
|
||||
struct module {
|
||||
struct module *next;
|
||||
const char *name;
|
||||
int gpl_compatible;
|
||||
struct symbol *unres;
|
||||
int seen;
|
||||
int skip;
|
||||
@ -115,6 +116,9 @@ struct elf_info {
|
||||
Elf_Shdr *sechdrs;
|
||||
Elf_Sym *symtab_start;
|
||||
Elf_Sym *symtab_stop;
|
||||
Elf_Section export_sec;
|
||||
Elf_Section export_gpl_sec;
|
||||
Elf_Section export_gpl_future_sec;
|
||||
const char *strtab;
|
||||
char *modinfo;
|
||||
unsigned int modinfo_len;
|
||||
|
@ -73,8 +73,13 @@ echo "%ifarch ia64"
|
||||
echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
|
||||
echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
|
||||
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 "%endif"
|
||||
echo "%endif"
|
||||
|
||||
echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE"
|
||||
|
||||
|
@ -11,12 +11,12 @@ cd "${1:-.}" || usage
|
||||
# Check for git and a git repo.
|
||||
if head=`git rev-parse --verify HEAD 2>/dev/null`; then
|
||||
# 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`
|
||||
fi
|
||||
|
||||
# Are there uncommitted changes?
|
||||
if git diff-files | read dummy; then
|
||||
if git diff-index HEAD | read dummy; then
|
||||
printf '%s' -dirty
|
||||
fi
|
||||
fi
|
||||
|
@ -839,6 +839,6 @@ config SOUND_SH_DAC_AUDIO
|
||||
depends on SOUND_PRIME && CPU_SH3
|
||||
|
||||
config SOUND_SH_DAC_AUDIO_CHANNEL
|
||||
int " DAC channel"
|
||||
int "DAC channel"
|
||||
default "1"
|
||||
depends on SOUND_SH_DAC_AUDIO
|
||||
|
@ -21,8 +21,7 @@ ramfs-input := $(if $(filter-out "",$(CONFIG_INITRAMFS_SOURCE)), \
|
||||
$(CONFIG_INITRAMFS_SOURCE),-d)
|
||||
ramfs-args := \
|
||||
$(if $(CONFIG_INITRAMFS_ROOT_UID), -u $(CONFIG_INITRAMFS_ROOT_UID)) \
|
||||
$(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID)) \
|
||||
$(ramfs-input)
|
||||
$(if $(CONFIG_INITRAMFS_ROOT_GID), -g $(CONFIG_INITRAMFS_ROOT_GID))
|
||||
|
||||
# .initramfs_data.cpio.gz.d is used to identify all files included
|
||||
# in initramfs and to detect if any files are added/removed.
|
||||
|
Loading…
Reference in New Issue
Block a user