带有变体目录的分层构建中的 scons 依赖问题 [英] scons dependency problems in a hierarchical build with variant dirs

查看:60
本文介绍了带有变体目录的分层构建中的 scons 依赖问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 scons 的新手,并且在 scons 依赖方面有问题在带有变体目录的分层构建中.

我能够在包含以下内容的简化环境中重现该问题SConscript目录下的2个子目录(moduleA和moduleB)如下:

<预><代码>.|-- SConstruct|-- 文件.conf|-- 模块A||-- 征兵|`--conf2cc`--模块B|-- 征兵`--fileB.cc

以下是需要完成的工作流程:

  1. moduleA 执行shell脚本:conf2cc,输入:$projRootDir/file.conf,输出:moduleA/$variantDir/source.cc
  2. moduleA 编译 source.cc 并创建 moduleA/$variantDir/libmoduleA.a
  3. moduleB 需要将 moduleA/$variantDir/source.cc 复制到 moduleB/source.cc
  4. moduleB 需要将 moduleB/source.cc 和 moduleB/fileB.cc 编译成它的库 libmoduleB.a

我完全有可能在这里做错了几件事.例如,我知道我没有在 moduleA Command() 中使用 $TARGET/$SOURCE,但这是故意的,因为脚本需要绝对路径名,并且 scons 不会删除前导的#"

我遇到的问题是 moduleB(上面的第 3 步)中的 Command() 构建器永远不会执行.

以下是 SConstruct 和 SConscript 文件:

构造

导入操作系统环境 = 环境()env['variantDir'] = 'linux' # 对于这个例子,只需要让 variantDir = linux模块 = ['moduleA', 'moduleB']对于模块中的目录:士兵(os.path.join(dir, 'SConscript'),variant_dir = os.path.join(dir, env['variantDir']),出口 = ['env'],重复 = 0)

moduleA/Sconscript

导入操作系统导入('环境')脚本输入 = '#file.conf'sourceFile = os.path.join('#moduleA', env['variantDir'], 'source.cc')conf2ccScript = File('#moduleA/conf2cc').abspath# 脚本需要用于输入和输出的 abspaths,而不是前置的 scons '#'# 脚本语法为:script <输出文件>cmd = '%s %s %s' % (conf2ccScript, File(scriptInput).abspath, File(sourceFile).abspath)# 根据file.conf生成source.cc文件conf2ccNode = env.Command(target = sourceFile,源 = 脚本输入,动作 = cmd)libNode = env.Library(target = 'moduleA', source = sourceFile)env.Depends(libNode, conf2ccNode)

moduleB/Sconscript

导入操作系统导入('环境')sourceFiles = ['fileB.cc', 'source.cc']# 获取source.cc文件externalSourceFile = os.path.join('#moduleA', env['variantDir'], 'source.cc')sourceTarget = os.path.join('#moduleB', 'source.cc')cmdNode = env.Command(target = sourceTarget,源 = 外部源文件,action = Copy('$TARGET', '$SOURCE'))libNode = env.Library(target = 'moduleB', source = sourceFiles)env.Depends(libNode, cmdNode)

这是我执行 scons 时的输出:

任何帮助将不胜感激!

布雷迪

notroot@ubuntu:~/projects/sconsTest/sconsTestHierDeps$ sconsscons:读取 SConscript 文件...scons:完成读取 SConscript 文件.scons:建立目标....../home/notroot/projects/sconsTest/sconsTestHierDeps/moduleA/conf2cc/home/notroot/projects/sconsTest/sconsTestHierDeps/file.conf/home/notroot/projects/sconsTest/sconsTestHierDeps/moduleA/linux/source.ccg++ -o moduleA/linux/source.o -c moduleA/linux/source.ccar rc moduleA/linux/libmoduleA.a moduleA/linux/source.oranlib 模块A/linux/libmoduleA.ag++ -o moduleB/linux/fileB.o -c moduleB/fileB.ccscons: *** [moduleB/linux/source.o] 找不到源moduleB/source.cc",目标moduleB/linux/source.o"需要.scons:建筑物因错误而终止.

解决方案

我建议您使用的内容和文件名不正确.

可能是moduleB 的variant_dir 和源文件有问题,您使用Command 生成#/moduleB/source.cc,但在sourceFiles 中您有'source.cc'.

因此,帮助您的方法之一可能是正确的 moduleB SConscript :

#获取source.cc文件externalSourceFile = os.path.join('#moduleA', env['variantDir'], 'source.cc')sourceTarget = os.path.join('#moduleB', 'source.cc')sourceFiles = ['fileB.cc', sourceTarget]cmdNode = env.Command(target = sourceTarget,源 = 外部源文件,action = Copy('$TARGET', '$SOURCE'))libNode = env.Library(target = 'moduleB', source = sourceFiles)

并尝试使用像源文件一样的命令.而是文件名.看起来更正确.模块A:

conf2ccNode = env.Command(target = sourceFile,源 = 脚本输入,动作 = cmd)libNode = env.Library(target = 'moduleA', source = conf2ccNode)

模块B:

cmdNode = env.Command(target = sourceTarget,源 = 外部源文件,action = Copy('$TARGET', '$SOURCE'))libNode = env.Library(target = 'moduleB', source = ['fileB.cc', cmdNode])

Im new to scons and am having problems with scons dependancies in a hierarchichal build with a variant directory.

Im able to reproduce the problem in a reduced environment that consists of 2 subdirs under the SConscript directory (moduleA and moduleB) as follows:

.
|-- SConstruct
|-- file.conf
|-- moduleA
|   |-- SConscript
|   `-- conf2cc
`-- moduleB
    |-- SConscript
    `-- fileB.cc

