我正在尝试使用Haiku Jam构建一个项目。 (该项目的代码可在https://github.com/Andromeda-OS/LLVM在线获得。我建议至少查看该项目中的目录名称,以便了解我在下面提到的组件。)
我正在尝试(重新)构建llvm-tblgen实用程序。 llvm-tblgen
对libLLVMSupport和libLLVMTableGen具有链接时依赖性。如果我添加了Jam DEPENDS
语句,以便llvm-tblgen
要求首先构建libLLVMSupport
,那么Jam根本不会构建llvm-tblgen
。 Jam输出don't know how to make ./bin/llvm-tblgen/llvm-tblgen
,即使在高详细级别运行时也没有其他有用的诊断信息。
如果我从llvm-tblgen
删除所有依赖命令,那么只有Jam编译该文件。但是,如果libLLVMSupport.a
不存在,将导致链接器错误,因为Jam没有被告知首先编译libLLVMSupport
。但是,如果我告诉Jam首先构建libLLVMSupport
,则根本不会构建llvm-tblgen
!有什么指针吗?
答案 0 :(得分:2)
要分析这样的问题,您可以使用:
jam -n -dm
这将打印制作树。处理制作树时会打印错误,因此您可以在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中的目标名称只是文字字符串 - 因此可能的路径没有匹配 - 这与目标" llvm-tblgen"你在" bin / llvm-tblgen / Jamfile"中定义。
解决方案是:切勿将目标名称与路径组件一起使用,只需使用文件名即可。如果两个不同的目标具有文件名,则将grist添加到其中一个或两个(例如" foo"和" foo")以使它们再次成为唯一。如果在目标上正确设置了SEARCH
或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-])
}
&#34; LLVM-tblgen&#34;现在作为目标传递给动作,从而自动绑定到正确的路径。
您可以简化&#34; include / llvm / Jamfile&#34;:
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的第三个参数并在那里设置变量,因此规则变得更加方便使用。
我注意到的其他一些事情:
return $(results:BS) ;
。字符串/路径操作应用于列表的每个元素,因此无需手动执行此操作。LinkLibraries $(1) : lib$(3).a ;
而不是&#34; for&#34;环。规则建立依赖关系并将库添加到链接行(使用其路径而不是&#34; -L ... -l ...&#34;)。