【问题标题】:How to handle build rule with unknown targets in OMake when target list generator is built构建目标列表生成器时如何在 OMake 中处理具有未知目标的构建规则
【发布时间】:2010-03-26 18:37:57
【问题描述】:

我有一个使用 OMake 构建系统的项目,我正在尝试处理一个相当棘手的极端情况。

我有一些定义文件和一个可以获取这些定义文件并创建 GraphViz 文件的工具。但是有两个问题:

  • 每个定义文件可以生成多个图形,并且它可以生成的图形列表被编码在文件中。我的转储工具确实有一个-list 选项,它列出了定义文件将生成的所有图形。
  • 此转储工具内置于源代码树中。
  • 我希望 OMakefile 中提供此列表,这样我就可以使用其他规则将 DOT 文件转换为 SVG,并且有一个依赖于所有 SVG 的虚假目标(目标:一个构建命令,用于构建我所有图形的 SVG 描述)。

如果我只有第一个问题,那就很容易了——我会运行该工具来构建一个列表,然后使用该列表来构建一个目标,该目标调用转储程序来输出 GraphViz 文件。但是,我宁愿在需要之前强制构建转储工具。

如果这是make,我会递归地运行make 来构建转储工具。然而,OMake 不允许递归调用,并且 build 函数只能在 osh 中使用。

有什么好的解决这个问题的建议吗?

【问题讨论】:

    标签: build-system omake


    【解决方案1】:

    好的,这是我的建议。首先,这是一个用 bash 制作的快速生成器,它可以接受一个“--list”参数,该参数创建一个 omake 变量来包含要执行的操作列表。生成器称为“generator.txt”,因为我们将通过将其重命名为 .sh 来“制作”它。

    #!/bin/bash
    
    if [ "$1" = "--list" ]; then
        echo -e 'FILES[] = \n\ta\n\tb\n\tc'
    else
        echo 1 > a.dot
        echo 2 > b.dot
        echo 3 > c.dot
    fi
    

    然后,OMakefile 本身:

    .INCLUDE: rules : generator.txt
        cp generator.txt generator.sh
        chmod 755 generator.sh  
        ./generator.sh
        ./generator.sh --list > rules
    
    DOTS[] =
        $(addsuffix .dot, $(FILES))
    
    SVGS[] =
        $(addsuffix .svg, $(FILES))
    
    # rule to turn a .dot into a .svg
    %.svg: %.dot
        cp $*.dot $*.svg
    
    .DEFAULT: $(SVGS)
    
    .PHONY: clean
    clean:
        rm -f generator.sh a.* b.* c.* rules
    

    这里的技巧是从 generator.txt 生成“规则”文件,并包含在 OMakefile 中。每当 generator.txt(我们的生成器的源代码)更改时,我们重新创建(构建)生成器,运行它(创建文件 a.dot、b.dot、c.dot),最后使用 --list 运行它以生成我们的FILE[] 变量包含要生成的文件列表。

    然后,生成 DOTS 和 SVGS 变量以及将点转换为 svg 的规则变得微不足道。默认目标取决于 svg 列表,它将按顺序构建所有内容。

    这种方法的问题是构建生成器非常粗糙,因为我们必须将“包含”依赖项列表作为真实文件。尽管如此,这至少应该以正确的顺序执行操作。

    注意修改 generator.txt(例如,添加另一个要生成的 .dot,或更改 .dot 内容的生成方式)如何正确强制重新生成 generator.sh,然后重新生成任何生成的文件会被修改的。

    编辑

    我认为主要问题是 omake 希望能够在开始执行任何工作之前生成整个依赖关系图。因此,它无法处理某些依赖项来构建生成器,然后生成更多依赖项来处理其输出。

    我想有办法解决:

    • 第一个是将生成器构建为 .INCLUDE 指令的一部分,正如我首先描述的那样,这很麻烦,因为您必须将所有生成器构建过程放入该指令中。

    • 第二个问题是失去一些灵活性,并处理一个输入到一个输出,例如让生成器只生成一个包含所有连接输入的文件。如您所知,您将只有一个文件,您可以轻松设置依赖关系。

    • 第三个是我最喜欢的,它是一个两阶段构建系统。在子目录中,您有一个生成生成器并输出文件的 OMakefile。在另一个子目录中,您有另一个 OMakefile,它读取第一个目录的内容以生成要处理的文件列表,然后运行转换。然后,在主目录中,bash 脚本在第一个目录中调用 omake,然后在第二个目录中调用。希望这意味着您可以使用单个命令生成所有内容,而且重建将是最小的:第一个 omake 只会在输入发生更改时重新生成文件,而第二个 omake 只会转换更改的文件或新文件。

    【讨论】:

    • 谢谢。我尝试了使用 INCLUDE 的类似解决方案。但是,我的生成器程序本身就是一个重要的 OCaml 程序。我没有意识到 INCLUDE deps 必须是真实文件,并试图将我的程序用作依赖项;这不起作用(程序无法构建)。由于 OMake 缺乏对递归构建的支持,我看不到使用此解决方案的直接方法。有什么建议吗?
    猜你喜欢
    • 2018-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多