I am using scons to compile my project. In my project source files are in different directories. Do we need sconscript file in every directory to compile those project source files?
I tried to compile all directories with the single sconscript file. But all object files are adding to my source directory only.
I am using this function:
env.Library('libs',files_list)
If files_list contains the only file names then Obj files are generating @ variant directory.
If files_list contains the file path names then Obj files are generating @ source directory.
Can you tell me how to do this?
I prepared an example that shows how to compile a project like yours with just one SConstruct script (no subsidiary SConscripts) using the SCons VariantDir() function. I decided to do this in a separate answer so that it would be easier to read.
The VariantDir() function isnt documented very well, so the behavior you mention regarding the placement of the compiled object files isnt straight-forward to fix. The "trick" is to refer to all of your source files in the variant directory, not in your actual source directory, as can be seen below.
Here is the structure of the source files in my project:
$ tree .
.
├── SConstruct
├── src1
│ ├── class1.cc
│ └── class1.h
├── src2
│ ├── class2.cc
│ └── class2.h
└── srcMain
└── main.cc
Here is the 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])
Here is the compilation output:
$ 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.
And here is the resulting project structure after compiling:
$ 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
It should be mentioned that a more straight-forward way to do this is with the SConscript() function, specifying the variant_dir, but if your requirements dont allow you to do so, this example will work. The SCons man page has more info about the VariantDir() function. There you will also find the following:
Note that VariantDir() works most naturally with a subsidiary SConscript file.