100

変数から名前を計算することにより、その場で多数のターゲットを作成するかなり大きなメイクファイルがあります。(例: foo$(VAR) : $(PREREQS))。これらの変数を展開した後、gnu make がターゲットのリストを吐き出すように説得できる方法はありますか?

任意のメイクファイルのターゲットを取得できるようにしたいと考えています。シェルの補完関数を作成しようとしています。

4

16 に答える 16

116
make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'     

チャームのように機能する make arg 補完から取得。

于 2012-03-01T22:03:18.617 に答える
79

make -pn(つまり)からの出力を解析できますmake --print-data-base --dry-runか?すべての変数、ルール、暗黙のルール、およびどのコマンドを実行するかが面倒な詳細で出力されます。

于 2010-09-03T02:02:12.597 に答える
14

これが gnu make だけのものかどうかはわかりませんが、これはうまく機能します:

make help

于 2012-10-11T21:23:28.113 に答える
10

何人かのレスポンダーはmake -pn、ルールのデータベースを出力するが何も実行しない - 多かれ少なかれ - を使用することを提案しました。このアプローチの問題点は、-nすべての再帰的な make を呼び出すことであり、通常のビルドで呼び出すすべてのコマンドを出力するため、必要以上に多くの作業を行うことです。より効率的な解決策は、次の内容の単純な makefile、dummy.mk を作成することです。

__all_targets__: ; #no-op

ここで make as を呼び出しますmake -p -f Makefile -f dummy.mk __all_targets__。実質的なビルドでは、make によって生成される出力の量に大きな違いがあります。例えば:

$ gmake -pn | wc
 138985 2632330 69612711
$ gmake -f Makefile -f /tmp/dummy.mk -pn __all_targets__ | wc
  21673   93437  878985

実行時間も劇的に改善され、最初のバージョンで 2.063 秒、2 番目のバージョンで 0.059 秒になりました。

于 2011-09-12T16:14:51.960 に答える
9

GitHubで make のbash補完を確認してください。

于 2011-09-22T20:47:01.370 に答える
7

編集:参考までに、別の回答の debian bash 補完 git リポジトリには、bash 補完のユースケースに合わせて調整されたこのスクリプトの拡張バージョンが組み込まれています。

#!/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

これは、debian bash 補完スクリプトよりもはるかに完全なスクリプトです。これは、質問が求めるものである生成されたルールの結果を提供し、上位投票の回答 (debian git サーバーでの debian bash 補完スクリプト) が不十分であるためです。

これは私がリンクした元のスクリプトではありませんが、はるかに単純で、少し高速です。

于 2012-08-26T16:48:24.773 に答える
4

これは、Todd Hodes ソリューションに基づくエイリアスのコードです。

alias mtargets='make -qp | awk -F":" "/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split(\$1,A,/ /);for(i in A)print A[i]}"'
于 2015-03-20T06:40:23.550 に答える
3

いくつかの sed と egrep マジックを使用した非常に優れたソリューションがここにあります: https://gist.github.com/pvdb/777954

于 2013-02-06T08:42:19.967 に答える
3

これにより、適切な出力が得られます。

make -pn | perl -F: -ane 'print "$F[0]\n" if /^\w+\s*:/' | sort
于 2011-07-08T13:22:19.283 に答える
2

私はこのパーティーに少し遅れていると思いますが、特定のコマンドを探している場合は、試すことができます

make -qp | grep -v '^# ' | grep -v '^[[:space:]]' | grep --only-matching '^.*:'

vpathこれはほとんどの場合機能しますが、ディレクティブのようなターゲット以外のものがまだ含まれている可能性があります。の組み込みルールに依存しない場合は、パイプラインの最初のコマンドとしてmake使用できます。make -qpR

于 2011-03-06T17:31:04.650 に答える
1

私はsolaris 10とターボCシェルに取り組んでいます。指定されたソリューションは、私のメイクファイル プロジェクトでは機能しません。上記のコマンドラインを tcsh 構文に変更した後でも。ただし、を使用して簡単な解決策を得ることができることがわかりました

remake --tasks | grep -v "clean some static output or just grep tabs on start of line" | awk ´{print $1}´

リメイク版:

remake --version

GNU Make 3.82+dbg0.8
Built for sparc-sun-sparc2-9

その他の重要でないバージョン データ

于 2015-09-20T05:14:41.733 に答える
1

Ruby ソリューション:

`make -qp`.split("\n").select{|l| l =~ /^\w/ && l !~ /=/}.map{|l| l.sub(/:.*/,'')}
于 2012-11-09T07:37:19.603 に答える
0

私は同じ質問を探しに行き、このスピンを思いついた:

make -pn | sed -rn '/^[^# \t\.%].*:/p'

これにより、すべてのコメント行、パターンルール(タブで始まる行)、すべての組み込み(例.c.o%.o: %.cパターン)が削除されます。

于 2011-09-12T14:04:27.990 に答える
-1

わかりましたが、いつ吐き出しますか?

ルールの実行時にターゲットの名前を報告するには、ルールに次の行を追加します。

foo$(VAR): $(PREREQS)
    @echo now making the foo target: $@
    do_other_stuff...

それらすべてを一度に吐き出すには、別の PHONY ターゲットを作成できます。

.PHONY: show_vars
show_vars:
    @echo foo$(VAR)
    @echo bar$(PARAM) blah$(FLAG)
    # and so on

そして、これをデフォルトのターゲットの前提条件にすることができます:

all: show_vars
    ...

編集:
任意のメイクファイルのすべての可能なターゲットを表示する方法が必要です。これは、非侵入的であることを意味すると思います。良い...

それを正確に行い、高度なメイクファイル (たとえば、ステートメントによって構築されたルールを含む) に対処できるようにするにevalは、Make エミュレーターに近いものを作成する必要があります。非現実的。

単純なルールのターゲットを確認するには、任意のメイクファイルを操作するメイクファイル スキャナーとして機能するメイクファイルを作成します。

  1. sed を使用して、makefile からすべてのターゲット名を取得します。
  2. 変数の展開に使用するために、makefile を「include」します。
  3. `show_%: を使用します。echo $$*` ですべてのターゲットを表示

これは印象的な作品でしょう。その目標は努力する価値があると確信していますか?

于 2010-06-17T17:14:09.180 に答える
-4
grep ^[a-z].*\:$ Makefile | sed s,:,,g
于 2011-12-20T19:21:24.467 に答える