我们从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
)
答案 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中是否有办法说我依赖于源文件,而不依赖于目标文件?还是这是周期性依赖关系中的错误/细微之处?