# -*-python-*-
#-------------------------------------------------------------------------------
#
# OpenAlea.SConsX: SCons extension package for building platform
# independant packages.
#
# Copyright 2005-2007 INRIA - CIRAD - INRA
#
# File author(s):
# Christophe Pradal <christophe.prada@cirad.fr>
# Pierre Barbier de Reuille <pierre.barbier@sophia.inria.fr>
# Samuel Dufour-Kowalski <samuel.dufour@sophia.inria.fr>
#
# Distributed under the Cecill-C License.
# See accompanying file LICENSE.txt or copy at
# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html
#
# OpenAlea WebSite : http://openalea.gforge.inria.fr
#
#--------------------------------------------------------------------------------
"""This module add some facilities to simplify the SConscript files to
the minimum. It contains wrapper functions that extend the SCons
environment and abstract the operating system.
Each function defines or populate global aliases like build or install.
"""
__license__ = "Cecill-C"
__revision__ = "$Id$"
import os, sys
#from path import path
from SCons.Script.SConscript import SConsEnvironment, DefaultEnvironmentCall
import SCons.Builder
import SCons.Action
import SCons.Node.FS
Alias = DefaultEnvironmentCall("Alias")
[docs]
def ALEALibrary(env, target, source, *args, **kwds):
"""
Build static or dynamic library depending on user flags.
Install the build library and associated files in specific directories.
Define 'build' and 'install' target.
"""
_target = env.subst("$build_libdir/%s"%target)
if env.get("static", False):
lib = env.StaticLibrary(_target, source, *args, **kwds)
else:
if (env['compiler'] == 'msvc') and ('8.0' in env['MSVC_VERSION']):
kwds['SHLINKCOM'] = [env['SHLINKCOM'],
'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;2']
lib = env.SharedLibrary(_target, source, *args, **kwds)
def select_dll(lib):
# On windows, we need to separate dll and lib
try:
# Visual style
dll, lib, exp = lib
except:
# mingw style
dll, lib = lib
return dll, lib
# Building
bld_lib = lib
if os.name != 'posix' and not env.get("static", False) :
# For windows, we should still move the dll and lib in separate directory.
dll, lib = select_dll(lib)
dll = env.Install("$build_bindir", dll)
Alias("build_lib", dll)
Alias("build", dll)
bld_lib = dll + [lib]
Alias("build_lib", lib)
Alias("build", lib)
# Installing
inst_lib = []
if os.name != 'posix' and not env.get("static", False):
# On windows, we need to install the dll.
if env.subst("$build_bindir") != env.subst("$bindir"):
dll = env.Install("$bindir", dll)
inst_lib += dll
# else we reuse the already installed dll
Alias("install_lib", dll)
Alias("install", dll)
if env.subst("$build_libdir") != env.subst("$libdir"):
# We should install the lib in libdir
lib = env.Install("$libdir", lib)
inst_lib += lib
# else we reuse the already installed lib
Alias("install_lib", lib)
Alias("install", lib)
return (bld_lib, inst_lib)
[docs]
def ALEAIncludes(env, target, includes, *args, **kwds):
"""
Install the headers in the directory .../include/mypackage
Define 'build' and 'install' target.
"""
inc = env.Install("$build_includedir/%s" % (target,), includes, *args, **kwds)
env.Alias("build_lib", inc)
env.Alias("build", inc)
if env.subst("$build_includedir") == env.subst("$includedir"):
inst_inc = []
# In this case, this target should simply be build for install mode
Alias("install_lib", inc)
Alias("install", inc)
else:
inst_inc = env.Install("$includedir/%s" % (target,), includes, *args, **kwds)
Alias("install_lib", inst_inc)
Alias("install", inst_inc)
return (inc, inst_inc)
[docs]
def ALEAProgram(env, target, source, *args, **kwds):
"""
Build a program and install it in local and system directories.
"""
bin = env.Program("$build_bindir/%s" % (target,), source, *args, **kwds)
Alias("build", bin)
Alias("build_lib", bin)
if env.subst("$build_bindir") == env.subst("$bindir"):
inst_bin = []
# In this case, this target should simply be build for install mode
Alias("install_lib", bin)
Alias("install", bin)
else:
inst_bin = env.Install("$bindir", bin)
Alias("install_lib", inst_bin)
Alias("install", inst_bin)
return (bin, inst_bin)
[docs]
def ALEAWrapper(env, python_dir, target, source, *args, **kwds):
"""
Build a python wrapper and install it in a python package.
"""
real_target = "%s/%s" % (str(env.Dir(python_dir).srcnode()), target)
if os.name == 'nt':
kwds['SHLIBSUFFIX'] = '.pyd'
else:
kwds['SHLIBSUFFIX'] = '.so'
if (env['compiler'] == 'msvc') and ('8.0' in env['MSVC_VERSION']):
kwds['SHLINKCOM'] = [env['SHLINKCOM'],
'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;2']
if os.name == 'nt':
# Fix bug with Scons 0.97, Solved in newer versions.
wrap = env.SharedLibrary(real_target, source,
SHLIBPREFIX='',
*args, **kwds)
elif sys.platform == 'darwin':
wrap = env.LoadableModule(real_target, source,
SHLIBPREFIX='',
LDMODULESUFFIX='.so',
FRAMEWORKSFLAGS = \
'-flat_namespace -undefined suppress',
*args, **kwds)
else:
wrap = env.LoadableModule(real_target, source,
SHLIBPREFIX='',
*args, **kwds)
Alias("build_wrapper", wrap)
Alias("build", wrap)
# This target should simply be build for install mode
Alias("install", wrap)
return wrap
## def ALEAPython(env, python_dir, depends = [], *args, **kwds):
## """
## Install recursively python package and data.
## """
## p = env.Dir(python_dir).srcnode()
## base = "$pythondir/$package_name"
## base_py = len(path(python_dir).abspath())
## fi = []
## for d in depends:
## real_d = "%s/%s" % (str(env.Dir(python_dir).srcnode()), str(d))
## fi.append(env.Install(base, d))
## for f in p.walk():
## fi.append(env.Install("%s/%s" % (base, f.parent[base_py:]), str(f)))
## Alias("install", fi)
## return fi
[docs]
def ALEAGlob(env, pattern, dir = '.'):
import os, fnmatch, glob
files = []
dirs = []
is_multidirs = False
if '*' in dir:
here = env.Dir('.').srcnode().abspath
d = os.path.join(here, dir)
dirs = list(filter(os.path.isdir, glob.glob(d)))
is_multidirs = True
else:
here = env.Dir(dir).srcnode().abspath
dirs = [here]
for d in dirs:
for ufile in os.listdir(d):
if fnmatch.fnmatch(ufile, pattern) :
if is_multidirs:
files.append(os.path.join(os.path.basename(d), ufile))
else:
files.append(os.path.join(dir, ufile))
return files
[docs]
def ALEAGlobDir(env, pattern, dir='.'):
import os, glob
here = env.Dir(dir).srcnode().abspath
d = os.path.join(here, pattern)
dirs = list(filter(os.path.isdir, glob.glob(d)))
dirs = [d.replace(here, dir) for d in dirs]
return dirs
SConsEnvironment.ALEALibrary = ALEALibrary
SConsEnvironment.ALEAIncludes = ALEAIncludes
SConsEnvironment.ALEAProgram = ALEAProgram
SConsEnvironment.ALEAWrapper = ALEAWrapper
SConsEnvironment.ALEAGlob = ALEAGlob
SConsEnvironment.ALEAGlobDir = ALEAGlobDir
##SConsEnvironment.ALEAPython = ALEAPython