我试图用SCons构建一个flex-bison解析器,使用自定义决策器。(您可以在this question中了解更多关于决定器的信息,不过,细节可能与当前问题不太相关。)
文件:
我的SConstruct
env = DefaultEnvironment()
deciderEnv = env.Clone()
def source_and_target_decider(dependency, target, prev_ni, repo_node=None):
src_old_csig = prev_ni.csig if hasattr(prev_ni, 'csig') else None
src_new_csig = dependency.get_csig()
tgt_stored_info = target.get_stored_info()
tgt_old_csig = tgt_stored_info.ninfo.csig if hasattr(tgt_stored_info.ninfo, 'csig') else None
tgt_new_csig = target.get_csig()
return src_new_csig != src_old_csig or tgt_new_csig != tgt_old_csig
deciderEnv.Decider(source_and_target_decider)
deciderEnv['YACCFLAGS'] = ['-d']
deciderEnv['YACCHXXFILESUFFIX'] = '.hh'
bison_source = deciderEnv.CXXFile('src/test.yy.cc', 'src/test.yy')[0]
deciderEnv['LEXFLAGS'] = [f'--header-file=${{SOURCE}}.hh']
flex_source = deciderEnv.CXXFile('src/test.ll.cc', 'src/test.ll')[0]
Program('test', [bison_source, flex_source])src/test.yy
%language "c++"
%code {
int yylex(int*);
}
%token X
%%
everything: X {}和src/test.ll
%{
#include "./test.yy.hh"
%}
%option c++
%%
. { return yy::parser::token::X; }结果:
我运行一个命令scons ./src/test.ll.o。第一次运行它时,它工作正常。
flex --header-file=src/test.ll.hh -t src/test.ll > src/test.ll.cc
bison -d -o src/test.yy.cc src/test.yy
g++ -o src/test.ll.o -c src/test.ll.ccSCons似乎明白,在编译src/test.ll.o之前,它需要使用bison生成src/test.yy.hh,因为src/test.ll.cc #include的标题是这样的。
但是,如果我随后删除.sconsign.dblite (保留其余的文件完整),SCons似乎在下一次构建过程中失去了这种理解。运行scons ./src/test.ll.o会产生:
flex --header-file=src/test.ll.hh -t src/test.ll > src/test.ll.cc
g++ -o src/test.ll.o -c src/test.ll.cc只有在第二次调用它之后,它才决定构建src/test.yy.hh
bison -d -o src/test.yy.cc src/test.yy
g++ -o src/test.ll.o -c src/test.ll.cc依赖树:
通常,依赖树(scons --tree=all src/test.ll.o)如下所示:
+-src/test.ll.o
+-src/test.ll.cc
| +-src/test.ll
| +-/bin/flex
+-src/test.yy.hh
| +-src/test.yy
| +-/bin/bison
+-/bin/g++但是,在删除.sconsign.dblite之后,它是不完整的:
+-src/test.ll.o
+-src/test.ll.cc
| +-src/test.ll
| +-/bin/flex
+-/bin/g++进一步意见:
定制决定的最后一行似乎是罪魁祸首。具体来说,部分是or tgt_new_csig != tgt_old_csig。如果删除此部分,问题将不再发生。
但是,我不知道为什么这段特定的代码破坏了构建。
知道怎么解决这个问题吗?
发布于 2022-01-24 21:40:15
SCons在这里存储有关以前构建的信息。
如果您删除它,那么SCons将没有该信息,并将重建一切。
因为在你的决策中你正在设置:
tgt_old_csig = tgt_stored_info.ninfo.csig if hasattr(tgt_stored_info.ninfo, 'csig') else None然后将None与当前csig进行比较,后者不相等,需要重新构建。
当您显式地删除tgt_stored_info的源时,您可能需要进行如下更改才能正常工作( sconsign文件)。
def source_and_target_decider(dependency, target, prev_ni, repo_node=None):
src_old_csig = prev_ni.csig if hasattr(prev_ni, 'csig') else None
src_new_csig = dependency.get_csig()
tgt_stored_info = target.get_stored_info()
tgt_old_csig = tgt_stored_info.ninfo.csig if hasattr(tgt_stored_info.ninfo, 'csig') else None
tgt_new_csig = target.get_csig()
if tgt_old_csig:
return src_new_csig != src_old_csig or tgt_new_csig != tgt_old_csig
else:
return src_new_csig != src_old_csig你为什么要删除.sconsign.dblite?
https://stackoverflow.com/questions/70838718
复制相似问题