xref: /linux/scripts/bash-completion/make (revision bbfd5594756011167b8f8de9a00e0c946afda1e6)
1*eb47ee01SMasahiro Yamada# SPDX-License-Identifier: GPL-2.0-only
2*eb47ee01SMasahiro Yamada# bash completion for GNU make with kbuild extension       -*- shell-script -*-
3*eb47ee01SMasahiro Yamada
4*eb47ee01SMasahiro Yamada# Load the default completion script for make. It is typically located at
5*eb47ee01SMasahiro Yamada# /usr/share/bash-completion/completions/make, but we do not rely on it.
6*eb47ee01SMasahiro Yamada__kbuild_load_default_make_completion()
7*eb47ee01SMasahiro Yamada{
8*eb47ee01SMasahiro Yamada	local -a dirs=("${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions")
9*eb47ee01SMasahiro Yamada	local ifs=$IFS IFS=: dir compfile this_dir
10*eb47ee01SMasahiro Yamada
11*eb47ee01SMasahiro Yamada	for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do
12*eb47ee01SMasahiro Yamada	        dirs+=("$dir"/bash-completion/completions)
13*eb47ee01SMasahiro Yamada	done
14*eb47ee01SMasahiro Yamada	IFS=$ifs
15*eb47ee01SMasahiro Yamada
16*eb47ee01SMasahiro Yamada	this_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
17*eb47ee01SMasahiro Yamada
18*eb47ee01SMasahiro Yamada	for dir in "${dirs[@]}"; do
19*eb47ee01SMasahiro Yamada		if [[ ! -d ${dir} || ${dir} = "${this_dir}" ]]; then
20*eb47ee01SMasahiro Yamada			continue
21*eb47ee01SMasahiro Yamada		fi
22*eb47ee01SMasahiro Yamada
23*eb47ee01SMasahiro Yamada		for compfile in make make.bash _make; do
24*eb47ee01SMasahiro Yamada			compfile=$dir/$compfile
25*eb47ee01SMasahiro Yamada			# Avoid trying to source dirs; https://bugzilla.redhat.com/903540
26*eb47ee01SMasahiro Yamada			if [[ -f ${compfile} ]] && . "${compfile}" &>/dev/null; then
27*eb47ee01SMasahiro Yamada
28*eb47ee01SMasahiro Yamada				__kbuild_default_make_completion=$(
29*eb47ee01SMasahiro Yamada					# shellcheck disable=SC2046 # word splitting is the point here
30*eb47ee01SMasahiro Yamada					set -- $(complete -p make)
31*eb47ee01SMasahiro Yamada
32*eb47ee01SMasahiro Yamada					while [[ $# -gt 1 && "$1" != -F ]]; do
33*eb47ee01SMasahiro Yamada						shift
34*eb47ee01SMasahiro Yamada					done
35*eb47ee01SMasahiro Yamada
36*eb47ee01SMasahiro Yamada					if [[ "$1" = -F ]]; then
37*eb47ee01SMasahiro Yamada						echo "$2"
38*eb47ee01SMasahiro Yamada					fi
39*eb47ee01SMasahiro Yamada				)
40*eb47ee01SMasahiro Yamada
41*eb47ee01SMasahiro Yamada				return
42*eb47ee01SMasahiro Yamada			fi
43*eb47ee01SMasahiro Yamada		done
44*eb47ee01SMasahiro Yamada	done
45*eb47ee01SMasahiro Yamada}
46*eb47ee01SMasahiro Yamada
47*eb47ee01SMasahiro Yamada__kbuild_load_default_make_completion
48*eb47ee01SMasahiro Yamada
49*eb47ee01SMasahiro Yamada__kbuild_handle_variable()
50*eb47ee01SMasahiro Yamada{
51*eb47ee01SMasahiro Yamada	local var=${1%%=*}
52*eb47ee01SMasahiro Yamada	local cur=${cur#"${var}"=}
53*eb47ee01SMasahiro Yamada	local srctree=$2
54*eb47ee01SMasahiro Yamada	local keywords=()
55*eb47ee01SMasahiro Yamada
56*eb47ee01SMasahiro Yamada	case $var in
57*eb47ee01SMasahiro Yamada	ARCH)
58*eb47ee01SMasahiro Yamada		# sub-directories under arch/
59*eb47ee01SMasahiro Yamada		keywords+=($(find "${srctree}/arch" -mindepth 1 -maxdepth 1 -type d -printf '%P\n'))
60*eb47ee01SMasahiro Yamada		# architectures hard-coded in the top Makefile
61*eb47ee01SMasahiro Yamada		keywords+=(i386 x86_64 sparc32 sparc64 parisc64)
62*eb47ee01SMasahiro Yamada		;;
63*eb47ee01SMasahiro Yamada	CROSS_COMPILE)
64*eb47ee01SMasahiro Yamada		# toolchains with a full path
65*eb47ee01SMasahiro Yamada		local cross_compile=()
66*eb47ee01SMasahiro Yamada		local c c2
67*eb47ee01SMasahiro Yamada		_filedir
68*eb47ee01SMasahiro Yamada
69*eb47ee01SMasahiro Yamada		for c in "${COMPREPLY[@]}"; do
70*eb47ee01SMasahiro Yamada			# eval for tilde expansion
71*eb47ee01SMasahiro Yamada			# suppress error, as this fails when it contains a space
72*eb47ee01SMasahiro Yamada			eval "c2=${c}" 2>/dev/null || continue
73*eb47ee01SMasahiro Yamada			if [[ ${c} == *-elfedit && ! -d ${c2} && -x ${c2} ]]; then
74*eb47ee01SMasahiro Yamada				cross_compile+=("${c%elfedit}")
75*eb47ee01SMasahiro Yamada			fi
76*eb47ee01SMasahiro Yamada		done
77*eb47ee01SMasahiro Yamada
78*eb47ee01SMasahiro Yamada		# toolchains in the PATH environment
79*eb47ee01SMasahiro Yamada		while read -r c; do
80*eb47ee01SMasahiro Yamada			if [[ ${c} == *-elfedit ]]; then
81*eb47ee01SMasahiro Yamada				keywords+=("${c%elfedit}")
82*eb47ee01SMasahiro Yamada			fi
83*eb47ee01SMasahiro Yamada		done < <(compgen -c)
84*eb47ee01SMasahiro Yamada
85*eb47ee01SMasahiro Yamada		COMPREPLY=()
86*eb47ee01SMasahiro Yamada		_filedir -d
87*eb47ee01SMasahiro Yamada
88*eb47ee01SMasahiro Yamada		# Add cross_compile directly without passing it to compgen.
89*eb47ee01SMasahiro Yamada		# Otherwise, toolchain paths with a tilde do not work.
90*eb47ee01SMasahiro Yamada		# e.g.)
91*eb47ee01SMasahiro Yamada		#   CROSS_COMPILE=~/0day/gcc-14.2.0-nolibc/aarch64-linux/bin/aarch64-linux-
92*eb47ee01SMasahiro Yamada		COMPREPLY+=("${cross_compile[@]}")
93*eb47ee01SMasahiro Yamada		;;
94*eb47ee01SMasahiro Yamada	LLVM)
95*eb47ee01SMasahiro Yamada		# LLVM=1 uses the default 'clang' etc.
96*eb47ee01SMasahiro Yamada		keywords+=(1)
97*eb47ee01SMasahiro Yamada
98*eb47ee01SMasahiro Yamada		# suffix for a particular version. LLVM=-18 uses 'clang-18' etc.
99*eb47ee01SMasahiro Yamada		while read -r c; do
100*eb47ee01SMasahiro Yamada			if [[ ${c} == clang-[0-9]* ]]; then
101*eb47ee01SMasahiro Yamada				keywords+=("${c#clang}")
102*eb47ee01SMasahiro Yamada			fi
103*eb47ee01SMasahiro Yamada		done < <(compgen -c)
104*eb47ee01SMasahiro Yamada
105*eb47ee01SMasahiro Yamada		# directory path to LLVM toolchains
106*eb47ee01SMasahiro Yamada		_filedir -d
107*eb47ee01SMasahiro Yamada		;;
108*eb47ee01SMasahiro Yamada	KCONFIG_ALLCONFIG)
109*eb47ee01SMasahiro Yamada		# KCONFIG_ALLCONFIG=1 selects the default fragment
110*eb47ee01SMasahiro Yamada		keywords+=(1)
111*eb47ee01SMasahiro Yamada		# or the path to a fragment file
112*eb47ee01SMasahiro Yamada		_filedir
113*eb47ee01SMasahiro Yamada		;;
114*eb47ee01SMasahiro Yamada	C | KBUILD_CHECKSRC)
115*eb47ee01SMasahiro Yamada		keywords+=(1 2)
116*eb47ee01SMasahiro Yamada		;;
117*eb47ee01SMasahiro Yamada	V | KBUILD_VERBOSE)
118*eb47ee01SMasahiro Yamada		keywords+=({,1}{,2})
119*eb47ee01SMasahiro Yamada		;;
120*eb47ee01SMasahiro Yamada	W | KBUILD_EXTRA_WARN)
121*eb47ee01SMasahiro Yamada		keywords+=({,1}{,2}{,3}{,c}{,e})
122*eb47ee01SMasahiro Yamada		;;
123*eb47ee01SMasahiro Yamada	KBUILD_ABS_SRCTREE | KBUILD_MODPOST_NOFINAL | KBUILD_MODPOST_WARN | \
124*eb47ee01SMasahiro Yamada		CLIPPY | KBUILD_CLIPPY | KCONFIG_NOSILENTUPDATE | \
125*eb47ee01SMasahiro Yamada		KCONFIG_OVERWRITECONFIG | KCONFIG_WARN_UNKNOWN_SYMBOL | \
126*eb47ee01SMasahiro Yamada		KCONFIG_WERROR )
127*eb47ee01SMasahiro Yamada		keywords+=(1)
128*eb47ee01SMasahiro Yamada		;;
129*eb47ee01SMasahiro Yamada	INSTALL_MOD_STRIP)
130*eb47ee01SMasahiro Yamada		keywords+=(1 --strip-debug --strip-unneeded)
131*eb47ee01SMasahiro Yamada		;;
132*eb47ee01SMasahiro Yamada	O | KBUILD_OUTPUT | M | KBUILD_EXTMOD | MO | KBUILD_EXTMOD_OUTPUT | *_PATH)
133*eb47ee01SMasahiro Yamada		# variables that take a directory.
134*eb47ee01SMasahiro Yamada		_filedir -d
135*eb47ee01SMasahiro Yamada		return
136*eb47ee01SMasahiro Yamada		;;
137*eb47ee01SMasahiro Yamada	KBUILD_EXTRA_SYMBOL | KBUILD_KCONFIG | KCONFIG_CONFIG)
138*eb47ee01SMasahiro Yamada		# variables that take a file.
139*eb47ee01SMasahiro Yamada		_filedir
140*eb47ee01SMasahiro Yamada		return
141*eb47ee01SMasahiro Yamada	esac
142*eb47ee01SMasahiro Yamada
143*eb47ee01SMasahiro Yamada	COMPREPLY+=($(compgen -W "${keywords[*]}" -- "${cur}"))
144*eb47ee01SMasahiro Yamada}
145*eb47ee01SMasahiro Yamada
146*eb47ee01SMasahiro Yamada# Check the -C, -f options and 'source' symlink. Return the source tree we are
147*eb47ee01SMasahiro Yamada# working in.
148*eb47ee01SMasahiro Yamada__kbuild_get_srctree()
149*eb47ee01SMasahiro Yamada{
150*eb47ee01SMasahiro Yamada	local words=("$@")
151*eb47ee01SMasahiro Yamada	local cwd makef_dir
152*eb47ee01SMasahiro Yamada
153*eb47ee01SMasahiro Yamada	# see if a path was specified with -C/--directory
154*eb47ee01SMasahiro Yamada	for ((i = 1; i < ${#words[@]}; i++)); do
155*eb47ee01SMasahiro Yamada		if [[ ${words[i]} == -@(C|-directory) ]]; then
156*eb47ee01SMasahiro Yamada			# eval for tilde expansion.
157*eb47ee01SMasahiro Yamada			# suppress error, as this fails when it contains a space
158*eb47ee01SMasahiro Yamada			eval "cwd=${words[i + 1]}" 2>/dev/null
159*eb47ee01SMasahiro Yamada			break
160*eb47ee01SMasahiro Yamada		fi
161*eb47ee01SMasahiro Yamada	done
162*eb47ee01SMasahiro Yamada
163*eb47ee01SMasahiro Yamada	if [[ -z ${cwd} ]]; then
164*eb47ee01SMasahiro Yamada		cwd=.
165*eb47ee01SMasahiro Yamada	fi
166*eb47ee01SMasahiro Yamada
167*eb47ee01SMasahiro Yamada	# see if a Makefile was specified with -f/--file/--makefile
168*eb47ee01SMasahiro Yamada	for ((i = 1; i < ${#words[@]}; i++)); do
169*eb47ee01SMasahiro Yamada		if [[ ${words[i]} == -@(f|-?(make)file) ]]; then
170*eb47ee01SMasahiro Yamada			# eval for tilde expansion
171*eb47ee01SMasahiro Yamada			# suppress error, as this fails when it contains a space
172*eb47ee01SMasahiro Yamada			eval "makef_dir=${words[i + 1]%/*}" 2>/dev/null
173*eb47ee01SMasahiro Yamada			break
174*eb47ee01SMasahiro Yamada		fi
175*eb47ee01SMasahiro Yamada	done
176*eb47ee01SMasahiro Yamada
177*eb47ee01SMasahiro Yamada	if [ -z "${makef_dir}" ]; then
178*eb47ee01SMasahiro Yamada		makef_dir=${cwd}
179*eb47ee01SMasahiro Yamada	elif [[ ${makef_dir} != /* ]]; then
180*eb47ee01SMasahiro Yamada		makef_dir=${cwd}/${makef_dir}
181*eb47ee01SMasahiro Yamada	fi
182*eb47ee01SMasahiro Yamada
183*eb47ee01SMasahiro Yamada	# If ${makef_dir} is a build directory created by the O= option, there
184*eb47ee01SMasahiro Yamada	# is a symbolic link 'source', which points to the kernel source tree.
185*eb47ee01SMasahiro Yamada	if [[ -L ${makef_dir}/source ]]; then
186*eb47ee01SMasahiro Yamada		makef_dir=$(readlink "${makef_dir}/source")
187*eb47ee01SMasahiro Yamada	fi
188*eb47ee01SMasahiro Yamada
189*eb47ee01SMasahiro Yamada	echo "${makef_dir}"
190*eb47ee01SMasahiro Yamada}
191*eb47ee01SMasahiro Yamada
192*eb47ee01SMasahiro Yamada# Get SRCARCH to do a little more clever things
193*eb47ee01SMasahiro Yamada__kbuild_get_srcarch()
194*eb47ee01SMasahiro Yamada{
195*eb47ee01SMasahiro Yamada	local words=("$@")
196*eb47ee01SMasahiro Yamada	local arch srcarch uname_m
197*eb47ee01SMasahiro Yamada
198*eb47ee01SMasahiro Yamada	# see if ARCH= is explicitly specified
199*eb47ee01SMasahiro Yamada	for ((i = 1; i < ${#words[@]}; i++)); do
200*eb47ee01SMasahiro Yamada		if [[ ${words[i]} == ARCH=* ]]; then
201*eb47ee01SMasahiro Yamada			arch=${words[i]#ARCH=}
202*eb47ee01SMasahiro Yamada			break
203*eb47ee01SMasahiro Yamada		fi
204*eb47ee01SMasahiro Yamada	done
205*eb47ee01SMasahiro Yamada
206*eb47ee01SMasahiro Yamada	# If ARCH= is not specified, check the build marchine's architecture
207*eb47ee01SMasahiro Yamada	if [[ -z ${arch} ]]; then
208*eb47ee01SMasahiro Yamada		uname_m=$(uname -m)
209*eb47ee01SMasahiro Yamada
210*eb47ee01SMasahiro Yamada		# shellcheck disable=SC2209 # 'sh' is SuperH, not a shell command
211*eb47ee01SMasahiro Yamada		case ${uname_m} in
212*eb47ee01SMasahiro Yamada		arm64 | aarch64*) arch=arm64 ;;
213*eb47ee01SMasahiro Yamada		arm* | sa110)     arch=arm ;;
214*eb47ee01SMasahiro Yamada		i?86 | x86_64)    arch=x86 ;;
215*eb47ee01SMasahiro Yamada		loongarch*)       arch=loongarch ;;
216*eb47ee01SMasahiro Yamada		mips*)            arch=mips ;;
217*eb47ee01SMasahiro Yamada		ppc*)             arch=powerpc ;;
218*eb47ee01SMasahiro Yamada		riscv*)           arch=riscv ;;
219*eb47ee01SMasahiro Yamada		s390x)            arch=s390 ;;
220*eb47ee01SMasahiro Yamada		sh[234]*)         arch=sh ;;
221*eb47ee01SMasahiro Yamada		sun4u)            arch=sparc64 ;;
222*eb47ee01SMasahiro Yamada		*)                arch=${uname_m} ;;
223*eb47ee01SMasahiro Yamada		esac
224*eb47ee01SMasahiro Yamada	fi
225*eb47ee01SMasahiro Yamada
226*eb47ee01SMasahiro Yamada	case ${arch} in
227*eb47ee01SMasahiro Yamada		parisc64)          srcarch=parisc ;;
228*eb47ee01SMasahiro Yamada		sparc32 | sparc64) srcarch=sparc ;;
229*eb47ee01SMasahiro Yamada		i386 | x86_64)     srcarch=x86 ;;
230*eb47ee01SMasahiro Yamada		*)                 srcarch=${arch} ;;
231*eb47ee01SMasahiro Yamada	esac
232*eb47ee01SMasahiro Yamada
233*eb47ee01SMasahiro Yamada	echo "$srcarch"
234*eb47ee01SMasahiro Yamada}
235*eb47ee01SMasahiro Yamada
236*eb47ee01SMasahiro Yamada# small Makefile to parse obj-* syntax
237*eb47ee01SMasahiro Yamada__kbuild_tmp_makefile()
238*eb47ee01SMasahiro Yamada{
239*eb47ee01SMasahiro Yamadacat <<'EOF'
240*eb47ee01SMasahiro Yamada.PHONY: __default
241*eb47ee01SMasahiro Yamada__default:
242*eb47ee01SMasahiro Yamada	$(foreach m,$(obj-y) $(obj-m) $(obj-),$(foreach s, -objs -y -m -,$($(m:%.o=%$s))) $(m))
243*eb47ee01SMasahiro YamadaEOF
244*eb47ee01SMasahiro Yamadaecho "include ${1}"
245*eb47ee01SMasahiro Yamada}
246*eb47ee01SMasahiro Yamada
247*eb47ee01SMasahiro Yamada_make_for_kbuild ()
248*eb47ee01SMasahiro Yamada{
249*eb47ee01SMasahiro Yamada	# shellcheck disable=SC2034 # these are set by _init_completion
250*eb47ee01SMasahiro Yamada	local cur prev words cword split
251*eb47ee01SMasahiro Yamada	_init_completion -s || return
252*eb47ee01SMasahiro Yamada
253*eb47ee01SMasahiro Yamada	local srctree
254*eb47ee01SMasahiro Yamada	srctree=$(__kbuild_get_srctree "${words[@]}")
255*eb47ee01SMasahiro Yamada
256*eb47ee01SMasahiro Yamada	# If 'kernel' and 'Documentation' directories are found, we assume this
257*eb47ee01SMasahiro Yamada	# is a kernel tree. Otherwise, we fall back to the generic rule provided
258*eb47ee01SMasahiro Yamada	# by the bash-completion project.
259*eb47ee01SMasahiro Yamada	if [[ ! -d ${srctree}/kernel || ! -d ${srctree}/Documentation ]]; then
260*eb47ee01SMasahiro Yamada		if [ -n "${__kbuild_default_make_completion}" ]; then
261*eb47ee01SMasahiro Yamada			"${__kbuild_default_make_completion}" "$@"
262*eb47ee01SMasahiro Yamada		fi
263*eb47ee01SMasahiro Yamada		return
264*eb47ee01SMasahiro Yamada	fi
265*eb47ee01SMasahiro Yamada
266*eb47ee01SMasahiro Yamada	# make options with a parameter (copied from the bash-completion project)
267*eb47ee01SMasahiro Yamada	case ${prev} in
268*eb47ee01SMasahiro Yamada	--file | --makefile | --old-file | --assume-old | --what-if | --new-file | \
269*eb47ee01SMasahiro Yamada		--assume-new | -!(-*)[foW])
270*eb47ee01SMasahiro Yamada		_filedir
271*eb47ee01SMasahiro Yamada		return
272*eb47ee01SMasahiro Yamada		;;
273*eb47ee01SMasahiro Yamada	--include-dir | --directory | -!(-*)[ICm])
274*eb47ee01SMasahiro Yamada		_filedir -d
275*eb47ee01SMasahiro Yamada		return
276*eb47ee01SMasahiro Yamada		;;
277*eb47ee01SMasahiro Yamada	-!(-*)E)
278*eb47ee01SMasahiro Yamada		COMPREPLY=($(compgen -v -- "$cur"))
279*eb47ee01SMasahiro Yamada		return
280*eb47ee01SMasahiro Yamada		;;
281*eb47ee01SMasahiro Yamada	--eval | -!(-*)[DVx])
282*eb47ee01SMasahiro Yamada		return
283*eb47ee01SMasahiro Yamada		;;
284*eb47ee01SMasahiro Yamada	--jobs | -!(-*)j)
285*eb47ee01SMasahiro Yamada		COMPREPLY=($(compgen -W "{1..$(($(_ncpus) * 2))}" -- "$cur"))
286*eb47ee01SMasahiro Yamada		return
287*eb47ee01SMasahiro Yamada		;;
288*eb47ee01SMasahiro Yamada	esac
289*eb47ee01SMasahiro Yamada
290*eb47ee01SMasahiro Yamada	local keywords=()
291*eb47ee01SMasahiro Yamada
292*eb47ee01SMasahiro Yamada	case ${cur} in
293*eb47ee01SMasahiro Yamada	-*)
294*eb47ee01SMasahiro Yamada		# make options (copied from the bash-completion project)
295*eb47ee01SMasahiro Yamada		local opts
296*eb47ee01SMasahiro Yamada		opts="$(_parse_help "$1")"
297*eb47ee01SMasahiro Yamada		COMPREPLY=($(compgen -W "${opts:-$(_parse_usage "$1")}" -- "$cur"))
298*eb47ee01SMasahiro Yamada		if [[ ${COMPREPLY-} == *= ]]; then
299*eb47ee01SMasahiro Yamada			compopt -o nospace
300*eb47ee01SMasahiro Yamada		fi
301*eb47ee01SMasahiro Yamada		return
302*eb47ee01SMasahiro Yamada		;;
303*eb47ee01SMasahiro Yamada	*=*)
304*eb47ee01SMasahiro Yamada		__kbuild_handle_variable "${cur}" "${srctree}"
305*eb47ee01SMasahiro Yamada		return
306*eb47ee01SMasahiro Yamada		;;
307*eb47ee01SMasahiro Yamada	KBUILD_*)
308*eb47ee01SMasahiro Yamada		# There are many variables prefixed with 'KBUILD_'.
309*eb47ee01SMasahiro Yamada		# Display them only when 'KBUILD_' is entered.
310*eb47ee01SMasahiro Yamada		# shellcheck disable=SC2191 # '=' is appended for variables
311*eb47ee01SMasahiro Yamada		keywords+=(
312*eb47ee01SMasahiro Yamada			KBUILD_{CHECKSRC,EXTMOD,EXTMOD_OUTPUT,OUTPUT,VERBOSE,EXTRA_WARN,CLIPPY}=
313*eb47ee01SMasahiro Yamada			KBUILD_BUILD_{USER,HOST,TIMESTAMP}=
314*eb47ee01SMasahiro Yamada			KBUILD_MODPOST_{NOFINAL,WARN}=
315*eb47ee01SMasahiro Yamada			KBUILD_{ABS_SRCTREE,EXTRA_SYMBOLS,KCONFIG}=
316*eb47ee01SMasahiro Yamada		)
317*eb47ee01SMasahiro Yamada		;;
318*eb47ee01SMasahiro Yamada	KCONFIG_*)
319*eb47ee01SMasahiro Yamada		# There are many variables prefixed with 'KCONFIG_'.
320*eb47ee01SMasahiro Yamada		# Display them only when 'KCONFIG_' is entered.
321*eb47ee01SMasahiro Yamada		# shellcheck disable=SC2191 # '=' is appended for variables
322*eb47ee01SMasahiro Yamada		keywords+=(
323*eb47ee01SMasahiro Yamada			KCONFIG_{CONFIG,ALLCONFIG,NOSILENTUPDATE,OVERWRITECONFIG}=
324*eb47ee01SMasahiro Yamada			KCONFIG_{SEED,PROBABILITY}=
325*eb47ee01SMasahiro Yamada			KCONFIG_WARN_UNKNOWN_SYMBOL=
326*eb47ee01SMasahiro Yamada			KCONFIG_WERROR=
327*eb47ee01SMasahiro Yamada		)
328*eb47ee01SMasahiro Yamada		;;
329*eb47ee01SMasahiro Yamada	*)
330*eb47ee01SMasahiro Yamada		# By default, hide KBUILD_* and KCONFIG_* variables.
331*eb47ee01SMasahiro Yamada		# Instead, display only the prefix parts.
332*eb47ee01SMasahiro Yamada		keywords+=(KBUILD_ KCONFIG_)
333*eb47ee01SMasahiro Yamada		;;
334*eb47ee01SMasahiro Yamada	esac
335*eb47ee01SMasahiro Yamada
336*eb47ee01SMasahiro Yamada	if [[ ${cur} != /* && ${cur} != *//* ]]; then
337*eb47ee01SMasahiro Yamada		local dir srcarch kbuild_file tmp
338*eb47ee01SMasahiro Yamada		srcarch=$(__kbuild_get_srcarch "${words[@]}")
339*eb47ee01SMasahiro Yamada
340*eb47ee01SMasahiro Yamada		# single build
341*eb47ee01SMasahiro Yamada		dir=${cur}
342*eb47ee01SMasahiro Yamada		while true; do
343*eb47ee01SMasahiro Yamada			if [[ ${dir} == */* ]]; then
344*eb47ee01SMasahiro Yamada				dir=${dir%/*}
345*eb47ee01SMasahiro Yamada			else
346*eb47ee01SMasahiro Yamada				dir=.
347*eb47ee01SMasahiro Yamada			fi
348*eb47ee01SMasahiro Yamada
349*eb47ee01SMasahiro Yamada			# Search for 'Kbuild' or 'Makefile' in the parent
350*eb47ee01SMasahiro Yamada			# directories (may not be a direct parent)
351*eb47ee01SMasahiro Yamada			if [[ -f ${srctree}/${dir}/Kbuild ]]; then
352*eb47ee01SMasahiro Yamada				kbuild_file=${srctree}/${dir}/Kbuild
353*eb47ee01SMasahiro Yamada				break
354*eb47ee01SMasahiro Yamada			fi
355*eb47ee01SMasahiro Yamada			if [[ -f ${srctree}/${dir}/Makefile ]]; then
356*eb47ee01SMasahiro Yamada				kbuild_file=${srctree}/${dir}/Makefile
357*eb47ee01SMasahiro Yamada				break
358*eb47ee01SMasahiro Yamada			fi
359*eb47ee01SMasahiro Yamada
360*eb47ee01SMasahiro Yamada			if [[ ${dir} == . ]]; then
361*eb47ee01SMasahiro Yamada				break
362*eb47ee01SMasahiro Yamada			fi
363*eb47ee01SMasahiro Yamada		done
364*eb47ee01SMasahiro Yamada
365*eb47ee01SMasahiro Yamada		if [[ -n ${kbuild_file} ]]; then
366*eb47ee01SMasahiro Yamada			tmp=($(__kbuild_tmp_makefile "${kbuild_file}" |
367*eb47ee01SMasahiro Yamada			       SRCARCH=${srcarch} obj=${dir} src=${srctree}/${dir} \
368*eb47ee01SMasahiro Yamada			       "${1}" -n -f - 2>/dev/null))
369*eb47ee01SMasahiro Yamada
370*eb47ee01SMasahiro Yamada			# Add $(obj)/ prefix
371*eb47ee01SMasahiro Yamada			if [[ ${dir} != . ]]; then
372*eb47ee01SMasahiro Yamada				tmp=("${tmp[@]/#/${dir}\/}")
373*eb47ee01SMasahiro Yamada			fi
374*eb47ee01SMasahiro Yamada
375*eb47ee01SMasahiro Yamada			keywords+=("${tmp[@]}")
376*eb47ee01SMasahiro Yamada		fi
377*eb47ee01SMasahiro Yamada
378*eb47ee01SMasahiro Yamada		# *_defconfig and *.config files. These might be grouped into
379*eb47ee01SMasahiro Yamada		# subdirectories, e.g., arch/powerpc/configs/*/*_defconfig.
380*eb47ee01SMasahiro Yamada		if [[ ${cur} == */* ]]; then
381*eb47ee01SMasahiro Yamada			dir=${cur%/*}
382*eb47ee01SMasahiro Yamada		else
383*eb47ee01SMasahiro Yamada			dir=.
384*eb47ee01SMasahiro Yamada		fi
385*eb47ee01SMasahiro Yamada
386*eb47ee01SMasahiro Yamada		tmp=($(find "${srctree}/arch/${srcarch}/configs/${dir}" \
387*eb47ee01SMasahiro Yamada		       "${srctree}/kernel/configs/${dir}" \
388*eb47ee01SMasahiro Yamada		       -mindepth 1 -maxdepth 1 -type d -printf '%P/\n' \
389*eb47ee01SMasahiro Yamada		       -o -printf '%P\n' 2>/dev/null))
390*eb47ee01SMasahiro Yamada
391*eb47ee01SMasahiro Yamada		if [[ ${dir} != . ]]; then
392*eb47ee01SMasahiro Yamada			tmp=("${tmp[@]/#/${dir}\/}")
393*eb47ee01SMasahiro Yamada		fi
394*eb47ee01SMasahiro Yamada
395*eb47ee01SMasahiro Yamada		keywords+=("${tmp[@]}")
396*eb47ee01SMasahiro Yamada	fi
397*eb47ee01SMasahiro Yamada
398*eb47ee01SMasahiro Yamada	# shellcheck disable=SC2191 # '=' is appended for variables
399*eb47ee01SMasahiro Yamada	keywords+=(
400*eb47ee01SMasahiro Yamada		#
401*eb47ee01SMasahiro Yamada		# variables (append =)
402*eb47ee01SMasahiro Yamada		#
403*eb47ee01SMasahiro Yamada		ARCH=
404*eb47ee01SMasahiro Yamada		CROSS_COMPILE=
405*eb47ee01SMasahiro Yamada		LLVM=
406*eb47ee01SMasahiro Yamada		C= M= MO= O= V= W=
407*eb47ee01SMasahiro Yamada		INSTALL{,_MOD,_HDR,_DTBS}_PATH=
408*eb47ee01SMasahiro Yamada		KERNELRELEASE=
409*eb47ee01SMasahiro Yamada
410*eb47ee01SMasahiro Yamada		#
411*eb47ee01SMasahiro Yamada		# targets
412*eb47ee01SMasahiro Yamada		#
413*eb47ee01SMasahiro Yamada		all help
414*eb47ee01SMasahiro Yamada		clean mrproper distclean
415*eb47ee01SMasahiro Yamada		clang-{tidy,analyzer} compile_commands.json
416*eb47ee01SMasahiro Yamada		coccicheck
417*eb47ee01SMasahiro Yamada		dtbs{,_check,_install} dt_binding_{check,schemas}
418*eb47ee01SMasahiro Yamada		headers{,_install}
419*eb47ee01SMasahiro Yamada		vmlinux install
420*eb47ee01SMasahiro Yamada		modules{,_prepare,_install,_sign}
421*eb47ee01SMasahiro Yamada		vdso_install
422*eb47ee01SMasahiro Yamada		tags TAGS cscope gtags
423*eb47ee01SMasahiro Yamada		rust{available,fmt,fmtcheck}
424*eb47ee01SMasahiro Yamada		kernel{version,release} image_name
425*eb47ee01SMasahiro Yamada		kselftest{,-all,-install,-clean,-merge}
426*eb47ee01SMasahiro Yamada
427*eb47ee01SMasahiro Yamada		# configuration
428*eb47ee01SMasahiro Yamada		{,old,olddef,sync,def,savedef,rand,listnew,helpnew,test,tiny}config
429*eb47ee01SMasahiro Yamada		{,build_}{menu,n,g,x}config
430*eb47ee01SMasahiro Yamada		local{mod,yes}config
431*eb47ee01SMasahiro Yamada		all{no,yes,mod,def}config
432*eb47ee01SMasahiro Yamada		{yes2mod,mod2yes,mod2no}config
433*eb47ee01SMasahiro Yamada
434*eb47ee01SMasahiro Yamada		# docs
435*eb47ee01SMasahiro Yamada		{html,textinfo,info,latex,pdf,epub,xml,linkcheck,refcheck,clean}docs
436*eb47ee01SMasahiro Yamada
437*eb47ee01SMasahiro Yamada		# package
438*eb47ee01SMasahiro Yamada		{,bin,src}{rpm,deb}-pkg
439*eb47ee01SMasahiro Yamada		{pacman,dir,tar}-pkg
440*eb47ee01SMasahiro Yamada		tar{,gz,bz2,xz,zst}-pkg
441*eb47ee01SMasahiro Yamada		perf-tar{,gz,bz2,xz,zst}-src-pkg
442*eb47ee01SMasahiro Yamada	)
443*eb47ee01SMasahiro Yamada
444*eb47ee01SMasahiro Yamada	COMPREPLY=($(compgen -W "${keywords[*]}" -- "${cur}"))
445*eb47ee01SMasahiro Yamada
446*eb47ee01SMasahiro Yamada	# Do not append a space for variables, subdirs, "KBUILD_", "KCONFIG_".
447*eb47ee01SMasahiro Yamada	if [[ ${COMPREPLY-} == *[=/] || ${COMPREPLY-} =~ ^(KBUILD|KCONFIG)_$ ]]; then
448*eb47ee01SMasahiro Yamada		compopt -o nospace
449*eb47ee01SMasahiro Yamada	fi
450*eb47ee01SMasahiro Yamada
451*eb47ee01SMasahiro Yamada} && complete -F _make_for_kbuild make
452