我正在使用外部工具为工作中的应用程序生成源代码。该工具采用一个充满JSON文件的目录树,并生成C ++和其他一些实用程序文件。我已经能够设置一个规则和一个目标,当源发生变化时会重新运行生成器,但我很难确定如何控制构建顺序。
因为我没有直接的方法来生成将由代码生成器生成的C ++ / H文件列表(因为它是由运行时配置确定的),所以除了运行生成器之外我没有看到任何替代方法然后对输出目录中的所有文件执行GLOB。
当我将源(JSON)文件设置为我的可执行文件的依赖项时,Boost.Build会在事情发生变化时运行生成器,但是,它会在运行之前计算我的可执行文件的依赖项代码生成器,因此不会重建正确的东西(例如,如果生成新文件,或者头文件被更改,其依赖关系不会被重新编译),因为在代码生成器运行之前执行该检查,因此GLOB采用当前(过时)生成的文件,而不是新文件。
我通过两次调用b2来解决这个问题,首先是使用生成代码的目标,然后再次使新生成的代码正确地进行GLOBbed并重建我的可执行文件。这是有效的,但我真的更喜欢指定“运行代码生成器,如果需要,然后 GLOB输出目录中的任何文件,并确定需要重建的内容”。我没有成功找到合适的搜索条件--bbv2有自己的“生成器”概念,这使我很难找到我正在寻找的东西,而且我没有找到一个很好的例子来源。 / p>
我的规则看起来像这样,我担心我不能更具体。这是一个生成器,它接收* .foo和* .bar类型的文件,并创建一堆CPP文件和一个.baz文件,我用它来确定它是否是最新的。
type.register FOO : foo ;
type.register BAR : bar ;
type.register BAZ : baz ;
generators.register-composing fileset2baz : FOO BAR : BAZ ;
rule fileset2baz ( target : sources * : properties * )
{
# I actually have a switch here based on OS type, but it is not germane to this example
codegen $(target) : $(sources) : $(properties) ;
}
actions codegen
{
./run-the-code-generator
}
# take the fileset and a target object, and invoke the generator
rule fileset ( fileset : target )
{
local FILES = [ path.glob-tree $(fileset) : *.foo *.bar ] ;
local target_baz = $(fileset:B).baz;
baz $(target_baz) : $(FILES) ;
return $(target_baz) ;
}
....然后在我的主项目中,我有类似的东西:
alias cg : [ fileset $(PATH_TO_FILESET) : $(OUTPUT_DIR) ] ;
lib CodeGen : [ GLOB $(OUTPUT_DIR) : *.cpp *.c ] : : : <include>$(OUTPUT_DIR);
如果我将文件集作为CodeGen的源,那么它会评估是否需要与是否需要重建输出文件并行重建。我正在寻找一种强制cg运行的方法(如果需要的话),只有在$(OUTPUT_DIR)中对文件进行全局运行。