【问题标题】:Duplicate variant directory before running SConscript在运行 SConscript 之前复制变体目录
【发布时间】:2016-10-03 07:18:40
【问题描述】:

我有 SConscripts,它在 SConscript 目录中包含的所有目录中递归调用 SConscripts。

这不适用于变体构建,因为在评估附属 SConscripts 之前,不会将整个源目录复制到变体目录。

例子

.
├── SConstruct
└── src
    ├── a
    │   ├── a.c
    │   ├── a.h
    │   ├── SConscript
    │   ├── x
    │   │   ├── ax.h
    │   │   └── SConscript
    │   └── y
    │       ├── ay.h
    │       └── SConscript
    ├── b
    │   ├── b.c
    │   ├── b.h
    │   ├── SConscript
    │   ├── x
    │   │   ├── bx.h
    │   │   └── SConscript
    │   └── y
    │       ├── by.h
    │       └── SConscript
    ├── main.c
    └── SConscript

S构造

env = Environment()
objects = SConscript('src/SConscript', exports=['env'], variant_dir='build')
objects = [x for x in env.Flatten(objects) if x is not None]
program = env.Program(target='prog', source=objects)

所有其他 SConscripts

import os

Import('env')
env.AppendUnique(CPPPATH=[Dir('.')])
objects = SConscript(
    dirs=[name for name in os.listdir('.')
          if os.path.isdir(os.path.join('.', name))],
    exports=['env'])
objects = objects + env.Object(env.Glob('*.c'))
Return('objects')

输出

$ scons . --tree=all
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o build/main.o -c -Ibuild build/main.c
build/main.c:1:15: fatal error: a.h: No such file or directory
compilation terminated.
scons: *** [build/main.o] Error 1
+-.
  +-SConstruct
  +-build
  | +-build/SConscript
  | +-build/main.c
  | +-build/main.o
  |   +-build/main.c
  |   +-/usr/bin/gcc
  +-prog
  | +-build/main.o
  | | +-build/main.c
  | | +-/usr/bin/gcc
  | +-/usr/bin/gcc
  +-src
    +-src/SConscript
    +-src/main.c
scons: building terminated because of errors.

在调用 build/SConscript 之前,不会将 src/a 和 src/b 目录复制到 build/a 和 build/b。因此,build/SConscript 不会调用附属的 SConscripts,因为这些目录还不存在。

从 SConstruct 中删除变体目录的输出

$ scons --tree=all
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o src/b/b.o -c -Isrc -Isrc/b -Isrc/b/x -Isrc/b/y -Isrc/a -Isrc/a/x -Isrc/a/y src/b/b.c
gcc -o src/a/a.o -c -Isrc -Isrc/b -Isrc/b/x -Isrc/b/y -Isrc/a -Isrc/a/x -Isrc/a/y src/a/a.c
gcc -o src/main.o -c -Isrc -Isrc/b -Isrc/b/x -Isrc/b/y -Isrc/a -Isrc/a/x -Isrc/a/y src/main.c
gcc -o prog src/b/b.o src/a/a.o src/main.o
+-.
  +-SConstruct
  +-prog
  | +-src/b/b.o
  | | +-src/b/b.c
  | | +-src/b/b.h
  | | +-src/b/x/bx.h
  | | +-src/b/y/by.h
  | | +-/usr/bin/gcc
  | +-src/a/a.o
  | | +-src/a/a.c
  | | +-src/a/a.h
  | | +-src/a/x/ax.h
  | | +-src/a/y/ay.h
  | | +-/usr/bin/gcc
  | +-src/main.o
  | | +-src/main.c
  | | +-src/a/a.h
  | | +-src/b/b.h
  | | +-/usr/bin/gcc
  | +-/usr/bin/gcc
  +-src
    +-src/SConscript
    +-src/a
    | +-src/a/SConscript
    | +-src/a/a.c
    | +-src/a/a.h
    | +-src/a/a.o
    | | +-src/a/a.c
    | | +-src/a/a.h
    | | +-src/a/x/ax.h
    | | +-src/a/y/ay.h
    | | +-/usr/bin/gcc
    | +-src/a/x
    | | +-src/a/x/SConscript
    | | +-src/a/x/ax.h
    | +-src/a/y
    |   +-src/a/y/SConscript
    |   +-src/a/y/ay.h
    +-src/b
    | +-src/b/SConscript
    | +-src/b/b.c
    | +-src/b/b.h
    | +-src/b/b.o
    | | +-src/b/b.c
    | | +-src/b/b.h
    | | +-src/b/x/bx.h
    | | +-src/b/y/by.h
    | | +-/usr/bin/gcc
    | +-src/b/x
    | | +-src/b/x/SConscript
    | | +-src/b/x/bx.h
    | +-src/b/y
    |   +-src/b/y/SConscript
    |   +-src/b/y/by.h
    +-src/main.c
    +-src/main.o
      +-src/main.c
      +-src/a/a.h
      +-src/b/b.h
      +-/usr/bin/gcc
scons: done building targets.

那么有没有办法让 SCons 在运行附属 SConscripts 之前复制源目录,或者让附属 SConscripts 引用源目录。


编辑:我想保持目录列表的动态生成。硬编码目录名称是可行的,但这不是一个可行的解决方案,因为我拥有的目录数量很大并且会不断变化。

【问题讨论】:

  • 是的,按照第 1 章所述的基本设置进行操作。 14“分层构建”和章节。 UserGuide 中的 15 个“分离源和构建目录”。
  • @dirkbaechle SCons 文档中的示例没有考虑使用 os.listdir() 动态生成子目录的情况。随着目录数量的增加,对所有目录名称进行硬编码并不是解决方案。
  • 做你正在做的事情没有什么价值?为什么不让顶级 SConstruct 遍历您的目录树并找到所有 SConscripts 并调用它们,而不是递归。

标签: scons


【解决方案1】:

基于https://stackoverflow.com/a/29218216/2694385,SConscripts 必须引用文件和文件夹,就好像它们已经在变体目录中一样,即使它们实际上不是。

环境中可以保存源码和变体目录,每个SConscript都可以找到对应源码目录的路径(根据其在变体目录中的深度)。

修改后的文件是

S构造

import os

env = Environment()
env['VARIANT_DIR'] = Dir("build")
env['SOURCE_DIR'] = Dir("src")
objects = SConscript(os.path.join(env['SOURCE_DIR'].path, 'SConscript'),
                     exports=['env'],
                     variant_dir=env['VARIANT_DIR'])
objects = [x for x in env.Flatten(objects) if x is not None]
program = env.Program(target='prog', source=objects)

所有 SConscripts

import os

Import('env')
env.AppendUnique(CPPPATH=[Dir('.')])

dir_depth_from_variant = env['VARIANT_DIR'].rel_path(Dir('.'))
corresponding_src_dir = os.path.join(Dir('.').rel_path(env['SOURCE_DIR']),
                                     dir_depth_from_variant)
dirs = [name for name in os.listdir(corresponding_src_dir)
        if os.path.isdir(os.path.join(corresponding_src_dir, name))]
objects = SConscript(
    dirs=dirs,
    exports=['env'])
objects = objects + env.Object(env.Glob('*.c'))
Return('objects')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 2020-10-30
    相关资源
    最近更新 更多