Scons循环依赖

时间:2016-12-19 18:05:42

标签: scons

我们从scons 2.4.1更新到2.5.1并突然出现了几个错误: scons:***找到依赖周期:   内部错误:找不到节点的循环...

我认为这个问题与我们尝试在SCM检测到源文件编辑时自动更新的版本文件有关。这个过程的要点是我们维护一个文件> version.cfg'有#defines。此文件已签入我们的SCM。如果文件已经更新一次,则在文件提交给SCM之前不会再次更新。然后,该文件用于自动生成名为' kb_version.hh的C ++头文件。

什么是循环依赖,我该如何消除它? (注意,无论问题是什么,都没有在scons 2.4.1中引起问题(只有当我们使用新版本2.5.1时才检测到循环依赖)。

相关的scons片段如下:

 SRCDIR = '../../src'

 SRCS = [
   'kb.cc',
 ]

 SOURCE = [ os.path.join(SRCDIR, s) for s in SRCS ]

 SCRIPT_VERSION_GEN = os.path.join(env['_ROOT'], 'kb/build/scripts/versionGen.sh')
 SCRIPT_VERSION_UPD = os.path.join(env['_ROOT'], 'kb/build/scripts/versionUpdate.sh')

 FILE_VERSION_CFG = 'version.cfg'
 FILE_VERSION_HH  = 'kb_version.hh'

 scriptVerGen = env.File(SCRIPT_VERSION_GEN)
 scriptVerUpd = env.File(SCRIPT_VERSION_UPD)
 verCfg = env.File(os.path.join(SRCDIR, FILE_VERSION_CFG))
 verHH  = env.File(os.path.join(SRCDIR, FILE_VERSION_HH))

 ## this command detects for change in source files, then updates, when necessary, the source version.cfg
 env.Command(
   target = verCfg,
   source = [ SOURCE, scriptVerUpd ],
   action = [ scriptVerUpd.path + ' ' + env['BS_DIR_SRCROOT'] + '/kb/foo' + verCfg.srcnode().path, Copy(verCfg.path, verCfg.srcnode().path) ]
 )

 env.Command(
   target = verHH,
   source = [ verCfg, scriptVerGen ],
   action = scriptVerGen.path + ' ' + verHH.path + ' ' + verCfg.path
 )

2 个答案:

答案 0 :(得分:0)

一些内联问题。上面的评论部分不容易做到.. (参见下面的##评论)

 SRCDIR = '../../src'

 SRCS = [
   'kb.cc',
 ]

 SOURCE = [ os.path.join(SRCDIR, s) for s in SRCS ]


 ## Is _ROOT the top of your tree where SConstruct lives?
 SCRIPT_VERSION_GEN = os.path.join(env['_ROOT'], 'kb/build/scripts/versionGen.sh')
 SCRIPT_VERSION_UPD = os.path.join(env['_ROOT'], 'kb/build/scripts/versionUpdate.sh')

 FILE_VERSION_CFG = 'version.cfg'
 FILE_VERSION_HH  = 'kb_version.hh'

 scriptVerGen = env.File(SCRIPT_VERSION_GEN)
 scriptVerUpd = env.File(SCRIPT_VERSION_UPD)
 verCfg = env.File(os.path.join(SRCDIR, FILE_VERSION_CFG))
 verHH  = env.File(os.path.join(SRCDIR, FILE_VERSION_HH))

 ## this command detects for change in source files, then updates, when necessary, the source version.cfg
 env.Command(
   target = verCfg,
   source = [ SOURCE, scriptVerUpd ],

   ## Why not do this?
   action = [ '$SCRIPT_VERSION_UPD $BS_DIR_SRCROOT /kb/foo ' + verCfg.srcnode().path,  ## Why srcnode()?
              ## Why do this? 
              Copy(verCfg.path, verCfg.srcnode().path) ]
 )

 env.Command(
   target = verHH,
   source = [ verCfg, scriptVerGen ],  
   ## How about this change
   action = '$SCRIPT_VERSION_GEN $TARGET' + verCfg.path
 )

答案 1 :(得分:0)

我能够找到问题所在,尽管我不确定这是否是scons所希望的行为。

问题是这个。 (1)C ++源文件取决于version.h(通过#include) (2)version.h是从version.cfg自动生成的 (3)如果已更新任何源文件,其中包括依赖于version.h的源文件(因此具有循环依赖性),则version.cfg会自动递增。但是,c ++源文件可能没有实际更改,但是文件本身#includes version.h。因此,我们的意图是,当且仅当源文件本身已更改时,才应更新version.cfg(而不是源于编译源文件的目标文件)。

在下面的注释中,可以通过在第一次env.Command()调用的“ source =”行中删除SOURCE变量来消除循环依赖。

在scons中是否有办法说我依赖于源文件,而不依赖于目标文件?还是这是周期性依赖关系中的错误/细微之处?