hostprogs     := lxdialog
                always-y      := $(hostprogs)
 
+       Kbuild provides the following shorthand for this:
+
+               hostprogs-always-y := lxdialog
+
        This will tell kbuild to build lxdialog even if not referenced in
        any rule.
 
 5.4 When userspace programs are actually built
 ----------------------------------------------
 
-       Same as "When host programs are actually built".
+       Kbuild builds userspace programs only when told to do so.
+       There are two ways to do this.
+
+       (1) Add it as the prerequisite of another file
+
+       Example::
+
+               #net/bpfilter/Makefile
+               userprogs := bpfilter_umh
+               $(obj)/bpfilter_umh_blob.o: $(obj)/bpfilter_umh
+
+       $(obj)/bpfilter_umh is built before $(obj)/bpfilter_umh_blob.o
+
+       (2) Use always-y
+
+       Example::
+
+               userprogs := binderfs_example
+               always-y := $(userprogs)
+
+       Kbuild provides the following shorthand for this:
+
+               userprogs-always-y := binderfs_example
+
+       This will tell Kbuild to build binderfs_example when it visits this
+       Makefile.
 
 6 Kbuild clean infrastructure
 =============================
 
 # SPDX-License-Identifier: GPL-2.0
-userprogs := cfag12864b-example
-always-y := $(userprogs)
+userprogs-always-y += cfag12864b-example
 
 # SPDX-License-Identifier: GPL-2.0-only
-userprogs := binderfs_example
-always-y := $(userprogs)
+userprogs-always-y += binderfs_example
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_SAMPLE_CONNECTOR) += cn_test.o
 
-userprogs := ucon
-always-$(CONFIG_CC_CAN_LINK) := $(userprogs)
+userprogs-always-$(CONFIG_CC_CAN_LINK) += ucon
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0
-userprogs := hid-example
-always-y := $(userprogs)
+userprogs-always-y += hid-example
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0
 # Copyright (c) 2012-2019, Intel Corporation. All rights reserved.
-
-userprogs := mei-amt-version
-always-y := $(userprogs)
+userprogs-always-y += mei-amt-version
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0
-
-usertprogs := pidfd-metadata
-always-y := $(userprogs)
+usertprogs-always-y += pidfd-metadata
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0
-userprogs := bpf-fancy dropper bpf-direct user-trap
+userprogs-always-y += bpf-fancy dropper bpf-direct user-trap
 
 bpf-fancy-objs := bpf-fancy.o bpf-helper.o
 
 userccflags += -I usr/include
-
-always-y := $(userprogs)
 
 # SPDX-License-Identifier: GPL-2.0
-userprogs := hpet_example
-always-y := $(userprogs)
+userprogs-always-y += hpet_example
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0-only
-userprogs := uhid-example
-always-y := $(userprogs)
+userprogs-always-y += uhid-example
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0-only
-userprogs := test-fsmount test-statx
-always-y := $(userprogs)
+userprogs-always-y += test-fsmount test-statx
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0-only
-userprogs := watch_test
-always-y := $(userprogs)
+userprogs-always-y += watch_test
 
 userccflags += -I usr/include
 
 # SPDX-License-Identifier: GPL-2.0
-userprogs := watchdog-simple
-always-y := $(userprogs)
+userprogs-always-y += watchdog-simple
 
 # scripts contains sources for various helper programs used throughout
 # the kernel for the build process.
 
-always-$(CONFIG_BUILD_BIN2C)                   += bin2c
-always-$(CONFIG_KALLSYMS)                      += kallsyms
-always-$(BUILD_C_RECORDMCOUNT)                 += recordmcount
-always-$(CONFIG_BUILDTIME_TABLE_SORT)          += sorttable
-always-$(CONFIG_ASN1)                          += asn1_compiler
-always-$(CONFIG_MODULE_SIG_FORMAT)             += sign-file
-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING)                += extract-cert
-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE)      += insert-sys-cert
+hostprogs-always-$(CONFIG_BUILD_BIN2C)                 += bin2c
+hostprogs-always-$(CONFIG_KALLSYMS)                    += kallsyms
+hostprogs-always-$(BUILD_C_RECORDMCOUNT)               += recordmcount
+hostprogs-always-$(CONFIG_BUILDTIME_TABLE_SORT)                += sorttable
+hostprogs-always-$(CONFIG_ASN1)                                += asn1_compiler
+hostprogs-always-$(CONFIG_MODULE_SIG_FORMAT)           += sign-file
+hostprogs-always-$(CONFIG_SYSTEM_TRUSTED_KEYRING)      += extract-cert
+hostprogs-always-$(CONFIG_SYSTEM_EXTRA_CERTIFICATE)    += insert-sys-cert
 
 HOSTCFLAGS_sorttable.o = -I$(srctree)/tools/include
 HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include
 HOSTLDLIBS_sorttable = -lpthread
 endif
 
