Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F104768075
SConstruct
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Wed, Mar 12, 05:51
Size
10 KB
Mime Type
text/x-python
Expires
Fri, Mar 14, 05:51 (1 d, 12 h)
Engine
blob
Format
Raw Data
Handle
24857260
Attached To
rTAMAAS tamaas
SConstruct
View Options
# -*- mode:python; coding: utf-8 -*-
# vim: set ft=python:
# @file
# @section LICENSE
#
# Copyright (©) 2016-19 EPFL (École Polytechnique Fédérale de Lausanne),
# Laboratory (LSMS - Laboratoire de Simulation en Mécanique des Solides)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
# ------------------------------------------------------------------------------
# Imports
# ------------------------------------------------------------------------------
from __future__ import print_function
import os
from os.path import join, abspath
from version import write_info_file
from detect import FindFFTW, FindBoost, FindThrust, FindCuda, FindExpolit
# ------------------------------------------------------------------------------
EnsurePythonVersion(2, 7)
EnsureSConsVersion(2, 4)
# ------------------------------------------------------------------------------
def detect_dependencies(env):
"""Detect all dependencies"""
FindFFTW(env, ['omp'], precision=env['real_type'])
FindBoost(env, ['boost/preprocessor/seq.hpp'])
FindExpolit(env)
thrust_var = 'THRUST_ROOT'
# Take cuda version of thrust if available
if 'CUDA_ROOT' in env['ENV']:
thrust_var = 'CUDA_ROOT'
FindThrust(env, env['backend'], thrust_var)
# Activate cuda if needed
if env['backend'] == 'cuda':
FindCuda(env)
# ------------------------------------------------------------------------------
# Main compilation
# ------------------------------------------------------------------------------
# Compilation colors
colors = {
'cyan': '\033[96m',
'purple': '\033[95m',
'blue': '\033[94m',
'green': '\033[92m',
'yellow': '\033[93m',
'red': '\033[91m',
'end': '\033[0m'
}
# Inherit all environment variables (for CXX detection, etc.)
main_env = Environment(ENV=os.environ)
main_env['COLOR_DICT'] = colors
# Compiler detection
compiler_default = os.getenv('CXX', 'g++')
# Build variables
vars = Variables('build-setup.conf')
vars.AddVariables(
EnumVariable('build_type', 'Build type', 'release',
allowed_values=('release', 'profiling', 'debug'),
ignorecase=2),
EnumVariable('backend', 'Thrust backend', 'omp',
allowed_values=('omp', 'tbb'),
# allowed_values=('omp', 'cuda'),
ignorecase=2),
EnumVariable('sanitizer', 'Sanitizer type', 'none',
allowed_values=('none', 'memory', 'leaks', 'address'),
ignorecase=2),
PathVariable('prefix',
'Prefix where to install', '/usr/local'),
# Dependencies paths
PathVariable('FFTW_ROOT',
'FFTW custom path', os.getenv('FFTW_ROOT', ''),
PathVariable.PathAccept),
PathVariable('THRUST_ROOT',
'Thrust custom path', os.getenv('THRUST_ROOT', ''),
PathVariable.PathAccept),
PathVariable('BOOST_ROOT',
'Boost custom path', os.getenv('BOOST_ROOT', ''),
PathVariable.PathAccept),
PathVariable('CUDA_ROOT',
'Cuda custom path', os.getenv('CUDA_ROOT', ''),
PathVariable.PathAccept),
# Dependencies provided as submodule get different default
PathVariable('GTEST_ROOT',
'Googletest custom path',
os.getenv('GTEST_ROOT', '#third-party/googletest/googletest'),
PathVariable.PathAccept),
PathVariable('PYBIND11_ROOT',
'Pybind11 custom path',
os.getenv('PYBIND11_ROOT', '#third-party/pybind11/include'),
PathVariable.PathAccept),
PathVariable('EXPOLIT_ROOT',
'Expolit custom path',
os.getenv('EXPOLIT_ROOT', '#third-party/expolit/include'),
PathVariable.PathAccept),
# Executables
('CXX', 'Compiler', compiler_default),
('py_exec', 'Python executable', 'python3'),
# Cosmetic
BoolVariable('verbose', 'Activate verbosity', False),
BoolVariable('color', 'Color the non-verbose compilation output', False),
# Tamaas components
BoolVariable('build_doc', 'Build documentation', False),
BoolVariable('build_tests', 'Build test suite', False),
BoolVariable('build_python', 'Build python wrapper', True),
# Dependencies
BoolVariable('use_googletest', 'Build tests using GTest', False),
# Strip binary of extra info
BoolVariable('strip_info', 'Strip binary of added information', False),
# Type variables
EnumVariable('real_type', 'Type for real precision variables', 'double',
allowed_values=('double', 'long double')),
EnumVariable('integer_type', 'Type for integer variables', 'int',
allowed_values=('int', 'long')),
)
# Set variables of environment
vars.Update(main_env)
Help(vars.GenerateHelpText(main_env))
# Save all options, not just those that differ from default
with open('build-setup.conf', 'w') as setup:
for option in vars.options:
setup.write("# " + option.help + "\n")
setup.write("{} = '{}'\n".format(option.key, main_env[option.key]))
main_env['should_configure'] = \
not main_env.GetOption('clean') and not main_env.GetOption('help')
build_type = main_env['build_type']
build_dir = 'build-' + main_env['build_type']
if main_env['should_configure']:
print("Building in " + build_dir)
verbose = main_env['verbose']
# Remove colors if not set
if not main_env['color']:
for key in colors:
colors[key] = ''
if not verbose:
main_env['SHCXXCOMSTR'] = \
u'{0}[Compiling ($SHCXX)] {1}$SOURCE'.format(colors['green'],
colors['end'])
main_env['SHLINKCOMSTR'] = \
u'{0}[Linking] {1}$TARGET'.format(colors['purple'],
colors['end'])
# Include paths
main_env.AppendUnique(CPPPATH=['#/src',
'#/src/core',
'#/src/bem',
'#/src/surface',
'#/src/python',
'#/src/percolation',
'#/src/model',
'#/src/model/elasto_plastic',
'#/src/solvers',
'#/src/gpu',
'#/python'])
# Changing the shared object extension
main_env['SHOBJSUFFIX'] = '.o'
# Back to gcc if cuda is activated
if main_env['backend'] == "cuda":
main_env['CXX'] = "g++"
compiler_aliases = {
"c++": "g++",
"g++-7": "g++",
"g++-6": "g++",
"clang++-6.0": "clang++",
}
def cxx_alias(alias):
return compiler_aliases.get(alias, alias)
# OpenMP flags - compiler dependent
omp_flags = {
"g++": ["-fopenmp"],
"clang++": ["-fopenmp"],
"icpc": ["-qopenmp"]
}
cxx = cxx_alias(main_env['CXX'])
main_env.Append(CXXFLAGS='-std=c++14 -Wall')
if main_env['backend'] == 'omp':
main_env.AppendUnique(CXXFLAGS=omp_flags[cxx])
main_env.AppendUnique(LINKFLAGS=omp_flags[cxx])
elif main_env['backend'] == 'tbb':
main_env.AppendUnique(LIBS=['tbb'])
main_env.Append(CXXFLAGS='-Wno-unknown-pragmas')
# Flags and options
if main_env['build_python']:
main_env.AppendUnique(CPPDEFINES=['USE_PYTHON'])
if main_env['strip_info']:
main_env.AppendUnique(CPPDEFINES=['STRIP_INFO'])
# Define the scalar types
main_env.AppendUnique(CPPDEFINES={'REAL_TYPE': main_env['real_type'],
'INT_TYPE': main_env['integer_type']})
if main_env['real_type'] == 'long double':
main_env.AppendUnique(CPPDEFINES=['LONG_PRECISION'])
# Adding compile flags defined in evironment
main_env.AppendUnique(CXXFLAGS=Split(os.getenv('CXXFLAGS', "")))
if build_type == 'debug':
main_env.AppendUnique(CPPDEFINES=['TAMAAS_DEBUG'])
# Compilation flags
cxxflags_dict = {
"debug": Split("-g -O0"),
"profiling": Split("-g -O3 -fno-omit-frame-pointer"),
"release": Split("-O3")
}
# Link flags for shared libs
shlinkflags_dict = {
"debug": Split(""),
"profiling": Split("-g -O3 -fno-omit-frame-pointer"),
"release": []
}
if main_env['sanitizer'] != 'none':
if main_env['backend'] == 'cuda':
print("Sanitizers with cuda are not yet supported!")
Exit(1)
cxxflags_dict[build_type].append(
'-fsanitize={}'.format(main_env['sanitizer']))
shlinkflags_dict[build_type].append(
'-fsanitize={}'.format(main_env['sanitizer']))
main_env.AppendUnique(CXXFLAGS=cxxflags_dict[build_type])
main_env.AppendUnique(SHLINKFLAGS=shlinkflags_dict[build_type])
main_env.AppendUnique(LINKFLAGS=shlinkflags_dict[build_type])
main_env['LIBPATH'] = [abspath(join(build_dir, 'src'))]
main_env['RPATH'] = "$LIBPATH"
if main_env['should_configure']:
detect_dependencies(main_env)
# Writing information file
write_info_file("src/tamaas_info.cpp", main_env['build_type'])
def write_env_file(target, source, env):
"""Builder to write content to file"""
env_content = """
export PYTHONPATH=$PYTHONPATH:{0}/python
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:{0}/src
"""
with open(str(target[0]), 'w') as env_file:
env_file.write(env_content.format(abspath(build_dir)))
# Saving the env file
main_env['gen_print'] = gen_print
env_file_env = main_env.Clone(
PRINT_CMD_LINE_FUNC=gen_print("Writing", "cyan", main_env)
)
# Need to have a command and manage tamaas_environement.sh as target because
# the build directory does not always exist
env_file_env.Command(join(build_dir, 'tamaas_environement.sh'),
None, write_env_file)
# Building subdirs
def subdir(dir):
return SConscript(join(dir, 'SConscript'),
variant_dir=join(build_dir, dir),
duplicate=True)
# Building Tamaas library
Export('main_env')
subdir('src')
# Building Tamaas extra components
for dir in ['python', 'tests']:
if main_env['build_{}'.format(dir)] and not main_env.GetOption('help'):
subdir(dir)
# Building API + Sphinx documentation if requested
if main_env['build_doc'] and not main_env.GetOption('help'):
main_env.Command('#doc/build/sphinx', '', 'make -C doc sphinx')
Event Timeline
Log In to Comment