我在我的项目中使用scons。问题是我必须两次调用scons才能将构建转换为scons不会重新编译任何东西的状态。我的构建顺序如下:
问题是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选项1st运行scons的输出。时间:
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。这四个文件,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; }
;
%%
答案 0 :(得分:0)
为了正确检测到您的bison/yacc
调用也在创建头文件,SCons需要设置“-d
”命令行标志。然后,相应的Emitter会自动将头文件添加到目标列表中,并将其作为源文件hello.cpp
的隐式依赖项包含在内,而不必通过Depends()
指定显式依赖项。
以下SConstruct
似乎在我身边工作正常:
env = Environment(YACCHXXFILESUFFIX='.hh',
YACCFLAGS=['-d'])
env.CXXFile('parser.cc', 'parser.yy')
env.Program('hello', 'hello.cpp')
请注意我如何实例化命名的构建环境env
,以便我可以更轻松地操作其设置。必须设置文件后缀,因为无论出于何种原因,SCons中的默认值都是*.hpp
。
您可以在UserGuide(http://scons.org/doc/production/HTML/scons-user.html)中找到有关上面使用的环境变量的更多信息,特别是在附录A“构造变量”中。
关于其他文件location.hh
,stack.hh
和position.hh
,最新版本的SCons yacc
工具不支持这些文件。它看起来好像更新版本的yacc/bison
添加了新的关键字,如%locations
,这些关键字当前未被解析以发出正确的目标列表。如果您希望更改此内容,请访问我们的用户邮件列表scons-users@scons.org
(另请参阅http://scons.org/lists.php),描述您的问题并提供有关所需关键字语法的更多信息。然后,我们可以通过扩展yacc
工具来帮助您和所有其他用户。