gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 13:26:51 25 4
gpt4 key购买 nike

我在我的项目中使用 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com