bash completion of makefile target

断了今生、忘了曾经 提交于 2020-06-24 02:55:40

问题


Suppose I have a simple makefile like:

hello:
   echo "hello world"

bye:
   echo "bye bye"

Then in bash I want something like:

make h < tab >

so it can complete to

make hello

I found a simple way like creating empty files hello and bye but I'm looking for something more sophisticated.


回答1:


Could this be what you're looking for?

http://freshmeat.net/projects/bashcompletion/

make [Tab] would complete on all targets in Makefile. This project was conceived to produce programmable completion routines for the most common Linux/UNIX commands, reducing the amount of typing sysadmins and programmers need to do on a daily basis.




回答2:


Add this in your ~/.bash_profile file or ~/.bashrc file

complete -W "\`grep -oE '^[a-zA-Z0-9_.-]+:([^=]|$)' ?akefile | sed 's/[^a-zA-Z0-9_.-]*$//'\`" make

This searches for a target in your Makefile titled 'Makefile' or 'makefile' (note the capital ? wildcard in ?akefile) using grep, and pipes it over to the complete command in bash which is used to specify how arguments are autocompleted. The -W flag denotes that the input to the complete command will be a wordlist which is accomplished by passing the results of grep through sed which arranges it into the desirable wordlist format.

Caveats and gotchas:

  1. Your make file is named 'GNUMakefile' or anything else other than 'Makefile' or 'makefile'. If you frequently encounter such titles consider changing the regular expression ?akefile accordingly.

  2. Forgetting to source your ~/.bash_profile or ~/.bashrc file after making the changes. I add this seemingly trivial detail since, to the uninitiated it is unfamiliar. For any change to your bash files to take effect, source them using the command

    source ~/.bashrc
    

    or

    source ~/.bash_profile
    

PS. You also now have the added ability to display the possible make targets by pressing [Tab] twice just like in bash completion. Just make sure you add a space after the command make before typing [Tab] twice.




回答3:


There's a useful package called bash-completion available for most every OS. It includes Makefile completion.

(If you're using macOS and Homebrew, you can get this via brew install bash-completion.)




回答4:


This seems to be default in at least Debian Lenny:

$ grep Makefile /etc/bash_completion
    # make reads `GNUmakefile', then `makefile', then `Makefile'
    elif [ -f ${makef_dir}/Makefile ]; then
        makef=${makef_dir}/Makefile
    # before we scan for targets, see if a Makefile name was
    # deal with included Makefiles

The header of this file states:

#   The latest version of this software can be obtained here:
#
#   http://bash-completion.alioth.debian.org/
#
#   RELEASE: 20080617.5



回答5:


Here is a completion script that looks at the .PHONY: declaration.

_make_phony_words() {
  local opt_revert

  if [ -n "${BASH_VERSION:-}" ]; then
    shopt -q nullglob || {
      opt_revert=1 ; shopt -s nullglob ;
    }

  elif [ -n "${ZSH_VERSION:-}" ]; then
    [[ -o nullglob ]] || {
      opt_revert=1 ; setopt nullglob
    }
  fi

  for f in ./?akefile ./*.make ; do
    sed -nEe '/^.PHONY/ { s/^.PHONY:[ ]?// ; p ; } ' "$f" | tr ' ' $'\n' | sort -u
  done

  if [ -n "$opt_revert" ]; then

    [ -n "${ZSH_VERSION:-}" ] && unsetopt nullglob
    [ -n "${BASH_VERSION:-}" ] && shopt -u nullglob
  fi
  unset opt_revert

}

_make_phony_complete() {
  local cur="${COMP_WORDS[COMP_CWORD]}"

  COMPREPLY+=( $(compgen -W "$( _make_phony_words )" -- ${cur}) )

}
complete -F _make_phony_complete make



回答6:


In Ubuntu 10.04, source the following file:

. /etc/bash_completion

or uncomment it in

/etc/bash.bashrc


来源:https://stackoverflow.com/questions/4188324/bash-completion-of-makefile-target

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!