To analyze problems like this you can use:
jam -n -dm
This prints the make tree. The error is printed while processing the make tree, so you see it right where Jam encounters it and can easily track back the dependencies that lead to it. In this case "Intrinsics.gen" has the non-existent dependency and grep reveals the following line in "include/llvm/Jamfile":
DEPENDS $(Intrinsics.gen) : $(Intrinsics.gen:D) $(TOP)/bin/llvm-tblgen/llvm-tblgen ;
So, if you're jamming in the top directory, the latter dependency expands to "./bin/llvm-tblgen/llvm-tblgen". Since target names in Jam are just literal strings -- there's no matching for possible paths happing -- this does not match the target "llvm-tblgen" you define in "bin/llvm-tblgen/Jamfile".
The solution is: Never use target names with path components, just use the file name. If two different targets have the file name, add grist to one or both of them (e.g. "foo" and "foo") to make them unique again. If SEARCH
or LOCATE
is properly set on the target -- which almost all standard rules do -- Jam will automatically resolve the target name to the matching path (aka bind the target) when used in actions. For instance your TableGen rule should rather look like:
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" is now passed as a target to the actions and thus automatically bound to the correct path.
You can simplify "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 ;
Usually one adds the subdirectory grist to source files (using [ FGristFiles Intrinsics.td ]
in this case), so clashes with equally named source files in other directories are avoided preemptively. If you use the TableGen rule elsewhere as well, you may also want to move the above MakeLocate
and SEARCH
there as well. Instead of setting TABLEGEN_FLAGS
here, I would make that a third parameter of TableGen and set the variable there, so the rule becomes even more convenient to use.
A few other things I noted:
- Your Wildcard rule is unnecessarily complicated. After the first line you can just
return $(results:BS) ;
. The string/path operations are applied to each element of a list, so there's no need to do that manually.
- Your LLVMLinkExecutable and _GetLinkerFlags are rather complicated as well. If the "libraries" parameter of LLVMLinkExecutable is always the abbreviated name of a library the build system builds, you can just use
LinkLibraries $(1) : lib$(3).a ;
instead of the "for" loop. The rule establishes the dependencies and adds the libraries to the link line (with their path instead of "-L... -l...").