C++ Scons重新编译我的代码
我在我的项目中使用SCON。问题是我必须调用scons两次,以使构建达到scons不重新编译任何内容的状态。我的构建顺序如下:C++ Scons重新编译我的代码,c++,bison,scons,C++,Bison,Scons,我在我的项目中使用SCON。问题是我必须调用scons两次,以使构建达到scons不重新编译任何内容的状态。我的构建顺序如下: 调用BISIN生成C++编译中包含的CPP和.HH文件。 调用C++编译器将C++编译成二进制。 问题是scons在运行bison之前计算依赖项,此时自动生成的.hh文件不存在。下次运行scons时,它会检测到对.hh文件的新依赖并重新编译。在bison运行并生成头文件后,我如何告诉scons执行依赖链 下面是一个示例SConscript,它演示了这个问题 Progra
Program(target = 'hello', source = 'hello.cpp')
CXXFile (source='parser.yy', target=['parser.cc'])
Depends('hello.cpp', 'parser.cc')
下面是使用--tree=prune选项1运行SCON的输出。时间:
烤饼——树=修剪
这是第二次运行的输出。您可以看到,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;
}
你好。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; }
;
%%
为了正确检测您的
bison/yacc
调用是否也在创建头文件,SCons需要设置“-d
”命令行标志。然后,相应的发射器将头文件自动添加到目标列表中,并将其作为源文件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()中找到关于上面使用的环境变量的更多信息,尤其是在附录A“构造变量”中
关于附加文件
location.hh
、stack.hh
和position.hh
,最新版本的SConsyacc
工具不支持这些文件。在我看来,较新版本的yacc/bison
似乎添加了新的关键字,如%locations
,这些关键字当前未被解析以发出正确的目标列表。如果您想更改此内容,请访问我们的用户邮件列表scons-users@scons.org
(另请参见),描述您的问题并提供有关所需关键字语法的更多信息。然后,我们可以尝试通过扩展yacc
工具来帮助您和所有其他用户。为了正确检测您的bison/yacc
调用是否也在创建头文件,SCons需要设置“-d
”命令行标志。然后,相应的发射器将头文件自动添加到目标列表中,并将其作为源文件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()中找到关于上面使用的环境变量的更多信息,尤其是在附录A“构造变量”中
关于附加文件
location.hh
、stack.hh
和position.hh
,最新版本的SConsyacc
工具不支持这些文件。在我看来,较新版本的yacc/bison
似乎添加了新的关键字,如%locations
,这些关键字当前未被解析以发出正确的目标列表。如果您想更改此内容,请访问我们的用户邮件列表scons-users@scons.org
(另请参见),描述您的问题并提供有关所需关键字语法的更多信息。然后,我们可以尝试通过扩展yacc
工具来帮助您和所有其他用户。尝试使您的目标依赖于生成的文件,program=program(…);环境依赖(程序、生成的源)代码>尝试运行:scons--tree=修剪并粘贴或粘贴结果。SCons不需要头文件就知道它会在那里。这就是发射器的用途。这是一条非常陈旧的路径,所以很可能是一些次要的东西使它无法工作。第二次和第二次。您可以看到,scons仅在第二次运行时才找到对bison生成的.hh文件的依赖关系。您是否也可以发布hello.cpp
的逐字副本?我不清楚您实际上是如何将生成的解析器源代码包含到程序中的。您是否尝试直接包含parser.yy
,还是包含头parser.hh
?添加了hello.cpp和hello.h代码。它们实际上只是演示问题的最小可编译文件。请尝试使您的目标依赖于生成的文件,program=program(…);环境依赖(程序、生成的源)代码>尝试运行:scons--tree=修剪并粘贴或粘贴结果。SCons不需要头文件就知道它会在那里。这就是发射器的用途。这是一条非常陈旧的路径,所以很可能是一些次要的东西使它无法工作。第二次和第二次。您可以看到,scons仅在第二次运行时才找到对bison生成的.hh文件的依赖关系。您可以发布一个ve吗