c++ - Scons 重新编译我的代码

标签 c++ bison scons

我在我的项目中使用 scons。问题是我必须两次调用 scons 才能使构建达到 scons 不重新编译任何东西的状态。我的构建顺序如下:

  1. 调用 bison 生成 .cpp 和 .hh 文件以包含在 C++ 编译中。
  2. 调用C++编译器将C++编译成二进制。

问题是 scons 在运行 bison 之前计算依赖关系,此时自动生成的 .hh 文件不存在。下次我运行 scons 时,它会检测到对 .hh 文件的新依赖并重新编译。 bison 运行并生成头文件后,如何告诉 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 --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;           }   
;
%%

最佳答案

为了正确检测到您的 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

您可以在用户指南 ( http://scons.org/doc/production/HTML/scons-user.html ) 中找到有关上面使用的环境变量的更多信息,尤其是在附录 A“构造变量”中。

关于附加文件location.hhstack.hhposition.hh,最新版本的SCons不支持它们' yacc 工具。在我看来,较新版本的 yacc/bison 添加了新的关键字,如 %locations,目前尚未解析这些关键字以发出正确的目标列表。如果您希望对此进行更改,请访问我们的用户邮件列表 scons-users@scons.org(另请参阅 http://scons.org/lists.php),描述您的问题并提供有关语法的更多信息所需的关键字。然后我们可以尝试通过扩展 yacc 工具来帮助您和所有其他用户。

关于c++ - Scons 重新编译我的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33048378/

相关文章:

c++ - 编码 PHP 代码浏览器 : is Bison/Flex a choice?

c++ - 未找到 Windows SDK 注册表变量

c++ - CRT库类型

compiler-construction - BISON + FLEX 语法 - 为什么标记被连接在一起

c++ - 解析 C/C++ 源代码 : How are token boundaries/interactions specified in lex/yacc?

scons - 如何从 Builder() 内部获取 variant_dir 路径?

c++ - scons 如何将 sysroot 传递给 g++

c++11 - 使用 scons 编译带有 -std=c++11 标志的 c++ 文件

C++ std move 文件错误?

c++ - Excel 文档解析器/导入器?