-hostprogs := $(always-y) $(always-m)
-
 # The following programs are only built on demand
 hostprogs += unifdef
 
 
 # build a list of files to remove, usually relative to the current
 # directory
 
-__clean-files  := $(extra-y) $(extra-m) $(extra-)       \
-                  $(always) $(always-y) $(always-m) $(always-) $(targets) $(clean-files)   \
-                  $(hostprogs) $(hostprogs-y) $(hostprogs-m) $(hostprogs-) $(userprogs)
+__clean-files  := \
+       $(clean-files) $(targets) $(hostprogs) $(userprogs) \
+       $(extra-y) $(extra-m) $(extra-) \
+       $(always-y) $(always-m) $(always-) \
+       $(hostprogs-always-y) $(hostprogs-always-m) $(hostprogs-always-) \
+       $(userprogs-always-y) $(userprogs-always-m) $(userprogs-always-)
+
+# deprecated
+__clean-files  += $(always) $(hostprogs-y) $(hostprogs-m) $(hostprogs-)
 
 __clean-files   := $(filter-out $(no-clean-files), $(__clean-files))
 
 
 
 always-y += $(always-m)
 
+# hostprogs-always-y += foo
+# ... is a shorthand for
+# hostprogs += foo
+# always-y  += foo
+hostprogs += $(hostprogs-always-y) $(hostprogs-always-m)
+always-y += $(hostprogs-always-y) $(hostprogs-always-m)
+
+# userprogs-always-y is likewise.
+userprogs += $(userprogs-always-y) $(userprogs-always-m)
+always-y += $(userprogs-always-y) $(userprogs-always-m)
+
 # DTB
 # If CONFIG_OF_ALL_DTBS is enabled, all DT blobs are built
 extra-y                                += $(dtb-y)
 
 #
 # fixdep: used to generate dependency information during build process
 
-hostprogs      := fixdep
-always-y       := $(hostprogs)
+hostprogs-always-y     += fixdep
 
 # SPDX-License-Identifier: GPL-2.0
 # scripts/dtc makefile
 
-hostprogs                      := dtc
-always-$(CONFIG_DTC)           += $(hostprogs)
-always-$(CHECK_DT_BINDING)     += $(hostprogs)
+hostprogs-always-$(CONFIG_DTC)         += dtc
+hostprogs-always-$(CHECK_DT_BINDING)   += dtc
 
 dtc-objs       := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
                   srcpos.o checks.o util.o
 
 # SPDX-License-Identifier: GPL-2.0
 
-hostprogs      := genksyms
-always-y       := $(hostprogs)
+hostprogs-always-y     += genksyms
 
 genksyms-objs  := genksyms.o parse.tab.o lex.lex.o
 
 
 # SPDX-License-Identifier: GPL-2.0
 OBJECT_FILES_NON_STANDARD := y
 
-hostprogs      := modpost mk_elfconfig
-always-y       := $(hostprogs) empty.o
+hostprogs-always-y     += modpost mk_elfconfig
+always-y               += empty.o
 
 modpost-objs   := modpost.o file2alias.o sumversion.o
 
 
 # SPDX-License-Identifier: GPL-2.0
-hostprogs      := genheaders
+hostprogs-always-y += genheaders
 HOST_EXTRACFLAGS += \
        -I$(srctree)/include/uapi -I$(srctree)/include \
        -I$(srctree)/security/selinux/include
-
-always-y       := $(hostprogs)
 
 # SPDX-License-Identifier: GPL-2.0
-hostprogs      := mdp
+hostprogs-always-y += mdp
 HOST_EXTRACFLAGS += \
        -I$(srctree)/include/uapi -I$(srctree)/include \
        -I$(srctree)/security/selinux/include -I$(objtree)/include
 
-always-y       := $(hostprogs)
 clean-files    := policy.* file_contexts