変数から名前を計算することにより、その場で多数のターゲットを作成するかなり大きなメイクファイルがあります。(例: foo$(VAR) : $(PREREQS))。これらの変数を展開した後、gnu make がターゲットのリストを吐き出すように説得できる方法はありますか?
任意のメイクファイルのターゲットを取得できるようにしたいと考えています。シェルの補完関数を作成しようとしています。
make -qp | awk -F':' '/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split($1,A,/ /);for(i in A)print A[i]}'
チャームのように機能する make arg 補完から取得。
make -pn
(つまり)からの出力を解析できますmake --print-data-base --dry-run
か?すべての変数、ルール、暗黙のルール、およびどのコマンドを実行するかが面倒な詳細で出力されます。
これが gnu make だけのものかどうかはわかりませんが、これはうまく機能します:
make help
何人かのレスポンダーは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 秒になりました。
GitHubで make のbash補完を確認してください。
編集:参考までに、別の回答の 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 補完スクリプト) が不十分であるためです。
これは私がリンクした元のスクリプトではありませんが、はるかに単純で、少し高速です。
これは、Todd Hodes ソリューションに基づくエイリアスのコードです。
alias mtargets='make -qp | awk -F":" "/^[a-zA-Z0-9][^$#\/\t=]*:([^=]|$)/ {split(\$1,A,/ /);for(i in A)print A[i]}"'
いくつかの sed と egrep マジックを使用した非常に優れたソリューションがここにあります: https://gist.github.com/pvdb/777954
これにより、適切な出力が得られます。
make -pn | perl -F: -ane 'print "$F[0]\n" if /^\w+\s*:/' | sort
私はこのパーティーに少し遅れていると思いますが、特定のコマンドを探している場合は、試すことができます
make -qp | grep -v '^# ' | grep -v '^[[:space:]]' | grep --only-matching '^.*:'
vpath
これはほとんどの場合機能しますが、ディレクティブのようなターゲット以外のものがまだ含まれている可能性があります。の組み込みルールに依存しない場合は、パイプラインの最初のコマンドとしてmake
使用できます。make -qpR
私は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
その他の重要でないバージョン データ
Ruby ソリューション:
`make -qp`.split("\n").select{|l| l =~ /^\w/ && l !~ /=/}.map{|l| l.sub(/:.*/,'')}
私は同じ質問を探しに行き、このスピンを思いついた:
make -pn | sed -rn '/^[^# \t\.%].*:/p'
これにより、すべてのコメント行、パターンルール(タブで始まる行)、すべての組み込み(例.c.o
と%.o: %.c
パターン)が削除されます。
わかりましたが、いつ吐き出しますか?
ルールの実行時にターゲットの名前を報告するには、ルールに次の行を追加します。
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 エミュレーターに近いものを作成する必要があります。非現実的。
単純なルールのターゲットを確認するには、任意のメイクファイルを操作するメイクファイル スキャナーとして機能するメイクファイルを作成します。
これは印象的な作品でしょう。その目標は努力する価値があると確信していますか?
grep ^[a-z].*\:$ Makefile | sed s,:,,g