| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 |
- # SPDX-License-Identifier: GPL-2.0-only
- # bash completion for GNU make with kbuild extension -*- shell-script -*-
- # Load the default completion script for make. It is typically located at
- # /usr/share/bash-completion/completions/make, but we do not rely on it.
- __kbuild_load_default_make_completion()
- {
- local -a dirs=("${BASH_COMPLETION_USER_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/bash-completion}/completions")
- local ifs=$IFS IFS=: dir compfile this_dir
- for dir in ${XDG_DATA_DIRS:-/usr/local/share:/usr/share}; do
- dirs+=("$dir"/bash-completion/completions)
- done
- IFS=$ifs
- this_dir="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
- for dir in "${dirs[@]}"; do
- if [[ ! -d ${dir} || ${dir} = "${this_dir}" ]]; then
- continue
- fi
- for compfile in make make.bash _make; do
- compfile=$dir/$compfile
- # Avoid trying to source dirs; https://bugzilla.redhat.com/903540
- if [[ -f ${compfile} ]] && . "${compfile}" &>/dev/null; then
- __kbuild_default_make_completion=$(
- # shellcheck disable=SC2046 # word splitting is the point here
- set -- $(complete -p make)
- while [[ $# -gt 1 && "$1" != -F ]]; do
- shift
- done
- if [[ "$1" = -F ]]; then
- echo "$2"
- fi
- )
- return
- fi
- done
- done
- }
- __kbuild_load_default_make_completion
- __kbuild_handle_variable()
- {
- local var=${1%%=*}
- local cur=${cur#"${var}"=}
- local srctree=$2
- local keywords=()
- case $var in
- ARCH)
- # sub-directories under arch/
- keywords+=($(find "${srctree}/arch" -mindepth 1 -maxdepth 1 -type d -printf '%P\n'))
- # architectures hard-coded in the top Makefile
- keywords+=(i386 x86_64 sparc32 sparc64 parisc64)
- ;;
- CROSS_COMPILE)
- # toolchains with a full path
- local cross_compile=()
- local c c2
- _filedir
- for c in "${COMPREPLY[@]}"; do
- # eval for tilde expansion
- # suppress error, as this fails when it contains a space
- eval "c2=${c}" 2>/dev/null || continue
- if [[ ${c} == *-elfedit && ! -d ${c2} && -x ${c2} ]]; then
- cross_compile+=("${c%elfedit}")
- fi
- done
- # toolchains in the PATH environment
- while read -r c; do
- if [[ ${c} == *-elfedit ]]; then
- keywords+=("${c%elfedit}")
- fi
- done < <(compgen -c)
- COMPREPLY=()
- _filedir -d
- # Add cross_compile directly without passing it to compgen.
- # Otherwise, toolchain paths with a tilde do not work.
- # e.g.)
- # CROSS_COMPILE=~/0day/gcc-14.2.0-nolibc/aarch64-linux/bin/aarch64-linux-
- COMPREPLY+=("${cross_compile[@]}")
- ;;
- LLVM)
- # LLVM=1 uses the default 'clang' etc.
- keywords+=(1)
- # suffix for a particular version. LLVM=-18 uses 'clang-18' etc.
- while read -r c; do
- if [[ ${c} == clang-[0-9]* ]]; then
- keywords+=("${c#clang}")
- fi
- done < <(compgen -c)
- # directory path to LLVM toolchains
- _filedir -d
- ;;
- KCONFIG_ALLCONFIG)
- # KCONFIG_ALLCONFIG=1 selects the default fragment
- keywords+=(1)
- # or the path to a fragment file
- _filedir
- ;;
- C | KBUILD_CHECKSRC)
- keywords+=(1 2)
- ;;
- V | KBUILD_VERBOSE)
- keywords+=({,1}{,2})
- ;;
- W | KBUILD_EXTRA_WARN)
- keywords+=({,1}{,2}{,3}{,c}{,e})
- ;;
- KBUILD_ABS_SRCTREE | KBUILD_MODPOST_NOFINAL | KBUILD_MODPOST_WARN | \
- CLIPPY | KBUILD_CLIPPY | KCONFIG_NOSILENTUPDATE | \
- KCONFIG_OVERWRITECONFIG | KCONFIG_WARN_UNKNOWN_SYMBOL | \
- KCONFIG_WERROR )
- keywords+=(1)
- ;;
- INSTALL_MOD_STRIP)
- keywords+=(1 --strip-debug --strip-unneeded)
- ;;
- O | KBUILD_OUTPUT | M | KBUILD_EXTMOD | MO | KBUILD_EXTMOD_OUTPUT | *_PATH)
- # variables that take a directory.
- _filedir -d
- return
- ;;
- KBUILD_EXTRA_SYMBOL | KBUILD_KCONFIG | KCONFIG_CONFIG)
- # variables that take a file.
- _filedir
- return
- esac
- COMPREPLY+=($(compgen -W "${keywords[*]}" -- "${cur}"))
- }
- # Check the -C, -f options and 'source' symlink. Return the source tree we are
- # working in.
- __kbuild_get_srctree()
- {
- local words=("$@")
- local cwd makef_dir
- # see if a path was specified with -C/--directory
- for ((i = 1; i < ${#words[@]}; i++)); do
- if [[ ${words[i]} == -@(C|-directory) ]]; then
- # eval for tilde expansion.
- # suppress error, as this fails when it contains a space
- eval "cwd=${words[i + 1]}" 2>/dev/null
- break
- fi
- done
- if [[ -z ${cwd} ]]; then
- cwd=.
- fi
- # see if a Makefile was specified with -f/--file/--makefile
- for ((i = 1; i < ${#words[@]}; i++)); do
- if [[ ${words[i]} == -@(f|-?(make)file) ]]; then
- # eval for tilde expansion
- # suppress error, as this fails when it contains a space
- eval "makef_dir=${words[i + 1]%/*}" 2>/dev/null
- break
- fi
- done
- if [ -z "${makef_dir}" ]; then
- makef_dir=${cwd}
- elif [[ ${makef_dir} != /* ]]; then
- makef_dir=${cwd}/${makef_dir}
- fi
- # If ${makef_dir} is a build directory created by the O= option, there
- # is a symbolic link 'source', which points to the kernel source tree.
- if [[ -L ${makef_dir}/source ]]; then
- makef_dir=$(readlink "${makef_dir}/source")
- fi
- echo "${makef_dir}"
- }
- # Get SRCARCH to do a little more clever things
- __kbuild_get_srcarch()
- {
- local words=("$@")
- local arch srcarch uname_m
- # see if ARCH= is explicitly specified
- for ((i = 1; i < ${#words[@]}; i++)); do
- if [[ ${words[i]} == ARCH=* ]]; then
- arch=${words[i]#ARCH=}
- break
- fi
- done
- # If ARCH= is not specified, check the build marchine's architecture
- if [[ -z ${arch} ]]; then
- uname_m=$(uname -m)
- # shellcheck disable=SC2209 # 'sh' is SuperH, not a shell command
- case ${uname_m} in
- arm64 | aarch64*) arch=arm64 ;;
- arm* | sa110) arch=arm ;;
- i?86 | x86_64) arch=x86 ;;
- loongarch*) arch=loongarch ;;
- mips*) arch=mips ;;
- ppc*) arch=powerpc ;;
- riscv*) arch=riscv ;;
- s390x) arch=s390 ;;
- sh[234]*) arch=sh ;;
- sun4u) arch=sparc64 ;;
- *) arch=${uname_m} ;;
- esac
- fi
- case ${arch} in
- parisc64) srcarch=parisc ;;
- sparc32 | sparc64) srcarch=sparc ;;
- i386 | x86_64) srcarch=x86 ;;
- *) srcarch=${arch} ;;
- esac
- echo "$srcarch"
- }
- # small Makefile to parse obj-* syntax
- __kbuild_tmp_makefile()
- {
- cat <<'EOF'
- .PHONY: __default
- __default:
- $(foreach m,$(obj-y) $(obj-m) $(obj-),$(foreach s, -objs -y -m -,$($(m:%.o=%$s))) $(m))
- EOF
- echo "include ${1}"
- }
- _make_for_kbuild ()
- {
- # shellcheck disable=SC2034 # these are set by _init_completion
- local cur prev words cword split
- _init_completion -s || return
- local srctree
- srctree=$(__kbuild_get_srctree "${words[@]}")
- # If 'kernel' and 'Documentation' directories are found, we assume this
- # is a kernel tree. Otherwise, we fall back to the generic rule provided
- # by the bash-completion project.
- if [[ ! -d ${srctree}/kernel || ! -d ${srctree}/Documentation ]]; then
- if [ -n "${__kbuild_default_make_completion}" ]; then
- "${__kbuild_default_make_completion}" "$@"
- fi
- return
- fi
- # make options with a parameter (copied from the bash-completion project)
- case ${prev} in
- --file | --makefile | --old-file | --assume-old | --what-if | --new-file | \
- --assume-new | -!(-*)[foW])
- _filedir
- return
- ;;
- --include-dir | --directory | -!(-*)[ICm])
- _filedir -d
- return
- ;;
- -!(-*)E)
- COMPREPLY=($(compgen -v -- "$cur"))
- return
- ;;
- --eval | -!(-*)[DVx])
- return
- ;;
- --jobs | -!(-*)j)
- COMPREPLY=($(compgen -W "{1..$(($(_ncpus) * 2))}" -- "$cur"))
- return
- ;;
- esac
- local keywords=()
- case ${cur} in
- -*)
- # make options (copied from the bash-completion project)
- local opts
- opts="$(_parse_help "$1")"
- COMPREPLY=($(compgen -W "${opts:-$(_parse_usage "$1")}" -- "$cur"))
- if [[ ${COMPREPLY-} == *= ]]; then
- compopt -o nospace
- fi
- return
- ;;
- *=*)
- __kbuild_handle_variable "${cur}" "${srctree}"
- return
- ;;
- KBUILD_*)
- # There are many variables prefixed with 'KBUILD_'.
- # Display them only when 'KBUILD_' is entered.
- # shellcheck disable=SC2191 # '=' is appended for variables
- keywords+=(
- KBUILD_{CHECKSRC,EXTMOD,EXTMOD_OUTPUT,OUTPUT,VERBOSE,EXTRA_WARN,CLIPPY}=
- KBUILD_BUILD_{USER,HOST,TIMESTAMP}=
- KBUILD_MODPOST_{NOFINAL,WARN}=
- KBUILD_{ABS_SRCTREE,EXTRA_SYMBOLS,KCONFIG}=
- )
- ;;
- KCONFIG_*)
- # There are many variables prefixed with 'KCONFIG_'.
- # Display them only when 'KCONFIG_' is entered.
- # shellcheck disable=SC2191 # '=' is appended for variables
- keywords+=(
- KCONFIG_{CONFIG,ALLCONFIG,NOSILENTUPDATE,OVERWRITECONFIG}=
- KCONFIG_{SEED,PROBABILITY}=
- KCONFIG_WARN_UNKNOWN_SYMBOL=
- KCONFIG_WERROR=
- )
- ;;
- *)
- # By default, hide KBUILD_* and KCONFIG_* variables.
- # Instead, display only the prefix parts.
- keywords+=(KBUILD_ KCONFIG_)
- ;;
- esac
- if [[ ${cur} != /* && ${cur} != *//* ]]; then
- local dir srcarch kbuild_file tmp
- srcarch=$(__kbuild_get_srcarch "${words[@]}")
- # single build
- dir=${cur}
- while true; do
- if [[ ${dir} == */* ]]; then
- dir=${dir%/*}
- else
- dir=.
- fi
- # Search for 'Kbuild' or 'Makefile' in the parent
- # directories (may not be a direct parent)
- if [[ -f ${srctree}/${dir}/Kbuild ]]; then
- kbuild_file=${srctree}/${dir}/Kbuild
- break
- fi
- if [[ -f ${srctree}/${dir}/Makefile ]]; then
- kbuild_file=${srctree}/${dir}/Makefile
- break
- fi
- if [[ ${dir} == . ]]; then
- break
- fi
- done
- if [[ -n ${kbuild_file} ]]; then
- tmp=($(__kbuild_tmp_makefile "${kbuild_file}" |
- SRCARCH=${srcarch} obj=${dir} src=${srctree}/${dir} \
- "${1}" -n -f - 2>/dev/null))
- # Add $(obj)/ prefix
- if [[ ${dir} != . ]]; then
- tmp=("${tmp[@]/#/${dir}\/}")
- fi
- keywords+=("${tmp[@]}")
- fi
- # *_defconfig and *.config files. These might be grouped into
- # subdirectories, e.g., arch/powerpc/configs/*/*_defconfig.
- if [[ ${cur} == */* ]]; then
- dir=${cur%/*}
- else
- dir=.
- fi
- tmp=($(find "${srctree}/arch/${srcarch}/configs/${dir}" \
- "${srctree}/kernel/configs/${dir}" \
- -mindepth 1 -maxdepth 1 -type d -printf '%P/\n' \
- -o -printf '%P\n' 2>/dev/null))
- if [[ ${dir} != . ]]; then
- tmp=("${tmp[@]/#/${dir}\/}")
- fi
- keywords+=("${tmp[@]}")
- fi
- # shellcheck disable=SC2191 # '=' is appended for variables
- keywords+=(
- #
- # variables (append =)
- #
- ARCH=
- CROSS_COMPILE=
- LLVM=
- C= M= MO= O= V= W=
- INSTALL{,_MOD,_HDR,_DTBS}_PATH=
- KERNELRELEASE=
- #
- # targets
- #
- all help
- clean mrproper distclean
- clang-{tidy,analyzer} compile_commands.json
- coccicheck
- dtbs{,_check,_install} dt_binding_{check,schemas}
- headers{,_install}
- vmlinux install
- modules{,_prepare,_install,_sign}
- vdso_install
- tags TAGS cscope gtags
- rust{available,fmt,fmtcheck}
- kernel{version,release} image_name
- kselftest{,-all,-install,-clean,-merge}
- # configuration
- {,old,olddef,sync,def,savedef,rand,listnew,helpnew,test,tiny}config
- {,build_}{menu,n,g,x}config
- local{mod,yes}config
- all{no,yes,mod,def}config
- {yes2mod,mod2yes,mod2no}config
- # docs
- {html,textinfo,info,latex,pdf,epub,xml,linkcheck,refcheck,clean}docs
- # package
- {,bin,src}{rpm,deb}-pkg
- {pacman,dir,tar}-pkg
- tar{,gz,bz2,xz,zst}-pkg
- perf-tar{,gz,bz2,xz,zst}-src-pkg
- )
- COMPREPLY=($(compgen -W "${keywords[*]}" -- "${cur}"))
- # Do not append a space for variables, subdirs, "KBUILD_", "KCONFIG_".
- if [[ ${COMPREPLY-} == *[=/] || ${COMPREPLY-} =~ ^(KBUILD|KCONFIG)_$ ]]; then
- compopt -o nospace
- fi
- } && complete -F _make_for_kbuild make
|