问题
Here's my simple case. I got a source file structure as following:
.
├── SConstruct
└── src
├── SConscript
├── staticLib
│ ├── classInStaticLib.cpp
│ ├── classInStaticLib.h
│ └── SConscript
└── test.cpp
SConstruct:
VariantDir('build', 'src', duplicate=0)
SConscript('build/SConscript')
src/SConscript:
import os
lib = 'staticLib'
SConscript(os.path.join(lib, 'SConscript'))
Program( 'test',
'test.cpp',
CPPPATH = lib,
LIBS = lib,
LIBPATH = lib )
src/staticLib/SConscript:
Library('staticLib', 'classInStaticLib.cpp')
After I run scons, I got following in shell:
g++ -o build/staticLib/classInStaticLib.o -c src/staticLib/classInStaticLib.cpp
ar rc build/staticLib/libstaticLib.a build/staticLib/classInStaticLib.o
ranlib build/staticLib/libstaticLib.a
g++ -o build/test.o -c -Ibuild/staticLib -Isrc/staticLib src/test.cpp
g++ -o build/test build/test.o -Lbuild/staticLib -Lsrc/staticLib -lstaticLib
scons completed with no error. But please attention that there're both "-Ibuild/staticLib" and "-Isrc/staticLib" in 4th line, and both "-Lbuild/staticLib" and "-Lsrc/staticLib" in 5th line. There should be only one.
Why this happens ?
回答1:
I think this is happening because you are using the SCons VariantDir()
function, which causes SCons to look in the build directory. Ive never seen that it uses both the source and variant_dir directories.
The VariantDir()
function is usually only used when you're not using the SConscript()
function. Try changing the call to SConscript()
in your SConstruct
to use the variant_dir
parameter and remove the call to VariantDir()
, as follows:
SConscript('src/SConscript', variant_dir='build', duplicate=0)
I would also consider changing the src/SConscript
as follows:
import os
lib = 'staticLib'
SConscript(os.path.join(lib, 'SConscript'),
variant_dir=os.path.join(lib, 'build'),
duplicate=0)
Program( 'test',
'test.cpp',
CPPPATH = lib,
LIBS = lib,
LIBPATH = lib )
Here is the result I get when executing scons, which BTW is the same as yours:
$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
g++ -o build/staticLib/classInStaticLib.o -c src/staticLib/classInStaticLib.cpp
ar rc build/staticLib/libstaticLib.a build/staticLib/classInStaticLib.o
ranlib build/staticLib/libstaticLib.a
g++ -o build/test.o -c -Ibuild/staticLib -Isrc/staticLib src/test.cpp
g++ -o build/test build/test.o -Lbuild/staticLib -Lsrc/staticLib -lstaticLib
scons: done building targets.
$ tree build/
build/
|-- staticLib
| |-- classInStaticLib.o
| `-- libstaticLib.a
|-- test
`-- test.o
1 directory, 4 files
I have never noticed that SCons does this and cant explain why it does so. I tried playing with different variant_dir options and always get the same. I would say you arent doing anything wrong, and that its a peculiar SCons behavior.
回答2:
This is a "normal and intended" effect of using VariantDir() according to a response I got about this on the SCons-users mailing list.
See four.pairlist.net/pipermail/scons-users/2014-April/002440.html
Pawel said: "You may have source files/headers generated (with SWIG for example or by SConf) and they go to variant dir, others are taken directly from source dir, so -Ibuild/staticLib -Isrc/staticLib is correct in my opinion."
回答3:
Here is a workaround that I have used:
import os
def abs_path(rel_path):
return os.path.join(Dir('.').srcnode().abspath, rel_path)
lib = 'staticLib'
SConscript(os.path.join(lib, 'SConscript'))
Program( 'test',
'test.cpp',
CPPPATH = abs_path(lib),
LIBS = lib,
LIBPATH = lib )
回答4:
I created this directory structure:
stest.cpp
Sconstruct
dira/hello.cpp
dira/hello.h
dirb/hello.cpp
dirb/hello.h
My Sconstruct contains this:
SOURCES = [ 'stest.cpp', 'hello.cpp' ]
common = Environment ()
a=common.Clone (CPPPATH='#')
a.Repository ('#/dira')
a.Object ('obja/stest.o', 'stest.cpp')
a.Object ('obja/hello.o', 'dira/hello.cpp')
a.Program ('obja/a', ['obja/stest.o', 'obja/hello.o'])
a.Alias ('a', 'obja/a')
b=common.Clone (CPPPATH='#')
b.Repository ('#/dirb')
b.Object ('objb/stest.o', 'stest.cpp')
b.Object ('objb/hello.o', 'dirb/hello.cpp')
b.Program ('objb/b', ['objb/stest.o', 'objb/hello.o'])
b.Alias ('b', 'objb/b')
Running scons -n a b
gives this:
g++ -o obja/stest.o -c -I. -Idira -Idirb obja/stest.cpp
g++ -o obja/hello.o -c -I. -Idira -Idirb obja/hello.cpp
g++ -o obja/a obja/stest.o obja/hello.o
g++ -o objb/stest.o -c -I. -Idira -Idirb objb/stest.cpp
g++ -o objb/hello.o -c -I. -Idira -Idirb objb/hello.cpp
g++ -o objb/b objb/stest.o objb/hello.o
So, this obviously has nothing to do with VariantDir()
.
来源:https://stackoverflow.com/questions/21217008/scons-variantdir-duplicated-cpppath-and-libpath-when-compiling