Here is the flow of what needs to be done:

  1. moduleA executes a shell script: conf2cc, input: $projRootDir/file.conf, output: moduleA/$variantDir/source.cc
  2. moduleA compiles source.cc and creates moduleA/$variantDir/libmoduleA.a
  3. moduleB needs to copy moduleA/$variantDir/source.cc to moduleB/source.cc
  4. moduleB needs to compile moduleB/source.cc and moduleB/fileB.cc into its library libmoduleB.a

Its entirely possible that Im doing several things wrong here. For example, I know Im not using $TARGET/$SOURCE in moduleA Command(), but thats on purpose, since the script needs the absolute path names, and scons doesnt remove the leading '#'

The problem I have is the Command() builder in moduleB (step 3 above) never executes.

Here are the SConstruct and SConscript files:

Sconstruct

import os

env = Environment()
env['variantDir'] = 'linux'  # for this example, just make variantDir = linux
modules = ['moduleA', 'moduleB']

for dir in modules:
    SConscript(
        os.path.join(dir, 'SConscript'),
        variant_dir = os.path.join(dir, env['variantDir']),
        exports = ['env'],
        duplicate = 0)

moduleA/Sconscript

import os

Import('env')

scriptInput   = '#file.conf'
sourceFile    = os.path.join('#moduleA', env['variantDir'],  'source.cc')
conf2ccScript = File('#moduleA/conf2cc').abspath

# The script needs abspaths for input and output, not the scons '#' prepended
# the script syntax is: script <inputFile> <outputFile>
cmd = '%s %s %s' % (conf2ccScript, File(scriptInput).abspath, File(sourceFile).abspath)

# Generate source.cc file based on file.conf
conf2ccNode = env.Command(target = sourceFile,
                          source = scriptInput,
                          action = cmd)

libNode = env.Library(target = 'moduleA', source = sourceFile)
env.Depends(libNode, conf2ccNode)

moduleB/Sconscript

import os

Import('env')

sourceFiles = ['fileB.cc', 'source.cc']

# Get the source.cc file
externalSourceFile  = os.path.join('#moduleA', env['variantDir'], 'source.cc')
sourceTarget        = os.path.join('#moduleB', 'source.cc')

cmdNode = env.Command(target = sourceTarget,
                      source = externalSourceFile,
                      action = Copy('$TARGET', '$SOURCE'))

libNode = env.Library(target = 'moduleB', source = sourceFiles)
env.Depends(libNode, cmdNode)

Here is the output when I execute scons:

Any help would be greatly appreciated!

Brady

notroot@ubuntu:~/projects/sconsTest/sconsTestHierDeps$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
/home/notroot/projects/sconsTest/sconsTestHierDeps/moduleA/conf2cc /home/notroot/projects/sconsTest/sconsTestHierDeps/file.conf /home/notroot/projects/sconsTest/sconsTestHierDeps/moduleA/linux/source.cc
g++ -o moduleA/linux/source.o -c moduleA/linux/source.cc
ar rc moduleA/linux/libmoduleA.a moduleA/linux/source.o
ranlib moduleA/linux/libmoduleA.a
g++ -o moduleB/linux/fileB.o -c moduleB/fileB.cc
scons: *** [moduleB/linux/source.o] Source `moduleB/source.cc' not found, needed by target `moduleB/linux/source.o'.
scons: building terminated because of errors.

解决方案

I suggest problem in incorrect dependency what you use and filenames.

May be problem in variant_dir and source files for moduleB, you use Command to generate #/moduleB/source.cc, but in sourceFiles you have 'source.cc'.

So, one of ways to help you may be correct moduleB SConscript :

# Get the source.cc file
externalSourceFile  = os.path.join('#moduleA', env['variantDir'], 'source.cc')
sourceTarget        = os.path.join('#moduleB', 'source.cc')

sourceFiles = ['fileB.cc', sourceTarget]

cmdNode = env.Command(target = sourceTarget,
                      source = externalSourceFile,
                      action = Copy('$TARGET', '$SOURCE'))

libNode = env.Library(target = 'moduleB', source = sourceFiles)

And try to use Command like source file. instead filename. It's looks more correct. moduleA :

conf2ccNode = env.Command(target = sourceFile,
                          source = scriptInput,
                          action = cmd)
libNode = env.Library(target = 'moduleA', source = conf2ccNode)

moduleB:

cmdNode = env.Command(target = sourceTarget,
                      source = externalSourceFile,
                      action = Copy('$TARGET', '$SOURCE'))

libNode = env.Library(target = 'moduleB', source = ['fileB.cc', cmdNode])

这篇关于带有变体目录的分层构建中的 scons 依赖问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