0

在我看来,scons 目标不是按声明顺序生成的。我的问题是,我需要先生成一些代码,我正在使用 protoc 将 my.proto 文件处理为 .h 和 .cc 文件,我需要一些这样的伪代码(工作代码应该是什么样的?)

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')

我的问题是:

  1. 如何在 SConstruct/SConscript 中指定 protoc 的 ShellExecution?

  2. 如何确保'main.cpp'的编译依赖于'my.cc'的存在,即等到'my.cc'生成后再执行?

4

1 回答 1

4

您的观察和假设是正确的,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')它将检测您的文件*.cc,从protoc工具中出来,并将它们作为最终目标的依赖项main

您始终可以在SCons中编写自己的构建器和发射器,这是使SCons依赖分析已知的新工具/工具链的规范方式。在UserGuide中,第。“18 编写您自己的构建器”,尤其是我们的ToolsForFools 指南,您可以找到有关此的更多信息。

于 2018-09-14T08:06:35.637 回答