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