【发布时间】:2015-10-09 23:06:17
【问题描述】:
我在我的项目中使用 scons。问题是我必须调用 scons 两次才能使构建达到 scons 不会重新编译任何东西的状态。我的构建顺序如下:
- 调用 bison 生成 .cpp 和 .hh 文件以包含在 C++ 编译中。
- 调用C++编译器将C++编译成二进制。
问题是 scons 在运行 bison 之前计算依赖关系,此时自动生成的 .hh 文件不存在。下次我运行 scons 时,它会检测到 .hh 文件的新依赖关系并重新编译。野牛运行并生成头文件后如何告诉scons做依赖链?
这是一个演示问题的示例 SConscript。
Program(target = 'hello', source = 'hello.cpp')
CXXFile (source='parser.yy', target=['parser.cc'])
Depends('hello.cpp', 'parser.cc')
这是使用 --tree=prune 选项 1 运行 scons 的输出。时间:
scons --tree=prune
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
bison -o parser.cc parser.yy
g++ -o hello.o -c hello.cpp
g++ -o hello hello.o
+-.
+-SConstruct
+-hello
| +-hello.o
| | +-hello.cpp
| | | +-parser.cc
| | | +-parser.yy
| | | +-/usr/local/bin/bison
| | +-hello.h
| | +-/bin/g++
| +-/bin/g++
+-[hello.cpp]
+-hello.h
+-[hello.o]
+-[parser.cc]
+-parser.yy
scons: done building targets.
这是第二次运行的输出。您可以看到 scons 仅在第二次运行时才找到对 bison 生成的 .hh 文件的依赖关系,这就是它重新编译的原因。
# scons --tree=prune
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o hello.o -c hello.cpp
+-.
+-SConstruct
+-hello
| +-hello.o
| | +-hello.cpp
| | | +-parser.cc
| | | +-parser.yy
| | | +-/usr/local/bin/bison
| | +-hello.h
| | +-parser.hh
| | +-location.hh
| | +-stack.hh
| | +-position.hh
| | +-/bin/g++
| +-/bin/g++
+-[hello.cpp]
+-hello.h
+-[hello.o]
+-location.hh
+-[parser.cc]
+-parser.hh
+-parser.yy
+-position.hh
+-stack.hh
scons: done building targets.
hello.cpp 看起来像这样:
#include "hello.h"
#include "parser.hh"
int main() {
return 0;
}
还有 hello.h:
#define foo 1
这里是 parser.yy 。这 4 个文件 hello.cpp、hello.h、parser.yy 和 SConscript 应该构成一个完整的工作示例来演示该问题。
{
%}
%start input
%defines
%skeleton "lalr1.cc"
%locations
%initial-action
{
@$.begin.filename = @$.end.filename = &driver.streamname;
};
%define api.value.type {double}
%token NUM
%left '-' '+'
%left '*' '/'
%precedence NEG
%right '^'
%%
input:
%empty
| input line
;
line:
'\n'
| exp '\n' { printf ("\t%.10g\n", $1); }
;
exp:
NUM { $$ = $1; }
;
%%
【问题讨论】:
-
尝试让你的目标依赖于生成的文件,
program = Program(...); env.Depends(program, generated_sources); -
尝试运行:scons --tree=prune 并粘贴或粘贴结果。 SCons 不需要头文件就知道它会在那里。这就是发射器的用途。这是一条陈旧的路径,因此很可能是一些小问题导致它无法正常工作。
-
上面我添加了运行 scons 的输出,使用 --tree=prune 选项 1st。时间和第二次。您可以看到 scons 仅在第二次运行时才找到对 bison 生成的 .hh 文件的依赖关系。
-
你也可以发一份
hello.cpp的逐字副本吗?我不清楚您实际上是如何将生成的解析器源包含到您的程序中的。你尝试直接包含parser.yy,还是标题parser.hh? -
添加了 hello.cpp 和 hello.h 代码。它们实际上只是演示问题的最小可编译文件。