このような問題を分析するには、次を使用できます。
jam -n -dm
これにより、make ツリーが出力されます。make ツリーの処理中にエラーが出力されるため、Jam がエラーに遭遇した場所でエラーが表示され、エラーにつながる依存関係を簡単に追跡できます。この場合、「Intrinsics.gen」には存在しない依存関係があり、grep は「include/llvm/Jamfile」の次の行を明らかにします。
DEPENDS $(Intrinsics.gen) : $(Intrinsics.gen:D) $(TOP)/bin/llvm-tblgen/llvm-tblgen ;
したがって、最上位のディレクトリでジャムを行っている場合、後者の依存関係は「./bin/llvm-tblgen/llvm-tblgen」に展開されます。Jam のターゲット名は単なるリテラル文字列であるため (可能性のあるパス ハッピングとの一致はありません)、これは「bin/llvm-tblgen/Jamfile」で定義したターゲット「llvm-tblgen」と一致しません。
解決策は次のとおりです。パス コンポーネントでターゲット名を使用しないでください。ファイル名だけを使用してください。2 つの異なるターゲットにファイル名がある場合は、それらの一方または両方に grist を追加して (例: "foo" と "foo")、再度一意にします。SEARCH
orがターゲットに適切に設定されている場合(LOCATE
ほぼすべての標準ルールがそうです)、Jam は、アクションで使用されたときに、ターゲット名を一致するパスに自動的に解決します (つまり、ターゲットをバインドします)。たとえば、TableGen ルールは次のようになります。
rule TableGen
{
DEPENDS $(<) : llvm-tblgen $(>) ;
TableGen1 $(<) : llvm-tblgen $(>) ;
}
actions TableGen1
{
$(2[1]) $(TABLEGEN_FLAGS) -I $(TOP)/generated-include -I $(TOP)/lib/Target -I $(TOP)/include -o $(1) $(2[2-])
}
「llvm-tblgen」がターゲットとしてアクションに渡されるようになり、正しいパスに自動的にバインドされます。
「include/llvm/Jamfile」を単純化できます:
SubDir TOP include llvm ;
MakeLocate Intrinsics.gen : $(TOP)/generated-include/llvm ;
SEARCH on Intrinsics.td = $(SUBDIR) ;
TableGen Intrinsics.gen : Intrinsics.td ;
TABLEGEN_FLAGS on Intrinsics.gen = -gen-intrinsic ;
通常、サブディレクトリ grist をソース ファイルに追加する ([ FGristFiles Intrinsics.td ]
この場合は を使用) ため、他のディレクトリにある同じ名前のソース ファイルとの衝突は予防的に回避されます。TableGen ルールを別の場所でも使用する場合は、上記を移動することもできMakeLocate
ますSEARCH
。ここで設定する代わりにTABLEGEN_FLAGS
、それを TableGen の 3 番目のパラメーターにしてそこに変数を設定すると、ルールがさらに使いやすくなります。
私が指摘した他のいくつかのこと:
- ワイルドカード ルールは不必要に複雑です。最初の行の後は、
return $(results:BS) ;
. 文字列/パス操作はリストの各要素に適用されるため、手動で行う必要はありません。
- LLVMLinkExecutable と _GetLinkerFlags もかなり複雑です。LLVMLinkExecutable の "libraries" パラメータが常にビルド システムがビルドするライブラリの省略名である場合
LinkLibraries $(1) : lib$(3).a ;
は、"for" ループの代わりに使用できます。ルールは依存関係を確立し、ライブラリをリンク行に追加します (「-L... -l...」の代わりにパスを使用)。