C++ 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

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

  • 调用BISIN生成C++编译中包含的CPP和.HH文件。 调用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选项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
    ,最新版本的SCons
    yacc
    工具不支持这些文件。在我看来,较新版本的
    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
    ,最新版本的SCons
    yacc
    工具不支持这些文件。在我看来,较新版本的
    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吗