我有一个项目,它使用OMake作为其构建系统,我正在尝试处理一个相当棘手的角落案例。
我有一些定义文件和一个可以获取这些定义文件并创建GraphViz文件的工具。但是有两个问题:
-list
选项,列出了定义文件将生成的所有图形。如果我只遇到第一个问题,那就很容易了 - 我会运行该工具来构建一个列表,然后使用该列表构建一个调用转储器输出GraphViz文件的目标。但是,我宁愿强迫转储工具在需要之前构建。
如果这是make
,我将以递归方式运行make
来构建转储工具。但是,OMake不允许递归调用,build
函数只能从osh
使用。
有关此问题的良好解决方案的任何建议吗?
答案 0 :(得分: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生成“rules”文件,以包含在OMakefile中。每当generator.txt(我们的生成器的源)发生变化时,我们重新创建(构建)生成器,运行它(创建文件a.dot,b.dot,c.dot),最后用--list运行它来生成我们的FILE []变量,包含要生成的文件列表。
然后,生成DOTS和SVGS变量以及将点变成svg的规则变得微不足道。默认目标取决于svgs列表,它将按顺序构建所有内容。
这种方法的问题在于构建生成器非常粗糙,因为我们必须将“INCLUDE”依赖列表作为真实文件。然而,这应该至少以正确的顺序执行操作。
注意如何修改generator.txt(例如,添加另一个.dot来生成,或者更改.dot的内容将如何生成)会正确地强制生成generator.sh,然后再生成任何生成的文件哪些会被修改。
修改
我认为主要问题是omake希望能够在开始做任何工作之前生成整个依赖关系图。因此,它无法在某些依赖项上构建生成器,然后生成更多依赖项来处理其输出。
我想有办法解决这个问题:
第一个是将生成器作为.INCLUDE指令的一部分构建,正如我先描述的那样,这很麻烦,因为你必须将所有生成器构建过程放入该指令中。
第二个是失去一些灵活性,并在一个输出上处理一个输出,例如让生成器只生成一个包含所有连接输入的文件。如您所知,您将只有一个文件,您可以轻松设置依赖项。
第三个,这是我最喜欢的,是一个2阶段构建系统。在子目录中,您有一个生成生成器并输出文件的OMakefile。在另一个子目录中,您有另一个OMakefile,它读取第一个目录的内容以生成要处理的文件列表,然后运行转换。然后,在主目录中,bash脚本在第一个目录中调用omake,然后在第二个目录中调用omake。这有望意味着您可以使用单个命令生成所有内容,而且重建将是最小的:第一个omake将仅在输入已更改时重新生成文件,第二个omake将仅转换已更改的文件或新文件。 / p>