# -*- python -*-
#--------------------------------------------------------------------------------
#
# OpenAlea.SConsX: SCons extension package for building platform
# independant packages.
#
# Copyright 2006-2022 INRIA - CIRAD - INRAE
#
# 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
#
#------------------------------------------------------------------------------
""" See OpenAlea WebSite / Packages / SConsX """
from __future__ import print_function
import os
import sys
from os.path import exists, join
pj = os.path.join
from SCons.Script import SConsignFile, Help, GetOption
try:
from SCons.Script import VariantDir
except ImportError:
from SCons.Script import BuildDir as VariantDir
from SCons.Variables import PathVariable
from SCons.Variables import BoolVariable
from SCons.Variables import EnumVariable
from SCons.Variables import Variables
from SCons.Util import Split, WhereIs
from SCons.Tool import Tool
from SCons.SConf import SConf
from SCons.Environment import Environment
from SCons.Builder import Builder
from SCons.Node.FS import Dir, File
__license__ = "Cecill-C"
__revision__ = "$Id$"
# Errors
[docs]
class CircularDependency(Exception):
pass
# Utilitaries
[docs]
def exist(s, path):
""" Test if the file s exist in the path """
files = os.listdir(path)
for f in files:
if f.find(s) != -1:
return True
return False
[docs]
def getLocalPath():
""" Return the absolute path of this package """
return os.path.dirname(__file__)
#------------------------------------------------------------------------------
# Global Path settings
#tool_path = os.path.join(getLocalPath() , 'tools')
#sys.path = [tool_path] + sys.path
#------------------------------------------------------------------------------
# Method to build bison and flex files for AMAPmod software
[docs]
def BisonFlex(env, bison, flex, prefix):
""" Smart autoscan function. """
LEXFLAGS = env.get("LEXFLAGS")[:]
YACCFLAGS = env.get("YACCFLAGS")[:]
if prefix :
LEXFLAGS += ["-P" + prefix]
YACCFLAGS += ["-p " + prefix]
targets = []
bison_ext = ".hpp"
if not env.get("BISON_HPP"):
bison_ext = ".cpp.h"
(bison_name, _ext) = os.path.splitext(bison)
h = env.CXXFile(source=bison,
target= [bison_name+".cpp", bison_name + bison_ext],
LEXFLAGS=LEXFLAGS,
YACCFLAGS=YACCFLAGS)
targets.append(h[0])
(flex_name, _ext) = os.path.splitext(flex)
cpp = env.CXXFile(source=flex,
LEXFLAGS=LEXFLAGS,
YACCFLAGS=YACCFLAGS)
targets.append(cpp)
return targets
#----------------------------------
# Platform class
[docs]
class Posix(Platform):
def __init__(self):
self.name = "posix"
self.sharedlibextension = 'so'
[docs]
class Linux(Posix):
def __init__(self):
self.name = "linux"
[docs]
def distribution(self):
import platform
return platform.linux_distribution()[0].lower()
[docs]
class Irix(Posix):
def __init__(self):
self.name = "irix"
[docs]
class Cygwin(Posix):
def __init__(self):
self.name = "cygwin"
self.sharedlibextension = 'dll'
[docs]
class Darwin(Posix):
def __init__(self):
self.name = "darwin"
self.sharedlibextension = 'dylib'
[docs]
class Win32(Platform):
def __init__(self):
self.name = "win32"
self.sharedlibextension = 'dll'
# Create a static instance ...
# (very pythonic way, isn't it?)
platform = GetPlatform()
#------------------------------------------------------------------------------
# User Configuration class
default_tools = ['compiler', 'builddir', 'multicpu', 'install']
[docs]
class Config(object):
def __init__(self, tools=[], dir=[]):
self.init_tools = default_tools + tools
self.tools = []
self.tools_dict = {}
self._walk = []
self.dir = [os.getcwd()] + dir
self.custom_tests = { }
for t in self.init_tools:
self.add_tool(t)
def __str__(self):
return str([t.name for t in self.tools])
[docs]
def Options(self, *args, **kwds):
"""
Add each tool options
"""
opts = Options(*args, **kwds)
self.UpdateOptions(opts)
return opts
[docs]
def UpdateOptions(self, opts):
for tool in self.tools:
tool.option(opts)
[docs]
def Update(self, env):
"""
Update the environment for each tools.
"""
# Create Configure
import traceback, sys
import warnings
for tool in self.tools:
try:
tool.update(env)
except:
traceback.print_exception(*sys.exc_info())
warnings.warn("Cannot update correctly tool "+repr(tool.name))
#------------------------------------------------------------------------------
# Specific OpenAlea facilities.
[docs]
class ALEAConfig(Config):
def __init__(self, package_name, *args, **kwds):
Config.__init__(self, *args, **kwds)
self.package_name = package_name
[docs]
def Update(self, env):
Config.Update(self, env)
env["package_name"] = self.package_name
[docs]
def ALEAEnvironment(conf, *args, **kwds):
if 'options' in kwds:
opts = kwds['options']
conf.UpdateOptions(opts)
else:
opts = conf.Options(*args, **kwds)
env = Environment(options=opts)
conf.Update(env)
env.Prepend(CPPPATH='$build_includedir')
env.Prepend(LIBPATH='$build_libdir')
return env
[docs]
def ALEASolution(options, tools=[], dir=[]):
from copy import deepcopy
SConsignFile()
env_compiler_options = {}
if isinstance(platform, Win32):
# Checking for compiler info first
compileroptions = deepcopy(options)
compilerconf = Config([],dir)
compilerconf.UpdateOptions(compileroptions)
compilerenv = Environment()
compileroptions.Update(compilerenv)
compilerconf.Update(compilerenv)
if compilerenv['compiler'] == 'msvc':
if compilerenv['MSVC_VERSION'] != '':
env_compiler_options['MSVC_VERSION'] = compilerenv['MSVC_VERSION']
env_compiler_options['TARGET_ARCH'] = compilerenv['TARGET_ARCH']
elif compilerenv['compiler'] == 'mingw':
env_compiler_options['tools'] = ['mingw']
env_compiler_options['ENV'] = {'PATH': [find_executable_path_from_env('gcc.exe', strip_bin=False)],'TMP': os.environ['TMP']}
conf = Config(tools, dir)
conf.UpdateOptions(options)
if len(env_compiler_options) > 0:
print('Force environment with compiler options : '+str(env_compiler_options))
env = Environment(options=options, **env_compiler_options)
else:
env = Environment(options=options)
options.Update(env)
conf.Update(env)
Help(options.GenerateHelpText(env))
prefix = env['build_prefix']
VariantDir(prefix, '.')
env.Prepend(CPPPATH='$build_includedir')
env.Prepend(LIBPATH='$build_libdir')
# If scons is run in a conda environment, append paths
if CONDA_ENV:
PREFIX = CONDA_PREFIX
env.Prepend(CPPPATH=pj(PREFIX, 'include'))
env.Prepend(LIBPATH=pj(PREFIX, 'lib'))
return env
from .util.lib_check import *
from .util.env_check import *
CONDA_ENV = is_conda()
CONDA_PREFIX = conda_prefix()
CONDA_LIBRARY_PREFIX = conda_library_prefix()