Scons VariantDir() duplicated CPPPATH and LIBPATH when compiling?

北城以北 提交于 2020-02-22 04:19:41

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!