web-dev-qa-db-ja.com

定義に変数を含むGNU makeでゴール/ターゲットをリストする

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

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

99
BitShifter

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

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

Make argの補完から取得します。これは魅力のように機能します。

113
todd hodes

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

make help

13
Zdenik

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

__all_targets__: ; #no-op

Makeを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秒です。

10
Eric Melski

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

9
js.

編集:参考までに、別の回答の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完了スクリプトよりもはるかに完全なスクリプトです。

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

7
codeshot

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

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

これにより、素敵な出力が得られます。

make -pn | Perl -F: -ane 'print "$F[0]\n" if /^\w+\s*:/' | sort
3
Andor

いくつかのsedおよびegrepマジックを使用した非常に素晴らしいソリューションがあります: https://Gist.github.com/pvdb/777954

3
Atilla Filiz

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

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

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

2
DGrady

Rubyソリューション:

`make -qp`.split("\n").select{|l| l =~ /^\w/ && l !~ /=/}.map{|l| l.sub(/:.*/,'')}
1
gdub

私はsolaris 10とturbo C Shellに取り組んでいます。与えられたソリューションは、私のmakefileプロジェクトでは機能しません。上記のコマンドラインを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

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

1
Aviv

別のスレッドでこのソリューションを見つけました:

sh -c "cat Makefile | egrep \"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$\""

Makefileに追加することもできます:

list:
    sh -c "cat Makefile | egrep \"^[[:alnum:][:punct:]]{0,}:[[:space:]]{0,}[[:alnum:][:punct:][:space:]]{0,}$\\""

そして、make list

0
thisismydesign

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

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

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

0
Jamie