Commit 1d35aae7 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'kbuild-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kbuild updates from Masahiro Yamada:

 - Generate a list of built DTB files (arch/*/boot/dts/dtbs-list)

 - Use more threads when building Debian packages in parallel

 - Fix warnings shown during the RPM kernel package uninstallation

 - Change OBJECT_FILES_NON_STANDARD_*.o etc. to take a relative path to
   Makefile

 - Support GCC's -fmin-function-alignment flag

 - Fix a null pointer dereference bug in modpost

 - Add the DTB support to the RPM package

 - Various fixes and cleanups in Kconfig

* tag 'kbuild-v6.9' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild: (67 commits)
  kconfig: tests: test dependency after shuffling choices
  kconfig: tests: add a test for randconfig with dependent choices
  kconfig: tests: support KCONFIG_SEED for the randconfig runner
  kbuild: rpm-pkg: add dtb files in kernel rpm
  kconfig: remove unneeded menu_is_visible() call in conf_write_defconfig()
  kconfig: check prompt for choice while parsing
  kconfig: lxdialog: remove unused dialog colors
  kconfig: lxdialog: fix button color for blackbg theme
  modpost: fix null pointer dereference
  kbuild: remove GCC's default -Wpacked-bitfield-compat flag
  kbuild: unexport abs_srctree and abs_objtree
  kbuild: Move -Wenum-{compare-conditional,enum-conversion} into W=1
  kconfig: remove named choice support
  kconfig: use linked list in get_symbol_str() to iterate over menus
  kconfig: link menus to a symbol
  kbuild: fix inconsistent indentation in top Makefile
  kbuild: Use -fmin-function-alignment when available
  alpha: merge two entries for CONFIG_ALPHA_GAMMA
  alpha: merge two entries for CONFIG_ALPHA_EV4
  kbuild: change DTC_FLAGS_<basetarget>.o to take the path relative to $(obj)
  ...
parents 88d92fb1 f2fd2aad
...@@ -52,6 +52,7 @@ ...@@ -52,6 +52,7 @@
*.xz *.xz
*.zst *.zst
Module.symvers Module.symvers
dtbs-list
modules.order modules.order
# #
......
...@@ -393,7 +393,7 @@ of C0, which doesn't depend on M:: ...@@ -393,7 +393,7 @@ of C0, which doesn't depend on M::
choices:: choices::
"choice" [symbol] "choice"
<choice options> <choice options>
<choice block> <choice block>
"endchoice" "endchoice"
...@@ -412,10 +412,6 @@ the kernel, but all drivers can be compiled as modules. ...@@ -412,10 +412,6 @@ the kernel, but all drivers can be compiled as modules.
A choice accepts another option "optional", which allows to set the A choice accepts another option "optional", which allows to set the
choice to 'n' and no entry needs to be selected. choice to 'n' and no entry needs to be selected.
If no [symbol] is associated with a choice, then you can not have multiple
definitions of that choice. If a [symbol] is associated to the choice,
then you may define the same choice (i.e. with the same entries) in another
place.
comment:: comment::
......
=================== =================================
Kconfig make config Configuration targets and editors
=================== =================================
This file contains some assistance for using `make *config`. This file contains some assistance for using ``make *config``.
Use "make help" to list all of the possible configuration targets. Use ``make help`` to list all of the possible configuration targets.
The xconfig ('qconf'), menuconfig ('mconf'), and nconfig ('nconf') The xconfig ('qconf'), menuconfig ('mconf'), and nconfig ('nconf')
programs also have embedded help text. Be sure to check that for programs also have embedded help text. Be sure to check that for
...@@ -12,8 +12,9 @@ navigation, search, and other general help text. ...@@ -12,8 +12,9 @@ navigation, search, and other general help text.
The gconfig ('gconf') program has limited help text. The gconfig ('gconf') program has limited help text.
General General
------- =======
New kernel releases often introduce new config symbols. Often more New kernel releases often introduce new config symbols. Often more
important, new kernel releases may rename config symbols. When important, new kernel releases may rename config symbols. When
...@@ -24,118 +25,102 @@ symbols have been introduced. ...@@ -24,118 +25,102 @@ symbols have been introduced.
To see a list of new config symbols, use:: To see a list of new config symbols, use::
cp user/some/old.config .config cp user/some/old.config .config
make listnewconfig make listnewconfig
and the config program will list any new symbols, one per line. and the config program will list any new symbols, one per line.
Alternatively, you can use the brute force method:: Alternatively, you can use the brute force method::
make oldconfig make oldconfig
scripts/diffconfig .config.old .config | less scripts/diffconfig .config.old .config | less
----------------------------------------------------------------------
Environment variables for `*config`
KCONFIG_CONFIG
--------------
This environment variable can be used to specify a default kernel config
file name to override the default name of ".config".
KCONFIG_DEFCONFIG_LIST Environment variables
---------------------- =====================
This environment variable specifies a list of config files which can be used Environment variables for ``*config``:
as a base configuration in case the .config does not exist yet. Entries in
the list are separated with whitespaces to each other, and the first one
that exists is used.
KCONFIG_OVERWRITECONFIG ``KCONFIG_CONFIG``
----------------------- This environment variable can be used to specify a default kernel config
If you set KCONFIG_OVERWRITECONFIG in the environment, Kconfig will not file name to override the default name of ".config".
break symlinks when .config is a symlink to somewhere else.
KCONFIG_WARN_UNKNOWN_SYMBOLS ``KCONFIG_DEFCONFIG_LIST``
---------------------------- This environment variable specifies a list of config files which can be
This environment variable makes Kconfig warn about all unrecognized used as a base configuration in case the .config does not exist yet.
symbols in the config input. Entries in the list are separated with whitespaces to each other, and
the first one that exists is used.
KCONFIG_WERROR ``KCONFIG_OVERWRITECONFIG``
-------------- If you set KCONFIG_OVERWRITECONFIG in the environment, Kconfig will not
If set, Kconfig treats warnings as errors. break symlinks when .config is a symlink to somewhere else.
`CONFIG_` ``KCONFIG_WARN_UNKNOWN_SYMBOLS``
--------- This environment variable makes Kconfig warn about all unrecognized
If you set `CONFIG_` in the environment, Kconfig will prefix all symbols symbols in the config input.
with its value when saving the configuration, instead of using the default,
`CONFIG_`.
---------------------------------------------------------------------- ``KCONFIG_WERROR``
If set, Kconfig treats warnings as errors.
Environment variables for '{allyes/allmod/allno/rand}config' ``CONFIG_``
If you set ``CONFIG_`` in the environment, Kconfig will prefix all symbols
with its value when saving the configuration, instead of using the
default, ``CONFIG_``.
KCONFIG_ALLCONFIG Environment variables for ``{allyes/allmod/allno/rand}config``:
-----------------
(partially based on lkml email from/by Rob Landley, re: miniconfig)
-------------------------------------------------- ``KCONFIG_ALLCONFIG``
The allyesconfig/allmodconfig/allnoconfig/randconfig variants can also
use the environment variable KCONFIG_ALLCONFIG as a flag or a filename
that contains config symbols that the user requires to be set to a
specific value. If KCONFIG_ALLCONFIG is used without a filename where
KCONFIG_ALLCONFIG == "" or KCONFIG_ALLCONFIG == "1", ``make *config``
checks for a file named "all{yes/mod/no/def/random}.config"
(corresponding to the ``*config`` command that was used) for symbol values
that are to be forced. If this file is not found, it checks for a
file named "all.config" to contain forced values.
The allyesconfig/allmodconfig/allnoconfig/randconfig variants can also This enables you to create "miniature" config (miniconfig) or custom
use the environment variable KCONFIG_ALLCONFIG as a flag or a filename config files containing just the config symbols that you are interested
that contains config symbols that the user requires to be set to a in. Then the kernel config system generates the full .config file,
specific value. If KCONFIG_ALLCONFIG is used without a filename where including symbols of your miniconfig file.
KCONFIG_ALLCONFIG == "" or KCONFIG_ALLCONFIG == "1", `make *config`
checks for a file named "all{yes/mod/no/def/random}.config"
(corresponding to the `*config` command that was used) for symbol values
that are to be forced. If this file is not found, it checks for a
file named "all.config" to contain forced values.
This enables you to create "miniature" config (miniconfig) or custom This ``KCONFIG_ALLCONFIG`` file is a config file which contains
config files containing just the config symbols that you are interested (usually a subset of all) preset config symbols. These variable
in. Then the kernel config system generates the full .config file, settings are still subject to normal dependency checks.
including symbols of your miniconfig file.
This 'KCONFIG_ALLCONFIG' file is a config file which contains
(usually a subset of all) preset config symbols. These variable
settings are still subject to normal dependency checks.
Examples::
KCONFIG_ALLCONFIG=custom-notebook.config make allnoconfig Examples::
or:: KCONFIG_ALLCONFIG=custom-notebook.config make allnoconfig
KCONFIG_ALLCONFIG=mini.config make allnoconfig or::
or:: KCONFIG_ALLCONFIG=mini.config make allnoconfig
make KCONFIG_ALLCONFIG=mini.config allnoconfig or::
These examples will disable most options (allnoconfig) but enable or make KCONFIG_ALLCONFIG=mini.config allnoconfig
disable the options that are explicitly listed in the specified
mini-config files.
---------------------------------------------------------------------- These examples will disable most options (allnoconfig) but enable or
disable the options that are explicitly listed in the specified
mini-config files.
Environment variables for 'randconfig' Environment variables for ``randconfig``:
KCONFIG_SEED ``KCONFIG_SEED``
------------ You can set this to the integer value used to seed the RNG, if you want
You can set this to the integer value used to seed the RNG, if you want to somehow debug the behaviour of the kconfig parser/frontends.
to somehow debug the behaviour of the kconfig parser/frontends. If not set, the current time will be used.
If not set, the current time will be used.
KCONFIG_PROBABILITY ``KCONFIG_PROBABILITY``
------------------- This variable can be used to skew the probabilities. This variable can
This variable can be used to skew the probabilities. This variable can be unset or empty, or set to three different formats:
be unset or empty, or set to three different formats:
======================= ================== ===================== ======================= ================== =====================
KCONFIG_PROBABILITY y:n split y:m:n split KCONFIG_PROBABILITY y:n split y:m:n split
======================= ================== ===================== ======================= ================== =====================
unset or empty 50 : 50 33 : 33 : 34 unset or empty 50 : 50 33 : 33 : 34
N N : 100-N N/2 : N/2 : 100-N N N : 100-N N/2 : N/2 : 100-N
[1] N:M N+M : 100-(N+M) N : M : 100-(N+M) [1] N:M N+M : 100-(N+M) N : M : 100-(N+M)
[2] N:M:L N : 100-N M : L : 100-(M+L) [2] N:M:L N : 100-N M : L : 100-(M+L)
======================= ================== ===================== ======================= ================== =====================
...@@ -149,112 +134,98 @@ that: ...@@ -149,112 +134,98 @@ that:
Examples:: Examples::
KCONFIG_PROBABILITY=10 KCONFIG_PROBABILITY=10
10% of booleans will be set to 'y', 90% to 'n' 10% of booleans will be set to 'y', 90% to 'n'
5% of tristates will be set to 'y', 5% to 'm', 90% to 'n' 5% of tristates will be set to 'y', 5% to 'm', 90% to 'n'
KCONFIG_PROBABILITY=15:25 KCONFIG_PROBABILITY=15:25
40% of booleans will be set to 'y', 60% to 'n' 40% of booleans will be set to 'y', 60% to 'n'
15% of tristates will be set to 'y', 25% to 'm', 60% to 'n' 15% of tristates will be set to 'y', 25% to 'm', 60% to 'n'
KCONFIG_PROBABILITY=10:15:15 KCONFIG_PROBABILITY=10:15:15
10% of booleans will be set to 'y', 90% to 'n' 10% of booleans will be set to 'y', 90% to 'n'
15% of tristates will be set to 'y', 15% to 'm', 70% to 'n' 15% of tristates will be set to 'y', 15% to 'm', 70% to 'n'
---------------------------------------------------------------------- Environment variables for ``syncconfig``:
Environment variables for 'syncconfig' ``KCONFIG_NOSILENTUPDATE``
If this variable has a non-blank value, it prevents silent kernel
config updates (requires explicit updates).
KCONFIG_NOSILENTUPDATE ``KCONFIG_AUTOCONFIG``
---------------------- This environment variable can be set to specify the path & name of the
If this variable has a non-blank value, it prevents silent kernel "auto.conf" file. Its default value is "include/config/auto.conf".
config updates (requires explicit updates).
KCONFIG_AUTOCONFIG ``KCONFIG_AUTOHEADER``
------------------ This environment variable can be set to specify the path & name of the
This environment variable can be set to specify the path & name of the "autoconf.h" (header) file.
"auto.conf" file. Its default value is "include/config/auto.conf". Its default value is "include/generated/autoconf.h".
KCONFIG_AUTOHEADER
------------------
This environment variable can be set to specify the path & name of the
"autoconf.h" (header) file.
Its default value is "include/generated/autoconf.h".
----------------------------------------------------------------------
menuconfig menuconfig
---------- ==========
SEARCHING for CONFIG symbols
Searching in menuconfig: Searching in menuconfig:
The Search function searches for kernel configuration symbol The Search function searches for kernel configuration symbol
names, so you have to know something close to what you are names, so you have to know something close to what you are
looking for. looking for.
Example:: Example::
/hotplug /hotplug
This lists all config symbols that contain "hotplug", This lists all config symbols that contain "hotplug",
e.g., HOTPLUG_CPU, MEMORY_HOTPLUG. e.g., HOTPLUG_CPU, MEMORY_HOTPLUG.
For search help, enter / followed by TAB-TAB (to highlight For search help, enter / followed by TAB-TAB (to highlight
<Help>) and Enter. This will tell you that you can also use <Help>) and Enter. This will tell you that you can also use
regular expressions (regexes) in the search string, so if you regular expressions (regexes) in the search string, so if you
are not interested in MEMORY_HOTPLUG, you could try:: are not interested in MEMORY_HOTPLUG, you could try::
/^hotplug /^hotplug
When searching, symbols are sorted thus: When searching, symbols are sorted thus:
- first, exact matches, sorted alphabetically (an exact match - first, exact matches, sorted alphabetically (an exact match
is when the search matches the complete symbol name); is when the search matches the complete symbol name);
- then, other matches, sorted alphabetically. - then, other matches, sorted alphabetically.
For example: ^ATH.K matches: For example, ^ATH.K matches:
ATH5K ATH9K ATH5K_AHB ATH5K_DEBUG [...] ATH6KL ATH6KL_DEBUG ATH5K ATH9K ATH5K_AHB ATH5K_DEBUG [...] ATH6KL ATH6KL_DEBUG
[...] ATH9K_AHB ATH9K_BTCOEX_SUPPORT ATH9K_COMMON [...] [...] ATH9K_AHB ATH9K_BTCOEX_SUPPORT ATH9K_COMMON [...]
of which only ATH5K and ATH9K match exactly and so are sorted of which only ATH5K and ATH9K match exactly and so are sorted
first (and in alphabetical order), then come all other symbols, first (and in alphabetical order), then come all other symbols,
sorted in alphabetical order. sorted in alphabetical order.
In this menu, pressing the key in the (#) prefix will jump In this menu, pressing the key in the (#) prefix will jump
directly to that location. You will be returned to the current directly to that location. You will be returned to the current
search results after exiting this new menu. search results after exiting this new menu.
---------------------------------------------------------------------- User interface options for 'menuconfig':
User interface options for 'menuconfig' ``MENUCONFIG_COLOR``
It is possible to select different color themes using the variable
MENUCONFIG_COLOR. To select a theme use::
MENUCONFIG_COLOR make MENUCONFIG_COLOR=<theme> menuconfig
----------------
It is possible to select different color themes using the variable
MENUCONFIG_COLOR. To select a theme use::
make MENUCONFIG_COLOR=<theme> menuconfig Available themes are::
Available themes are:: - mono => selects colors suitable for monochrome displays
- blackbg => selects a color scheme with black background
- classic => theme with blue background. The classic look
- bluetitle => a LCD friendly version of classic. (default)
- mono => selects colors suitable for monochrome displays ``MENUCONFIG_MODE``
- blackbg => selects a color scheme with black background This mode shows all sub-menus in one large tree.
- classic => theme with blue background. The classic look
- bluetitle => a LCD friendly version of classic. (default)
MENUCONFIG_MODE Example::
---------------
This mode shows all sub-menus in one large tree.
Example:: make MENUCONFIG_MODE=single_menu menuconfig
make MENUCONFIG_MODE=single_menu menuconfig
----------------------------------------------------------------------
nconfig nconfig
------- =======
nconfig is an alternate text-based configurator. It lists function nconfig is an alternate text-based configurator. It lists function
keys across the bottom of the terminal (window) that execute commands. keys across the bottom of the terminal (window) that execute commands.
...@@ -266,61 +237,59 @@ Use F1 for Global help or F3 for the Short help menu. ...@@ -266,61 +237,59 @@ Use F1 for Global help or F3 for the Short help menu.
Searching in nconfig: Searching in nconfig:
You can search either in the menu entry "prompt" strings You can search either in the menu entry "prompt" strings
or in the configuration symbols. or in the configuration symbols.
Use / to begin a search through the menu entries. This does
not support regular expressions. Use <Down> or <Up> for
Next hit and Previous hit, respectively. Use <Esc> to
terminate the search mode.
Use / to begin a search through the menu entries. This does F8 (SymSearch) searches the configuration symbols for the
not support regular expressions. Use <Down> or <Up> for given string or regular expression (regex).
Next hit and Previous hit, respectively. Use <Esc> to
terminate the search mode.
F8 (SymSearch) searches the configuration symbols for the In the SymSearch, pressing the key in the (#) prefix will
given string or regular expression (regex). jump directly to that location. You will be returned to the
current search results after exiting this new menu.
In the SymSearch, pressing the key in the (#) prefix will Environment variables:
jump directly to that location. You will be returned to the
current search results after exiting this new menu.
NCONFIG_MODE ``NCONFIG_MODE``
------------ This mode shows all sub-menus in one large tree.
This mode shows all sub-menus in one large tree.
Example:: Example::
make NCONFIG_MODE=single_menu nconfig make NCONFIG_MODE=single_menu nconfig
----------------------------------------------------------------------
xconfig xconfig
------- =======
Searching in xconfig: Searching in xconfig:
The Search function searches for kernel configuration symbol The Search function searches for kernel configuration symbol
names, so you have to know something close to what you are names, so you have to know something close to what you are
looking for. looking for.
Example::
Ctrl-F hotplug Example::
or:: Ctrl-F hotplug
Menu: File, Search, hotplug or::
lists all config symbol entries that contain "hotplug" in Menu: File, Search, hotplug
the symbol name. In this Search dialog, you may change the
config setting for any of the entries that are not grayed out.
You can also enter a different search string without having
to return to the main menu.
lists all config symbol entries that contain "hotplug" in
the symbol name. In this Search dialog, you may change the
config setting for any of the entries that are not grayed out.
You can also enter a different search string without having
to return to the main menu.
----------------------------------------------------------------------
gconfig gconfig
------- =======
Searching in gconfig: Searching in gconfig:
There is no search command in gconfig. However, gconfig does There is no search command in gconfig. However, gconfig does
have several different viewing choices, modes, and options. have several different viewing choices, modes, and options.
...@@ -39,8 +39,8 @@ __all: ...@@ -39,8 +39,8 @@ __all:
# prepare rule. # prepare rule.
this-makefile := $(lastword $(MAKEFILE_LIST)) this-makefile := $(lastword $(MAKEFILE_LIST))
export abs_srctree := $(realpath $(dir $(this-makefile))) abs_srctree := $(realpath $(dir $(this-makefile)))
export abs_objtree := $(CURDIR) abs_objtree := $(CURDIR)
ifneq ($(sub_make_done),1) ifneq ($(sub_make_done),1)
...@@ -295,51 +295,51 @@ single-build := ...@@ -295,51 +295,51 @@ single-build :=
ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
need-config := need-config :=
endif endif
endif endif
ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),) ifneq ($(filter $(no-sync-config-targets), $(MAKECMDGOALS)),)
ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),) ifeq ($(filter-out $(no-sync-config-targets), $(MAKECMDGOALS)),)
may-sync-config := may-sync-config :=
endif endif
endif endif
need-compiler := $(may-sync-config) need-compiler := $(may-sync-config)
ifneq ($(KBUILD_EXTMOD),) ifneq ($(KBUILD_EXTMOD),)
may-sync-config := may-sync-config :=
endif endif
ifeq ($(KBUILD_EXTMOD),) ifeq ($(KBUILD_EXTMOD),)
ifneq ($(filter %config,$(MAKECMDGOALS)),) ifneq ($(filter %config,$(MAKECMDGOALS)),)
config-build := 1 config-build := 1
ifneq ($(words $(MAKECMDGOALS)),1) ifneq ($(words $(MAKECMDGOALS)),1)
mixed-build := 1 mixed-build := 1
endif
endif endif
endif
endif endif
# We cannot build single targets and the others at the same time # We cannot build single targets and the others at the same time
ifneq ($(filter $(single-targets), $(MAKECMDGOALS)),) ifneq ($(filter $(single-targets), $(MAKECMDGOALS)),)
single-build := 1 single-build := 1
ifneq ($(filter-out $(single-targets), $(MAKECMDGOALS)),) ifneq ($(filter-out $(single-targets), $(MAKECMDGOALS)),)
mixed-build := 1 mixed-build := 1
endif endif
endif endif
# For "make -j clean all", "make -j mrproper defconfig all", etc. # For "make -j clean all", "make -j mrproper defconfig all", etc.
ifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),) ifneq ($(filter $(clean-targets),$(MAKECMDGOALS)),)
ifneq ($(filter-out $(clean-targets),$(MAKECMDGOALS)),) ifneq ($(filter-out $(clean-targets),$(MAKECMDGOALS)),)
mixed-build := 1 mixed-build := 1
endif endif
endif endif
# install and modules_install need also be processed one by one # install and modules_install need also be processed one by one
ifneq ($(filter install,$(MAKECMDGOALS)),) ifneq ($(filter install,$(MAKECMDGOALS)),)
ifneq ($(filter modules_install,$(MAKECMDGOALS)),) ifneq ($(filter modules_install,$(MAKECMDGOALS)),)
mixed-build := 1 mixed-build := 1
endif endif
endif endif
ifdef mixed-build ifdef mixed-build
...@@ -965,8 +965,15 @@ export CC_FLAGS_CFI ...@@ -965,8 +965,15 @@ export CC_FLAGS_CFI
endif endif
ifneq ($(CONFIG_FUNCTION_ALIGNMENT),0) ifneq ($(CONFIG_FUNCTION_ALIGNMENT),0)
# Set the minimal function alignment. Use the newer GCC option
# -fmin-function-alignment if it is available, or fall back to -falign-funtions.
# See also CONFIG_CC_HAS_SANE_FUNCTION_ALIGNMENT.
ifdef CONFIG_CC_HAS_MIN_FUNCTION_ALIGNMENT
KBUILD_CFLAGS += -fmin-function-alignment=$(CONFIG_FUNCTION_ALIGNMENT)
else
KBUILD_CFLAGS += -falign-functions=$(CONFIG_FUNCTION_ALIGNMENT) KBUILD_CFLAGS += -falign-functions=$(CONFIG_FUNCTION_ALIGNMENT)
endif endif
endif
# arch Makefile may override CC so keep this after arch Makefile is included # arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS += -nostdinc NOSTDINC_FLAGS += -nostdinc
...@@ -1384,7 +1391,7 @@ ifneq ($(dtstree),) ...@@ -1384,7 +1391,7 @@ ifneq ($(dtstree),)
PHONY += dtbs dtbs_prepare dtbs_install dtbs_check PHONY += dtbs dtbs_prepare dtbs_install dtbs_check
dtbs: dtbs_prepare dtbs: dtbs_prepare
$(Q)$(MAKE) $(build)=$(dtstree) $(Q)$(MAKE) $(build)=$(dtstree) need-dtbslist=1
# include/config/kernel.release is actually needed when installing DTBs because # include/config/kernel.release is actually needed when installing DTBs because
# INSTALL_DTBS_PATH contains $(KERNELRELEASE). However, we do not want to make # INSTALL_DTBS_PATH contains $(KERNELRELEASE). However, we do not want to make
...@@ -1402,7 +1409,7 @@ endif ...@@ -1402,7 +1409,7 @@ endif
dtbs_check: dtbs dtbs_check: dtbs
dtbs_install: dtbs_install:
$(Q)$(MAKE) $(dtbinst)=$(dtstree) dst=$(INSTALL_DTBS_PATH) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.dtbinst obj=$(dtstree)
ifdef CONFIG_OF_EARLY_FLATTREE ifdef CONFIG_OF_EARLY_FLATTREE
all: dtbs all: dtbs
...@@ -1923,7 +1930,7 @@ clean: $(clean-dirs) ...@@ -1923,7 +1930,7 @@ clean: $(clean-dirs)
-o -name '*.ko.*' \ -o -name '*.ko.*' \
-o -name '*.dtb' -o -name '*.dtbo' \ -o -name '*.dtb' -o -name '*.dtbo' \
-o -name '*.dtb.S' -o -name '*.dtbo.S' \ -o -name '*.dtb.S' -o -name '*.dtbo.S' \
-o -name '*.dt.yaml' \ -o -name '*.dt.yaml' -o -name 'dtbs-list' \
-o -name '*.dwo' -o -name '*.lst' \ -o -name '*.dwo' -o -name '*.lst' \
-o -name '*.su' -o -name '*.mod' \ -o -name '*.su' -o -name '*.mod' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
......
...@@ -1597,4 +1597,16 @@ config FUNCTION_ALIGNMENT ...@@ -1597,4 +1597,16 @@ config FUNCTION_ALIGNMENT
default 4 if FUNCTION_ALIGNMENT_4B default 4 if FUNCTION_ALIGNMENT_4B
default 0 default 0
config CC_HAS_MIN_FUNCTION_ALIGNMENT
# Detect availability of the GCC option -fmin-function-alignment which
# guarantees minimal alignment for all functions, unlike
# -falign-functions which the compiler ignores for cold functions.
def_bool $(cc-option, -fmin-function-alignment=8)
config CC_HAS_SANE_FUNCTION_ALIGNMENT
# Set if the guaranteed alignment with -fmin-function-alignment is
# available or extra care is required in the kernel. Clang provides
# strict alignment always, even with -falign-functions.
def_bool CC_HAS_MIN_FUNCTION_ALIGNMENT || CC_IS_CLANG
endmenu endmenu
...@@ -339,6 +339,7 @@ config ALPHA_EV4 ...@@ -339,6 +339,7 @@ config ALPHA_EV4
bool bool
depends on ALPHA_JENSEN || (ALPHA_SABLE && !ALPHA_GAMMA) || ALPHA_LYNX || ALPHA_NORITAKE && !ALPHA_PRIMO || ALPHA_MIKASA && !ALPHA_PRIMO || ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P_CH || ALPHA_XL || ALPHA_NONAME || ALPHA_EB66 || ALPHA_EB66P || ALPHA_P2K depends on ALPHA_JENSEN || (ALPHA_SABLE && !ALPHA_GAMMA) || ALPHA_LYNX || ALPHA_NORITAKE && !ALPHA_PRIMO || ALPHA_MIKASA && !ALPHA_PRIMO || ALPHA_CABRIOLET || ALPHA_AVANTI_CH || ALPHA_EB64P_CH || ALPHA_XL || ALPHA_NONAME || ALPHA_EB66 || ALPHA_EB66P || ALPHA_P2K
default y if !ALPHA_LYNX default y if !ALPHA_LYNX
default y if !ALPHA_EV5
config ALPHA_LCA config ALPHA_LCA
bool bool
...@@ -366,10 +367,6 @@ config ALPHA_EV5 ...@@ -366,10 +367,6 @@ config ALPHA_EV5
bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_LYNX bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_LYNX
default y if ALPHA_RX164 || ALPHA_RAWHIDE || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_SABLE && ALPHA_GAMMA || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR default y if ALPHA_RX164 || ALPHA_RAWHIDE || ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_SABLE && ALPHA_GAMMA || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR
config ALPHA_EV4
bool
default y if ALPHA_LYNX && !ALPHA_EV5
config ALPHA_CIA config ALPHA_CIA
bool bool
depends on ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR depends on ALPHA_MIATA || ALPHA_LX164 || ALPHA_SX164 || ALPHA_RUFFIAN || ALPHA_NORITAKE && ALPHA_PRIMO || ALPHA_MIKASA && ALPHA_PRIMO || ALPHA_PC164 || ALPHA_TAKARA || ALPHA_EB164 || ALPHA_ALCOR
...@@ -394,16 +391,12 @@ config ALPHA_PRIMO ...@@ -394,16 +391,12 @@ config ALPHA_PRIMO
Say Y if you have an AS 1000 5/xxx or an AS 1000A 5/xxx. Say Y if you have an AS 1000 5/xxx or an AS 1000A 5/xxx.
config ALPHA_GAMMA config ALPHA_GAMMA
bool "EV5 CPU(s) (model 5/xxx)?" bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_SABLE
depends on ALPHA_SABLE depends on ALPHA_SABLE || ALPHA_LYNX
default ALPHA_LYNX
help help
Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx. Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx.
config ALPHA_GAMMA
bool
depends on ALPHA_LYNX
default y
config ALPHA_T2 config ALPHA_T2
bool bool
depends on ALPHA_SABLE || ALPHA_LYNX depends on ALPHA_SABLE || ALPHA_LYNX
......
...@@ -7,11 +7,13 @@ config HEXAGON ...@@ -7,11 +7,13 @@ config HEXAGON
select ARCH_32BIT_OFF_T select ARCH_32BIT_OFF_T
select ARCH_HAS_SYNC_DMA_FOR_DEVICE select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_NO_PREEMPT select ARCH_NO_PREEMPT
select ARCH_WANT_FRAME_POINTERS
select DMA_GLOBAL_POOL select DMA_GLOBAL_POOL
select HAVE_PAGE_SIZE_4KB select HAVE_PAGE_SIZE_4KB
select HAVE_PAGE_SIZE_16KB select HAVE_PAGE_SIZE_16KB
select HAVE_PAGE_SIZE_64KB select HAVE_PAGE_SIZE_64KB
select HAVE_PAGE_SIZE_256KB select HAVE_PAGE_SIZE_256KB
select FRAME_POINTER
# Other pending projects/to-do items. # Other pending projects/to-do items.
# select HAVE_REGS_AND_STACK_ACCESS_API # select HAVE_REGS_AND_STACK_ACCESS_API
# select HAVE_HW_BREAKPOINT if PERF_EVENTS # select HAVE_HW_BREAKPOINT if PERF_EVENTS
...@@ -23,6 +25,7 @@ config HEXAGON ...@@ -23,6 +25,7 @@ config HEXAGON
select HAVE_PERF_EVENTS select HAVE_PERF_EVENTS
# GENERIC_ALLOCATOR is used by dma_alloc_coherent() # GENERIC_ALLOCATOR is used by dma_alloc_coherent()
select GENERIC_ALLOCATOR select GENERIC_ALLOCATOR
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW
select HAVE_ARCH_KGDB select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_TRACEHOOK
...@@ -47,9 +50,6 @@ config HEXAGON_PHYS_OFFSET ...@@ -47,9 +50,6 @@ config HEXAGON_PHYS_OFFSET
help help
Platforms that don't load the kernel at zero set this. Platforms that don't load the kernel at zero set this.
config FRAME_POINTER
def_bool y
config LOCKDEP_SUPPORT config LOCKDEP_SUPPORT
def_bool y def_bool y
...@@ -62,12 +62,6 @@ config MMU ...@@ -62,12 +62,6 @@ config MMU
config GENERIC_CSUM config GENERIC_CSUM
def_bool y def_bool y
#
# Use the generic interrupt handling code in kernel/irq/:
#
config GENERIC_IRQ_PROBE
def_bool y
config GENERIC_HWEIGHT config GENERIC_HWEIGHT
def_bool y def_bool y
......
...@@ -238,9 +238,9 @@ config PARISC_HUGE_KERNEL ...@@ -238,9 +238,9 @@ config PARISC_HUGE_KERNEL
def_bool y if !MODULES || UBSAN || FTRACE || COMPILE_TEST def_bool y if !MODULES || UBSAN || FTRACE || COMPILE_TEST
config MLONGCALLS config MLONGCALLS
def_bool y if PARISC_HUGE_KERNEL
bool "Enable the -mlong-calls compiler option for big kernels" if !PARISC_HUGE_KERNEL bool "Enable the -mlong-calls compiler option for big kernels" if !PARISC_HUGE_KERNEL
depends on PA8X00 depends on PA8X00
default PARISC_HUGE_KERNEL
help help
If you configure the kernel to include many drivers built-in instead If you configure the kernel to include many drivers built-in instead
as modules, the kernel executable may become too big, so that the as modules, the kernel executable may become too big, so that the
...@@ -255,9 +255,9 @@ config MLONGCALLS ...@@ -255,9 +255,9 @@ config MLONGCALLS
Enabling this option will probably slow down your kernel. Enabling this option will probably slow down your kernel.
config 64BIT config 64BIT
def_bool y if "$(ARCH)" = "parisc64"
bool "64-bit kernel" if "$(ARCH)" = "parisc" bool "64-bit kernel" if "$(ARCH)" = "parisc"
depends on PA8X00 depends on PA8X00
default "$(ARCH)" = "parisc64"
help help
Enable this if you want to support 64bit kernel on PA-RISC platform. Enable this if you want to support 64bit kernel on PA-RISC platform.
......
...@@ -6,7 +6,7 @@ config AS_HAS_ULEB128 ...@@ -6,7 +6,7 @@ config AS_HAS_ULEB128
menuconfig RUNTIME_KERNEL_TESTING_MENU menuconfig RUNTIME_KERNEL_TESTING_MENU
bool "arch/riscv/kernel runtime Testing" bool "arch/riscv/kernel runtime Testing"
def_bool y default y
help help
Enable riscv kernel runtime testing. Enable riscv kernel runtime testing.
......
...@@ -9,7 +9,9 @@ include $(srctree)/lib/vdso/Makefile ...@@ -9,7 +9,9 @@ include $(srctree)/lib/vdso/Makefile
# Sanitizer runtimes are unavailable and cannot be linked here. # Sanitizer runtimes are unavailable and cannot be linked here.
KASAN_SANITIZE := n KASAN_SANITIZE := n
KMSAN_SANITIZE_vclock_gettime.o := n KMSAN_SANITIZE_vclock_gettime.o := n
KMSAN_SANITIZE_vdso32/vclock_gettime.o := n
KMSAN_SANITIZE_vgetcpu.o := n KMSAN_SANITIZE_vgetcpu.o := n
KMSAN_SANITIZE_vdso32/vgetcpu.o := n
UBSAN_SANITIZE := n UBSAN_SANITIZE := n
KCSAN_SANITIZE := n KCSAN_SANITIZE := n
......
...@@ -118,8 +118,8 @@ config KVM_AMD ...@@ -118,8 +118,8 @@ config KVM_AMD
will be called kvm-amd. will be called kvm-amd.
config KVM_AMD_SEV config KVM_AMD_SEV
def_bool y
bool "AMD Secure Encrypted Virtualization (SEV) support" bool "AMD Secure Encrypted Virtualization (SEV) support"
default y
depends on KVM_AMD && X86_64 depends on KVM_AMD && X86_64
depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m) depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m)
help help
......
...@@ -4,7 +4,8 @@ ccflags-y += -I $(srctree)/arch/x86/kvm ...@@ -4,7 +4,8 @@ ccflags-y += -I $(srctree)/arch/x86/kvm
ccflags-$(CONFIG_KVM_WERROR) += -Werror ccflags-$(CONFIG_KVM_WERROR) += -Werror
ifeq ($(CONFIG_FRAME_POINTER),y) ifeq ($(CONFIG_FRAME_POINTER),y)
OBJECT_FILES_NON_STANDARD_vmenter.o := y OBJECT_FILES_NON_STANDARD_vmx/vmenter.o := y
OBJECT_FILES_NON_STANDARD_svm/vmenter.o := y
endif endif
include $(srctree)/virt/kvm/Makefile.kvm include $(srctree)/virt/kvm/Makefile.kvm
......
...@@ -81,7 +81,6 @@ config XEN_PVH ...@@ -81,7 +81,6 @@ config XEN_PVH
bool "Xen PVH guest support" bool "Xen PVH guest support"
depends on XEN && XEN_PVHVM && ACPI depends on XEN && XEN_PVHVM && ACPI
select PVH select PVH
def_bool n
help help
Support for running as a Xen PVH guest. Support for running as a Xen PVH guest.
......
...@@ -460,7 +460,6 @@ config ACPI_BGRT ...@@ -460,7 +460,6 @@ config ACPI_BGRT
config ACPI_REDUCED_HARDWARE_ONLY config ACPI_REDUCED_HARDWARE_ONLY
bool "Hardware-reduced ACPI support only" if EXPERT bool "Hardware-reduced ACPI support only" if EXPERT
def_bool n
help help
This config item changes the way the ACPI code is built. When this This config item changes the way the ACPI code is built. When this
option is selected, the kernel will use a specialized version of option is selected, the kernel will use a specialized version of
......
...@@ -87,8 +87,8 @@ config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON ...@@ -87,8 +87,8 @@ config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON
the default value. the default value.
config INTEL_IOMMU_PERF_EVENTS config INTEL_IOMMU_PERF_EVENTS
def_bool y
bool "Intel IOMMU performance events" bool "Intel IOMMU performance events"
default y
depends on INTEL_IOMMU && PERF_EVENTS depends on INTEL_IOMMU && PERF_EVENTS
help help
Selecting this option will enable the performance monitoring Selecting this option will enable the performance monitoring
......
...@@ -519,7 +519,6 @@ config DM_VERITY ...@@ -519,7 +519,6 @@ config DM_VERITY
If unsure, say N. If unsure, say N.
config DM_VERITY_VERIFY_ROOTHASH_SIG config DM_VERITY_VERIFY_ROOTHASH_SIG
def_bool n
bool "Verity data device root hash signature verification support" bool "Verity data device root hash signature verification support"
depends on DM_VERITY depends on DM_VERITY
select SYSTEM_DATA_VERIFICATION select SYSTEM_DATA_VERIFICATION
......
...@@ -99,17 +99,17 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { } ...@@ -99,17 +99,17 @@ static inline void __chk_io_ptr(const volatile void __iomem *ptr) { }
* gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute * gcc: https://gcc.gnu.org/onlinedocs/gcc/Label-Attributes.html#index-cold-label-attribute
* *
* When -falign-functions=N is in use, we must avoid the cold attribute as * When -falign-functions=N is in use, we must avoid the cold attribute as
* contemporary versions of GCC drop the alignment for cold functions. Worse, * GCC drops the alignment for cold functions. Worse, GCC can implicitly mark
* GCC can implicitly mark callees of cold functions as cold themselves, so * callees of cold functions as cold themselves, so it's not sufficient to add
* it's not sufficient to add __function_aligned here as that will not ensure * __function_aligned here as that will not ensure that callees are correctly
* that callees are correctly aligned. * aligned.
* *
* See: * See:
* *
* https://lore.kernel.org/lkml/Y77%2FqVgvaJidFpYt@FVFF77S0Q05N * https://lore.kernel.org/lkml/Y77%2FqVgvaJidFpYt@FVFF77S0Q05N
* https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88345#c9 * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88345#c9
*/ */
#if !defined(CONFIG_CC_IS_GCC) || (CONFIG_FUNCTION_ALIGNMENT == 0) #if defined(CONFIG_CC_HAS_SANE_FUNCTION_ALIGNMENT) || (CONFIG_FUNCTION_ALIGNMENT == 0)
#define __cold __attribute__((__cold__)) #define __cold __attribute__((__cold__))
#else #else
#define __cold #define __cold
......
...@@ -1499,7 +1499,7 @@ config MULTIUSER ...@@ -1499,7 +1499,7 @@ config MULTIUSER
config SGETMASK_SYSCALL config SGETMASK_SYSCALL
bool "sgetmask/ssetmask syscalls support" if EXPERT bool "sgetmask/ssetmask syscalls support" if EXPERT
def_bool PARISC || M68K || PPC || MIPS || X86 || SPARC || MICROBLAZE || SUPERH default PARISC || M68K || PPC || MIPS || X86 || SPARC || MICROBLAZE || SUPERH
help help
sys_sgetmask and sys_ssetmask are obsolete system calls sys_sgetmask and sys_ssetmask are obsolete system calls
no longer supported in libc but still enabled by default in some no longer supported in libc but still enabled by default in some
......
...@@ -362,8 +362,7 @@ config MODPROBE_PATH ...@@ -362,8 +362,7 @@ config MODPROBE_PATH
userspace can still load modules explicitly). userspace can still load modules explicitly).
config TRIM_UNUSED_KSYMS config TRIM_UNUSED_KSYMS
bool "Trim unused exported kernel symbols" if EXPERT bool "Trim unused exported kernel symbols"
depends on !COMPILE_TEST
help help
The kernel and some modules make many symbols available for The kernel and some modules make many symbols available for
other modules to use via EXPORT_SYMBOL() and variants. Depending other modules to use via EXPORT_SYMBOL() and variants. Depending
......
...@@ -2127,7 +2127,7 @@ config KCOV_IRQ_AREA_SIZE ...@@ -2127,7 +2127,7 @@ config KCOV_IRQ_AREA_SIZE
menuconfig RUNTIME_TESTING_MENU menuconfig RUNTIME_TESTING_MENU
bool "Runtime Testing" bool "Runtime Testing"
def_bool y default y
if RUNTIME_TESTING_MENU if RUNTIME_TESTING_MENU
......
...@@ -583,7 +583,7 @@ config MEMORY_BALLOON ...@@ -583,7 +583,7 @@ config MEMORY_BALLOON
# support for memory balloon compaction # support for memory balloon compaction
config BALLOON_COMPACTION config BALLOON_COMPACTION
bool "Allow for balloon memory compaction/migration" bool "Allow for balloon memory compaction/migration"
def_bool y default y
depends on COMPACTION && MEMORY_BALLOON depends on COMPACTION && MEMORY_BALLOON
help help
Memory fragmentation introduced by ballooning might reduce Memory fragmentation introduced by ballooning might reduce
...@@ -598,7 +598,7 @@ config BALLOON_COMPACTION ...@@ -598,7 +598,7 @@ config BALLOON_COMPACTION
# support for memory compaction # support for memory compaction
config COMPACTION config COMPACTION
bool "Allow for memory compaction" bool "Allow for memory compaction"
def_bool y default y
select MIGRATION select MIGRATION
depends on MMU depends on MMU
help help
...@@ -621,7 +621,6 @@ config COMPACT_UNEVICTABLE_DEFAULT ...@@ -621,7 +621,6 @@ config COMPACT_UNEVICTABLE_DEFAULT
# support for free page reporting # support for free page reporting
config PAGE_REPORTING config PAGE_REPORTING
bool "Free page reporting" bool "Free page reporting"
def_bool n
help help
Free page reporting allows for the incremental acquisition of Free page reporting allows for the incremental acquisition of
free pages from the buddy allocator for the purpose of reporting free pages from the buddy allocator for the purpose of reporting
...@@ -633,7 +632,7 @@ config PAGE_REPORTING ...@@ -633,7 +632,7 @@ config PAGE_REPORTING
# #
config MIGRATION config MIGRATION
bool "Page migration" bool "Page migration"
def_bool y default y
depends on (NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA) && MMU depends on (NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA) && MMU
help help
Allows the migration of the physical location of pages of processes Allows the migration of the physical location of pages of processes
......
...@@ -13,7 +13,7 @@ config IP_DCCP_CCID2_DEBUG ...@@ -13,7 +13,7 @@ config IP_DCCP_CCID2_DEBUG
config IP_DCCP_CCID3 config IP_DCCP_CCID3
bool "CCID-3 (TCP-Friendly)" bool "CCID-3 (TCP-Friendly)"
def_bool y if (IP_DCCP = y || IP_DCCP = m) default IP_DCCP = y || IP_DCCP = m
help help
CCID-3 denotes TCP-Friendly Rate Control (TFRC), an equation-based CCID-3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
rate-controlled congestion control mechanism. TFRC is designed to rate-controlled congestion control mechanism. TFRC is designed to
......
...@@ -100,7 +100,7 @@ rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \ ...@@ -100,7 +100,7 @@ rustdoc: rustdoc-core rustdoc-macros rustdoc-compiler_builtins \
-e 's:rust-logo-[0-9a-f]+\.svg:logo.svg:g' \ -e 's:rust-logo-[0-9a-f]+\.svg:logo.svg:g' \
-e 's:favicon-[0-9a-f]+\.svg:logo.svg:g' \ -e 's:favicon-[0-9a-f]+\.svg:logo.svg:g' \
-e 's:<link rel="alternate icon" type="image/png" href="[/.]+/static\.files/favicon-(16x16|32x32)-[0-9a-f]+\.png">::g' \ -e 's:<link rel="alternate icon" type="image/png" href="[/.]+/static\.files/favicon-(16x16|32x32)-[0-9a-f]+\.png">::g' \
-e 's:<a href="srctree/([^"]+)">:<a href="$(abs_srctree)/\1">:g' -e 's:<a href="srctree/([^"]+)">:<a href="$(realpath $(srctree))/\1">:g'
$(Q)for f in $(rustdoc_output)/static.files/rustdoc-*.css; do \ $(Q)for f in $(rustdoc_output)/static.files/rustdoc-*.css; do \
echo ".logo-container > img { object-fit: contain; }" >> $$f; done echo ".logo-container > img { object-fit: contain; }" >> $$f; done
...@@ -414,7 +414,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L ...@@ -414,7 +414,7 @@ quiet_cmd_rustc_library = $(if $(skip_clippy),RUSTC,$(RUSTC_OR_CLIPPY_QUIET)) L
rust-analyzer: rust-analyzer:
$(Q)$(srctree)/scripts/generate_rust_analyzer.py \ $(Q)$(srctree)/scripts/generate_rust_analyzer.py \
--cfgs='core=$(core-cfgs)' --cfgs='alloc=$(alloc-cfgs)' \ --cfgs='core=$(core-cfgs)' --cfgs='alloc=$(alloc-cfgs)' \
$(abs_srctree) $(abs_objtree) \ $(realpath $(srctree)) $(realpath $(objtree)) \
$(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \ $(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \
$(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json $(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json
......
...@@ -113,12 +113,6 @@ endef ...@@ -113,12 +113,6 @@ endef
# $(Q)$(MAKE) $(build)=dir # $(Q)$(MAKE) $(build)=dir
build := -f $(srctree)/scripts/Makefile.build obj build := -f $(srctree)/scripts/Makefile.build obj
###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.dtbinst obj=
# Usage:
# $(Q)$(MAKE) $(dtbinst)=dir
dtbinst := -f $(srctree)/scripts/Makefile.dtbinst obj
### ###
# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj= # Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=
# Usage: # Usage:
......
...@@ -71,6 +71,7 @@ endif ...@@ -71,6 +71,7 @@ endif
# subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...) # subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...)
subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y))) subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y)))
subdir-modorder := $(sort $(filter %/modules.order, $(obj-m))) subdir-modorder := $(sort $(filter %/modules.order, $(obj-m)))
subdir-dtbslist := $(sort $(filter %/dtbs-list, $(dtb-y)))
targets-for-builtin := $(extra-y) targets-for-builtin := $(extra-y)
...@@ -213,7 +214,7 @@ endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT ...@@ -213,7 +214,7 @@ endif # CONFIG_FTRACE_MCOUNT_USE_RECORDMCOUNT
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'y': skip objtool checking for a file
# 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file # 'OBJECT_FILES_NON_STANDARD_foo.o := 'n': override directory skip for a file
is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(basetarget).o)$(OBJECT_FILES_NON_STANDARD)n),y) is-standard-object = $(if $(filter-out y%, $(OBJECT_FILES_NON_STANDARD_$(target-stem).o)$(OBJECT_FILES_NON_STANDARD)n),y)
$(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y)) $(obj)/%.o: objtool-enabled = $(if $(is-standard-object),$(if $(delay-objtool),$(is-single-obj-m),y))
...@@ -388,6 +389,7 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler ...@@ -388,6 +389,7 @@ $(obj)/%.asn1.c $(obj)/%.asn1.h: $(src)/%.asn1 $(objtree)/scripts/asn1_compiler
# To build objects in subdirs, we need to descend into the directories # To build objects in subdirs, we need to descend into the directories
$(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ; $(subdir-builtin): $(obj)/%/built-in.a: $(obj)/% ;
$(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ; $(subdir-modorder): $(obj)/%/modules.order: $(obj)/% ;
$(subdir-dtbslist): $(obj)/%/dtbs-list: $(obj)/% ;
# #
# Rule to compile a set of .o files into one .a file (without symbol table) # Rule to compile a set of .o files into one .a file (without symbol table)
...@@ -404,19 +406,21 @@ $(obj)/built-in.a: $(real-obj-y) FORCE ...@@ -404,19 +406,21 @@ $(obj)/built-in.a: $(real-obj-y) FORCE
$(call if_changed,ar_builtin) $(call if_changed,ar_builtin)
# #
# Rule to create modules.order file # Rule to create modules.order and dtbs-list
# #
# Create commands to either record .ko file or cat modules.order from # This is a list of build artifacts (module or dtb) from the current Makefile
# a subdirectory # and its sub-directories. The timestamp should be updated when any of the
# Add $(obj-m) as the prerequisite to avoid updating the timestamp of # member files.
# modules.order unless contained modules are updated.
cmd_modules_order = { $(foreach m, $(real-prereqs), \ cmd_gen_order = { $(foreach m, $(real-prereqs), \
$(if $(filter %/modules.order, $m), cat $m, echo $m);) :; } \ $(if $(filter %/$(notdir $@), $m), cat $m, echo $m);) :; } \
> $@ > $@
$(obj)/modules.order: $(obj-m) FORCE $(obj)/modules.order: $(obj-m) FORCE
$(call if_changed,modules_order) $(call if_changed,gen_order)
$(obj)/dtbs-list: $(dtb-y) FORCE
$(call if_changed,gen_order)
# #
# Rule to compile a set of .o files into one .a file (with symbol table) # Rule to compile a set of .o files into one .a file (with symbol table)
......
...@@ -8,32 +8,36 @@ ...@@ -8,32 +8,36 @@
# $INSTALL_PATH/dtbs/$KERNELRELEASE # $INSTALL_PATH/dtbs/$KERNELRELEASE
# ========================================================================== # ==========================================================================
src := $(obj)
PHONY := __dtbs_install PHONY := __dtbs_install
__dtbs_install: __dtbs_install:
include include/config/auto.conf include include/config/auto.conf
include $(srctree)/scripts/Kbuild.include include $(srctree)/scripts/Kbuild.include
include $(kbuild-file)
dtbs := $(addprefix $(dst)/, $(dtb-y) $(if $(CONFIG_OF_ALL_DTBS),$(dtb-)))
subdirs := $(addprefix $(obj)/, $(subdir-y) $(subdir-m))
__dtbs_install: $(dtbs) $(subdirs) dst := $(INSTALL_DTBS_PATH)
@:
quiet_cmd_dtb_install = INSTALL $@ quiet_cmd_dtb_install = INSTALL $@
cmd_dtb_install = install -D $< $@ cmd_dtb_install = install -D $< $@
$(dst)/%.dtb: $(obj)/%.dtb $(dst)/%: $(obj)/%
$(call cmd,dtb_install) $(call cmd,dtb_install)
$(dst)/%.dtbo: $(obj)/%.dtbo dtbs := $(patsubst $(obj)/%,%,$(call read-file, $(obj)/dtbs-list))
$(call cmd,dtb_install)
ifdef CONFIG_ARCH_WANT_FLAT_DTB_INSTALL
PHONY += $(subdirs) define gen_install_rules
$(subdirs): $(dst)/%: $(obj)/$(1)%
$(Q)$(MAKE) $(dtbinst)=$@ dst=$(if $(CONFIG_ARCH_WANT_FLAT_DTB_INSTALL),$(dst),$(patsubst $(obj)/%,$(dst)/%,$@)) $$(call cmd,dtb_install)
endef
$(foreach d, $(sort $(dir $(dtbs))), $(eval $(call gen_install_rules,$(d))))
dtbs := $(notdir $(dtbs))
endif # CONFIG_ARCH_WANT_FLAT_DTB_INSTALL
__dtbs_install: $(addprefix $(dst)/, $(dtbs))
@:
.PHONY: $(PHONY) .PHONY: $(PHONY)
...@@ -132,6 +132,8 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast) ...@@ -132,6 +132,8 @@ KBUILD_CFLAGS += $(call cc-disable-warning, pointer-to-enum-cast)
KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare KBUILD_CFLAGS += -Wno-tautological-constant-out-of-range-compare
KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access) KBUILD_CFLAGS += $(call cc-disable-warning, unaligned-access)
KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict) KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict)
KBUILD_CFLAGS += -Wno-enum-compare-conditional
KBUILD_CFLAGS += -Wno-enum-enum-conversion
endif endif
endif endif
...@@ -185,7 +187,6 @@ KBUILD_CFLAGS += -Wpointer-arith ...@@ -185,7 +187,6 @@ KBUILD_CFLAGS += -Wpointer-arith
KBUILD_CFLAGS += -Wredundant-decls KBUILD_CFLAGS += -Wredundant-decls
KBUILD_CFLAGS += -Wsign-compare KBUILD_CFLAGS += -Wsign-compare
KBUILD_CFLAGS += -Wswitch-default KBUILD_CFLAGS += -Wswitch-default
KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat)
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3 KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3
......
...@@ -45,6 +45,11 @@ else ...@@ -45,6 +45,11 @@ else
obj-y := $(filter-out %/, $(obj-y)) obj-y := $(filter-out %/, $(obj-y))
endif endif
ifdef need-dtbslist
dtb-y += $(addsuffix /dtbs-list, $(subdir-ym))
always-y += dtbs-list
endif
# Expand $(foo-objs) $(foo-y) etc. by replacing their individuals # Expand $(foo-objs) $(foo-y) etc. by replacing their individuals
suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s)))) suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s))))
# List composite targets that are constructed by combining other targets # List composite targets that are constructed by combining other targets
...@@ -99,6 +104,7 @@ lib-y := $(addprefix $(obj)/,$(lib-y)) ...@@ -99,6 +104,7 @@ lib-y := $(addprefix $(obj)/,$(lib-y))
real-obj-y := $(addprefix $(obj)/,$(real-obj-y)) real-obj-y := $(addprefix $(obj)/,$(real-obj-y))
real-obj-m := $(addprefix $(obj)/,$(real-obj-m)) real-obj-m := $(addprefix $(obj)/,$(real-obj-m))
multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m)) multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m))
dtb-y := $(addprefix $(obj)/, $(dtb-y))
multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y)) multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y))
real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y)) real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y))
subdir-ym := $(addprefix $(obj)/,$(subdir-ym)) subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
...@@ -148,7 +154,7 @@ _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds) ...@@ -148,7 +154,7 @@ _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds)
# #
ifeq ($(CONFIG_GCOV_KERNEL),y) ifeq ($(CONFIG_GCOV_KERNEL),y)
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(GCOV_PROFILE_$(basetarget).o)$(GCOV_PROFILE)$(CONFIG_GCOV_PROFILE_ALL)), \ $(GCOV_PROFILE_$(target-stem).o)$(GCOV_PROFILE)$(CONFIG_GCOV_PROFILE_ALL)), \
$(CFLAGS_GCOV)) $(CFLAGS_GCOV))
endif endif
...@@ -159,32 +165,32 @@ endif ...@@ -159,32 +165,32 @@ endif
ifeq ($(CONFIG_KASAN),y) ifeq ($(CONFIG_KASAN),y)
ifneq ($(CONFIG_KASAN_HW_TAGS),y) ifneq ($(CONFIG_KASAN_HW_TAGS),y)
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(KASAN_SANITIZE_$(basetarget).o)$(KASAN_SANITIZE)y), \ $(KASAN_SANITIZE_$(target-stem).o)$(KASAN_SANITIZE)y), \
$(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE)) $(CFLAGS_KASAN), $(CFLAGS_KASAN_NOSANITIZE))
endif endif
endif endif
ifeq ($(CONFIG_KMSAN),y) ifeq ($(CONFIG_KMSAN),y)
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(KMSAN_SANITIZE_$(basetarget).o)$(KMSAN_SANITIZE)y), \ $(KMSAN_SANITIZE_$(target-stem).o)$(KMSAN_SANITIZE)y), \
$(CFLAGS_KMSAN)) $(CFLAGS_KMSAN))
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(KMSAN_ENABLE_CHECKS_$(basetarget).o)$(KMSAN_ENABLE_CHECKS)y), \ $(KMSAN_ENABLE_CHECKS_$(target-stem).o)$(KMSAN_ENABLE_CHECKS)y), \
, -mllvm -msan-disable-checks=1) , -mllvm -msan-disable-checks=1)
endif endif
ifeq ($(CONFIG_UBSAN),y) ifeq ($(CONFIG_UBSAN),y)
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)y), \ $(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SANITIZE)y), \
$(CFLAGS_UBSAN)) $(CFLAGS_UBSAN))
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(UBSAN_SIGNED_WRAP_$(basetarget).o)$(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SIGNED_WRAP)$(UBSAN_SANITIZE)y), \ $(UBSAN_SIGNED_WRAP_$(target-stem).o)$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SIGNED_WRAP)$(UBSAN_SANITIZE)y), \
$(CFLAGS_UBSAN_SIGNED_WRAP)) $(CFLAGS_UBSAN_SIGNED_WRAP))
endif endif
ifeq ($(CONFIG_KCOV),y) ifeq ($(CONFIG_KCOV),y)
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(KCOV_INSTRUMENT_$(basetarget).o)$(KCOV_INSTRUMENT)$(CONFIG_KCOV_INSTRUMENT_ALL)), \ $(KCOV_INSTRUMENT_$(target-stem).o)$(KCOV_INSTRUMENT)$(CONFIG_KCOV_INSTRUMENT_ALL)), \
$(CFLAGS_KCOV)) $(CFLAGS_KCOV))
endif endif
...@@ -194,12 +200,12 @@ endif ...@@ -194,12 +200,12 @@ endif
# #
ifeq ($(CONFIG_KCSAN),y) ifeq ($(CONFIG_KCSAN),y)
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(KCSAN_SANITIZE_$(basetarget).o)$(KCSAN_SANITIZE)y), \ $(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)y), \
$(CFLAGS_KCSAN)) $(CFLAGS_KCSAN))
# Some uninstrumented files provide implied barriers required to avoid false # Some uninstrumented files provide implied barriers required to avoid false
# positives: set KCSAN_INSTRUMENT_BARRIERS for barrier instrumentation only. # positives: set KCSAN_INSTRUMENT_BARRIERS for barrier instrumentation only.
_c_flags += $(if $(patsubst n%,, \ _c_flags += $(if $(patsubst n%,, \
$(KCSAN_INSTRUMENT_BARRIERS_$(basetarget).o)$(KCSAN_INSTRUMENT_BARRIERS)n), \ $(KCSAN_INSTRUMENT_BARRIERS_$(target-stem).o)$(KCSAN_INSTRUMENT_BARRIERS)n), \
-D__KCSAN_INSTRUMENT_BARRIERS__) -D__KCSAN_INSTRUMENT_BARRIERS__)
endif endif
...@@ -364,7 +370,7 @@ DTC_FLAGS += -Wnode_name_chars_strict \ ...@@ -364,7 +370,7 @@ DTC_FLAGS += -Wnode_name_chars_strict \
-Wunique_unit_address -Wunique_unit_address
endif endif
DTC_FLAGS += $(DTC_FLAGS_$(basetarget)) DTC_FLAGS += $(DTC_FLAGS_$(target-stem))
# Set -@ if the target is a base DTB that overlay is applied onto # Set -@ if the target is a base DTB that overlay is applied onto
DTC_FLAGS += $(if $(filter $(patsubst $(obj)/%,%,$@), $(base-dtb-y)), -@) DTC_FLAGS += $(if $(filter $(patsubst $(obj)/%,%,$@), $(base-dtb-y)), -@)
......
...@@ -135,7 +135,7 @@ snap-pkg: ...@@ -135,7 +135,7 @@ snap-pkg:
mkdir $(objtree)/snap mkdir $(objtree)/snap
$(MAKE) clean $(MAKE) clean
sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \ sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \
s@SRCTREE@$(abs_srctree)@" \ s@SRCTREE@$(realpath $(srctree))@" \
$(srctree)/scripts/package/snapcraft.template > \ $(srctree)/scripts/package/snapcraft.template > \
$(objtree)/snap/snapcraft.yaml $(objtree)/snap/snapcraft.yaml
cd $(objtree)/snap && \ cd $(objtree)/snap && \
......
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef ARRAY_SIZE_H
#define ARRAY_SIZE_H
/**
* ARRAY_SIZE - get the number of elements in array @arr
* @arr: array to be sized
*/
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#endif /* ARRAY_SIZE_H */
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <sys/time.h> #include <sys/time.h>
#include <errno.h> #include <errno.h>
#include "internal.h"
#include "lkc.h" #include "lkc.h"
static void conf(struct menu *menu); static void conf(struct menu *menu);
...@@ -171,7 +172,7 @@ enum conf_def_mode { ...@@ -171,7 +172,7 @@ enum conf_def_mode {
static bool conf_set_all_new_symbols(enum conf_def_mode mode) static bool conf_set_all_new_symbols(enum conf_def_mode mode)
{ {
struct symbol *sym, *csym; struct symbol *sym, *csym;
int i, cnt; int cnt;
/* /*
* can't go as the default in switch-case below, otherwise gcc whines * can't go as the default in switch-case below, otherwise gcc whines
* about -Wmaybe-uninitialized * about -Wmaybe-uninitialized
...@@ -226,7 +227,7 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode) ...@@ -226,7 +227,7 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
} }
} }
for_all_symbols(i, sym) { for_all_symbols(sym) {
if (sym_has_value(sym) || sym->flags & SYMBOL_VALID) if (sym_has_value(sym) || sym->flags & SYMBOL_VALID)
continue; continue;
switch (sym_get_type(sym)) { switch (sym_get_type(sym)) {
...@@ -278,14 +279,14 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode) ...@@ -278,14 +279,14 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
* and the rest to no. * and the rest to no.
*/ */
if (mode != def_random) { if (mode != def_random) {
for_all_symbols(i, csym) { for_all_symbols(csym) {
if ((sym_is_choice(csym) && !sym_has_value(csym)) || if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
sym_is_choice_value(csym)) sym_is_choice_value(csym))
csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES; csym->flags |= SYMBOL_NEED_SET_CHOICE_VALUES;
} }
} }
for_all_symbols(i, csym) { for_all_symbols(csym) {
if (sym_has_value(csym) || !sym_is_choice(csym)) if (sym_has_value(csym) || !sym_is_choice(csym))
continue; continue;
...@@ -304,9 +305,8 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode) ...@@ -304,9 +305,8 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
static void conf_rewrite_tristates(tristate old_val, tristate new_val) static void conf_rewrite_tristates(tristate old_val, tristate new_val)
{ {
struct symbol *sym; struct symbol *sym;
int i;
for_all_symbols(i, sym) { for_all_symbols(sym) {
if (sym_get_type(sym) == S_TRISTATE && if (sym_get_type(sym) == S_TRISTATE &&
sym->def[S_DEF_USER].tri == old_val) sym->def[S_DEF_USER].tri == old_val)
sym->def[S_DEF_USER].tri = new_val; sym->def[S_DEF_USER].tri = new_val;
......
...@@ -18,8 +18,11 @@ ...@@ -18,8 +18,11 @@
#include <time.h> #include <time.h>
#include <unistd.h> #include <unistd.h>
#include "internal.h"
#include "lkc.h" #include "lkc.h"
struct gstr autoconf_cmd;
/* return true if 'path' exists, false otherwise */ /* return true if 'path' exists, false otherwise */
static bool is_present(const char *path) static bool is_present(const char *path)
{ {
...@@ -293,63 +296,12 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p) ...@@ -293,63 +296,12 @@ static int conf_set_sym_val(struct symbol *sym, int def, int def_flags, char *p)
return 0; return 0;
} }
#define LINE_GROWTH 16
static int add_byte(int c, char **lineptr, size_t slen, size_t *n)
{
size_t new_size = slen + 1;
if (new_size > *n) {
new_size += LINE_GROWTH - 1;
new_size *= 2;
*lineptr = xrealloc(*lineptr, new_size);
*n = new_size;
}
(*lineptr)[slen] = c;
return 0;
}
static ssize_t compat_getline(char **lineptr, size_t *n, FILE *stream)
{
char *line = *lineptr;
size_t slen = 0;
for (;;) {
int c = getc(stream);
switch (c) {
case '\n':
if (add_byte(c, &line, slen, n) < 0)
goto e_out;
slen++;
/* fall through */
case EOF:
if (add_byte('\0', &line, slen, n) < 0)
goto e_out;
*lineptr = line;
if (slen == 0)
return -1;
return slen;
default:
if (add_byte(c, &line, slen, n) < 0)
goto e_out;
slen++;
}
}
e_out:
line[slen-1] = '\0';
*lineptr = line;
return -1;
}
/* like getline(), but the newline character is stripped away */ /* like getline(), but the newline character is stripped away */
static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream) static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
{ {
ssize_t len; ssize_t len;
len = compat_getline(lineptr, n, stream); len = getline(lineptr, n, stream);
if (len > 0 && (*lineptr)[len - 1] == '\n') { if (len > 0 && (*lineptr)[len - 1] == '\n') {
len--; len--;
...@@ -371,7 +323,7 @@ int conf_read_simple(const char *name, int def) ...@@ -371,7 +323,7 @@ int conf_read_simple(const char *name, int def)
size_t line_asize = 0; size_t line_asize = 0;
char *p, *val; char *p, *val;
struct symbol *sym; struct symbol *sym;
int i, def_flags; int def_flags;
const char *warn_unknown, *sym_name; const char *warn_unknown, *sym_name;
warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS"); warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
...@@ -429,7 +381,7 @@ int conf_read_simple(const char *name, int def) ...@@ -429,7 +381,7 @@ int conf_read_simple(const char *name, int def)
conf_warnings = 0; conf_warnings = 0;
def_flags = SYMBOL_DEF << def; def_flags = SYMBOL_DEF << def;
for_all_symbols(i, sym) { for_all_symbols(sym) {
sym->flags |= SYMBOL_CHANGED; sym->flags |= SYMBOL_CHANGED;
sym->flags &= ~(def_flags|SYMBOL_VALID); sym->flags &= ~(def_flags|SYMBOL_VALID);
if (sym_is_choice(sym)) if (sym_is_choice(sym))
...@@ -538,7 +490,6 @@ int conf_read(const char *name) ...@@ -538,7 +490,6 @@ int conf_read(const char *name)
{ {
struct symbol *sym; struct symbol *sym;
int conf_unsaved = 0; int conf_unsaved = 0;
int i;
conf_set_changed(false); conf_set_changed(false);
...@@ -549,7 +500,7 @@ int conf_read(const char *name) ...@@ -549,7 +500,7 @@ int conf_read(const char *name)
sym_calc_value(modules_sym); sym_calc_value(modules_sym);
for_all_symbols(i, sym) { for_all_symbols(sym) {
sym_calc_value(sym); sym_calc_value(sym);
if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE)) if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
continue; continue;
...@@ -573,7 +524,7 @@ int conf_read(const char *name) ...@@ -573,7 +524,7 @@ int conf_read(const char *name)
/* maybe print value in verbose mode... */ /* maybe print value in verbose mode... */
} }
for_all_symbols(i, sym) { for_all_symbols(sym) {
if (sym_has_value(sym) && !sym_is_choice_value(sym)) { if (sym_has_value(sym) && !sym_is_choice_value(sym)) {
/* Reset values of generates values, so they'll appear /* Reset values of generates values, so they'll appear
* as new, if they should become visible, but that * as new, if they should become visible, but that
...@@ -848,10 +799,7 @@ int conf_write_defconfig(const char *filename) ...@@ -848,10 +799,7 @@ int conf_write_defconfig(const char *filename)
while (menu != NULL) while (menu != NULL)
{ {
sym = menu->sym; sym = menu->sym;
if (sym == NULL) { if (sym && !sym_is_choice(sym)) {
if (!menu_is_visible(menu))
goto next_menu;
} else if (!sym_is_choice(sym)) {
sym_calc_value(sym); sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE)) if (!(sym->flags & SYMBOL_WRITE))
goto next_menu; goto next_menu;
...@@ -911,7 +859,6 @@ int conf_write(const char *name) ...@@ -911,7 +859,6 @@ int conf_write(const char *name)
const char *str; const char *str;
char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1]; char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
char *env; char *env;
int i;
bool need_newline = false; bool need_newline = false;
if (!name) if (!name)
...@@ -995,7 +942,7 @@ int conf_write(const char *name) ...@@ -995,7 +942,7 @@ int conf_write(const char *name)
} }
fclose(out); fclose(out);
for_all_symbols(i, sym) for_all_symbols(sym)
sym->flags &= ~SYMBOL_WRITTEN; sym->flags &= ~SYMBOL_WRITTEN;
if (*tmpname) { if (*tmpname) {
...@@ -1023,7 +970,6 @@ int conf_write(const char *name) ...@@ -1023,7 +970,6 @@ int conf_write(const char *name)
static int conf_write_autoconf_cmd(const char *autoconf_name) static int conf_write_autoconf_cmd(const char *autoconf_name)
{ {
char name[PATH_MAX], tmp[PATH_MAX]; char name[PATH_MAX], tmp[PATH_MAX];
struct file *file;
FILE *out; FILE *out;
int ret; int ret;
...@@ -1044,15 +990,9 @@ static int conf_write_autoconf_cmd(const char *autoconf_name) ...@@ -1044,15 +990,9 @@ static int conf_write_autoconf_cmd(const char *autoconf_name)
return -1; return -1;
} }
fprintf(out, "deps_config := \\\n"); fprintf(out, "autoconfig := %s\n", autoconf_name);
for (file = file_list; file; file = file->next)
fprintf(out, "\t%s \\\n", file->name);
fprintf(out, "\n%s: $(deps_config)\n\n", autoconf_name);
env_write_dep(out, autoconf_name); fputs(str_get(&autoconf_cmd), out);
fprintf(out, "\n$(deps_config): ;\n");
fflush(out); fflush(out);
ret = ferror(out); /* error check for all fprintf() calls */ ret = ferror(out); /* error check for all fprintf() calls */
...@@ -1072,7 +1012,7 @@ static int conf_touch_deps(void) ...@@ -1072,7 +1012,7 @@ static int conf_touch_deps(void)
{ {
const char *name, *tmp; const char *name, *tmp;
struct symbol *sym; struct symbol *sym;
int res, i; int res;
name = conf_get_autoconfig_name(); name = conf_get_autoconfig_name();
tmp = strrchr(name, '/'); tmp = strrchr(name, '/');
...@@ -1086,7 +1026,7 @@ static int conf_touch_deps(void) ...@@ -1086,7 +1026,7 @@ static int conf_touch_deps(void)
conf_read_simple(name, S_DEF_AUTO); conf_read_simple(name, S_DEF_AUTO);
sym_calc_value(modules_sym); sym_calc_value(modules_sym);
for_all_symbols(i, sym) { for_all_symbols(sym) {
sym_calc_value(sym); sym_calc_value(sym);
if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name) if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
continue; continue;
...@@ -1152,7 +1092,7 @@ static int __conf_write_autoconf(const char *filename, ...@@ -1152,7 +1092,7 @@ static int __conf_write_autoconf(const char *filename,
char tmp[PATH_MAX]; char tmp[PATH_MAX];
FILE *file; FILE *file;
struct symbol *sym; struct symbol *sym;
int ret, i; int ret;
if (make_parent_dir(filename)) if (make_parent_dir(filename))
return -1; return -1;
...@@ -1169,7 +1109,7 @@ static int __conf_write_autoconf(const char *filename, ...@@ -1169,7 +1109,7 @@ static int __conf_write_autoconf(const char *filename,
conf_write_heading(file, comment_style); conf_write_heading(file, comment_style);
for_all_symbols(i, sym) for_all_symbols(sym)
if ((sym->flags & SYMBOL_WRITE) && sym->name) if ((sym->flags & SYMBOL_WRITE) && sym->name)
print_symbol(file, sym); print_symbol(file, sym);
...@@ -1192,7 +1132,7 @@ int conf_write_autoconf(int overwrite) ...@@ -1192,7 +1132,7 @@ int conf_write_autoconf(int overwrite)
{ {
struct symbol *sym; struct symbol *sym;
const char *autoconf_name = conf_get_autoconfig_name(); const char *autoconf_name = conf_get_autoconfig_name();
int ret, i; int ret;
if (!overwrite && is_present(autoconf_name)) if (!overwrite && is_present(autoconf_name))
return 0; return 0;
...@@ -1204,7 +1144,7 @@ int conf_write_autoconf(int overwrite) ...@@ -1204,7 +1144,7 @@ int conf_write_autoconf(int overwrite)
if (conf_touch_deps()) if (conf_touch_deps())
return 1; return 1;
for_all_symbols(i, sym) for_all_symbols(sym)
sym_calc_value(sym); sym_calc_value(sym);
ret = __conf_write_autoconf(conf_get_autoheader_name(), ret = __conf_write_autoconf(conf_get_autoheader_name(),
......
...@@ -12,17 +12,12 @@ extern "C" { ...@@ -12,17 +12,12 @@ extern "C" {
#include <assert.h> #include <assert.h>
#include <stdio.h> #include <stdio.h>
#include "list.h" #include "list_types.h"
#ifndef __cplusplus #ifndef __cplusplus
#include <stdbool.h> #include <stdbool.h>
#endif #endif
struct file { #include "list_types.h"
struct file *next;
struct file *parent;
const char *name;
int lineno;
};
typedef enum tristate { typedef enum tristate {
no, mod, yes no, mod, yes
...@@ -81,8 +76,8 @@ enum { ...@@ -81,8 +76,8 @@ enum {
* SYMBOL_CHOICE bit set in 'flags'. * SYMBOL_CHOICE bit set in 'flags'.
*/ */
struct symbol { struct symbol {
/* The next symbol in the same bucket in the symbol hash table */ /* link node for the hash table */
struct symbol *next; struct hlist_node node;
/* The name of the symbol, e.g. "FOO" for 'config FOO' */ /* The name of the symbol, e.g. "FOO" for 'config FOO' */
char *name; char *name;
...@@ -113,6 +108,9 @@ struct symbol { ...@@ -113,6 +108,9 @@ struct symbol {
*/ */
tristate visible; tristate visible;
/* config entries associated with this symbol */
struct list_head menus;
/* SYMBOL_* flags */ /* SYMBOL_* flags */
int flags; int flags;
...@@ -131,8 +129,6 @@ struct symbol { ...@@ -131,8 +129,6 @@ struct symbol {
struct expr_value implied; struct expr_value implied;
}; };
#define for_all_symbols(i, sym) for (i = 0; i < SYMBOL_HASHSIZE; i++) for (sym = symbol_hash[i]; sym; sym = sym->next)
#define SYMBOL_CONST 0x0001 /* symbol is const */ #define SYMBOL_CONST 0x0001 /* symbol is const */
#define SYMBOL_CHECK 0x0008 /* used during dependency checking */ #define SYMBOL_CHECK 0x0008 /* used during dependency checking */
#define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */ #define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */
...@@ -157,7 +153,6 @@ struct symbol { ...@@ -157,7 +153,6 @@ struct symbol {
#define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000 #define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000
#define SYMBOL_MAXLENGTH 256 #define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 9973
/* A property represent the config options that can be associated /* A property represent the config options that can be associated
* with a config "symbol". * with a config "symbol".
...@@ -195,7 +190,7 @@ struct property { ...@@ -195,7 +190,7 @@ struct property {
struct menu *menu; /* the menu the property are associated with struct menu *menu; /* the menu the property are associated with
* valid for: P_SELECT, P_RANGE, P_CHOICE, * valid for: P_SELECT, P_RANGE, P_CHOICE,
* P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */ * P_PROMPT, P_DEFAULT, P_MENU, P_COMMENT */
struct file *file; /* what file was this property defined */ const char *filename; /* what file was this property defined */
int lineno; /* what lineno was this property defined */ int lineno; /* what lineno was this property defined */
}; };
...@@ -230,6 +225,8 @@ struct menu { ...@@ -230,6 +225,8 @@ struct menu {
*/ */
struct symbol *sym; struct symbol *sym;
struct list_head link; /* link to symbol::menus */
/* /*
* The prompt associated with the node. This holds the prompt for a * The prompt associated with the node. This holds the prompt for a
* symbol as well as the text for a menu or comment, along with the * symbol as well as the text for a menu or comment, along with the
...@@ -256,7 +253,7 @@ struct menu { ...@@ -256,7 +253,7 @@ struct menu {
char *help; char *help;
/* The location where the menu node appears in the Kconfig files */ /* The location where the menu node appears in the Kconfig files */
struct file *file; const char *filename;
int lineno; int lineno;
/* For use by front ends that need to store auxiliary data */ /* For use by front ends that need to store auxiliary data */
...@@ -277,10 +274,6 @@ struct jump_key { ...@@ -277,10 +274,6 @@ struct jump_key {
struct menu *target; struct menu *target;
}; };
extern struct file *file_list;
extern struct file *current_file;
struct file *lookup_file(const char *name);
extern struct symbol symbol_yes, symbol_no, symbol_mod; extern struct symbol symbol_yes, symbol_no, symbol_mod;
extern struct symbol *modules_sym; extern struct symbol *modules_sym;
extern int cdebug; extern int cdebug;
......
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include "array_size.h"
#include "list.h"
#define HASH_SIZE(name) (ARRAY_SIZE(name))
#define HASHTABLE_DECLARE(name, size) struct hlist_head name[size]
#define HASHTABLE_DEFINE(name, size) \
HASHTABLE_DECLARE(name, size) = \
{ [0 ... ((size) - 1)] = HLIST_HEAD_INIT }
#define hash_head(table, key) (&(table)[(key) % HASH_SIZE(table)])
/**
* hash_add - add an object to a hashtable
* @table: hashtable to add to
* @node: the &struct hlist_node of the object to be added
* @key: the key of the object to be added
*/
#define hash_add(table, node, key) \
hlist_add_head(node, hash_head(table, key))
/**
* hash_for_each - iterate over a hashtable
* @table: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
*/
#define hash_for_each(table, obj, member) \
for (int _bkt = 0; _bkt < HASH_SIZE(table); _bkt++) \
hlist_for_each_entry(obj, &table[_bkt], member)
/**
* hash_for_each_possible - iterate over all possible objects hashing to the
* same bucket
* @table: hashtable to iterate
* @obj: the type * to use as a loop cursor for each entry
* @member: the name of the hlist_node within the struct
* @key: the key of the objects to iterate over
*/
#define hash_for_each_possible(table, obj, member, key) \
hlist_for_each_entry(obj, hash_head(table, key), member)
#endif /* HASHTABLE_H */
...@@ -2,8 +2,20 @@ ...@@ -2,8 +2,20 @@
#ifndef INTERNAL_H #ifndef INTERNAL_H
#define INTERNAL_H #define INTERNAL_H
#include "hashtable.h"
#define SYMBOL_HASHSIZE (1U << 14)
extern HASHTABLE_DECLARE(sym_hashtable, SYMBOL_HASHSIZE);
#define for_all_symbols(sym) \
hash_for_each(sym_hashtable, sym, node)
struct menu; struct menu;
extern struct menu *current_menu, *current_entry; extern struct menu *current_menu, *current_entry;
extern const char *cur_filename;
extern int cur_lineno;
#endif /* INTERNAL_H */ #endif /* INTERNAL_H */
...@@ -14,16 +14,22 @@ ...@@ -14,16 +14,22 @@
#include <string.h> #include <string.h>
#include "lkc.h" #include "lkc.h"
#include "preprocess.h"
#include "parser.tab.h" #include "parser.tab.h"
#define YY_DECL static int yylex1(void) #define YY_DECL static int yylex1(void)
#define START_STRSIZE 16 #define START_STRSIZE 16
static struct { /* The Kconfig file currently being parsed. */
struct file *file; const char *cur_filename;
int lineno;
} current_pos; /*
* The line number of the current statement. This does not match yylineno.
* yylineno is used by the lexer, while cur_lineno is used by the parser.
*/
int cur_lineno;
static int prev_prev_token = T_EOL; static int prev_prev_token = T_EOL;
static int prev_token = T_EOL; static int prev_token = T_EOL;
...@@ -33,6 +39,9 @@ static int text_size, text_asize; ...@@ -33,6 +39,9 @@ static int text_size, text_asize;
struct buffer { struct buffer {
struct buffer *parent; struct buffer *parent;
YY_BUFFER_STATE state; YY_BUFFER_STATE state;
int yylineno;
const char *filename;
int source_lineno;
}; };
static struct buffer *current_buf; static struct buffer *current_buf;
...@@ -77,7 +86,7 @@ static void warn_ignored_character(char chr) ...@@ -77,7 +86,7 @@ static void warn_ignored_character(char chr)
{ {
fprintf(stderr, fprintf(stderr,
"%s:%d:warning: ignoring unsupported character '%c'\n", "%s:%d:warning: ignoring unsupported character '%c'\n",
current_file->name, yylineno, chr); cur_filename, yylineno, chr);
} }
%} %}
...@@ -180,7 +189,7 @@ n [A-Za-z0-9_-] ...@@ -180,7 +189,7 @@ n [A-Za-z0-9_-]
\n { \n {
fprintf(stderr, fprintf(stderr,
"%s:%d:warning: multi-line strings not supported\n", "%s:%d:warning: multi-line strings not supported\n",
zconf_curname(), zconf_lineno()); cur_filename, cur_lineno);
unput('\n'); unput('\n');
BEGIN(INITIAL); BEGIN(INITIAL);
yylval.string = text; yylval.string = text;
...@@ -246,9 +255,9 @@ n [A-Za-z0-9_-] ...@@ -246,9 +255,9 @@ n [A-Za-z0-9_-]
if (prev_token != T_EOL && prev_token != T_HELPTEXT) if (prev_token != T_EOL && prev_token != T_HELPTEXT)
fprintf(stderr, "%s:%d:warning: no new line at end of file\n", fprintf(stderr, "%s:%d:warning: no new line at end of file\n",
current_file->name, yylineno); cur_filename, yylineno);
if (current_file) { if (current_buf) {
zconf_endfile(); zconf_endfile();
return T_EOL; return T_EOL;
} }
...@@ -267,19 +276,17 @@ repeat: ...@@ -267,19 +276,17 @@ repeat:
token = yylex1(); token = yylex1();
if (prev_token == T_EOL || prev_token == T_HELPTEXT) { if (prev_token == T_EOL || prev_token == T_HELPTEXT) {
if (token == T_EOL) { if (token == T_EOL)
/* Do not pass unneeded T_EOL to the parser. */ /* Do not pass unneeded T_EOL to the parser. */
goto repeat; goto repeat;
} else { else
/* /*
* For the parser, update file/lineno at the first token * For the parser, update lineno at the first token
* of each statement. Generally, \n is a statement * of each statement. Generally, \n is a statement
* terminator in Kconfig, but it is not always true * terminator in Kconfig, but it is not always true
* because \n could be escaped by a backslash. * because \n could be escaped by a backslash.
*/ */
current_pos.file = current_file; cur_lineno = yylineno;
current_pos.lineno = yylineno;
}
} }
if (prev_prev_token == T_EOL && prev_token == T_WORD && if (prev_prev_token == T_EOL && prev_token == T_WORD &&
...@@ -302,8 +309,11 @@ static char *expand_token(const char *in, size_t n) ...@@ -302,8 +309,11 @@ static char *expand_token(const char *in, size_t n)
new_string(); new_string();
append_string(in, n); append_string(in, n);
/* get the whole line because we do not know the end of token. */ /*
while ((c = input()) != EOF) { * get the whole line because we do not know the end of token.
* input() returns 0 (not EOF!) when it reachs the end of file.
*/
while ((c = input()) != 0) {
if (c == '\n') { if (c == '\n') {
unput(c); unput(c);
break; break;
...@@ -391,78 +401,60 @@ void zconf_initscan(const char *name) ...@@ -391,78 +401,60 @@ void zconf_initscan(const char *name)
exit(1); exit(1);
} }
current_buf = xmalloc(sizeof(*current_buf)); cur_filename = file_lookup(name);
memset(current_buf, 0, sizeof(*current_buf));
current_file = file_lookup(name);
yylineno = 1; yylineno = 1;
} }
void zconf_nextfile(const char *name) void zconf_nextfile(const char *name)
{ {
struct file *iter;
struct file *file = file_lookup(name);
struct buffer *buf = xmalloc(sizeof(*buf)); struct buffer *buf = xmalloc(sizeof(*buf));
memset(buf, 0, sizeof(*buf)); bool recur_include = false;
current_buf->state = YY_CURRENT_BUFFER; buf->state = YY_CURRENT_BUFFER;
yyin = zconf_fopen(file->name); buf->yylineno = yylineno;
buf->filename = cur_filename;
buf->source_lineno = cur_lineno;
buf->parent = current_buf;
current_buf = buf;
yyin = zconf_fopen(name);
if (!yyin) { if (!yyin) {
fprintf(stderr, "%s:%d: can't open file \"%s\"\n", fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
zconf_curname(), zconf_lineno(), file->name); cur_filename, cur_lineno, name);
exit(1); exit(1);
} }
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE)); yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
buf->parent = current_buf;
current_buf = buf;
current_file->lineno = yylineno; for (buf = current_buf; buf; buf = buf->parent) {
file->parent = current_file; if (!strcmp(buf->filename, name))
recur_include = true;
for (iter = current_file; iter; iter = iter->parent) {
if (!strcmp(iter->name, file->name)) {
fprintf(stderr,
"Recursive inclusion detected.\n"
"Inclusion path:\n"
" current file : %s\n", file->name);
iter = file;
do {
iter = iter->parent;
fprintf(stderr, " included from: %s:%d\n",
iter->name, iter->lineno - 1);
} while (strcmp(iter->name, file->name));
exit(1);
}
} }
yylineno = 1; if (recur_include) {
current_file = file; fprintf(stderr,
} "Recursive inclusion detected.\n"
"Inclusion path:\n"
static void zconf_endfile(void) " current file : %s\n", name);
{
struct buffer *parent;
current_file = current_file->parent;
if (current_file)
yylineno = current_file->lineno;
parent = current_buf->parent; for (buf = current_buf; buf; buf = buf->parent)
if (parent) { fprintf(stderr, " included from: %s:%d\n",
fclose(yyin); buf->filename, buf->source_lineno);
yy_delete_buffer(YY_CURRENT_BUFFER); exit(1);
yy_switch_to_buffer(parent->state);
} }
free(current_buf);
current_buf = parent;
}
int zconf_lineno(void) yylineno = 1;
{ cur_filename = file_lookup(name);
return current_pos.lineno;
} }
const char *zconf_curname(void) static void zconf_endfile(void)
{ {
return current_pos.file ? current_pos.file->name : "<none>"; struct buffer *tmp;
fclose(yyin);
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(current_buf->state);
yylineno = current_buf->yylineno;
cur_filename = current_buf->filename;
tmp = current_buf;
current_buf = current_buf->parent;
free(tmp);
} }
...@@ -2,29 +2,39 @@ ...@@ -2,29 +2,39 @@
#ifndef LIST_H #ifndef LIST_H
#define LIST_H #define LIST_H
/* #include <stddef.h>
* Copied from include/linux/...
*/
#undef offsetof #include "list_types.h"
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
/* Are two types/vars the same type (ignoring qualifiers)? */
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))
/** /**
* container_of - cast a member of a structure out to the containing structure * container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member. * @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in. * @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct. * @member: the name of the member within the struct.
* *
*/ */
#define container_of(ptr, type, member) ({ \ #define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \ void *__mptr = (void *)(ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );}) _Static_assert(__same_type(*(ptr), ((type *)0)->member) || \
__same_type(*(ptr), void), \
"pointer type mismatch in container_of()"); \
((type *)(__mptr - offsetof(type, member))); })
struct list_head { #define LIST_POISON1 ((void *) 0x100)
struct list_head *next, *prev; #define LIST_POISON2 ((void *) 0x122)
};
/*
* Circular doubly linked list implementation.
*
* Some of the internal functions ("__xxx") are useful when
* manipulating whole lists rather than single entries, as
* sometimes we already know the next/prev entries and we can
* generate better code by using them directly rather than
* using the generic single-entry routines.
*/
#define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD_INIT(name) { &(name), &(name) }
...@@ -32,45 +42,16 @@ struct list_head { ...@@ -32,45 +42,16 @@ struct list_head {
struct list_head name = LIST_HEAD_INIT(name) struct list_head name = LIST_HEAD_INIT(name)
/** /**
* list_entry - get the struct for this entry * INIT_LIST_HEAD - Initialize a list_head structure
* @ptr: the &struct list_head pointer. * @list: list_head structure to be initialized.
* @type: the type of the struct this is embedded in. *
* @member: the name of the list_head within the struct. * Initializes the list_head to point to itself. If it is a list header,
*/ * the result is an empty list.
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/ */
static inline int list_empty(const struct list_head *head) static inline void INIT_LIST_HEAD(struct list_head *list)
{ {
return head->next == head; list->next = list;
list->prev = list;
} }
/* /*
...@@ -79,14 +60,27 @@ static inline int list_empty(const struct list_head *head) ...@@ -79,14 +60,27 @@ static inline int list_empty(const struct list_head *head)
* This is only for internal list manipulation where we know * This is only for internal list manipulation where we know
* the prev/next entries already! * the prev/next entries already!
*/ */
static inline void __list_add(struct list_head *_new, static inline void __list_add(struct list_head *new,
struct list_head *prev, struct list_head *prev,
struct list_head *next) struct list_head *next)
{ {
next->prev = _new; next->prev = new;
_new->next = next; new->next = next;
_new->prev = prev; new->prev = prev;
prev->next = _new; prev->next = new;
}
/**
* list_add - add a new entry
* @new: new entry to be added
* @head: list head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
} }
/** /**
...@@ -97,9 +91,9 @@ static inline void __list_add(struct list_head *_new, ...@@ -97,9 +91,9 @@ static inline void __list_add(struct list_head *_new,
* Insert a new entry before the specified head. * Insert a new entry before the specified head.
* This is useful for implementing queues. * This is useful for implementing queues.
*/ */
static inline void list_add_tail(struct list_head *_new, struct list_head *head) static inline void list_add_tail(struct list_head *new, struct list_head *head)
{ {
__list_add(_new, head->prev, head); __list_add(new, head->prev, head);
} }
/* /*
...@@ -115,8 +109,11 @@ static inline void __list_del(struct list_head *prev, struct list_head *next) ...@@ -115,8 +109,11 @@ static inline void __list_del(struct list_head *prev, struct list_head *next)
prev->next = next; prev->next = next;
} }
#define LIST_POISON1 ((void *) 0x00100100) static inline void __list_del_entry(struct list_head *entry)
#define LIST_POISON2 ((void *) 0x00200200) {
__list_del(entry->prev, entry->next);
}
/** /**
* list_del - deletes entry from list. * list_del - deletes entry from list.
* @entry: the element to delete from the list. * @entry: the element to delete from the list.
...@@ -125,8 +122,135 @@ static inline void __list_del(struct list_head *prev, struct list_head *next) ...@@ -125,8 +122,135 @@ static inline void __list_del(struct list_head *prev, struct list_head *next)
*/ */
static inline void list_del(struct list_head *entry) static inline void list_del(struct list_head *entry)
{ {
__list_del(entry->prev, entry->next); __list_del_entry(entry);
entry->next = (struct list_head*)LIST_POISON1; entry->next = LIST_POISON1;
entry->prev = (struct list_head*)LIST_POISON2; entry->prev = LIST_POISON2;
}
/**
* list_is_head - tests whether @list is the list @head
* @list: the entry to test
* @head: the head of the list
*/
static inline int list_is_head(const struct list_head *list, const struct list_head *head)
{
return list == head;
}
/**
* list_empty - tests whether a list is empty
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
/**
* list_first_entry - get the first element from a list
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_next_entry - get the next element in list
* @pos: the type * to cursor
* @member: the name of the list_head within the struct.
*/
#define list_next_entry(pos, member) \
list_entry((pos)->member.next, typeof(*(pos)), member)
/**
* list_entry_is_head - test if the entry points to the head of the list
* @pos: the type * to cursor
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_entry_is_head(pos, head, member) \
(&pos->member == (head))
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \
!list_entry_is_head(pos, head, member); \
pos = list_next_entry(pos, member))
/**
* list_for_each_entry_safe - iterate over list of given type. Safe against removal of list entry
* @pos: the type * to use as a loop cursor.
* @n: another type * to use as temporary storage
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member), \
n = list_next_entry(pos, member); \
!list_entry_is_head(pos, head, member); \
pos = n, n = list_next_entry(n, member))
/*
* Double linked lists with a single pointer list head.
* Mostly useful for hash tables where the two pointer list head is
* too wasteful.
* You lose the ability to access the tail in O(1).
*/
#define HLIST_HEAD_INIT { .first = NULL }
/**
* hlist_add_head - add a new entry at the beginning of the hlist
* @n: new entry to be added
* @h: hlist head to add it after
*
* Insert a new entry after the specified head.
* This is good for implementing stacks.
*/
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
{
struct hlist_node *first = h->first;
n->next = first;
if (first)
first->pprev = &n->next;
h->first = n;
n->pprev = &h->first;
} }
#endif
#define hlist_entry(ptr, type, member) container_of(ptr, type, member)
#define hlist_entry_safe(ptr, type, member) \
({ typeof(ptr) ____ptr = (ptr); \
____ptr ? hlist_entry(____ptr, type, member) : NULL; \
})
/**
* hlist_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the hlist_node within the struct.
*/
#define hlist_for_each_entry(pos, head, member) \
for (pos = hlist_entry_safe((head)->first, typeof(*(pos)), member);\
pos; \
pos = hlist_entry_safe((pos)->member.next, typeof(*(pos)), member))
#endif /* LIST_H */
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef LIST_TYPES_H
#define LIST_TYPES_H
struct list_head {
struct list_head *next, *prev;
};
struct hlist_head {
struct hlist_node *first;
};
struct hlist_node {
struct hlist_node *next, **pprev;
};
#endif /* LIST_TYPES_H */
...@@ -36,10 +36,9 @@ void zconf_starthelp(void); ...@@ -36,10 +36,9 @@ void zconf_starthelp(void);
FILE *zconf_fopen(const char *name); FILE *zconf_fopen(const char *name);
void zconf_initscan(const char *name); void zconf_initscan(const char *name);
void zconf_nextfile(const char *name); void zconf_nextfile(const char *name);
int zconf_lineno(void);
const char *zconf_curname(void);
/* confdata.c */ /* confdata.c */
extern struct gstr autoconf_cmd;
const char *conf_get_configname(void); const char *conf_get_configname(void);
void set_all_choice_values(struct symbol *csym); void set_all_choice_values(struct symbol *csym);
...@@ -53,7 +52,8 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out) ...@@ -53,7 +52,8 @@ static inline void xfwrite(const void *str, size_t len, size_t count, FILE *out)
} }
/* util.c */ /* util.c */
struct file *file_lookup(const char *name); unsigned int strhash(const char *s);
const char *file_lookup(const char *name);
void *xmalloc(size_t size); void *xmalloc(size_t size);
void *xcalloc(size_t nmemb, size_t size); void *xcalloc(size_t nmemb, size_t size);
void *xrealloc(void *p, size_t size); void *xrealloc(void *p, size_t size);
......
...@@ -18,8 +18,6 @@ void conf_set_message_callback(void (*fn)(const char *s)); ...@@ -18,8 +18,6 @@ void conf_set_message_callback(void (*fn)(const char *s));
bool conf_errors(void); bool conf_errors(void);
/* symbol.c */ /* symbol.c */
extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
struct symbol * sym_lookup(const char *name, int flags); struct symbol * sym_lookup(const char *name, int flags);
struct symbol * sym_find(const char *name); struct symbol * sym_find(const char *name);
void print_symbol_for_listconfig(struct symbol *sym); void print_symbol_for_listconfig(struct symbol *sym);
...@@ -40,19 +38,6 @@ const char * sym_get_string_value(struct symbol *sym); ...@@ -40,19 +38,6 @@ const char * sym_get_string_value(struct symbol *sym);
const char * prop_get_type_name(enum prop_type type); const char * prop_get_type_name(enum prop_type type);
/* preprocess.c */
enum variable_flavor {
VAR_SIMPLE,
VAR_RECURSIVE,
VAR_APPEND,
};
void env_write_dep(FILE *f, const char *auto_conf_name);
void variable_add(const char *name, const char *value,
enum variable_flavor flavor);
void variable_all_del(void);
char *expand_dollar(const char **str);
char *expand_one_token(const char **str);
/* expr.c */ /* expr.c */
void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken); void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken);
......
...@@ -188,9 +188,8 @@ int dialog_checklist(const char *title, const char *prompt, int height, ...@@ -188,9 +188,8 @@ int dialog_checklist(const char *title, const char *prompt, int height,
print_buttons(dialog, height, width, 0); print_buttons(dialog, height, width, 0);
wnoutrefresh(dialog); wmove(list, choice, check_x + 1);
wnoutrefresh(list); wrefresh(list);
doupdate();
while (key != KEY_ESC) { while (key != KEY_ESC) {
key = wgetch(dialog); key = wgetch(dialog);
......
...@@ -91,10 +91,6 @@ struct dialog_info { ...@@ -91,10 +91,6 @@ struct dialog_info {
struct dialog_color button_label_active; struct dialog_color button_label_active;
struct dialog_color button_label_inactive; struct dialog_color button_label_inactive;
struct dialog_color inputbox; struct dialog_color inputbox;
struct dialog_color inputbox_border;
struct dialog_color searchbox;
struct dialog_color searchbox_title;
struct dialog_color searchbox_border;
struct dialog_color position_indicator; struct dialog_color position_indicator;
struct dialog_color menubox; struct dialog_color menubox;
struct dialog_color menubox_border; struct dialog_color menubox_border;
......
...@@ -29,10 +29,6 @@ static void set_mono_theme(void) ...@@ -29,10 +29,6 @@ static void set_mono_theme(void)
dlg.button_label_active.atr = A_REVERSE; dlg.button_label_active.atr = A_REVERSE;
dlg.button_label_inactive.atr = A_NORMAL; dlg.button_label_inactive.atr = A_NORMAL;
dlg.inputbox.atr = A_NORMAL; dlg.inputbox.atr = A_NORMAL;
dlg.inputbox_border.atr = A_NORMAL;
dlg.searchbox.atr = A_NORMAL;
dlg.searchbox_title.atr = A_BOLD;
dlg.searchbox_border.atr = A_NORMAL;
dlg.position_indicator.atr = A_BOLD; dlg.position_indicator.atr = A_BOLD;
dlg.menubox.atr = A_NORMAL; dlg.menubox.atr = A_NORMAL;
dlg.menubox_border.atr = A_NORMAL; dlg.menubox_border.atr = A_NORMAL;
...@@ -69,10 +65,6 @@ static void set_classic_theme(void) ...@@ -69,10 +65,6 @@ static void set_classic_theme(void)
DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true); DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true);
DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true); DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true);
DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false); DLG_COLOR(inputbox, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(inputbox_border, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(searchbox, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_WHITE, true);
DLG_COLOR(searchbox_border, COLOR_WHITE, COLOR_WHITE, true);
DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true); DLG_COLOR(position_indicator, COLOR_YELLOW, COLOR_WHITE, true);
DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false); DLG_COLOR(menubox, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true); DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true);
...@@ -101,14 +93,9 @@ static void set_blackbg_theme(void) ...@@ -101,14 +93,9 @@ static void set_blackbg_theme(void)
DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true); DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true);
DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false); DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, false);
DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false); DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_RED, false);
DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_BLACK, true); DLG_COLOR(button_label_inactive, COLOR_WHITE, COLOR_BLACK, false);
DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false); DLG_COLOR(inputbox, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(inputbox_border, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(searchbox, COLOR_YELLOW, COLOR_BLACK, false);
DLG_COLOR(searchbox_title, COLOR_YELLOW, COLOR_BLACK, true);
DLG_COLOR(searchbox_border, COLOR_BLACK, COLOR_BLACK, true);
DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false); DLG_COLOR(position_indicator, COLOR_RED, COLOR_BLACK, false);
...@@ -136,7 +123,6 @@ static void set_bluetitle_theme(void) ...@@ -136,7 +123,6 @@ static void set_bluetitle_theme(void)
DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true); DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true); DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_BLUE, true);
DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true); DLG_COLOR(button_label_active, COLOR_WHITE, COLOR_BLUE, true);
DLG_COLOR(searchbox_title, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true); DLG_COLOR(position_indicator, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true); DLG_COLOR(tag, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true); DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true);
...@@ -189,10 +175,6 @@ static void init_dialog_colors(void) ...@@ -189,10 +175,6 @@ static void init_dialog_colors(void)
init_one_color(&dlg.button_label_active); init_one_color(&dlg.button_label_active);
init_one_color(&dlg.button_label_inactive); init_one_color(&dlg.button_label_inactive);
init_one_color(&dlg.inputbox); init_one_color(&dlg.inputbox);
init_one_color(&dlg.inputbox_border);
init_one_color(&dlg.searchbox);
init_one_color(&dlg.searchbox_title);
init_one_color(&dlg.searchbox_border);
init_one_color(&dlg.position_indicator); init_one_color(&dlg.position_indicator);
init_one_color(&dlg.menubox); init_one_color(&dlg.menubox);
init_one_color(&dlg.menubox_border); init_one_color(&dlg.menubox_border);
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
#include "list.h"
#include "lkc.h" #include "lkc.h"
#include "lxdialog/dialog.h" #include "lxdialog/dialog.h"
#include "mnconf-common.h" #include "mnconf-common.h"
......
...@@ -10,20 +10,18 @@ ...@@ -10,20 +10,18 @@
#include "lkc.h" #include "lkc.h"
#include "internal.h" #include "internal.h"
#include "list.h"
static const char nohelp_text[] = "There is no help available for this option."; static const char nohelp_text[] = "There is no help available for this option.";
struct menu rootmenu; struct menu rootmenu;
static struct menu **last_entry_ptr; static struct menu **last_entry_ptr;
struct file *file_list;
struct file *current_file;
void menu_warn(struct menu *menu, const char *fmt, ...) void menu_warn(struct menu *menu, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
fprintf(stderr, "%s:%d:warning: ", menu->file->name, menu->lineno); fprintf(stderr, "%s:%d:warning: ", menu->filename, menu->lineno);
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(ap); va_end(ap);
...@@ -33,7 +31,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...) ...@@ -33,7 +31,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...)
{ {
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
fprintf(stderr, "%s:%d:warning: ", prop->file->name, prop->lineno); fprintf(stderr, "%s:%d:warning: ", prop->filename, prop->lineno);
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(ap); va_end(ap);
...@@ -53,14 +51,16 @@ void menu_add_entry(struct symbol *sym) ...@@ -53,14 +51,16 @@ void menu_add_entry(struct symbol *sym)
memset(menu, 0, sizeof(*menu)); memset(menu, 0, sizeof(*menu));
menu->sym = sym; menu->sym = sym;
menu->parent = current_menu; menu->parent = current_menu;
menu->file = current_file; menu->filename = cur_filename;
menu->lineno = zconf_lineno(); menu->lineno = cur_lineno;
*last_entry_ptr = menu; *last_entry_ptr = menu;
last_entry_ptr = &menu->next; last_entry_ptr = &menu->next;
current_entry = menu; current_entry = menu;
if (sym) if (sym) {
menu_add_symbol(P_SYMBOL, sym, NULL); menu_add_symbol(P_SYMBOL, sym, NULL);
list_add_tail(&menu->link, &sym->menus);
}
} }
struct menu *menu_add_menu(void) struct menu *menu_add_menu(void)
...@@ -134,8 +134,8 @@ static struct property *menu_add_prop(enum prop_type type, struct expr *expr, ...@@ -134,8 +134,8 @@ static struct property *menu_add_prop(enum prop_type type, struct expr *expr,
prop = xmalloc(sizeof(*prop)); prop = xmalloc(sizeof(*prop));
memset(prop, 0, sizeof(*prop)); memset(prop, 0, sizeof(*prop));
prop->type = type; prop->type = type;
prop->file = current_file; prop->filename = cur_filename;
prop->lineno = zconf_lineno(); prop->lineno = cur_lineno;
prop->menu = current_entry; prop->menu = current_entry;
prop->expr = expr; prop->expr = expr;
prop->visible.expr = dep; prop->visible.expr = dep;
...@@ -307,12 +307,6 @@ void menu_finalize(struct menu *parent) ...@@ -307,12 +307,6 @@ void menu_finalize(struct menu *parent)
} }
} }
} }
/* set the type of the remaining choice values */
for (menu = parent->list; menu; menu = menu->next) {
current_entry = menu;
if (menu->sym && menu->sym->type == S_UNKNOWN)
menu_set_type(sym->type);
}
/* /*
* Use the choice itself as the parent dependency of * Use the choice itself as the parent dependency of
...@@ -567,9 +561,6 @@ void menu_finalize(struct menu *parent) ...@@ -567,9 +561,6 @@ void menu_finalize(struct menu *parent)
if (sym->type == S_UNKNOWN) if (sym->type == S_UNKNOWN)
menu_warn(parent, "config symbol defined without type"); menu_warn(parent, "config symbol defined without type");
if (sym_is_choice(sym) && !parent->prompt)
menu_warn(parent, "choice must have a prompt");
/* Check properties connected to this symbol */ /* Check properties connected to this symbol */
sym_check_prop(sym); sym_check_prop(sym);
sym->flags |= SYMBOL_WARNED; sym->flags |= SYMBOL_WARNED;
...@@ -676,7 +667,7 @@ struct menu *menu_get_parent_menu(struct menu *menu) ...@@ -676,7 +667,7 @@ struct menu *menu_get_parent_menu(struct menu *menu)
static void get_def_str(struct gstr *r, struct menu *menu) static void get_def_str(struct gstr *r, struct menu *menu)
{ {
str_printf(r, "Defined at %s:%d\n", str_printf(r, "Defined at %s:%d\n",
menu->file->name, menu->lineno); menu->filename, menu->lineno);
} }
static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix) static void get_dep_str(struct gstr *r, struct expr *expr, const char *prefix)
...@@ -777,6 +768,7 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym, ...@@ -777,6 +768,7 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
struct list_head *head) struct list_head *head)
{ {
struct property *prop; struct property *prop;
struct menu *menu;
if (sym && sym->name) { if (sym && sym->name) {
str_printf(r, "Symbol: %s [=%s]\n", sym->name, str_printf(r, "Symbol: %s [=%s]\n", sym->name,
...@@ -793,17 +785,17 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym, ...@@ -793,17 +785,17 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
} }
/* Print the definitions with prompts before the ones without */ /* Print the definitions with prompts before the ones without */
for_all_properties(sym, prop, P_SYMBOL) { list_for_each_entry(menu, &sym->menus, link) {
if (prop->menu->prompt) { if (menu->prompt) {
get_def_str(r, prop->menu); get_def_str(r, menu);
get_prompt_str(r, prop->menu->prompt, head); get_prompt_str(r, menu->prompt, head);
} }
} }
for_all_properties(sym, prop, P_SYMBOL) { list_for_each_entry(menu, &sym->menus, link) {
if (!prop->menu->prompt) { if (!menu->prompt) {
get_def_str(r, prop->menu); get_def_str(r, menu);
get_dep_str(r, prop->menu->dep, " Depends on: "); get_dep_str(r, menu->dep, " Depends on: ");
} }
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <strings.h> #include <strings.h>
#include <stdlib.h> #include <stdlib.h>
#include "list.h"
#include "lkc.h" #include "lkc.h"
#include "mnconf-common.h" #include "mnconf-common.h"
#include "nconf.h" #include "nconf.h"
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "lkc.h" #include "lkc.h"
#include "internal.h" #include "internal.h"
#include "preprocess.h"
#define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt) #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
...@@ -27,8 +28,6 @@ static void zconf_error(const char *err, ...); ...@@ -27,8 +28,6 @@ static void zconf_error(const char *err, ...);
static bool zconf_endtoken(const char *tokenname, static bool zconf_endtoken(const char *tokenname,
const char *expected_tokenname); const char *expected_tokenname);
struct symbol *symbol_hash[SYMBOL_HASHSIZE];
struct menu *current_menu, *current_entry; struct menu *current_menu, *current_entry;
%} %}
...@@ -95,12 +94,12 @@ struct menu *current_menu, *current_entry; ...@@ -95,12 +94,12 @@ struct menu *current_menu, *current_entry;
%type <expr> if_expr %type <expr> if_expr
%type <string> end %type <string> end
%type <menu> if_entry menu_entry choice_entry %type <menu> if_entry menu_entry choice_entry
%type <string> word_opt assign_val %type <string> assign_val
%type <flavor> assign_op %type <flavor> assign_op
%destructor { %destructor {
fprintf(stderr, "%s:%d: missing end statement for this entry\n", fprintf(stderr, "%s:%d: missing end statement for this entry\n",
$$->file->name, $$->lineno); $$->filename, $$->lineno);
if (current_menu == $$) if (current_menu == $$)
menu_end_menu(); menu_end_menu();
} if_entry menu_entry choice_entry } if_entry menu_entry choice_entry
...@@ -143,19 +142,19 @@ config_entry_start: T_CONFIG nonconst_symbol T_EOL ...@@ -143,19 +142,19 @@ config_entry_start: T_CONFIG nonconst_symbol T_EOL
{ {
$2->flags |= SYMBOL_OPTIONAL; $2->flags |= SYMBOL_OPTIONAL;
menu_add_entry($2); menu_add_entry($2);
printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2->name); printd(DEBUG_PARSE, "%s:%d:config %s\n", cur_filename, cur_lineno, $2->name);
}; };
config_stmt: config_entry_start config_option_list config_stmt: config_entry_start config_option_list
{ {
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
}; };
menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL menuconfig_entry_start: T_MENUCONFIG nonconst_symbol T_EOL
{ {
$2->flags |= SYMBOL_OPTIONAL; $2->flags |= SYMBOL_OPTIONAL;
menu_add_entry($2); menu_add_entry($2);
printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2->name); printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", cur_filename, cur_lineno, $2->name);
}; };
menuconfig_stmt: menuconfig_entry_start config_option_list menuconfig_stmt: menuconfig_entry_start config_option_list
...@@ -164,7 +163,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list ...@@ -164,7 +163,7 @@ menuconfig_stmt: menuconfig_entry_start config_option_list
current_entry->prompt->type = P_MENU; current_entry->prompt->type = P_MENU;
else else
zconfprint("warning: menuconfig statement without prompt"); zconfprint("warning: menuconfig statement without prompt");
printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:endconfig\n", cur_filename, cur_lineno);
}; };
config_option_list: config_option_list:
...@@ -177,15 +176,13 @@ config_option_list: ...@@ -177,15 +176,13 @@ config_option_list:
config_option: type prompt_stmt_opt T_EOL config_option: type prompt_stmt_opt T_EOL
{ {
menu_set_type($1); menu_set_type($1);
printd(DEBUG_PARSE, "%s:%d:type(%u)\n", printd(DEBUG_PARSE, "%s:%d:type(%u)\n", cur_filename, cur_lineno, $1);
zconf_curname(), zconf_lineno(),
$1);
}; };
config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL config_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
{ {
menu_add_prompt(P_PROMPT, $2, $3); menu_add_prompt(P_PROMPT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);
}; };
config_option: default expr if_expr T_EOL config_option: default expr if_expr T_EOL
...@@ -193,27 +190,26 @@ config_option: default expr if_expr T_EOL ...@@ -193,27 +190,26 @@ config_option: default expr if_expr T_EOL
menu_add_expr(P_DEFAULT, $2, $3); menu_add_expr(P_DEFAULT, $2, $3);
if ($1 != S_UNKNOWN) if ($1 != S_UNKNOWN)
menu_set_type($1); menu_set_type($1);
printd(DEBUG_PARSE, "%s:%d:default(%u)\n", printd(DEBUG_PARSE, "%s:%d:default(%u)\n", cur_filename, cur_lineno,
zconf_curname(), zconf_lineno(),
$1); $1);
}; };
config_option: T_SELECT nonconst_symbol if_expr T_EOL config_option: T_SELECT nonconst_symbol if_expr T_EOL
{ {
menu_add_symbol(P_SELECT, $2, $3); menu_add_symbol(P_SELECT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:select\n", cur_filename, cur_lineno);
}; };
config_option: T_IMPLY nonconst_symbol if_expr T_EOL config_option: T_IMPLY nonconst_symbol if_expr T_EOL
{ {
menu_add_symbol(P_IMPLY, $2, $3); menu_add_symbol(P_IMPLY, $2, $3);
printd(DEBUG_PARSE, "%s:%d:imply\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:imply\n", cur_filename, cur_lineno);
}; };
config_option: T_RANGE symbol symbol if_expr T_EOL config_option: T_RANGE symbol symbol if_expr T_EOL
{ {
menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4); menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:range\n", cur_filename, cur_lineno);
}; };
config_option: T_MODULES T_EOL config_option: T_MODULES T_EOL
...@@ -226,18 +222,23 @@ config_option: T_MODULES T_EOL ...@@ -226,18 +222,23 @@ config_option: T_MODULES T_EOL
/* choice entry */ /* choice entry */
choice: T_CHOICE word_opt T_EOL choice: T_CHOICE T_EOL
{ {
struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE); struct symbol *sym = sym_lookup(NULL, SYMBOL_CHOICE);
sym->flags |= SYMBOL_NO_WRITE; sym->flags |= SYMBOL_NO_WRITE;
menu_add_entry(sym); menu_add_entry(sym);
menu_add_expr(P_CHOICE, NULL, NULL); menu_add_expr(P_CHOICE, NULL, NULL);
free($2); printd(DEBUG_PARSE, "%s:%d:choice\n", cur_filename, cur_lineno);
printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
}; };
choice_entry: choice choice_option_list choice_entry: choice choice_option_list
{ {
if (!current_entry->prompt) {
fprintf(stderr, "%s:%d: error: choice must have a prompt\n",
current_entry->filename, current_entry->lineno);
yynerrs++;
}
$$ = menu_add_menu(); $$ = menu_add_menu();
}; };
...@@ -245,7 +246,7 @@ choice_end: end ...@@ -245,7 +246,7 @@ choice_end: end
{ {
if (zconf_endtoken($1, "choice")) { if (zconf_endtoken($1, "choice")) {
menu_end_menu(); menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:endchoice\n", cur_filename, cur_lineno);
} }
}; };
...@@ -262,27 +263,25 @@ choice_option_list: ...@@ -262,27 +263,25 @@ choice_option_list:
choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL choice_option: T_PROMPT T_WORD_QUOTE if_expr T_EOL
{ {
menu_add_prompt(P_PROMPT, $2, $3); menu_add_prompt(P_PROMPT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:prompt\n", cur_filename, cur_lineno);
}; };
choice_option: logic_type prompt_stmt_opt T_EOL choice_option: logic_type prompt_stmt_opt T_EOL
{ {
menu_set_type($1); menu_set_type($1);
printd(DEBUG_PARSE, "%s:%d:type(%u)\n", printd(DEBUG_PARSE, "%s:%d:type(%u)\n", cur_filename, cur_lineno, $1);
zconf_curname(), zconf_lineno(), $1);
}; };
choice_option: T_OPTIONAL T_EOL choice_option: T_OPTIONAL T_EOL
{ {
current_entry->sym->flags |= SYMBOL_OPTIONAL; current_entry->sym->flags |= SYMBOL_OPTIONAL;
printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:optional\n", cur_filename, cur_lineno);
}; };
choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL choice_option: T_DEFAULT nonconst_symbol if_expr T_EOL
{ {
menu_add_symbol(P_DEFAULT, $2, $3); menu_add_symbol(P_DEFAULT, $2, $3);
printd(DEBUG_PARSE, "%s:%d:default\n", printd(DEBUG_PARSE, "%s:%d:default\n", cur_filename, cur_lineno);
zconf_curname(), zconf_lineno());
}; };
type: type:
...@@ -304,7 +303,7 @@ default: ...@@ -304,7 +303,7 @@ default:
if_entry: T_IF expr T_EOL if_entry: T_IF expr T_EOL
{ {
printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:if\n", cur_filename, cur_lineno);
menu_add_entry(NULL); menu_add_entry(NULL);
menu_add_dep($2); menu_add_dep($2);
$$ = menu_add_menu(); $$ = menu_add_menu();
...@@ -314,7 +313,7 @@ if_end: end ...@@ -314,7 +313,7 @@ if_end: end
{ {
if (zconf_endtoken($1, "if")) { if (zconf_endtoken($1, "if")) {
menu_end_menu(); menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:endif\n", cur_filename, cur_lineno);
} }
}; };
...@@ -330,7 +329,7 @@ menu: T_MENU T_WORD_QUOTE T_EOL ...@@ -330,7 +329,7 @@ menu: T_MENU T_WORD_QUOTE T_EOL
{ {
menu_add_entry(NULL); menu_add_entry(NULL);
menu_add_prompt(P_MENU, $2, NULL); menu_add_prompt(P_MENU, $2, NULL);
printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:menu\n", cur_filename, cur_lineno);
}; };
menu_entry: menu menu_option_list menu_entry: menu menu_option_list
...@@ -342,7 +341,7 @@ menu_end: end ...@@ -342,7 +341,7 @@ menu_end: end
{ {
if (zconf_endtoken($1, "menu")) { if (zconf_endtoken($1, "menu")) {
menu_end_menu(); menu_end_menu();
printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:endmenu\n", cur_filename, cur_lineno);
} }
}; };
...@@ -357,7 +356,7 @@ menu_option_list: ...@@ -357,7 +356,7 @@ menu_option_list:
source_stmt: T_SOURCE T_WORD_QUOTE T_EOL source_stmt: T_SOURCE T_WORD_QUOTE T_EOL
{ {
printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2); printd(DEBUG_PARSE, "%s:%d:source %s\n", cur_filename, cur_lineno, $2);
zconf_nextfile($2); zconf_nextfile($2);
free($2); free($2);
}; };
...@@ -368,7 +367,7 @@ comment: T_COMMENT T_WORD_QUOTE T_EOL ...@@ -368,7 +367,7 @@ comment: T_COMMENT T_WORD_QUOTE T_EOL
{ {
menu_add_entry(NULL); menu_add_entry(NULL);
menu_add_prompt(P_COMMENT, $2, NULL); menu_add_prompt(P_COMMENT, $2, NULL);
printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:comment\n", cur_filename, cur_lineno);
}; };
comment_stmt: comment comment_option_list comment_stmt: comment comment_option_list
...@@ -383,7 +382,7 @@ comment_option_list: ...@@ -383,7 +382,7 @@ comment_option_list:
help_start: T_HELP T_EOL help_start: T_HELP T_EOL
{ {
printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:help\n", cur_filename, cur_lineno);
zconf_starthelp(); zconf_starthelp();
}; };
...@@ -408,7 +407,7 @@ help: help_start T_HELPTEXT ...@@ -408,7 +407,7 @@ help: help_start T_HELPTEXT
depends: T_DEPENDS T_ON expr T_EOL depends: T_DEPENDS T_ON expr T_EOL
{ {
menu_add_dep($3); menu_add_dep($3);
printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno()); printd(DEBUG_PARSE, "%s:%d:depends on\n", cur_filename, cur_lineno);
}; };
/* visibility option */ /* visibility option */
...@@ -455,9 +454,6 @@ symbol: nonconst_symbol ...@@ -455,9 +454,6 @@ symbol: nonconst_symbol
| T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); } | T_WORD_QUOTE { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
; ;
word_opt: /* empty */ { $$ = NULL; }
| T_WORD
/* assignment statement */ /* assignment statement */
assignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); } assignment_stmt: T_WORD assign_op assign_val T_EOL { variable_add($1, $3, $2); free($1); free($3); }
...@@ -477,8 +473,11 @@ assign_val: ...@@ -477,8 +473,11 @@ assign_val:
void conf_parse(const char *name) void conf_parse(const char *name)
{ {
struct symbol *sym; struct menu *menu;
int i;
autoconf_cmd = str_new();
str_printf(&autoconf_cmd, "\ndeps_config := \\\n");
zconf_initscan(name); zconf_initscan(name);
...@@ -488,13 +487,28 @@ void conf_parse(const char *name) ...@@ -488,13 +487,28 @@ void conf_parse(const char *name)
yydebug = 1; yydebug = 1;
yyparse(); yyparse();
/*
* FIXME:
* cur_filename and cur_lineno are used even after yyparse();
* menu_finalize() calls menu_add_symbol(). This should be fixed.
*/
cur_filename = "<none>";
cur_lineno = 0;
str_printf(&autoconf_cmd,
"\n"
"$(autoconfig): $(deps_config)\n"
"$(deps_config): ;\n");
env_write_dep(&autoconf_cmd);
/* Variables are expanded in the parse phase. We can free them here. */ /* Variables are expanded in the parse phase. We can free them here. */
variable_all_del(); variable_all_del();
if (yynerrs) if (yynerrs)
exit(1); exit(1);
if (!modules_sym) if (!modules_sym)
modules_sym = sym_find( "n" ); modules_sym = &symbol_no;
if (!menu_has_prompt(&rootmenu)) { if (!menu_has_prompt(&rootmenu)) {
current_entry = &rootmenu; current_entry = &rootmenu;
...@@ -502,10 +516,23 @@ void conf_parse(const char *name) ...@@ -502,10 +516,23 @@ void conf_parse(const char *name)
} }
menu_finalize(&rootmenu); menu_finalize(&rootmenu);
for_all_symbols(i, sym) {
if (sym_check_deps(sym)) menu = &rootmenu;
while (menu) {
if (menu->sym && sym_check_deps(menu->sym))
yynerrs++; yynerrs++;
if (menu->list) {
menu = menu->list;
continue;
}
while (!menu->next && menu->parent)
menu = menu->parent;
menu = menu->next;
} }
if (yynerrs) if (yynerrs)
exit(1); exit(1);
conf_set_changed(true); conf_set_changed(true);
...@@ -520,11 +547,11 @@ static bool zconf_endtoken(const char *tokenname, ...@@ -520,11 +547,11 @@ static bool zconf_endtoken(const char *tokenname,
yynerrs++; yynerrs++;
return false; return false;
} }
if (current_menu->file != current_file) { if (strcmp(current_menu->filename, cur_filename)) {
zconf_error("'%s' in different file than '%s'", zconf_error("'%s' in different file than '%s'",
tokenname, expected_tokenname); tokenname, expected_tokenname);
fprintf(stderr, "%s:%d: location of the '%s'\n", fprintf(stderr, "%s:%d: location of the '%s'\n",
current_menu->file->name, current_menu->lineno, current_menu->filename, current_menu->lineno,
expected_tokenname); expected_tokenname);
yynerrs++; yynerrs++;
return false; return false;
...@@ -536,7 +563,7 @@ static void zconfprint(const char *err, ...) ...@@ -536,7 +563,7 @@ static void zconfprint(const char *err, ...)
{ {
va_list ap; va_list ap;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno);
va_start(ap, err); va_start(ap, err);
vfprintf(stderr, err, ap); vfprintf(stderr, err, ap);
va_end(ap); va_end(ap);
...@@ -548,7 +575,7 @@ static void zconf_error(const char *err, ...) ...@@ -548,7 +575,7 @@ static void zconf_error(const char *err, ...)
va_list ap; va_list ap;
yynerrs++; yynerrs++;
fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno()); fprintf(stderr, "%s:%d: ", cur_filename, cur_lineno);
va_start(ap, err); va_start(ap, err);
vfprintf(stderr, err, ap); vfprintf(stderr, err, ap);
va_end(ap); va_end(ap);
...@@ -557,7 +584,7 @@ static void zconf_error(const char *err, ...) ...@@ -557,7 +584,7 @@ static void zconf_error(const char *err, ...)
static void yyerror(const char *err) static void yyerror(const char *err)
{ {
fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err); fprintf(stderr, "%s:%d: %s\n", cur_filename, cur_lineno, err);
} }
static void print_quoted_string(FILE *out, const char *str) static void print_quoted_string(FILE *out, const char *str)
......
...@@ -9,10 +9,11 @@ ...@@ -9,10 +9,11 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "array_size.h"
#include "internal.h"
#include "list.h" #include "list.h"
#include "lkc.h" #include "lkc.h"
#include "preprocess.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
static char *expand_string_with_args(const char *in, int argc, char *argv[]); static char *expand_string_with_args(const char *in, int argc, char *argv[]);
static char *expand_string(const char *in); static char *expand_string(const char *in);
...@@ -21,7 +22,7 @@ static void __attribute__((noreturn)) pperror(const char *format, ...) ...@@ -21,7 +22,7 @@ static void __attribute__((noreturn)) pperror(const char *format, ...)
{ {
va_list ap; va_list ap;
fprintf(stderr, "%s:%d: ", current_file->name, yylineno); fprintf(stderr, "%s:%d: ", cur_filename, yylineno);
va_start(ap, format); va_start(ap, format);
vfprintf(stderr, format, ap); vfprintf(stderr, format, ap);
va_end(ap); va_end(ap);
...@@ -87,14 +88,17 @@ static char *env_expand(const char *name) ...@@ -87,14 +88,17 @@ static char *env_expand(const char *name)
return xstrdup(value); return xstrdup(value);
} }
void env_write_dep(FILE *f, const char *autoconfig_name) void env_write_dep(struct gstr *s)
{ {
struct env *e, *tmp; struct env *e, *tmp;
list_for_each_entry_safe(e, tmp, &env_list, node) { list_for_each_entry_safe(e, tmp, &env_list, node) {
fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value); str_printf(s,
fprintf(f, "%s: FORCE\n", autoconfig_name); "\n"
fprintf(f, "endif\n"); "ifneq \"$(%s)\" \"%s\"\n"
"$(autoconfig): FORCE\n"
"endif\n",
e->name, e->value);
env_del(e); env_del(e);
} }
} }
...@@ -119,7 +123,7 @@ static char *do_error_if(int argc, char *argv[]) ...@@ -119,7 +123,7 @@ static char *do_error_if(int argc, char *argv[])
static char *do_filename(int argc, char *argv[]) static char *do_filename(int argc, char *argv[])
{ {
return xstrdup(current_file->name); return xstrdup(cur_filename);
} }
static char *do_info(int argc, char *argv[]) static char *do_info(int argc, char *argv[])
...@@ -181,8 +185,7 @@ static char *do_shell(int argc, char *argv[]) ...@@ -181,8 +185,7 @@ static char *do_shell(int argc, char *argv[])
static char *do_warning_if(int argc, char *argv[]) static char *do_warning_if(int argc, char *argv[])
{ {
if (!strcmp(argv[0], "y")) if (!strcmp(argv[0], "y"))
fprintf(stderr, "%s:%d: %s\n", fprintf(stderr, "%s:%d: %s\n", cur_filename, yylineno, argv[1]);
current_file->name, yylineno, argv[1]);
return xstrdup(""); return xstrdup("");
} }
......
/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef PREPROCESS_H
#define PREPROCESS_H
enum variable_flavor {
VAR_SIMPLE,
VAR_RECURSIVE,
VAR_APPEND,
};
struct gstr;
void env_write_dep(struct gstr *gs);
void variable_add(const char *name, const char *value,
enum variable_flavor flavor);
void variable_all_del(void);
char *expand_dollar(const char **str);
char *expand_one_token(const char **str);
#endif /* PREPROCESS_H */
...@@ -1058,7 +1058,7 @@ void ConfigInfoView::menuInfo(void) ...@@ -1058,7 +1058,7 @@ void ConfigInfoView::menuInfo(void)
stream << "<br><br>"; stream << "<br><br>";
} }
stream << "defined at " << _menu->file->name << ":" stream << "defined at " << _menu->filename << ":"
<< _menu->lineno << "<br><br>"; << _menu->lineno << "<br><br>";
} }
} }
......
...@@ -9,23 +9,27 @@ ...@@ -9,23 +9,27 @@
#include <string.h> #include <string.h>
#include <regex.h> #include <regex.h>
#include "internal.h"
#include "lkc.h" #include "lkc.h"
struct symbol symbol_yes = { struct symbol symbol_yes = {
.name = "y", .name = "y",
.curr = { "y", yes }, .curr = { "y", yes },
.menus = LIST_HEAD_INIT(symbol_yes.menus),
.flags = SYMBOL_CONST|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}; };
struct symbol symbol_mod = { struct symbol symbol_mod = {
.name = "m", .name = "m",
.curr = { "m", mod }, .curr = { "m", mod },
.menus = LIST_HEAD_INIT(symbol_mod.menus),
.flags = SYMBOL_CONST|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}; };
struct symbol symbol_no = { struct symbol symbol_no = {
.name = "n", .name = "n",
.curr = { "n", no }, .curr = { "n", no },
.menus = LIST_HEAD_INIT(symbol_no.menus),
.flags = SYMBOL_CONST|SYMBOL_VALID, .flags = SYMBOL_CONST|SYMBOL_VALID,
}; };
...@@ -160,9 +164,8 @@ static void sym_set_changed(struct symbol *sym) ...@@ -160,9 +164,8 @@ static void sym_set_changed(struct symbol *sym)
static void sym_set_all_changed(void) static void sym_set_all_changed(void)
{ {
struct symbol *sym; struct symbol *sym;
int i;
for_all_symbols(i, sym) for_all_symbols(sym)
sym_set_changed(sym); sym_set_changed(sym);
} }
...@@ -475,9 +478,8 @@ void sym_calc_value(struct symbol *sym) ...@@ -475,9 +478,8 @@ void sym_calc_value(struct symbol *sym)
void sym_clear_all_valid(void) void sym_clear_all_valid(void)
{ {
struct symbol *sym; struct symbol *sym;
int i;
for_all_symbols(i, sym) for_all_symbols(sym)
sym->flags &= ~SYMBOL_VALID; sym->flags &= ~SYMBOL_VALID;
conf_set_changed(true); conf_set_changed(true);
sym_calc_value(modules_sym); sym_calc_value(modules_sym);
...@@ -803,14 +805,7 @@ bool sym_is_changeable(struct symbol *sym) ...@@ -803,14 +805,7 @@ bool sym_is_changeable(struct symbol *sym)
return sym->visible > sym->rev_dep.tri; return sym->visible > sym->rev_dep.tri;
} }
static unsigned strhash(const char *s) HASHTABLE_DEFINE(sym_hashtable, SYMBOL_HASHSIZE);
{
/* fnv32 hash */
unsigned hash = 2166136261U;
for (; *s; s++)
hash = (hash ^ *s) * 0x01000193;
return hash;
}
struct symbol *sym_lookup(const char *name, int flags) struct symbol *sym_lookup(const char *name, int flags)
{ {
...@@ -826,9 +821,9 @@ struct symbol *sym_lookup(const char *name, int flags) ...@@ -826,9 +821,9 @@ struct symbol *sym_lookup(const char *name, int flags)
case 'n': return &symbol_no; case 'n': return &symbol_no;
} }
} }
hash = strhash(name) % SYMBOL_HASHSIZE; hash = strhash(name);
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { hash_for_each_possible(sym_hashtable, symbol, node, hash) {
if (symbol->name && if (symbol->name &&
!strcmp(symbol->name, name) && !strcmp(symbol->name, name) &&
(flags ? symbol->flags & flags (flags ? symbol->flags & flags
...@@ -846,9 +841,9 @@ struct symbol *sym_lookup(const char *name, int flags) ...@@ -846,9 +841,9 @@ struct symbol *sym_lookup(const char *name, int flags)
symbol->name = new_name; symbol->name = new_name;
symbol->type = S_UNKNOWN; symbol->type = S_UNKNOWN;
symbol->flags = flags; symbol->flags = flags;
INIT_LIST_HEAD(&symbol->menus);
symbol->next = symbol_hash[hash]; hash_add(sym_hashtable, &symbol->node, hash);
symbol_hash[hash] = symbol;
return symbol; return symbol;
} }
...@@ -868,9 +863,9 @@ struct symbol *sym_find(const char *name) ...@@ -868,9 +863,9 @@ struct symbol *sym_find(const char *name)
case 'n': return &symbol_no; case 'n': return &symbol_no;
} }
} }
hash = strhash(name) % SYMBOL_HASHSIZE; hash = strhash(name);
for (symbol = symbol_hash[hash]; symbol; symbol = symbol->next) { hash_for_each_possible(sym_hashtable, symbol, node, hash) {
if (symbol->name && if (symbol->name &&
!strcmp(symbol->name, name) && !strcmp(symbol->name, name) &&
!(symbol->flags & SYMBOL_CONST)) !(symbol->flags & SYMBOL_CONST))
...@@ -930,7 +925,7 @@ struct symbol **sym_re_search(const char *pattern) ...@@ -930,7 +925,7 @@ struct symbol **sym_re_search(const char *pattern)
if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE)) if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
return NULL; return NULL;
for_all_symbols(i, sym) { for_all_symbols(sym) {
if (sym->flags & SYMBOL_CONST || !sym->name) if (sym->flags & SYMBOL_CONST || !sym->name)
continue; continue;
if (regexec(&re, sym->name, 1, match, 0)) if (regexec(&re, sym->name, 1, match, 0))
...@@ -1041,42 +1036,42 @@ static void sym_check_print_recursive(struct symbol *last_sym) ...@@ -1041,42 +1036,42 @@ static void sym_check_print_recursive(struct symbol *last_sym)
} }
if (stack->sym == last_sym) if (stack->sym == last_sym)
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n", fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
prop->file->name, prop->lineno); prop->filename, prop->lineno);
if (sym_is_choice(sym)) { if (sym_is_choice(sym)) {
fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n", fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
menu->file->name, menu->lineno, menu->filename, menu->lineno,
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
} else if (sym_is_choice_value(sym)) { } else if (sym_is_choice_value(sym)) {
fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n", fprintf(stderr, "%s:%d:\tsymbol %s is part of choice %s\n",
menu->file->name, menu->lineno, menu->filename, menu->lineno,
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
} else if (stack->expr == &sym->dir_dep.expr) { } else if (stack->expr == &sym->dir_dep.expr) {
fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n", fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
prop->file->name, prop->lineno, prop->filename, prop->lineno,
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
} else if (stack->expr == &sym->rev_dep.expr) { } else if (stack->expr == &sym->rev_dep.expr) {
fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n", fprintf(stderr, "%s:%d:\tsymbol %s is selected by %s\n",
prop->file->name, prop->lineno, prop->filename, prop->lineno,
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
} else if (stack->expr == &sym->implied.expr) { } else if (stack->expr == &sym->implied.expr) {
fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n", fprintf(stderr, "%s:%d:\tsymbol %s is implied by %s\n",
prop->file->name, prop->lineno, prop->filename, prop->lineno,
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
} else if (stack->expr) { } else if (stack->expr) {
fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n", fprintf(stderr, "%s:%d:\tsymbol %s %s value contains %s\n",
prop->file->name, prop->lineno, prop->filename, prop->lineno,
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
prop_get_type_name(prop->type), prop_get_type_name(prop->type),
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
} else { } else {
fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n", fprintf(stderr, "%s:%d:\tsymbol %s %s is visible depending on %s\n",
prop->file->name, prop->lineno, prop->filename, prop->lineno,
sym->name ? sym->name : "<choice>", sym->name ? sym->name : "<choice>",
prop_get_type_name(prop->type), prop_get_type_name(prop->type),
next_sym->name ? next_sym->name : "<choice>"); next_sym->name ? next_sym->name : "<choice>");
......
choice
prompt "choose A or B"
config A
bool "A"
config B
bool "B"
endchoice
choice
prompt "choose X or Y"
depends on B
config X
bool "X"
config Y
bool "Y"
endchoice
# SPDX-License-Identifier: GPL-2.0-only
"""
Randomize all dependent choices
This is a somewhat tricky case for randconfig; the visibility of one choice is
determined by a member of another choice. Randconfig should be able to generate
all possible patterns.
"""
def test(conf):
expected0 = False
expected1 = False
expected2 = False
for i in range(100):
assert conf.randconfig(seed=i) == 0
if conf.config_matches('expected_config0'):
expected0 = True
elif conf.config_matches('expected_config1'):
expected1 = True
elif conf.config_matches('expected_config2'):
expected2 = True
else:
assert False
if expected0 and expected1 and expected2:
break
assert expected0
assert expected1
assert expected2
#
# Automatically generated file; DO NOT EDIT.
# Main menu
#
CONFIG_A=y
# CONFIG_B is not set
#
# Automatically generated file; DO NOT EDIT.
# Main menu
#
# CONFIG_A is not set
CONFIG_B=y
CONFIG_X=y
# CONFIG_Y is not set
#
# Automatically generated file; DO NOT EDIT.
# Main menu
#
# CONFIG_A is not set
CONFIG_B=y
# CONFIG_X is not set
CONFIG_Y=y
choice
prompt "This is always invisible"
depends on n
config DUMMY
bool "DUMMY"
endchoice
choice
prompt "Choose A or B"
config A
bool "A"
config B
bool "B"
endchoice
config FOO
bool "FOO"
depends on A
choice
prompt "Choose X"
depends on FOO
config X
bool "X"
endchoice
# SPDX-License-Identifier: GPL-2.0-only
"""
Randomize choices with correct dependencies
When shuffling a choice may potentially disrupt certain dependencies, symbol
values must be recalculated.
Related Linux commits:
- c8fb7d7e48d11520ad24808cfce7afb7b9c9f798
"""
def test(conf):
for i in range(20):
assert conf.randconfig(seed=i) == 0
assert (conf.config_matches('expected_config0') or
conf.config_matches('expected_config1') or
conf.config_matches('expected_config2'))
#
# Automatically generated file; DO NOT EDIT.
# Main menu
#
CONFIG_A=y
# CONFIG_B is not set
CONFIG_FOO=y
CONFIG_X=y
#
# Automatically generated file; DO NOT EDIT.
# Main menu
#
CONFIG_A=y
# CONFIG_B is not set
# CONFIG_FOO is not set
#
# Automatically generated file; DO NOT EDIT.
# Main menu
#
# CONFIG_A is not set
CONFIG_B=y
...@@ -154,12 +154,10 @@ class Conf: ...@@ -154,12 +154,10 @@ class Conf:
defconfig_path = os.path.join(self._test_dir, defconfig) defconfig_path = os.path.join(self._test_dir, defconfig)
return self._run_conf('--defconfig={}'.format(defconfig_path)) return self._run_conf('--defconfig={}'.format(defconfig_path))
def _allconfig(self, mode, all_config): def _allconfig(self, mode, all_config, extra_env={}):
if all_config: if all_config:
all_config_path = os.path.join(self._test_dir, all_config) all_config_path = os.path.join(self._test_dir, all_config)
extra_env = {'KCONFIG_ALLCONFIG': all_config_path} extra_env['KCONFIG_ALLCONFIG'] = all_config_path
else:
extra_env = {}
return self._run_conf('--{}config'.format(mode), extra_env=extra_env) return self._run_conf('--{}config'.format(mode), extra_env=extra_env)
...@@ -195,13 +193,19 @@ class Conf: ...@@ -195,13 +193,19 @@ class Conf:
""" """
return self._allconfig('alldef', all_config) return self._allconfig('alldef', all_config)
def randconfig(self, all_config=None): def randconfig(self, all_config=None, seed=None):
"""Run randconfig. """Run randconfig.
all_config: fragment config file for KCONFIG_ALLCONFIG (optional) all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
seed: the seed for randconfig (optional)
returncode: exit status of the Kconfig executable returncode: exit status of the Kconfig executable
""" """
return self._allconfig('rand', all_config) if seed is not None:
extra_env = {'KCONFIG_SEED': hex(seed)}
else:
extra_env = {}
return self._allconfig('rand', all_config, extra_env=extra_env)
def savedefconfig(self, dot_config): def savedefconfig(self, dot_config):
"""Run savedefconfig. """Run savedefconfig.
......
Kconfig:11:error: recursive dependency detected! Kconfig:5:error: recursive dependency detected!
Kconfig:11: symbol B is selected by B Kconfig:5: symbol A depends on A
For a resolution refer to Documentation/kbuild/kconfig-language.rst For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:5:error: recursive dependency detected! Kconfig:11:error: recursive dependency detected!
Kconfig:5: symbol A depends on A Kconfig:11: symbol B is selected by B
For a resolution refer to Documentation/kbuild/kconfig-language.rst For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
...@@ -14,9 +14,9 @@ Kconfig:21: symbol C2 depends on C1 ...@@ -14,9 +14,9 @@ Kconfig:21: symbol C2 depends on C1
For a resolution refer to Documentation/kbuild/kconfig-language.rst For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:32:error: recursive dependency detected! Kconfig:27:error: recursive dependency detected!
Kconfig:32: symbol D2 is selected by D1
Kconfig:27: symbol D1 depends on D2 Kconfig:27: symbol D1 depends on D2
Kconfig:32: symbol D2 is selected by D1
For a resolution refer to Documentation/kbuild/kconfig-language.rst For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
...@@ -26,13 +26,13 @@ Kconfig:42: symbol E2 is implied by E1 ...@@ -26,13 +26,13 @@ Kconfig:42: symbol E2 is implied by E1
For a resolution refer to Documentation/kbuild/kconfig-language.rst For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:60:error: recursive dependency detected! Kconfig:49:error: recursive dependency detected!
Kconfig:60: symbol G depends on G Kconfig:49: symbol F1 default value contains F2
Kconfig:51: symbol F2 depends on F1
For a resolution refer to Documentation/kbuild/kconfig-language.rst For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
Kconfig:51:error: recursive dependency detected! Kconfig:60:error: recursive dependency detected!
Kconfig:51: symbol F2 depends on F1 Kconfig:60: symbol G depends on G
Kconfig:49: symbol F1 default value contains F2
For a resolution refer to Documentation/kbuild/kconfig-language.rst For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations" subsection "Kconfig recursive dependency limitations"
...@@ -7,25 +7,50 @@ ...@@ -7,25 +7,50 @@
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "hashtable.h"
#include "lkc.h" #include "lkc.h"
unsigned int strhash(const char *s)
{
/* fnv32 hash */
unsigned int hash = 2166136261U;
for (; *s; s++)
hash = (hash ^ *s) * 0x01000193;
return hash;
}
/* hash table of all parsed Kconfig files */
static HASHTABLE_DEFINE(file_hashtable, 1U << 11);
struct file {
struct hlist_node node;
char name[];
};
/* file already present in list? If not add it */ /* file already present in list? If not add it */
struct file *file_lookup(const char *name) const char *file_lookup(const char *name)
{ {
struct file *file; struct file *file;
size_t len;
int hash = strhash(name);
for (file = file_list; file; file = file->next) { hash_for_each_possible(file_hashtable, file, node, hash)
if (!strcmp(name, file->name)) { if (!strcmp(name, file->name))
return file; return file->name;
}
}
file = xmalloc(sizeof(*file)); len = strlen(name);
file = xmalloc(sizeof(*file) + len + 1);
memset(file, 0, sizeof(*file)); memset(file, 0, sizeof(*file));
file->name = xstrdup(name); memcpy(file->name, name, len);
file->next = file_list; file->name[len] = '\0';
file_list = file;
return file; hash_add(file_hashtable, &file->node, hash);
str_printf(&autoconf_cmd, "\t%s \\\n", name);
return file->name;
} }
/* Allocate initial growable string */ /* Allocate initial growable string */
......
...@@ -1050,7 +1050,9 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf, ...@@ -1050,7 +1050,9 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
sec_mismatch_count++; sec_mismatch_count++;
warn("%s: section mismatch in reference: %s+0x%x (section: %s) -> %s (section: %s)\n", warn("%s: section mismatch in reference: %s+0x%x (section: %s) -> %s (section: %s)\n",
modname, fromsym, (unsigned int)(faddr - from->st_value), fromsec, tosym, tosec); modname, fromsym,
(unsigned int)(faddr - (from ? from->st_value : 0)),
fromsec, tosym, tosec);
if (mismatch->mismatch == EXTABLE_TO_NON_TEXT) { if (mismatch->mismatch == EXTABLE_TO_NON_TEXT) {
if (match(tosec, mismatch->bad_tosec)) if (match(tosec, mismatch->bad_tosec))
......
...@@ -24,24 +24,10 @@ if_enabled_echo() { ...@@ -24,24 +24,10 @@ if_enabled_echo() {
fi fi
} }
create_package() {
export DH_OPTIONS="-p${1}"
dh_installdocs
dh_installchangelogs
dh_compress
dh_fixperms
dh_gencontrol
dh_md5sums
dh_builddeb -- ${KDEB_COMPRESS:+-Z$KDEB_COMPRESS}
}
install_linux_image () { install_linux_image () {
pname=$1 pname=$1
pdir=debian/$1 pdir=debian/$1
rm -rf ${pdir}
# Only some architectures with OF support have this target # Only some architectures with OF support have this target
if is_enabled CONFIG_OF_EARLY_FLATTREE && [ -d "${srctree}/arch/${SRCARCH}/boot/dts" ]; then if is_enabled CONFIG_OF_EARLY_FLATTREE && [ -d "${srctree}/arch/${SRCARCH}/boot/dts" ]; then
${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/usr/lib/linux-image-${KERNELRELEASE}" dtbs_install ${MAKE} -f ${srctree}/Makefile INSTALL_DTBS_PATH="${pdir}/usr/lib/linux-image-${KERNELRELEASE}" dtbs_install
...@@ -109,8 +95,6 @@ install_linux_image () { ...@@ -109,8 +95,6 @@ install_linux_image () {
install_linux_image_dbg () { install_linux_image_dbg () {
pdir=debian/$1 pdir=debian/$1
rm -rf ${pdir}
# Parse modules.order directly because 'make modules_install' may sign, # Parse modules.order directly because 'make modules_install' may sign,
# compress modules, and then run unneeded depmod. # compress modules, and then run unneeded depmod.
while read -r mod; do while read -r mod; do
...@@ -140,8 +124,6 @@ install_kernel_headers () { ...@@ -140,8 +124,6 @@ install_kernel_headers () {
pdir=debian/$1 pdir=debian/$1
version=${1#linux-headers-} version=${1#linux-headers-}
rm -rf $pdir
"${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}" "${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}"
mkdir -p $pdir/lib/modules/$version/ mkdir -p $pdir/lib/modules/$version/
...@@ -151,8 +133,6 @@ install_kernel_headers () { ...@@ -151,8 +133,6 @@ install_kernel_headers () {
install_libc_headers () { install_libc_headers () {
pdir=debian/$1 pdir=debian/$1
rm -rf $pdir
$MAKE -f $srctree/Makefile headers_install INSTALL_HDR_PATH=$pdir/usr $MAKE -f $srctree/Makefile headers_install INSTALL_HDR_PATH=$pdir/usr
# move asm headers to /usr/include/<libc-machine>/asm to match the structure # move asm headers to /usr/include/<libc-machine>/asm to match the structure
...@@ -161,21 +141,15 @@ install_libc_headers () { ...@@ -161,21 +141,15 @@ install_libc_headers () {
mv "$pdir/usr/include/asm" "$pdir/usr/include/${DEB_HOST_MULTIARCH}" mv "$pdir/usr/include/asm" "$pdir/usr/include/${DEB_HOST_MULTIARCH}"
} }
rm -f debian/files package=$1
packages_enabled=$(dh_listpackages) case "${package}" in
*-dbg)
for package in ${packages_enabled} install_linux_image_dbg "${package}";;
do linux-image-*|user-mode-linux-*)
case ${package} in install_linux_image "${package}";;
*-dbg) linux-libc-dev)
install_linux_image_dbg "${package}";; install_libc_headers "${package}";;
linux-image-*|user-mode-linux-*) linux-headers-*)
install_linux_image "${package}";; install_kernel_headers "${package}";;
linux-libc-dev) esac
install_libc_headers "${package}";;
linux-headers-*)
install_kernel_headers "${package}";;
esac
create_package "${package}"
done
...@@ -11,28 +11,73 @@ ifneq (,$(filter-out parallel=1,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))) ...@@ -11,28 +11,73 @@ ifneq (,$(filter-out parallel=1,$(filter parallel=%,$(DEB_BUILD_OPTIONS))))
MAKEFLAGS += -j$(NUMJOBS) MAKEFLAGS += -j$(NUMJOBS)
endif endif
# When KBUILD_VERBOSE is undefined (presumably you are directly working with
# the debianized tree), show verbose logs unless DEB_BUILD_OPTION=terse is set.
ifeq ($(origin KBUILD_VERBOSE),undefined)
ifeq (,$(filter terse,$(DEB_BUILD_OPTIONS)))
export KBUILD_VERBOSE := 1
else
Q := @
endif
endif
revision = $(lastword $(subst -, ,$(shell dpkg-parsechangelog -S Version))) revision = $(lastword $(subst -, ,$(shell dpkg-parsechangelog -S Version)))
CROSS_COMPILE ?= $(filter-out $(DEB_BUILD_GNU_TYPE)-, $(DEB_HOST_GNU_TYPE)-) CROSS_COMPILE ?= $(filter-out $(DEB_BUILD_GNU_TYPE)-, $(DEB_HOST_GNU_TYPE)-)
make-opts = ARCH=$(ARCH) KERNELRELEASE=$(KERNELRELEASE) KBUILD_BUILD_VERSION=$(revision) $(addprefix CROSS_COMPILE=,$(CROSS_COMPILE)) make-opts = ARCH=$(ARCH) KERNELRELEASE=$(KERNELRELEASE) KBUILD_BUILD_VERSION=$(revision) $(addprefix CROSS_COMPILE=,$(CROSS_COMPILE))
binary-targets := $(addprefix binary-, image image-dbg headers libc-dev)
all-packages = $(shell dh_listpackages)
image-package = $(filter linux-image-% user-%, $(filter-out %-dbg, $(all-packages)))
image-dbg-package = $(filter %-dbg, $(all-packages))
libc-dev-package = $(filter linux-libc-dev, $(all-packages))
headers-package = $(filter linux-headers-%, $(all-packages))
mk-files = $(patsubst binary-%,debian/%.files,$1)
package = $($(@:binary-%=%-package))
# DH_OPTION is an environment variable common for all debhelper commands.
# We could 'export' it, but here it is passed from the command line to clarify
# which package is being processed in the build log.
DH_OPTIONS = -p$(package)
define binary
$(Q)dh_testdir $(DH_OPTIONS)
$(Q)dh_testroot $(DH_OPTIONS)
$(Q)dh_prep $(DH_OPTIONS)
$(Q)+$(MAKE) $(make-opts) run-command KBUILD_RUN_COMMAND='+$$(srctree)/scripts/package/builddeb $(package)'
$(Q)dh_installdocs $(DH_OPTIONS)
$(Q)dh_installchangelogs $(DH_OPTIONS)
$(Q)dh_compress $(DH_OPTIONS)
$(Q)dh_fixperms $(DH_OPTIONS)
$(Q)dh_gencontrol $(DH_OPTIONS) -- -f$(call mk-files,$@)
$(Q)dh_md5sums $(DH_OPTIONS)
$(Q)dh_builddeb $(DH_OPTIONS) -- $(addprefix -Z,$(KDEB_COMPRESS))
endef
.PHONY: $(binary-targets)
$(binary-targets): build-arch
$(Q)truncate -s0 $(call mk-files,$@)
$(if $(package),$(binary))
.PHONY: binary binary-indep binary-arch .PHONY: binary binary-indep binary-arch
binary: binary-arch binary-indep binary: binary-arch binary-indep
binary-indep: build-indep binary-indep: build-indep
binary-arch: build-arch binary-arch: $(binary-targets)
$(MAKE) $(make-opts) \ $(Q)cat $(call mk-files,$^) > debian/files
run-command KBUILD_RUN_COMMAND='+$$(srctree)/scripts/package/builddeb'
.PHONY: build build-indep build-arch .PHONY: build build-indep build-arch
build: build-arch build-indep build: build-arch build-indep
build-indep: build-indep:
build-arch: build-arch:
$(MAKE) $(make-opts) olddefconfig $(Q)$(MAKE) $(make-opts) olddefconfig
$(MAKE) $(make-opts) $(if $(filter um,$(ARCH)),,headers) all $(Q)$(MAKE) $(make-opts) $(if $(filter um,$(ARCH)),,headers) all
.PHONY: clean .PHONY: clean
clean: clean:
rm -rf debian/files debian/linux-* debian/deb-env.vars* $(Q)dh_clean
$(MAKE) ARCH=$(ARCH) clean $(Q)rm -rf debian/deb-env.vars* debian/*.files
$(Q)$(MAKE) ARCH=$(ARCH) clean
# If DEB_HOST_ARCH is empty, it is likely that debian/rules was executed # If DEB_HOST_ARCH is empty, it is likely that debian/rules was executed
# directly. Run 'dpkg-architecture --print-set --print-format=make' to # directly. Run 'dpkg-architecture --print-set --print-format=make' to
...@@ -41,6 +86,6 @@ ifndef DEB_HOST_ARCH ...@@ -41,6 +86,6 @@ ifndef DEB_HOST_ARCH
include debian/deb-env.vars include debian/deb-env.vars
debian/deb-env.vars: debian/deb-env.vars:
dpkg-architecture -a$$(cat debian/arch) --print-set --print-format=make > $@.tmp $(Q)dpkg-architecture -a$$(cat debian/arch) --print-set --print-format=make > $@.tmp
mv $@.tmp $@ $(Q)mv $@.tmp $@
endif endif
...@@ -61,11 +61,37 @@ cp $(%{make} %{makeflags} -s image_name) %{buildroot}/lib/modules/%{KERNELRELEAS ...@@ -61,11 +61,37 @@ cp $(%{make} %{makeflags} -s image_name) %{buildroot}/lib/modules/%{KERNELRELEAS
%{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install %{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
cp System.map %{buildroot}/lib/modules/%{KERNELRELEASE} cp System.map %{buildroot}/lib/modules/%{KERNELRELEASE}
cp .config %{buildroot}/lib/modules/%{KERNELRELEASE}/config cp .config %{buildroot}/lib/modules/%{KERNELRELEASE}/config
if %{make} %{makeflags} run-command KBUILD_RUN_COMMAND='test -d ${srctree}/arch/${SRCARCH}/boot/dts' 2>/dev/null; then
%{make} %{makeflags} INSTALL_DTBS_PATH=%{buildroot}/lib/modules/%{KERNELRELEASE}/dtb dtbs_install
fi
ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEASE}/build ln -fns /usr/src/kernels/%{KERNELRELEASE} %{buildroot}/lib/modules/%{KERNELRELEASE}/build
%if %{with_devel} %if %{with_devel}
%{make} %{makeflags} run-command KBUILD_RUN_COMMAND='${srctree}/scripts/package/install-extmod-build %{buildroot}/usr/src/kernels/%{KERNELRELEASE}' %{make} %{makeflags} run-command KBUILD_RUN_COMMAND='${srctree}/scripts/package/install-extmod-build %{buildroot}/usr/src/kernels/%{KERNELRELEASE}'
%endif %endif
{
for x in System.map config kernel modules.builtin \
modules.builtin.modinfo modules.order vmlinuz; do
echo "/lib/modules/%{KERNELRELEASE}/${x}"
done
for x in alias alias.bin builtin.alias.bin builtin.bin dep dep.bin \
devname softdep symbols symbols.bin; do
echo "%ghost /lib/modules/%{KERNELRELEASE}/modules.${x}"
done
for x in System.map config vmlinuz; do
echo "%ghost /boot/${x}-%{KERNELRELEASE}"
done
if [ -d "%{buildroot}/lib/modules/%{KERNELRELEASE}/dtb" ];then
echo "/lib/modules/%{KERNELRELEASE}/dtb"
find "%{buildroot}/lib/modules/%{KERNELRELEASE}/dtb" -printf "%%%ghost /boot/dtb-%{KERNELRELEASE}/%%P\n"
fi
echo "%exclude /lib/modules/%{KERNELRELEASE}/build"
} > %{buildroot}/kernel.list
%clean %clean
rm -rf %{buildroot} rm -rf %{buildroot}
...@@ -78,23 +104,23 @@ for file in vmlinuz System.map config; do ...@@ -78,23 +104,23 @@ for file in vmlinuz System.map config; do
cp "/lib/modules/%{KERNELRELEASE}/${file}" "/boot/${file}-%{KERNELRELEASE}" cp "/lib/modules/%{KERNELRELEASE}/${file}" "/boot/${file}-%{KERNELRELEASE}"
fi fi
done done
if [ -d "/lib/modules/%{KERNELRELEASE}/dtb" ] && \
! diff -rq "/lib/modules/%{KERNELRELEASE}/dtb" "/boot/dtb-%{KERNELRELEASE}" >/dev/null 2>&1; then
rm -rf "/boot/dtb-%{KERNELRELEASE}"
cp -r "/lib/modules/%{KERNELRELEASE}/dtb" "/boot/dtb-%{KERNELRELEASE}"
fi
if [ ! -e "/lib/modules/%{KERNELRELEASE}/modules.dep" ]; then
/usr/sbin/depmod %{KERNELRELEASE}
fi
%preun %preun
if [ -x /sbin/new-kernel-pkg ]; then if [ -x /usr/bin/kernel-install ]; then
new-kernel-pkg --remove %{KERNELRELEASE} --rminitrd --initrdfile=/boot/initramfs-%{KERNELRELEASE}.img
elif [ -x /usr/bin/kernel-install ]; then
kernel-install remove %{KERNELRELEASE} kernel-install remove %{KERNELRELEASE}
fi fi
%postun %files -f %{buildroot}/kernel.list
if [ -x /sbin/update-bootloader ]; then
/sbin/update-bootloader --remove %{KERNELRELEASE}
fi
%files
%defattr (-, root, root) %defattr (-, root, root)
/lib/modules/%{KERNELRELEASE} %exclude /kernel.list
%exclude /lib/modules/%{KERNELRELEASE}/build
%files headers %files headers
%defattr (-, root, root) %defattr (-, root, root)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Most of this file is copied from tools/lib/traceevent/Makefile # Most of this file is copied from tools/lib/traceevent/Makefile
RM ?= rm RM ?= rm
srctree = $(abs_srctree) srctree := $(realpath $(srctree))
VERSION_SCRIPT := libbpf.map VERSION_SCRIPT := libbpf.map
LIBBPF_VERSION := $(shell \ LIBBPF_VERSION := $(shell \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment