在我看来,scons目标不是按声明顺序生成的。我的问题是,我需要先生成一些代码,我正在使用protoc将my.proto文件处理为.h和.cc文件,我需要这样的伪代码(工作代码应该是什么样?)< / p>
import os
env=Environment(ENV=os.environ,LIBPATH='/usr/local/lib')
env.ShellExecute('protoc', '--outdir=. --out-lang=cpp', 'my.proto')//produces my.cc
myObj=Object('my.cc')//should wait until 'my.cc' is generated by protoc
Dependency(myObj, 'my.cc')
mainObj=Object('main.cpp')
我的问题是:
如何在SConstruct / SConscript中指定此协议的ShellExecution?
如何确保“ main.cpp”的编译取决于“ my.cc”的存在,换句话说,等到生成“ my.cc”后再执行?
答案 0 :(得分:3)
您的观察和假设是正确的, SCons 将不会按照您在SConstruct文件中列出的顺序执行单个构建命令。它将基于构建中目标和源文件的依赖关系来运行它们,这些依赖关系是隐式定义的(例如,C ++中的头文件)或显式定义的(通过Depends()
方法)。
因此,您必须正确定义和设置依赖项,以便 SCons 提供所需的输出。对于您的示例中的特殊protoc
案例,存在一个特殊的Builder,它将帮助您正确设置依赖关系图。它在我们的ToolsIndex中可用,在该处还可以找到对其他多种语言和方言的支持。
这些特殊的构建器将发出正确的目标节点,例如如果给定了*.proto
输入文件,并且 SCons 然后能够自动检测 protoc 输入文件与您的main
程序之间的依赖关系像这样说:
env=Environment(tools=['default','protoc'])
env.Protoc([], "test.proto")
env.Program('main', ['main.cpp'] + Glob('*.cc'))
Glob('*.cc')
将检测到来自 protoc 工具的*.cc
文件,并将其作为最终目标main
的依赖项。
您始终可以在 SCons 中编写自己的生成器和发射器,这是使 SCons 依赖性分析已知的新工具/工具链的规范方法。在UserGuide中,进行分组。 “ 18个编写自己的构建器”,尤其是我们的ToolsForFools Guide,您可以找到有关此的更多信息。