Permalink
Fetching contributors…
Cannot retrieve contributors at this time
273 lines (230 sloc) 9.26 KB
#! /usr/bin/env python
#| This file is a part of the sferes2 framework.
#| Copyright 2009, ISIR / Universite Pierre et Marie Curie (UPMC)
#| Main contributor(s): Jean-Baptiste Mouret, mouret@isir.fr
#|
#| This software is a computer program whose purpose is to facilitate
#| experiments in evolutionary computation and evolutionary robotics.
#|
#| This software is governed by the CeCILL license under French law
#| and abiding by the rules of distribution of free software. You
#| can use, modify and/ or redistribute the software under the terms
#| of the CeCILL license as circulated by CEA, CNRS and INRIA at the
#| following URL "http://www.cecill.info".
#|
#| As a counterpart to the access to the source code and rights to
#| copy, modify and redistribute granted by the license, users are
#| provided only with a limited warranty and the software's author,
#| the holder of the economic rights, and the successive licensors
#| have only limited liability.
#|
#| In this respect, the user's attention is drawn to the risks
#| associated with loading, using, modifying and/or developing or
#| reproducing the software by the user in light of its specific
#| status of free software, that may mean that it is complicated to
#| manipulate, and that also therefore means that it is reserved for
#| developers and experienced professionals having in-depth computer
#| knowledge. Users are therefore encouraged to load and test the
#| software's suitability as regards their requirements in conditions
#| enabling the security of their systems and/or data to be ensured
#| and, more generally, to use and operate it in the same conditions
#| as regards security.
#|
#| The fact that you are presently reading this means that you have
#| had knowledge of the CeCILL license and that you accept its terms.
import sys
import subprocess
sys.path.insert(0, './waf_tools')
try:
VERSION = str(subprocess.check_output(['git', 'rev-parse', 'HEAD'])).replace('\n', '')
except:
VERSION = "0.x"
APPNAME='sferes2'
srcdir = '.'
blddir = 'build'
import copy
import os, glob, types
import sferes
from waflib.Build import BuildContext
from waflib.Tools import waf_unit_test
from waflib import Logs
modules = sferes.parse_modules()
opt_flags = '-O3'
debug_flags = '-O0 -ggdb3 -DDBG_ENABLED'
def options(opt):
# tools
opt.load('compiler_cxx boost waf_unit_test')
opt.load('tbb')
opt.load('mpi')
opt.load('eigen')
# sferes specific
opt.add_option('--rpath', type='string', help='set rpath', dest='rpath')
opt.add_option('--includes', action='append', type='string', help='add an include path, e.g. /home/mandor/include', dest='includes')
opt.add_option('--libs', action='append', type='string', help='add a lib path, e.g. /home/mandor/lib', dest='libs')
opt.add_option('--cpp14', type='string', help='force / disable c++-14 compilation [--cpp14=yes]', dest='cpp14')
opt.add_option('--no-asserts', action='store_true', default=False, help='disable asserts [--no-asserts]', dest='no_asserts')
# exp commands
opt.add_option('--create', type='string', help='create a new exp', dest='create_exp')
opt.add_option('--exp', type='string', help='exp to build', dest='exp')
opt.add_option('--qsub', type='string', help='config file (json) to submit to torque', dest='qsub')
opt.add_option('--oar', type='string', help='config file (json) to submit to oar', dest='oar')
# debug flags
opt.add_option('--debug', type='string', help='compile with debugging symbols', dest='debug')
# tests
opt.add_option('--tests', action='store_true', default=False, help='compile tests or not', dest='tests')
opt.add_option('--tests-verbose', action='store_true', default=False, help='display the output of the unit tests', dest='tests_verbose')
opt.logger = Logs.make_logger(blddir + 'options.log', 'mylogger')
for i in modules:
opt.start_msg('Command-line options for module [%s]' % i)
try:
opt.recurse(i)
opt.end_msg('OK')
except:
opt.end_msg(' -> no option found', 'YELLOW')
for i in glob.glob('exp/*'):
opt.start_msg('Command-line options for exp [%s]' % i)
try:
opt.recurse(i)
opt.end_msg(' -> OK')
except:
opt.end_msg(' -> no option found', 'YELLOW')
def configure(conf):
# log configure options
fname = blddir + '/configure.options'
args = open(fname, 'a')
for i in sys.argv:
args.write(i + ' ')
args.write("\n")
args.close()
conf.load('compiler_cxx')
common_flags = "-D_REENTRANT -Wall -fPIC -ftemplate-depth-1024 -Wno-sign-compare -Wno-deprecated -Wno-unused "
common_flags += "-DSFERES_ROOT=\"" + os.getcwd() + "\" "
conf.env['CXXFLAGS'] += common_flags.split(' ')
conf.env['SFERES_ROOT'] = os.getcwd()
# link flags
if conf.options.libs:
for lib_dir in conf.options.libs:
conf.env.append_value("LINKFLAGS", " -L" + lib_dir)
# boost
conf.load('boost')
boost_libs = 'serialization filesystem system unit_test_framework program_options graph thread regex'
if not conf.options.no_mpi:
boost_libs += ' mpi'
conf.check_boost(lib=boost_libs, min_version='1.35')
# tbb
conf.load('tbb')
conf.check_tbb()
# mpi.h
conf.load('mpi')
conf.check_mpi()
# boost mpi
if ('mpi' in boost_libs and conf.env['MPI_FOUND']):
conf.env['MPI_ENABLED'] = True
else:
conf.env['MPI_ENABLED'] = False
# eigen 3 (optional)
conf.load('eigen')
conf.check_eigen()
if conf.options.rpath:
conf.env.append_value("LINKFLAGS", "--rpath="+conf.options.rpath)
# modules
for i in modules:
Logs.info('Configuring for module: [%s]' % i),
try:
conf.recurse(i)
Logs.info('%s -> ok' % i)
except:
Logs.warn(' %s -> no configuration found' % i, 'YELLOW')
if conf.options.exp:
for i in conf.options.exp.split(','):
Logs.info('Configuring for exp [%s]' %i)
try:
conf.recurse('exp/' + i)
Logs.info('%s -> ok' % i)
except:
Logs.warn('%s -> no configuration found' % i, 'YELLOW')
# we need c++11
conf.env['CXXFLAGS'] += ['-std=c++11']
if conf.options.cpp14 == 'yes':
conf.env['CXXFLAGS'] += ['-std=c++14']
if conf.options.includes :
for inlcude_dir in conf.options.includes:
conf.env['CXXFLAGS'] += [" -I" + inlcude_dir]
if conf.env['MPI_ENABLED']:
conf.env['CXXFLAGS'] += ['-DMPI_ENABLED']
if not conf.env['TBB_ENABLED']:
conf.env['CXXFLAGS'] += ['-DNO_PARALLEL']
if conf.env['EIGEN_FOUND']:
conf.env['CXXFLAGS'] += ['-DEIGEN3_ENABLED']
if conf.options.no_asserts:
conf.env['CXXFLAGS'] += ['-DNDEBUG']
# display flags
def flat(list) :
str = ""
for i in list :
str += i + ' '
return str
print('\n--- configuration ---')
print('compiler(s):')
print(' * CXX: ' + str(conf.env['CXX_NAME']))
print('boost version: ' + str(conf.env['BOOST_VERSION']))
print('mpi: ' + str(conf.env['MPI_ENABLED']))
print("Compilation flags :")
print(" CXXFLAGS : " + flat(conf.env['CXXFLAGS']))
print(" LINKFLAGS: " + flat(conf.env['LINKFLAGS']))
print("--- license ---")
print("Sferes2 is distributed under the CECILL license (GPL-compatible)")
print("Please check the accompanying COPYING file or http://www.cecill.info/")
def summary(bld):
lst = getattr(bld, 'utest_results', [])
total = 0
tfail = 0
if lst:
total = len(lst)
tfail = len([x for x in lst if x[1]])
failed_lines = []
for (f, code, out, err) in lst:
output = str(out).splitlines()
for line in output:
if ' failed' in line or 'fatal error' in line:
failed_lines += [line]
if bld.options.tests_verbose and ' passed' in line:
Logs.info(line)
elif bld.options.tests_verbose and (' failed' in line or 'fatal error' in line):
Logs.error(line)
elif bld.options.tests_verbose :
print(line)
waf_unit_test.summary(bld)
if tfail > 0:
Logs.error(str(tfail) + "/" + str(total) + " tests failed:")
for i in failed_lines:
Logs.error(i)
bld.fatal("Build failed, because some tests failed!")
def build(bld):
v = VERSION
bld.env['CXXFLAGS'].append("-DVERSION=\""+v+"\"")
if bld.options.debug:
Logs.info('DEBUG is enabled')
bld.env['CXXFLAGS'] += debug_flags.split(' ')
else:
Logs.info('DEBUG is is disabled')
bld.env['CXXFLAGS'] += opt_flags.split(' ')
print ("Entering directory `" + os.getcwd() + "'")
bld.recurse('sferes examples')
if bld.options.tests:
bld.recurse('tests')
if bld.options.exp:
for i in bld.options.exp.split(','):
Logs.info('Building exp: ' + i)
bld.recurse('exp/' + i)
for i in modules:
Logs.info('Building module: ' + i)
bld.recurse(i)
bld.add_post_fun(summary)
def shutdown (ctx):
if ctx.options.create_exp:
sferes.create_exp(ctx.options.create_exp)
if ctx.options.qsub:
sferes.qsub(ctx.options.qsub)
if ctx.options.oar:
sferes.oar(ctx.options.oar)