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 @@
*.xz
*.zst
Module.symvers
dtbs-list
modules.order
#
......
......@@ -393,7 +393,7 @@ of C0, which doesn't depend on M::
choices::
"choice" [symbol]
"choice"
<choice options>
<choice block>
"endchoice"
......@@ -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
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::
......
This diff is collapsed.
......@@ -39,8 +39,8 @@ __all:
# prepare rule.
this-makefile := $(lastword $(MAKEFILE_LIST))
export abs_srctree := $(realpath $(dir $(this-makefile)))
export abs_objtree := $(CURDIR)
abs_srctree := $(realpath $(dir $(this-makefile)))
abs_objtree := $(CURDIR)
ifneq ($(sub_make_done),1)
......@@ -965,8 +965,15 @@ export CC_FLAGS_CFI
endif
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)
endif
endif
# arch Makefile may override CC so keep this after arch Makefile is included
NOSTDINC_FLAGS += -nostdinc
......@@ -1384,7 +1391,7 @@ ifneq ($(dtstree),)
PHONY += dtbs dtbs_prepare dtbs_install dtbs_check
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
# INSTALL_DTBS_PATH contains $(KERNELRELEASE). However, we do not want to make
......@@ -1402,7 +1409,7 @@ endif
dtbs_check: dtbs
dtbs_install:
$(Q)$(MAKE) $(dtbinst)=$(dtstree) dst=$(INSTALL_DTBS_PATH)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.dtbinst obj=$(dtstree)
ifdef CONFIG_OF_EARLY_FLATTREE
all: dtbs
......@@ -1923,7 +1930,7 @@ clean: $(clean-dirs)
-o -name '*.ko.*' \
-o -name '*.dtb' -o -name '*.dtbo' \
-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 '*.su' -o -name '*.mod' \
-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
......
......@@ -1597,4 +1597,16 @@ config FUNCTION_ALIGNMENT
default 4 if FUNCTION_ALIGNMENT_4B
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
......@@ -339,6 +339,7 @@ config ALPHA_EV4
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
default y if !ALPHA_LYNX
default y if !ALPHA_EV5
config ALPHA_LCA
bool
......@@ -366,10 +367,6 @@ config ALPHA_EV5
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
config ALPHA_EV4
bool
default y if ALPHA_LYNX && !ALPHA_EV5
config ALPHA_CIA
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
......@@ -394,16 +391,12 @@ config ALPHA_PRIMO
Say Y if you have an AS 1000 5/xxx or an AS 1000A 5/xxx.
config ALPHA_GAMMA
bool "EV5 CPU(s) (model 5/xxx)?"
depends on ALPHA_SABLE
bool "EV5 CPU(s) (model 5/xxx)?" if ALPHA_SABLE
depends on ALPHA_SABLE || ALPHA_LYNX
default ALPHA_LYNX
help
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
bool
depends on ALPHA_SABLE || ALPHA_LYNX
......
......@@ -7,11 +7,13 @@ config HEXAGON
select ARCH_32BIT_OFF_T
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
select ARCH_NO_PREEMPT
select ARCH_WANT_FRAME_POINTERS
select DMA_GLOBAL_POOL
select HAVE_PAGE_SIZE_4KB
select HAVE_PAGE_SIZE_16KB
select HAVE_PAGE_SIZE_64KB
select HAVE_PAGE_SIZE_256KB
select FRAME_POINTER
# Other pending projects/to-do items.
# select HAVE_REGS_AND_STACK_ACCESS_API
# select HAVE_HW_BREAKPOINT if PERF_EVENTS
......@@ -23,6 +25,7 @@ config HEXAGON
select HAVE_PERF_EVENTS
# GENERIC_ALLOCATOR is used by dma_alloc_coherent()
select GENERIC_ALLOCATOR
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select HAVE_ARCH_KGDB
select HAVE_ARCH_TRACEHOOK
......@@ -47,9 +50,6 @@ config HEXAGON_PHYS_OFFSET
help
Platforms that don't load the kernel at zero set this.
config FRAME_POINTER
def_bool y
config LOCKDEP_SUPPORT
def_bool y
......@@ -62,12 +62,6 @@ config MMU
config GENERIC_CSUM
def_bool y
#
# Use the generic interrupt handling code in kernel/irq/:
#
config GENERIC_IRQ_PROBE
def_bool y
config GENERIC_HWEIGHT
def_bool y
......
......@@ -238,9 +238,9 @@ config PARISC_HUGE_KERNEL
def_bool y if !MODULES || UBSAN || FTRACE || COMPILE_TEST
config MLONGCALLS
def_bool y if PARISC_HUGE_KERNEL
bool "Enable the -mlong-calls compiler option for big kernels" if !PARISC_HUGE_KERNEL
depends on PA8X00
default PARISC_HUGE_KERNEL
help
If you configure the kernel to include many drivers built-in instead
as modules, the kernel executable may become too big, so that the
......@@ -255,9 +255,9 @@ config MLONGCALLS
Enabling this option will probably slow down your kernel.
config 64BIT
def_bool y if "$(ARCH)" = "parisc64"
bool "64-bit kernel" if "$(ARCH)" = "parisc"
depends on PA8X00
default "$(ARCH)" = "parisc64"
help
Enable this if you want to support 64bit kernel on PA-RISC platform.
......
......@@ -6,7 +6,7 @@ config AS_HAS_ULEB128
menuconfig RUNTIME_KERNEL_TESTING_MENU
bool "arch/riscv/kernel runtime Testing"
def_bool y
default y
help
Enable riscv kernel runtime testing.
......
......@@ -9,7 +9,9 @@ include $(srctree)/lib/vdso/Makefile
# Sanitizer runtimes are unavailable and cannot be linked here.
KASAN_SANITIZE := n
KMSAN_SANITIZE_vclock_gettime.o := n
KMSAN_SANITIZE_vdso32/vclock_gettime.o := n
KMSAN_SANITIZE_vgetcpu.o := n
KMSAN_SANITIZE_vdso32/vgetcpu.o := n
UBSAN_SANITIZE := n
KCSAN_SANITIZE := n
......
......@@ -118,8 +118,8 @@ config KVM_AMD
will be called kvm-amd.
config KVM_AMD_SEV
def_bool y
bool "AMD Secure Encrypted Virtualization (SEV) support"
default y
depends on KVM_AMD && X86_64
depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m)
help
......
......@@ -4,7 +4,8 @@ ccflags-y += -I $(srctree)/arch/x86/kvm
ccflags-$(CONFIG_KVM_WERROR) += -Werror
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
include $(srctree)/virt/kvm/Makefile.kvm
......
......@@ -81,7 +81,6 @@ config XEN_PVH
bool "Xen PVH guest support"
depends on XEN && XEN_PVHVM && ACPI
select PVH
def_bool n
help
Support for running as a Xen PVH guest.
......
......@@ -460,7 +460,6 @@ config ACPI_BGRT
config ACPI_REDUCED_HARDWARE_ONLY
bool "Hardware-reduced ACPI support only" if EXPERT
def_bool n
help
This config item changes the way the ACPI code is built. When this
option is selected, the kernel will use a specialized version of
......
......@@ -87,8 +87,8 @@ config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON
the default value.
config INTEL_IOMMU_PERF_EVENTS
def_bool y
bool "Intel IOMMU performance events"
default y
depends on INTEL_IOMMU && PERF_EVENTS
help
Selecting this option will enable the performance monitoring
......
......@@ -519,7 +519,6 @@ config DM_VERITY
If unsure, say N.
config DM_VERITY_VERIFY_ROOTHASH_SIG
def_bool n
bool "Verity data device root hash signature verification support"
depends on DM_VERITY
select SYSTEM_DATA_VERIFICATION
......
......@@ -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
*
* 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 can implicitly mark callees of cold functions as cold themselves, so
* it's not sufficient to add __function_aligned here as that will not ensure
* that callees are correctly aligned.
* GCC drops the alignment for cold functions. Worse, GCC can implicitly mark
* callees of cold functions as cold themselves, so it's not sufficient to add
* __function_aligned here as that will not ensure that callees are correctly
* aligned.
*
* See:
*
* https://lore.kernel.org/lkml/Y77%2FqVgvaJidFpYt@FVFF77S0Q05N
* 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__))
#else
#define __cold
......
......@@ -1499,7 +1499,7 @@ config MULTIUSER
config SGETMASK_SYSCALL
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
sys_sgetmask and sys_ssetmask are obsolete system calls
no longer supported in libc but still enabled by default in some
......
......@@ -362,8 +362,7 @@ config MODPROBE_PATH
userspace can still load modules explicitly).
config TRIM_UNUSED_KSYMS
bool "Trim unused exported kernel symbols" if EXPERT
depends on !COMPILE_TEST
bool "Trim unused exported kernel symbols"
help
The kernel and some modules make many symbols available for
other modules to use via EXPORT_SYMBOL() and variants. Depending
......
......@@ -2127,7 +2127,7 @@ config KCOV_IRQ_AREA_SIZE
menuconfig RUNTIME_TESTING_MENU
bool "Runtime Testing"
def_bool y
default y
if RUNTIME_TESTING_MENU
......
......@@ -583,7 +583,7 @@ config MEMORY_BALLOON
# support for memory balloon compaction
config BALLOON_COMPACTION
bool "Allow for balloon memory compaction/migration"
def_bool y
default y
depends on COMPACTION && MEMORY_BALLOON
help
Memory fragmentation introduced by ballooning might reduce
......@@ -598,7 +598,7 @@ config BALLOON_COMPACTION
# support for memory compaction
config COMPACTION
bool "Allow for memory compaction"
def_bool y
default y
select MIGRATION
depends on MMU
help
......@@ -621,7 +621,6 @@ config COMPACT_UNEVICTABLE_DEFAULT
# support for free page reporting
config PAGE_REPORTING
bool "Free page reporting"
def_bool n
help
Free page reporting allows for the incremental acquisition of
free pages from the buddy allocator for the purpose of reporting
......@@ -633,7 +632,7 @@ config PAGE_REPORTING
#
config MIGRATION
bool "Page migration"
def_bool y
default y
depends on (NUMA || ARCH_ENABLE_MEMORY_HOTREMOVE || COMPACTION || CMA) && MMU
help
Allows the migration of the physical location of pages of processes
......
......@@ -13,7 +13,7 @@ config IP_DCCP_CCID2_DEBUG
config IP_DCCP_CCID3
bool "CCID-3 (TCP-Friendly)"
def_bool y if (IP_DCCP = y || IP_DCCP = m)
default IP_DCCP = y || IP_DCCP = m
help
CCID-3 denotes TCP-Friendly Rate Control (TFRC), an equation-based
rate-controlled congestion control mechanism. TFRC is designed to
......
......@@ -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: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:<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 \
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
rust-analyzer:
$(Q)$(srctree)/scripts/generate_rust_analyzer.py \
--cfgs='core=$(core-cfgs)' --cfgs='alloc=$(alloc-cfgs)' \
$(abs_srctree) $(abs_objtree) \
$(realpath $(srctree)) $(realpath $(objtree)) \
$(RUST_LIB_SRC) $(KBUILD_EXTMOD) > \
$(if $(KBUILD_EXTMOD),$(extmod_prefix),$(objtree))/rust-project.json
......
......@@ -113,12 +113,6 @@ endef
# $(Q)$(MAKE) $(build)=dir
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=
# Usage:
......
......@@ -71,6 +71,7 @@ endif
# subdir-builtin and subdir-modorder may contain duplications. Use $(sort ...)
subdir-builtin := $(sort $(filter %/built-in.a, $(real-obj-y)))
subdir-modorder := $(sort $(filter %/modules.order, $(obj-m)))
subdir-dtbslist := $(sort $(filter %/dtbs-list, $(dtb-y)))
targets-for-builtin := $(extra-y)
......@@ -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 := '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))
......@@ -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
$(subdir-builtin): $(obj)/%/built-in.a: $(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)
......@@ -404,19 +406,21 @@ $(obj)/built-in.a: $(real-obj-y) FORCE
$(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
# a subdirectory
# Add $(obj-m) as the prerequisite to avoid updating the timestamp of
# modules.order unless contained modules are updated.
# This is a list of build artifacts (module or dtb) from the current Makefile
# and its sub-directories. The timestamp should be updated when any of the
# member files.
cmd_modules_order = { $(foreach m, $(real-prereqs), \
$(if $(filter %/modules.order, $m), cat $m, echo $m);) :; } \
cmd_gen_order = { $(foreach m, $(real-prereqs), \
$(if $(filter %/$(notdir $@), $m), cat $m, echo $m);) :; } \
> $@
$(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)
......
......@@ -8,32 +8,36 @@
# $INSTALL_PATH/dtbs/$KERNELRELEASE
# ==========================================================================
src := $(obj)
PHONY := __dtbs_install
__dtbs_install:
include include/config/auto.conf
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 $@
cmd_dtb_install = install -D $< $@
$(dst)/%.dtb: $(obj)/%.dtb
$(dst)/%: $(obj)/%
$(call cmd,dtb_install)
$(dst)/%.dtbo: $(obj)/%.dtbo
$(call cmd,dtb_install)
dtbs := $(patsubst $(obj)/%,%,$(call read-file, $(obj)/dtbs-list))
ifdef CONFIG_ARCH_WANT_FLAT_DTB_INSTALL
PHONY += $(subdirs)
$(subdirs):
$(Q)$(MAKE) $(dtbinst)=$@ dst=$(if $(CONFIG_ARCH_WANT_FLAT_DTB_INSTALL),$(dst),$(patsubst $(obj)/%,$(dst)/%,$@))
define gen_install_rules
$(dst)/%: $(obj)/$(1)%
$$(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)
......@@ -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 += $(call cc-disable-warning, unaligned-access)
KBUILD_CFLAGS += $(call cc-disable-warning, cast-function-type-strict)
KBUILD_CFLAGS += -Wno-enum-compare-conditional
KBUILD_CFLAGS += -Wno-enum-enum-conversion
endif
endif
......@@ -185,7 +187,6 @@ KBUILD_CFLAGS += -Wpointer-arith
KBUILD_CFLAGS += -Wredundant-decls
KBUILD_CFLAGS += -Wsign-compare
KBUILD_CFLAGS += -Wswitch-default
KBUILD_CFLAGS += $(call cc-option, -Wpacked-bitfield-compat)
KBUILD_CPPFLAGS += -DKBUILD_EXTRA_WARN3
......
......@@ -45,6 +45,11 @@ else
obj-y := $(filter-out %/, $(obj-y))
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
suffix-search = $(strip $(foreach s, $3, $($(1:%$(strip $2)=%$s))))
# List composite targets that are constructed by combining other targets
......@@ -99,6 +104,7 @@ lib-y := $(addprefix $(obj)/,$(lib-y))
real-obj-y := $(addprefix $(obj)/,$(real-obj-y))
real-obj-m := $(addprefix $(obj)/,$(real-obj-m))
multi-obj-m := $(addprefix $(obj)/, $(multi-obj-m))
dtb-y := $(addprefix $(obj)/, $(dtb-y))
multi-dtb-y := $(addprefix $(obj)/, $(multi-dtb-y))
real-dtb-y := $(addprefix $(obj)/, $(real-dtb-y))
subdir-ym := $(addprefix $(obj)/,$(subdir-ym))
......@@ -148,7 +154,7 @@ _cpp_flags = $(KBUILD_CPPFLAGS) $(cppflags-y) $(CPPFLAGS_$(target-stem).lds)
#
ifeq ($(CONFIG_GCOV_KERNEL),y)
_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))
endif
......@@ -159,32 +165,32 @@ endif
ifeq ($(CONFIG_KASAN),y)
ifneq ($(CONFIG_KASAN_HW_TAGS),y)
_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))
endif
endif
ifeq ($(CONFIG_KMSAN),y)
_c_flags += $(if $(patsubst n%,, \
$(KMSAN_SANITIZE_$(basetarget).o)$(KMSAN_SANITIZE)y), \
$(KMSAN_SANITIZE_$(target-stem).o)$(KMSAN_SANITIZE)y), \
$(CFLAGS_KMSAN))
_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)
endif
ifeq ($(CONFIG_UBSAN),y)
_c_flags += $(if $(patsubst n%,, \
$(UBSAN_SANITIZE_$(basetarget).o)$(UBSAN_SANITIZE)y), \
$(UBSAN_SANITIZE_$(target-stem).o)$(UBSAN_SANITIZE)y), \
$(CFLAGS_UBSAN))
_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))
endif
ifeq ($(CONFIG_KCOV),y)
_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))
endif
......@@ -194,12 +200,12 @@ endif
#
ifeq ($(CONFIG_KCSAN),y)
_c_flags += $(if $(patsubst n%,, \
$(KCSAN_SANITIZE_$(basetarget).o)$(KCSAN_SANITIZE)y), \
$(KCSAN_SANITIZE_$(target-stem).o)$(KCSAN_SANITIZE)y), \
$(CFLAGS_KCSAN))
# Some uninstrumented files provide implied barriers required to avoid false
# positives: set KCSAN_INSTRUMENT_BARRIERS for barrier instrumentation only.
_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__)
endif
......@@ -364,7 +370,7 @@ DTC_FLAGS += -Wnode_name_chars_strict \
-Wunique_unit_address
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
DTC_FLAGS += $(if $(filter $(patsubst $(obj)/%,%,$@), $(base-dtb-y)), -@)
......
......@@ -135,7 +135,7 @@ snap-pkg:
mkdir $(objtree)/snap
$(MAKE) clean
sed "s@KERNELRELEASE@$(KERNELRELEASE)@; \
s@SRCTREE@$(abs_srctree)@" \
s@SRCTREE@$(realpath $(srctree))@" \
$(srctree)/scripts/package/snapcraft.template > \
$(objtree)/snap/snapcraft.yaml
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 @@
#include <sys/time.h>
#include <errno.h>
#include "internal.h"
#include "lkc.h"
static void conf(struct menu *menu);
......@@ -171,7 +172,7 @@ enum conf_def_mode {
static bool conf_set_all_new_symbols(enum conf_def_mode mode)
{
struct symbol *sym, *csym;
int i, cnt;
int cnt;
/*
* can't go as the default in switch-case below, otherwise gcc whines
* about -Wmaybe-uninitialized
......@@ -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)
continue;
switch (sym_get_type(sym)) {
......@@ -278,14 +279,14 @@ static bool conf_set_all_new_symbols(enum conf_def_mode mode)
* and the rest to no.
*/
if (mode != def_random) {
for_all_symbols(i, csym) {
for_all_symbols(csym) {
if ((sym_is_choice(csym) && !sym_has_value(csym)) ||
sym_is_choice_value(csym))
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))
continue;
......@@ -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)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym) {
for_all_symbols(sym) {
if (sym_get_type(sym) == S_TRISTATE &&
sym->def[S_DEF_USER].tri == old_val)
sym->def[S_DEF_USER].tri = new_val;
......
......@@ -18,8 +18,11 @@
#include <time.h>
#include <unistd.h>
#include "internal.h"
#include "lkc.h"
struct gstr autoconf_cmd;
/* return true if 'path' exists, false otherwise */
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)
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 */
static ssize_t getline_stripped(char **lineptr, size_t *n, FILE *stream)
{
ssize_t len;
len = compat_getline(lineptr, n, stream);
len = getline(lineptr, n, stream);
if (len > 0 && (*lineptr)[len - 1] == '\n') {
len--;
......@@ -371,7 +323,7 @@ int conf_read_simple(const char *name, int def)
size_t line_asize = 0;
char *p, *val;
struct symbol *sym;
int i, def_flags;
int def_flags;
const char *warn_unknown, *sym_name;
warn_unknown = getenv("KCONFIG_WARN_UNKNOWN_SYMBOLS");
......@@ -429,7 +381,7 @@ int conf_read_simple(const char *name, int def)
conf_warnings = 0;
def_flags = SYMBOL_DEF << def;
for_all_symbols(i, sym) {
for_all_symbols(sym) {
sym->flags |= SYMBOL_CHANGED;
sym->flags &= ~(def_flags|SYMBOL_VALID);
if (sym_is_choice(sym))
......@@ -538,7 +490,6 @@ int conf_read(const char *name)
{
struct symbol *sym;
int conf_unsaved = 0;
int i;
conf_set_changed(false);
......@@ -549,7 +500,7 @@ int conf_read(const char *name)
sym_calc_value(modules_sym);
for_all_symbols(i, sym) {
for_all_symbols(sym) {
sym_calc_value(sym);
if (sym_is_choice(sym) || (sym->flags & SYMBOL_NO_WRITE))
continue;
......@@ -573,7 +524,7 @@ int conf_read(const char *name)
/* 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)) {
/* Reset values of generates values, so they'll appear
* as new, if they should become visible, but that
......@@ -848,10 +799,7 @@ int conf_write_defconfig(const char *filename)
while (menu != NULL)
{
sym = menu->sym;
if (sym == NULL) {
if (!menu_is_visible(menu))
goto next_menu;
} else if (!sym_is_choice(sym)) {
if (sym && !sym_is_choice(sym)) {
sym_calc_value(sym);
if (!(sym->flags & SYMBOL_WRITE))
goto next_menu;
......@@ -911,7 +859,6 @@ int conf_write(const char *name)
const char *str;
char tmpname[PATH_MAX + 1], oldname[PATH_MAX + 1];
char *env;
int i;
bool need_newline = false;
if (!name)
......@@ -995,7 +942,7 @@ int conf_write(const char *name)
}
fclose(out);
for_all_symbols(i, sym)
for_all_symbols(sym)
sym->flags &= ~SYMBOL_WRITTEN;
if (*tmpname) {
......@@ -1023,7 +970,6 @@ int conf_write(const char *name)
static int conf_write_autoconf_cmd(const char *autoconf_name)
{
char name[PATH_MAX], tmp[PATH_MAX];
struct file *file;
FILE *out;
int ret;
......@@ -1044,15 +990,9 @@ static int conf_write_autoconf_cmd(const char *autoconf_name)
return -1;
}
fprintf(out, "deps_config := \\\n");
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);
fprintf(out, "autoconfig := %s\n", autoconf_name);
env_write_dep(out, autoconf_name);
fprintf(out, "\n$(deps_config): ;\n");
fputs(str_get(&autoconf_cmd), out);
fflush(out);
ret = ferror(out); /* error check for all fprintf() calls */
......@@ -1072,7 +1012,7 @@ static int conf_touch_deps(void)
{
const char *name, *tmp;
struct symbol *sym;
int res, i;
int res;
name = conf_get_autoconfig_name();
tmp = strrchr(name, '/');
......@@ -1086,7 +1026,7 @@ static int conf_touch_deps(void)
conf_read_simple(name, S_DEF_AUTO);
sym_calc_value(modules_sym);
for_all_symbols(i, sym) {
for_all_symbols(sym) {
sym_calc_value(sym);
if ((sym->flags & SYMBOL_NO_WRITE) || !sym->name)
continue;
......@@ -1152,7 +1092,7 @@ static int __conf_write_autoconf(const char *filename,
char tmp[PATH_MAX];
FILE *file;
struct symbol *sym;
int ret, i;
int ret;
if (make_parent_dir(filename))
return -1;
......@@ -1169,7 +1109,7 @@ static int __conf_write_autoconf(const char *filename,
conf_write_heading(file, comment_style);
for_all_symbols(i, sym)
for_all_symbols(sym)
if ((sym->flags & SYMBOL_WRITE) && sym->name)
print_symbol(file, sym);
......@@ -1192,7 +1132,7 @@ int conf_write_autoconf(int overwrite)
{
struct symbol *sym;
const char *autoconf_name = conf_get_autoconfig_name();
int ret, i;
int ret;
if (!overwrite && is_present(autoconf_name))
return 0;
......@@ -1204,7 +1144,7 @@ int conf_write_autoconf(int overwrite)
if (conf_touch_deps())
return 1;
for_all_symbols(i, sym)
for_all_symbols(sym)
sym_calc_value(sym);
ret = __conf_write_autoconf(conf_get_autoheader_name(),
......
......@@ -12,17 +12,12 @@ extern "C" {
#include <assert.h>
#include <stdio.h>
#include "list.h"
#include "list_types.h"
#ifndef __cplusplus
#include <stdbool.h>
#endif
struct file {
struct file *next;
struct file *parent;
const char *name;
int lineno;
};
#include "list_types.h"
typedef enum tristate {
no, mod, yes
......@@ -81,8 +76,8 @@ enum {
* SYMBOL_CHOICE bit set in 'flags'.
*/
struct symbol {
/* The next symbol in the same bucket in the symbol hash table */
struct symbol *next;
/* link node for the hash table */
struct hlist_node node;
/* The name of the symbol, e.g. "FOO" for 'config FOO' */
char *name;
......@@ -113,6 +108,9 @@ struct symbol {
*/
tristate visible;
/* config entries associated with this symbol */
struct list_head menus;
/* SYMBOL_* flags */
int flags;
......@@ -131,8 +129,6 @@ struct symbol {
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_CHECK 0x0008 /* used during dependency checking */
#define SYMBOL_CHOICE 0x0010 /* start of a choice block (null name) */
......@@ -157,7 +153,6 @@ struct symbol {
#define SYMBOL_NEED_SET_CHOICE_VALUES 0x100000
#define SYMBOL_MAXLENGTH 256
#define SYMBOL_HASHSIZE 9973
/* A property represent the config options that can be associated
* with a config "symbol".
......@@ -195,7 +190,7 @@ struct property {
struct menu *menu; /* the menu the property are associated with
* valid for: P_SELECT, P_RANGE, P_CHOICE,
* 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 */
};
......@@ -230,6 +225,8 @@ struct menu {
*/
struct symbol *sym;
struct list_head link; /* link to symbol::menus */
/*
* 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
......@@ -256,7 +253,7 @@ struct menu {
char *help;
/* The location where the menu node appears in the Kconfig files */
struct file *file;
const char *filename;
int lineno;
/* For use by front ends that need to store auxiliary data */
......@@ -277,10 +274,6 @@ struct jump_key {
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 *modules_sym;
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 @@
#ifndef 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;
extern struct menu *current_menu, *current_entry;
extern const char *cur_filename;
extern int cur_lineno;
#endif /* INTERNAL_H */
......@@ -14,16 +14,22 @@
#include <string.h>
#include "lkc.h"
#include "preprocess.h"
#include "parser.tab.h"
#define YY_DECL static int yylex1(void)
#define START_STRSIZE 16
static struct {
struct file *file;
int lineno;
} current_pos;
/* The Kconfig file currently being parsed. */
const char *cur_filename;
/*
* 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_token = T_EOL;
......@@ -33,6 +39,9 @@ static int text_size, text_asize;
struct buffer {
struct buffer *parent;
YY_BUFFER_STATE state;
int yylineno;
const char *filename;
int source_lineno;
};
static struct buffer *current_buf;
......@@ -77,7 +86,7 @@ static void warn_ignored_character(char chr)
{
fprintf(stderr,
"%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_-]
\n {
fprintf(stderr,
"%s:%d:warning: multi-line strings not supported\n",
zconf_curname(), zconf_lineno());
cur_filename, cur_lineno);
unput('\n');
BEGIN(INITIAL);
yylval.string = text;
......@@ -246,9 +255,9 @@ n [A-Za-z0-9_-]
if (prev_token != T_EOL && prev_token != T_HELPTEXT)
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();
return T_EOL;
}
......@@ -267,19 +276,17 @@ repeat:
token = yylex1();
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. */
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
* terminator in Kconfig, but it is not always true
* because \n could be escaped by a backslash.
*/
current_pos.file = current_file;
current_pos.lineno = yylineno;
}
cur_lineno = yylineno;
}
if (prev_prev_token == T_EOL && prev_token == T_WORD &&
......@@ -302,8 +309,11 @@ static char *expand_token(const char *in, size_t n)
new_string();
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') {
unput(c);
break;
......@@ -391,78 +401,60 @@ void zconf_initscan(const char *name)
exit(1);
}
current_buf = xmalloc(sizeof(*current_buf));
memset(current_buf, 0, sizeof(*current_buf));
current_file = file_lookup(name);
cur_filename = file_lookup(name);
yylineno = 1;
}
void zconf_nextfile(const char *name)
{
struct file *iter;
struct file *file = file_lookup(name);
struct buffer *buf = xmalloc(sizeof(*buf));
memset(buf, 0, sizeof(*buf));
bool recur_include = false;
current_buf->state = YY_CURRENT_BUFFER;
yyin = zconf_fopen(file->name);
buf->state = YY_CURRENT_BUFFER;
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) {
fprintf(stderr, "%s:%d: can't open file \"%s\"\n",
zconf_curname(), zconf_lineno(), file->name);
cur_filename, cur_lineno, name);
exit(1);
}
yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
buf->parent = current_buf;
current_buf = buf;
current_file->lineno = yylineno;
file->parent = current_file;
for (buf = current_buf; buf; buf = buf->parent) {
if (!strcmp(buf->filename, name))
recur_include = true;
}
for (iter = current_file; iter; iter = iter->parent) {
if (!strcmp(iter->name, file->name)) {
if (recur_include) {
fprintf(stderr,
"Recursive inclusion detected.\n"
"Inclusion path:\n"
" current file : %s\n", file->name);
iter = file;
do {
iter = iter->parent;
" current file : %s\n", name);
for (buf = current_buf; buf; buf = buf->parent)
fprintf(stderr, " included from: %s:%d\n",
iter->name, iter->lineno - 1);
} while (strcmp(iter->name, file->name));
buf->filename, buf->source_lineno);
exit(1);
}
}
yylineno = 1;
current_file = file;
cur_filename = file_lookup(name);
}
static void zconf_endfile(void)
{
struct buffer *parent;
current_file = current_file->parent;
if (current_file)
yylineno = current_file->lineno;
struct buffer *tmp;
parent = current_buf->parent;
if (parent) {
fclose(yyin);
yy_delete_buffer(YY_CURRENT_BUFFER);
yy_switch_to_buffer(parent->state);
}
free(current_buf);
current_buf = parent;
}
int zconf_lineno(void)
{
return current_pos.lineno;
}
const char *zconf_curname(void)
{
return current_pos.file ? current_pos.file->name : "<none>";
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,12 +2,12 @@
#ifndef LIST_H
#define LIST_H
/*
* Copied from include/linux/...
*/
#include <stddef.h>
#undef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#include "list_types.h"
/* 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
......@@ -17,14 +17,24 @@
*
*/
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
void *__mptr = (void *)(ptr); \
_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 {
struct list_head *next, *prev;
};
#define LIST_POISON1 ((void *) 0x100)
#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) }
......@@ -32,45 +42,16 @@ struct list_head {
struct list_head name = LIST_HEAD_INIT(name)
/**
* 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_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.
* INIT_LIST_HEAD - Initialize a list_head structure
* @list: list_head structure to be initialized.
*
* Initializes the list_head to point to itself. If it is a list header,
* the result is an empty list.
*/
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)
* This is only for internal list manipulation where we know
* 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 *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
next->prev = new;
new->next = next;
new->prev = prev;
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,
* Insert a new entry before the specified head.
* 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)
prev->next = next;
}
#define LIST_POISON1 ((void *) 0x00100100)
#define LIST_POISON2 ((void *) 0x00200200)
static inline void __list_del_entry(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
/**
* list_del - deletes entry from 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)
*/
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = (struct list_head*)LIST_POISON1;
entry->prev = (struct list_head*)LIST_POISON2;
__list_del_entry(entry);
entry->next = LIST_POISON1;
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;
}
#endif
/**
* 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;
}
#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);
FILE *zconf_fopen(const char *name);
void zconf_initscan(const char *name);
void zconf_nextfile(const char *name);
int zconf_lineno(void);
const char *zconf_curname(void);
/* confdata.c */
extern struct gstr autoconf_cmd;
const char *conf_get_configname(void);
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)
}
/* 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 *xcalloc(size_t nmemb, size_t size);
void *xrealloc(void *p, size_t size);
......
......@@ -18,8 +18,6 @@ void conf_set_message_callback(void (*fn)(const char *s));
bool conf_errors(void);
/* symbol.c */
extern struct symbol * symbol_hash[SYMBOL_HASHSIZE];
struct symbol * sym_lookup(const char *name, int flags);
struct symbol * sym_find(const char *name);
void print_symbol_for_listconfig(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);
/* 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 */
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,
print_buttons(dialog, height, width, 0);
wnoutrefresh(dialog);
wnoutrefresh(list);
doupdate();
wmove(list, choice, check_x + 1);
wrefresh(list);
while (key != KEY_ESC) {
key = wgetch(dialog);
......
......@@ -91,10 +91,6 @@ struct dialog_info {
struct dialog_color button_label_active;
struct dialog_color button_label_inactive;
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 menubox;
struct dialog_color menubox_border;
......
......@@ -29,10 +29,6 @@ static void set_mono_theme(void)
dlg.button_label_active.atr = A_REVERSE;
dlg.button_label_inactive.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.menubox.atr = A_NORMAL;
dlg.menubox_border.atr = A_NORMAL;
......@@ -69,10 +65,6 @@ static void set_classic_theme(void)
DLG_COLOR(button_label_active, COLOR_YELLOW, COLOR_BLUE, true);
DLG_COLOR(button_label_inactive, COLOR_BLACK, COLOR_WHITE, true);
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(menubox, COLOR_BLACK, COLOR_WHITE, false);
DLG_COLOR(menubox_border, COLOR_WHITE, COLOR_WHITE, true);
......@@ -101,14 +93,9 @@ static void set_blackbg_theme(void)
DLG_COLOR(button_key_active, COLOR_YELLOW, COLOR_RED, true);
DLG_COLOR(button_key_inactive, COLOR_RED, COLOR_BLACK, 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_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);
......@@ -136,7 +123,6 @@ static void set_bluetitle_theme(void)
DLG_COLOR(title, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(button_key_active, COLOR_YELLOW, 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(tag, COLOR_BLUE, COLOR_WHITE, true);
DLG_COLOR(tag_key, COLOR_BLUE, COLOR_WHITE, true);
......@@ -189,10 +175,6 @@ static void init_dialog_colors(void)
init_one_color(&dlg.button_label_active);
init_one_color(&dlg.button_label_inactive);
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.menubox);
init_one_color(&dlg.menubox_border);
......
......@@ -19,6 +19,7 @@
#include <signal.h>
#include <unistd.h>
#include "list.h"
#include "lkc.h"
#include "lxdialog/dialog.h"
#include "mnconf-common.h"
......
......@@ -10,20 +10,18 @@
#include "lkc.h"
#include "internal.h"
#include "list.h"
static const char nohelp_text[] = "There is no help available for this option.";
struct menu rootmenu;
static struct menu **last_entry_ptr;
struct file *file_list;
struct file *current_file;
void menu_warn(struct menu *menu, const char *fmt, ...)
{
va_list ap;
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);
fprintf(stderr, "\n");
va_end(ap);
......@@ -33,7 +31,7 @@ static void prop_warn(struct property *prop, const char *fmt, ...)
{
va_list ap;
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);
fprintf(stderr, "\n");
va_end(ap);
......@@ -53,14 +51,16 @@ void menu_add_entry(struct symbol *sym)
memset(menu, 0, sizeof(*menu));
menu->sym = sym;
menu->parent = current_menu;
menu->file = current_file;
menu->lineno = zconf_lineno();
menu->filename = cur_filename;
menu->lineno = cur_lineno;
*last_entry_ptr = menu;
last_entry_ptr = &menu->next;
current_entry = menu;
if (sym)
if (sym) {
menu_add_symbol(P_SYMBOL, sym, NULL);
list_add_tail(&menu->link, &sym->menus);
}
}
struct menu *menu_add_menu(void)
......@@ -134,8 +134,8 @@ static struct property *menu_add_prop(enum prop_type type, struct expr *expr,
prop = xmalloc(sizeof(*prop));
memset(prop, 0, sizeof(*prop));
prop->type = type;
prop->file = current_file;
prop->lineno = zconf_lineno();
prop->filename = cur_filename;
prop->lineno = cur_lineno;
prop->menu = current_entry;
prop->expr = expr;
prop->visible.expr = dep;
......@@ -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
......@@ -567,9 +561,6 @@ void menu_finalize(struct menu *parent)
if (sym->type == S_UNKNOWN)
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 */
sym_check_prop(sym);
sym->flags |= SYMBOL_WARNED;
......@@ -676,7 +667,7 @@ struct menu *menu_get_parent_menu(struct menu *menu)
static void get_def_str(struct gstr *r, struct menu *menu)
{
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)
......@@ -777,6 +768,7 @@ static void get_symbol_str(struct gstr *r, struct symbol *sym,
struct list_head *head)
{
struct property *prop;
struct menu *menu;
if (sym && 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,
}
/* Print the definitions with prompts before the ones without */
for_all_properties(sym, prop, P_SYMBOL) {
if (prop->menu->prompt) {
get_def_str(r, prop->menu);
get_prompt_str(r, prop->menu->prompt, head);
list_for_each_entry(menu, &sym->menus, link) {
if (menu->prompt) {
get_def_str(r, menu);
get_prompt_str(r, menu->prompt, head);
}
}
for_all_properties(sym, prop, P_SYMBOL) {
if (!prop->menu->prompt) {
get_def_str(r, prop->menu);
get_dep_str(r, prop->menu->dep, " Depends on: ");
list_for_each_entry(menu, &sym->menus, link) {
if (!menu->prompt) {
get_def_str(r, menu);
get_dep_str(r, menu->dep, " Depends on: ");
}
}
......
......@@ -11,6 +11,7 @@
#include <strings.h>
#include <stdlib.h>
#include "list.h"
#include "lkc.h"
#include "mnconf-common.h"
#include "nconf.h"
......
This diff is collapsed.
......@@ -9,10 +9,11 @@
#include <stdlib.h>
#include <string.h>
#include "array_size.h"
#include "internal.h"
#include "list.h"
#include "lkc.h"
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#include "preprocess.h"
static char *expand_string_with_args(const char *in, int argc, char *argv[]);
static char *expand_string(const char *in);
......@@ -21,7 +22,7 @@ static void __attribute__((noreturn)) pperror(const char *format, ...)
{
va_list ap;
fprintf(stderr, "%s:%d: ", current_file->name, yylineno);
fprintf(stderr, "%s:%d: ", cur_filename, yylineno);
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
......@@ -87,14 +88,17 @@ static char *env_expand(const char *name)
return xstrdup(value);
}
void env_write_dep(FILE *f, const char *autoconfig_name)
void env_write_dep(struct gstr *s)
{
struct env *e, *tmp;
list_for_each_entry_safe(e, tmp, &env_list, node) {
fprintf(f, "ifneq \"$(%s)\" \"%s\"\n", e->name, e->value);
fprintf(f, "%s: FORCE\n", autoconfig_name);
fprintf(f, "endif\n");
str_printf(s,
"\n"
"ifneq \"$(%s)\" \"%s\"\n"
"$(autoconfig): FORCE\n"
"endif\n",
e->name, e->value);
env_del(e);
}
}
......@@ -119,7 +123,7 @@ static char *do_error_if(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[])
......@@ -181,8 +185,7 @@ static char *do_shell(int argc, char *argv[])
static char *do_warning_if(int argc, char *argv[])
{
if (!strcmp(argv[0], "y"))
fprintf(stderr, "%s:%d: %s\n",
current_file->name, yylineno, argv[1]);
fprintf(stderr, "%s:%d: %s\n", cur_filename, yylineno, argv[1]);
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)
stream << "<br><br>";
}
stream << "defined at " << _menu->file->name << ":"
stream << "defined at " << _menu->filename << ":"
<< _menu->lineno << "<br><br>";
}
}
......
......@@ -9,23 +9,27 @@
#include <string.h>
#include <regex.h>
#include "internal.h"
#include "lkc.h"
struct symbol symbol_yes = {
.name = "y",
.curr = { "y", yes },
.menus = LIST_HEAD_INIT(symbol_yes.menus),
.flags = SYMBOL_CONST|SYMBOL_VALID,
};
struct symbol symbol_mod = {
.name = "m",
.curr = { "m", mod },
.menus = LIST_HEAD_INIT(symbol_mod.menus),
.flags = SYMBOL_CONST|SYMBOL_VALID,
};
struct symbol symbol_no = {
.name = "n",
.curr = { "n", no },
.menus = LIST_HEAD_INIT(symbol_no.menus),
.flags = SYMBOL_CONST|SYMBOL_VALID,
};
......@@ -160,9 +164,8 @@ static void sym_set_changed(struct symbol *sym)
static void sym_set_all_changed(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
for_all_symbols(sym)
sym_set_changed(sym);
}
......@@ -475,9 +478,8 @@ void sym_calc_value(struct symbol *sym)
void sym_clear_all_valid(void)
{
struct symbol *sym;
int i;
for_all_symbols(i, sym)
for_all_symbols(sym)
sym->flags &= ~SYMBOL_VALID;
conf_set_changed(true);
sym_calc_value(modules_sym);
......@@ -803,14 +805,7 @@ bool sym_is_changeable(struct symbol *sym)
return sym->visible > sym->rev_dep.tri;
}
static unsigned strhash(const char *s)
{
/* fnv32 hash */
unsigned hash = 2166136261U;
for (; *s; s++)
hash = (hash ^ *s) * 0x01000193;
return hash;
}
HASHTABLE_DEFINE(sym_hashtable, SYMBOL_HASHSIZE);
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;
}
}
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 &&
!strcmp(symbol->name, name) &&
(flags ? symbol->flags & flags
......@@ -846,9 +841,9 @@ struct symbol *sym_lookup(const char *name, int flags)
symbol->name = new_name;
symbol->type = S_UNKNOWN;
symbol->flags = flags;
INIT_LIST_HEAD(&symbol->menus);
symbol->next = symbol_hash[hash];
symbol_hash[hash] = symbol;
hash_add(sym_hashtable, &symbol->node, hash);
return symbol;
}
......@@ -868,9 +863,9 @@ struct symbol *sym_find(const char *name)
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 &&
!strcmp(symbol->name, name) &&
!(symbol->flags & SYMBOL_CONST))
......@@ -930,7 +925,7 @@ struct symbol **sym_re_search(const char *pattern)
if (regcomp(&re, pattern, REG_EXTENDED|REG_ICASE))
return NULL;
for_all_symbols(i, sym) {
for_all_symbols(sym) {
if (sym->flags & SYMBOL_CONST || !sym->name)
continue;
if (regexec(&re, sym->name, 1, match, 0))
......@@ -1041,42 +1036,42 @@ static void sym_check_print_recursive(struct symbol *last_sym)
}
if (stack->sym == last_sym)
fprintf(stderr, "%s:%d:error: recursive dependency detected!\n",
prop->file->name, prop->lineno);
prop->filename, prop->lineno);
if (sym_is_choice(sym)) {
fprintf(stderr, "%s:%d:\tchoice %s contains symbol %s\n",
menu->file->name, menu->lineno,
menu->filename, menu->lineno,
sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>");
} else if (sym_is_choice_value(sym)) {
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>",
next_sym->name ? next_sym->name : "<choice>");
} else if (stack->expr == &sym->dir_dep.expr) {
fprintf(stderr, "%s:%d:\tsymbol %s depends on %s\n",
prop->file->name, prop->lineno,
prop->filename, prop->lineno,
sym->name ? sym->name : "<choice>",
next_sym->name ? next_sym->name : "<choice>");
} else if (stack->expr == &sym->rev_dep.expr) {
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>",
next_sym->name ? next_sym->name : "<choice>");
} else if (stack->expr == &sym->implied.expr) {
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>",
next_sym->name ? next_sym->name : "<choice>");
} else if (stack->expr) {
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>",
prop_get_type_name(prop->type),
next_sym->name ? next_sym->name : "<choice>");
} else {
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>",
prop_get_type_name(prop->type),
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:
defconfig_path = os.path.join(self._test_dir, defconfig)
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:
all_config_path = os.path.join(self._test_dir, all_config)
extra_env = {'KCONFIG_ALLCONFIG': all_config_path}
else:
extra_env = {}
extra_env['KCONFIG_ALLCONFIG'] = all_config_path
return self._run_conf('--{}config'.format(mode), extra_env=extra_env)
......@@ -195,13 +193,19 @@ class Conf:
"""
return self._allconfig('alldef', all_config)
def randconfig(self, all_config=None):
def randconfig(self, all_config=None, seed=None):
"""Run randconfig.
all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
seed: the seed for randconfig (optional)
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):
"""Run savedefconfig.
......
Kconfig:11:error: recursive dependency detected!
Kconfig:11: symbol B is selected by B
Kconfig:5:error: recursive dependency detected!
Kconfig:5: symbol A depends on A
For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations"
Kconfig:5:error: recursive dependency detected!
Kconfig:5: symbol A depends on A
Kconfig:11:error: recursive dependency detected!
Kconfig:11: symbol B is selected by B
For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations"
......@@ -14,9 +14,9 @@ Kconfig:21: symbol C2 depends on C1
For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations"
Kconfig:32:error: recursive dependency detected!
Kconfig:32: symbol D2 is selected by D1
Kconfig:27:error: recursive dependency detected!
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
subsection "Kconfig recursive dependency limitations"
......@@ -26,13 +26,13 @@ Kconfig:42: symbol E2 is implied by E1
For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations"
Kconfig:60:error: recursive dependency detected!
Kconfig:60: symbol G depends on G
Kconfig:49:error: recursive dependency detected!
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
subsection "Kconfig recursive dependency limitations"
Kconfig:51:error: recursive dependency detected!
Kconfig:51: symbol F2 depends on F1
Kconfig:49: symbol F1 default value contains F2
Kconfig:60:error: recursive dependency detected!
Kconfig:60: symbol G depends on G
For a resolution refer to Documentation/kbuild/kconfig-language.rst
subsection "Kconfig recursive dependency limitations"
......@@ -7,25 +7,50 @@
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "hashtable.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 */
struct file *file_lookup(const char *name)
const char *file_lookup(const char *name)
{
struct file *file;
size_t len;
int hash = strhash(name);
for (file = file_list; file; file = file->next) {
if (!strcmp(name, file->name)) {
return file;
}
}
hash_for_each_possible(file_hashtable, file, node, hash)
if (!strcmp(name, file->name))
return file->name;
file = xmalloc(sizeof(*file));
len = strlen(name);
file = xmalloc(sizeof(*file) + len + 1);
memset(file, 0, sizeof(*file));
file->name = xstrdup(name);
file->next = file_list;
file_list = file;
return file;
memcpy(file->name, name, len);
file->name[len] = '\0';
hash_add(file_hashtable, &file->node, hash);
str_printf(&autoconf_cmd, "\t%s \\\n", name);
return file->name;
}
/* Allocate initial growable string */
......
......@@ -1050,7 +1050,9 @@ static void default_mismatch_handler(const char *modname, struct elf_info *elf,
sec_mismatch_count++;
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 (match(tosec, mismatch->bad_tosec))
......
......@@ -24,24 +24,10 @@ if_enabled_echo() {
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 () {
pname=$1
pdir=debian/$1
rm -rf ${pdir}
# Only some architectures with OF support have this target
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
......@@ -109,8 +95,6 @@ install_linux_image () {
install_linux_image_dbg () {
pdir=debian/$1
rm -rf ${pdir}
# Parse modules.order directly because 'make modules_install' may sign,
# compress modules, and then run unneeded depmod.
while read -r mod; do
......@@ -140,8 +124,6 @@ install_kernel_headers () {
pdir=debian/$1
version=${1#linux-headers-}
rm -rf $pdir
"${srctree}/scripts/package/install-extmod-build" "${pdir}/usr/src/linux-headers-${version}"
mkdir -p $pdir/lib/modules/$version/
......@@ -151,8 +133,6 @@ install_kernel_headers () {
install_libc_headers () {
pdir=debian/$1
rm -rf $pdir
$MAKE -f $srctree/Makefile headers_install INSTALL_HDR_PATH=$pdir/usr
# move asm headers to /usr/include/<libc-machine>/asm to match the structure
......@@ -161,21 +141,15 @@ install_libc_headers () {
mv "$pdir/usr/include/asm" "$pdir/usr/include/${DEB_HOST_MULTIARCH}"
}
rm -f debian/files
package=$1
packages_enabled=$(dh_listpackages)
for package in ${packages_enabled}
do
case ${package} in
*-dbg)
case "${package}" in
*-dbg)
install_linux_image_dbg "${package}";;
linux-image-*|user-mode-linux-*)
linux-image-*|user-mode-linux-*)
install_linux_image "${package}";;
linux-libc-dev)
linux-libc-dev)
install_libc_headers "${package}";;
linux-headers-*)
linux-headers-*)
install_kernel_headers "${package}";;
esac
create_package "${package}"
done
esac
......@@ -11,28 +11,73 @@ ifneq (,$(filter-out parallel=1,$(filter parallel=%,$(DEB_BUILD_OPTIONS))))
MAKEFLAGS += -j$(NUMJOBS)
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)))
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))
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
binary: binary-arch binary-indep
binary-indep: build-indep
binary-arch: build-arch
$(MAKE) $(make-opts) \
run-command KBUILD_RUN_COMMAND='+$$(srctree)/scripts/package/builddeb'
binary-arch: $(binary-targets)
$(Q)cat $(call mk-files,$^) > debian/files
.PHONY: build build-indep build-arch
build: build-arch build-indep
build-indep:
build-arch:
$(MAKE) $(make-opts) olddefconfig
$(MAKE) $(make-opts) $(if $(filter um,$(ARCH)),,headers) all
$(Q)$(MAKE) $(make-opts) olddefconfig
$(Q)$(MAKE) $(make-opts) $(if $(filter um,$(ARCH)),,headers) all
.PHONY: clean
clean:
rm -rf debian/files debian/linux-* debian/deb-env.vars*
$(MAKE) ARCH=$(ARCH) clean
$(Q)dh_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
# directly. Run 'dpkg-architecture --print-set --print-format=make' to
......@@ -41,6 +86,6 @@ ifndef DEB_HOST_ARCH
include debian/deb-env.vars
debian/deb-env.vars:
dpkg-architecture -a$$(cat debian/arch) --print-set --print-format=make > $@.tmp
mv $@.tmp $@
$(Q)dpkg-architecture -a$$(cat debian/arch) --print-set --print-format=make > $@.tmp
$(Q)mv $@.tmp $@
endif
......@@ -61,11 +61,37 @@ cp $(%{make} %{makeflags} -s image_name) %{buildroot}/lib/modules/%{KERNELRELEAS
%{make} %{makeflags} INSTALL_HDR_PATH=%{buildroot}/usr headers_install
cp System.map %{buildroot}/lib/modules/%{KERNELRELEASE}
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
%if %{with_devel}
%{make} %{makeflags} run-command KBUILD_RUN_COMMAND='${srctree}/scripts/package/install-extmod-build %{buildroot}/usr/src/kernels/%{KERNELRELEASE}'
%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
rm -rf %{buildroot}
......@@ -78,23 +104,23 @@ for file in vmlinuz System.map config; do
cp "/lib/modules/%{KERNELRELEASE}/${file}" "/boot/${file}-%{KERNELRELEASE}"
fi
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
if [ -x /sbin/new-kernel-pkg ]; then
new-kernel-pkg --remove %{KERNELRELEASE} --rminitrd --initrdfile=/boot/initramfs-%{KERNELRELEASE}.img
elif [ -x /usr/bin/kernel-install ]; then
if [ -x /usr/bin/kernel-install ]; then
kernel-install remove %{KERNELRELEASE}
fi
%postun
if [ -x /sbin/update-bootloader ]; then
/sbin/update-bootloader --remove %{KERNELRELEASE}
fi
%files
%files -f %{buildroot}/kernel.list
%defattr (-, root, root)
/lib/modules/%{KERNELRELEASE}
%exclude /lib/modules/%{KERNELRELEASE}/build
%exclude /kernel.list
%files headers
%defattr (-, root, root)
......
......@@ -2,7 +2,7 @@
# Most of this file is copied from tools/lib/traceevent/Makefile
RM ?= rm
srctree = $(abs_srctree)
srctree := $(realpath $(srctree))
VERSION_SCRIPT := libbpf.map
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