List goals/targets in GNU make that contain variab

2019-01-20 22:17发布

I have a fairly large makefile that creates a number of targets on the fly by computing names from variables. (eg foo$(VAR) : $(PREREQS)). Is there any way that gnu make can be convinced to spit out a list of targets after it has expanded these variables?

I'd like to be able to get the targets for an aribitrary makefile. I'm trying to write a completion function for my shell.

16条回答
做自己的国王
2楼-- · 2019-01-20 22:42

Edit: FYI the debian bash completion git repository in another answer now incorporates an enhanced version of this script tailored to bash completion use cases.

#!/bin/bash

SCRIPT='
  /^# Make data base/,/^# Files/d             # skip until files section
  /^# Not a target/,+1          d             # following target isnt
  /^\.PHONY:/                   d             # special target
  /^\.SUFFIXES:/                d             # special target
  /^\.DEFAULT:/                 d             # special target
  /^\.PRECIOUS:/                d             # special target
  /^\.INTERMEDIATE:/            d             # special target
  /^\.SECONDARY:/               d             # special target
  /^\.SECONDEXPANSION/          d             # special target
  /^\.DELETE_ON_ERROR:/         d             # special target
  /^\.IGNORE:/                  d             # special target
  /^\.LOW_RESOLUTION_TIME:/     d             # special target
  /^\.SILENT:/                  d             # special target
  /^\.EXPORT_ALL_VARIABLES:/    d             # special target
  /^\.NOTPARALLEL:/             d             # special target
  /^\.ONESHELL:/                d             # special target
  /^\.POSIX:/                   d             # special target
  /^\.NOEXPORT:/                d             # special target
  /^\.MAKE:/                    d             # special target

# The stuff above here describes lines that are not
#  explicit targets or not targets other than special ones
# The stuff below here decides whether an explicit target
#  should be output.

  /^[^#\t:=%]+:([^=]|$)/ {                    # found target block
    h                                         # hold target
    d                                         # delete line
  }
  /^# File is an intermediate prerequisite/ { # nope
    s/^.*$//;x                                # unhold target
    d                                         # delete line
  }
  /^([^#]|$)/ {                               # end of target block
    s/^.*$//;x                                # unhold target
    s/:.*$//p                                 # write current target
    d                                         # hide any bugs
  }
'

make -npq .DEFAULT 2>/dev/null | sed -n -r "$SCRIPT" \
  | sort | uniq

This is a much more complete script than the debian bash completion script because it provides results for generated rules which is what the question asks for and the top voted answer (debian bash completion script at the debian git server) doesn't go far enough.

This is not the original script that I linked to but it is much simpler and is a touch faster.

查看更多
贼婆χ
3楼-- · 2019-01-20 22:42

There is a very nice solution with some sed and egrep magic here: https://gist.github.com/pvdb/777954

查看更多
时光不老,我们不散
4楼-- · 2019-01-20 22:47

This is the code for alias based on Todd Hodes solution

alias mtargets='make -qp | awk -F":" "/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split(\$1,A,/ /);for(i in A)print A[i]}"'
查看更多
Summer. ? 凉城
5楼-- · 2019-01-20 22:48
grep ^[a-z].*\:$ Makefile | sed s,:,,g
查看更多
登录 后发表回答