0

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

我正在尝试(重新)构建llvm-tblgen实用程序。llvm-tblgenlibLLVMSupportlibLLVMTableGen有链接时依赖性。如果我添加一个 JamDEPENDS语句以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根本不会构建!任何指针?

4

1 回答 1

2

要分析这样的问题,您可以使用:

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”不匹配。

解决方案是:永远不要将目标名称与路径组件一起使用,只需使用文件名即可。如果两个不同的目标具有文件名,则将 grist 添加到它们之一或两者(例如“foo”和“foo”)以使它们再次唯一。如果在目标上正确设置了SEARCHor 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 规则,您可能还希望将上面MakeLocateSEARCH那里也移动。我不会在此处设置TABLEGEN_FLAGS,而是将其作为 TableGen 的第三个参数并在此处设置变量,因此该规则使用起来更加方便。

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

  • 您的通配符规则过于复杂。在第一行之后你就可以了return $(results:BS) ;。字符串/路径操作适用于列表的每个元素,因此无需手动执行。
  • 您的 LLVMLinkExecutable 和 _GetLinkerFlags 也相当复杂。如果 LLVMLinkExecutable 的“libraries”参数始终是构建系统构建的库的缩写名称,则可以使用LinkLibraries $(1) : lib$(3).a ;而不是“for”循环。该规则建立依赖关系并将库添加到链接行(使用它们的路径而不是“-L...-l...”)。
于 2013-08-26T10:04:01.090 回答