我们需要在每一个源目录sconscript文件(Do we need sconscript file

2019-08-17 14:18发布

我使用scons的编译我的项目。 在我的项目源文件在不同的目录。 我们是否需要sconscript文件中的每个目录编译这些项目的源文件?

我试图编译所有目录与单sconscript文件。 但是,所有的目标文件添加到我的唯一源目录。

我使用这个功能:

env.Library('libs',files_list)

如果files_list包含唯一的文件名,那么的OBJ文件生成@ variant目录。

如果files_list包含文件路径名则的OBJ文件生成@源目录。

你能告诉我如何做到这一点?

Answer 1:

我准备演示了如何编写一个项目像你这样用利用Scons VariantDir()函数只是一个SConstruct脚本(无子公司SConscripts)的例子。 我决定做这在一个单独的答案,这样会更容易阅读。

该VariantDir()函数的心不是记录非常好,所以你提到的关于编译的对象文件的布局行为心不是直接的解决。 该“绝招”是指所有源文件中的variant目录,而不是在你实际的源目录,可以看到下面。

这是在我的项目源文件的结构:

$ tree .
.
├── SConstruct
├── src1
│   ├── class1.cc
│   └── class1.h
├── src2
│   ├── class2.cc
│   └── class2.h
└── srcMain
    └── main.cc

这里是SConstruct:

env = Environment()

# Set the include paths
env.Append(CPPPATH = ['src1', 'src2'])

# Notice the source files are referred to in the build dir
# If you dont do this, the compiled objects will be in the src dirs
src1Sources = ['build/lib1/class1.cc']
src2Sources = ['build/lib2/class2.cc']
mainSources = ['build/mainApp/main.cc']

env.VariantDir(variant_dir = 'build/lib1', src_dir = 'src1', duplicate = 0)
env.VariantDir(variant_dir = 'build/lib2', src_dir = 'src2', duplicate = 0)
env.VariantDir(variant_dir = 'build/mainApp', src_dir = 'srcMain', duplicate = 0)

lib1 = env.Library(target = 'build/lib1/src1', source = src1Sources)
lib2 = env.Library(target = 'build/lib1/src2', source = src2Sources)
env.Program(target = 'build/mainApp/main', source = [mainSources, lib1, lib2])

以下是编译输出:

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o build/lib1/class1.o -c -Isrc1 -Isrc2 src1/class1.cc
ar rc build/lib1/libsrc1.a build/lib1/class1.o
ranlib build/lib1/libsrc1.a
g++ -o build/lib2/class2.o -c -Isrc1 -Isrc2 src2/class2.cc
ar rc build/lib1/libsrc2.a build/lib2/class2.o
ranlib build/lib1/libsrc2.a
g++ -o build/mainApp/main.o -c -Isrc1 -Isrc2 srcMain/main.cc
g++ -o build/mainApp/main build/mainApp/main.o build/lib1/libsrc1.a build/lib1/libsrc2.a
scons: done building targets.

这里是编译后生成的项目结构:

$ tree .
.
├── build
│   ├── lib1
│   │   ├── class1.o
│   │   ├── libsrc1.a
│   │   └── libsrc2.a
│   ├── lib2
│   │   └── class2.o
│   └── mainApp
│       ├── main
│       └── main.o
├── SConstruct
├── src1
│   ├── class1.cc
│   └── class1.h
├── src2
│   ├── class2.cc
│   └── class2.h
└── srcMain
    └── main.cc

应该提到的是一个更直接的方式来做到这一点是与SConscript()函数,指定variant_dir,但如果你的要求不容许你这样做,这个例子会工作。 该SCons的手册页有关于VariantDir()函数的更多信息。 在那里,你还可以找到以下内容:

需要注意的是VariantDir()的作品最自然的一个子公司SConscript文件。



Answer 2:

要回答你的第一个问题:不,它不是必须有一个SConscript在每一个SRC子目录,以便能够编译该目录中的文件。 一切都可以从一个单一的SConstruct来完成。

话虽如此,它被认为是更清洁和更好的组织往往倍有SConscript在不断的src子目录。 通常,在这种情况下,根SConstruct将设置东西,是共同的整个项目,并协调调用到SRC子目录。 然后,在每个SRC子目录的SConstruct将重点放在子目录的细节。 我喜欢这种方法,因为它更模块化。 此外,这将让你与调用不同的环境相同的SRC子目录SConstruct编译成不同版本相同的代码,如调试和发布。

所有这一切都可以通过在SConstruct创造一种环境,然后将它传递给与SConscript()函数sudirs来完成。 下面是一个例子:

SConstruct

env = Environment()
env.Append(CPPPATH = '/some/dir/common/to/all')

SConscript('src/subdirA/SConscript',
           variant_dir = 'build/subdirA',
           duplicate = 0,
           exports = 'env')
SConscript('src/subdirB/SConscript',
           variant_dir = 'build/subdirB',
           duplicate = 0,
           exports = 'env')

SRC / subdirA / SConscript

Import('env')

# If you need to add specific things to the env, then you should clone it,
# else the changes will be seen in other subdirs: clonedEnv = env.Clone()
# No need to specify the path to the source files if all source files are in 
# the same dir as this SConscript.
env.Library(target='subdirA', source='fileA.cc')

SRC / subdirB / SConscript

Import('env')

# If you need to add specific things to the env, then you should clone it,
# else the changes will be seen in other subdirs: clonedEnv = env.Clone()
env.Library(target='subdirB', source='fileB.cc')

至于最后的问题,我真的不明白你在寻找什么,但我用上面解释了选项,编译后的目标将始终被放置在VariantDir。



文章来源: Do we need sconscript file in every source directory
标签: python scons