依赖性中断构建

时间:2013-08-26 00:07:53

标签: jam

我正在尝试使用Haiku Jam构建一个项目。 (该项目的代码可在https://github.com/Andromeda-OS/LLVM在线获得。我建议至少查看该项目中的目录名称,以便了解我在下面提到的组件。)

我正在尝试(重新)构建llvm-tblgen实用程序。 llvm-tblgenlibLLVMSupportlibLLVMTableGen具有链接时依赖性。如果我添加了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!有什么指针吗?

1 个答案:

答案 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")以使它们再次成为唯一。如果在目标上正确设置了SEARCHLOCATE - 几乎所有标准规则都会这样做 - 当在操作中使用时,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规则,您可能还想在那里移动上面的MakeLocateSEARCH。我不是在这里设置TABLEGEN_FLAGS,而是将其作为TableGen的第三个参数并在那里设置变量,因此规则变得更加方便使用。

我注意到的其他一些事情:

  • 您的通配符规则不必要地复杂化。在第一行之后,您可以return $(results:BS) ;。字符串/路径操作应用于列表的每个元素,因此无需手动执行此操作。
  • 您的LLVMLinkExecutable和_GetLinkerFlags也相当复杂。如果&#34;库&#34; LLVMLinkExecutable的参数始终是构建系统构建的库的缩写名称,您只需使用LinkLibraries $(1) : lib$(3).a ;而不是&#34; for&#34;环。规则建立依赖关系并将库添加到链接行(使用其路径而不是&#34; -L ... -l ...&#34;)。