[Scons-users] Install functions

Managan, Rob managan1 at llnl.gov
Mon Dec 9 12:28:54 EST 2013


Here is my install function. It creates dirs as needed and sets the owner and group and permissions

#
# Set the group and permissions to install files with
# installFunc is in cale_conf.py
#
env['INSTALL']=installFunc
env['INSTALL_GROUP']='mygroup'
env['INSTALL_MODE']=0710 # leading 0 implies octal

def installFunc(dest, source, env):
"""Install a source file into a destination by copying it (and its
permission/mode bits)."""

owner = env.get('INSTALL_OWNER', None)
if owner:
try:
uid = pwd.getpwnam(owner)[2]
except TypeError:
uid = owner
else:
uid = -1

group = env.get('INSTALL_GROUP', None)
# print 'group',group
if group:
try:
gid = grp.getgrnam(group)[2]
except TypeError:
gid = group
else:
gid = -1

mode = env.get('INSTALL_MODE', None)
# print 'mode',mode
if not mode:
st = os.stat(source)
mode = (stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)

dirname = os.path.dirname(dest)
if not os.path.isdir(dirname):
os.makedirs(dirname)
shutil.copy2(source, dest)

if owner or group:
os.chown(dest, uid, gid)

os.chmod(dest, mode)
return 0


*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-
Rob Managan email managan at llnl.gov
LLNL phone: 925-423-0903
P.O. Box 808, L-095 FAX: 925-422-3389
Livermore, CA 94551-0808




On 12/2/13 7:37 PM, "Francis Bolduc" <fbolduc at gmail.com<mailto:fbolduc at gmail.com>> wrote:

Firstly, I don't think it is a good idea to use the default 'duplicate' semantics
of variant_dir. There are simply far too many files for them to be copied
around so often. And the reasons for 'duplicate' do not apply to me (it seems
to be that duplicate=0 should be the default, not duplicate=1).

The reasoning behind duplicating the source files in the variant dir
is to guarantee reproducible builds. In order to do this, SCons must
know *all* the dependencies of your source files. So, by copying all
the files that it knows about in a separate directory (ie: the variant
dir), then any missing dependency won't be there and will fail the
build.

Obviously, copying files around is costly. So the idea of duplicate=0
is to do a bastard approach where SCons get's creative with the
command lines to build stuff in the variant dir, but use source files
from their actual location.


But now my problem is that the include dirs are being interpreted relative
to the build dir, and not the source dir. In the SConscript I have:
env.Append(CPPPATH=['../FooBar']) # I want this to be relative to the dir
the SConstruct file is in.

Using ".." with variant dir is a recipe for pain. As you found out,
this will be relative to the variant dir, and not the SConscript dir.
If you really can't have your SConscript files in the same directory
as your SConstruct, then you could use the # character, which is
replaced by the path to the SConstruct. Like this:

env.Append(CPPPATH=['#/woot/FooBar'])


Furthermore, there is some current directory wierdness going on.
In the SConscript file, I have "print os.getcwd()"
If the build dir is nonexistent, the first time I run I get cwd as the
directory with the SConscript in. This makes sense to me.
The second time I run, the cwd is the build dir! Even though, with
duplicate=0, the build dir is empty. Yet somehow, cppFiles =
Glob('*.cpp') still gets the correct files from the src dir (the one
with the SConscript file).

I just want the compiled files to end up in a directory that I specify.
This cannot be as hard as it seems to be right now...

Yes, you seem to be fighting an uphill battle. As I previously said, I
was in the same situation 3 years ago, and I decided to stop fighting
SCons. I simply accepted that I had to put the SConstruct and
SConscript files at the top-level of my project, and then everything
started working like a charm.

You can try to fight it. Who knows, maybe you'll win. But if you want
stuff to just work, I recommend you have the following tree for your
project:

somewhere/SConstruct
somewhere/A.SConscript
somewhere/A/include
somewhere/A/src
somewhere/B.SConscript
somewhere/B/include
somewhere/B/src
somewhere/C.SConscript
somewhere/C/include
somewhere/C/src
somewhere/P1.SConscript
somewhere/P1/include
somewhere/P1/src
somewhere/P2.SConscript
somewhere/P2/include
somewhere/P2/src

With the following content SConstruct:

global = Environment()
global.VariantDir('build/${NAME}')
release = global.Clone()
release['NAME'] = 'release'
release['DEBUG_SUFFIX'] = ''
release.AppendUnique(CCFLAGS=['-O2'])
release.Export(shared=release)
debug = global.Clone()
debug['NAME'] = 'debug'
debug['DEBUG_SUFFIX'] = 'g'
debug.AppendUnique(CCFLAGS=['g'])
debug.Export(shared=debug)
sconscripts = '''
A.SConscript
B.SConscript
C.SConscript
P1.SConscript
P2.SConscript
'''.split()
for i in sconscripts:
release.SConscript(i)
debug.SConscript(i)

And the following content for A.SConscript (same for B and C):

env = shared.Clone()
env.AppendUnique(CPPPATH=['A/include'])
env.SharedLibrary('A${DEBUG_SUFFIX}', source=env.Glob('A/src/*.cpp')

And the following content for P1.SConscript (same for P2):

env = shared.Clone()
env.AppendUnique(CPPPATH=['A/include'])
env.AppendUnique(CPPPATH=['P1/include'])
env.AppendUnique(LIBPATH=['.'])
env.AppendUnique(LIBS=['A${DEBUG_SUFFIX}'])
env.Program('P1${DEBUG_SUFFIX}', source=env.Glob('P1/src/*.cpp')


That is the fundamental thing I do where I work.
_______________________________________________
Scons-users mailing list
Scons-users at scons.org<mailto:Scons-users at scons.org>
http://four.pairlist.net/mailman/listinfo/scons-users

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://four.pairlist.net/pipermail/scons-users/attachments/20131209/8b2947e3/attachment.htm


More information about the Scons-users mailing list