Files
cantera/ext/SConscript
Bryan Weber 76825d1e73 [SCons] Build sundials_config and copy separately
This is the same mechanism as employed for config.h in the main
SConstruct. It's needed here to avoid repeatedly copying the include
directory into the sdist, which fails due to the existing directory.
2021-11-26 14:56:00 -05:00

179 lines
7.1 KiB
Python

from pathlib import Path
from buildutils import *
Import('env', 'build', 'install', 'libraryTargets')
localenv = env.Clone()
copyenv = localenv.Clone() # no CPPPATH addition, to avoid circular dependencies
license_files = {"Cantera": File("#License.txt"),
"Libexecstream": File("#ext/libexecstream/doc/license.txt")}
def prep_default(env):
localenv = env.Clone()
# Suppress warnings from external code and auto-generated code
if 'g++' in localenv['CXX'] or 'clang' in localenv['CXX']:
localenv.Append(CCFLAGS='-w')
return localenv
def prep_gtest(env):
localenv = prep_default(env)
localenv.Prepend(CPPPATH=[Dir('#ext/googletest/googletest'),
Dir('#ext/googletest/googletest/include')],
CPPDEFINES={'GTEST_HAS_PTHREAD': 0})
return localenv
def prep_gmock(env):
localenv = prep_default(env)
localenv.Prepend(CPPPATH=[Dir('#ext/googletest/googletest/include'),
Dir('#ext/googletest/googlemock'),
Dir('#ext/googletest/googlemock/include')],
CPPDEFINES={'GTEST_HAS_PTHREAD': 0})
return localenv
# each element of libs is: (subdir, (file extensions), prepfunction)
libs = [('libexecstream', ['cpp'], prep_default)]
for subdir, extensions, prepFunction in libs:
localenv = prepFunction(env)
objects = localenv.SharedObject(multi_glob(localenv, subdir, *extensions))
libraryTargets.extend(objects)
ext_copies = []
if not env['system_fmt']:
license_files["fmtlib"] = File("#ext/fmt/LICENSE.rst")
localenv = prep_default(env)
localenv.Prepend(CPPPATH=Dir('#ext/fmt/include'))
libraryTargets.extend(
localenv.SharedObject(multi_glob(localenv, 'fmt/src', 'cc')))
for name in ('format.h', 'ostream.h', 'printf.h', 'core.h', 'format-inl.h'):
ext_copies.extend(
copyenv.Command("#include/cantera/ext/fmt/" + name,
"#ext/fmt/include/fmt/" + name,
Copy("$TARGET", "$SOURCE"))
)
if env['system_sundials'] == 'n':
localenv = prep_default(env)
localenv.Prepend(CPPPATH=[Dir('#include/cantera/ext'),
Dir('#ext/sundials/src/sundials')])
license_files["Sundials"] = File("#ext/sundials/LICENSE")
# Generate sundials_config.h
sundials_configh = {}
if env['OS'] != 'Windows':
sundials_configh['SUNDIALS_USE_GENERIC_MATH'] = 1
if env['use_lapack']:
sundials_configh['SUNDIALS_BLAS_LAPACK'] = 1
sundials_configh_build = env.Command("#build/ext/sundials_config.h.build",
"sundials_config.h.in",
ConfigBuilder(sundials_configh))
# This separate copy operation, which SCons will skip if sundials_config.h.build is
# unmodified, prevents unnecessary re-copies of files in the #include directory
localenv.AlwaysBuild(sundials_configh_build)
ext_copies.extend(
localenv.Command("#include/cantera/ext/sundials/sundials_config.h",
"#build/ext/sundials_config.h.build",
Copy("$TARGET", "$SOURCE"))
)
# Copy sundials header files into common include directory
for subdir in ('sundials', 'nvector', 'cvodes', 'ida', 'sunmatrix',
'sunlinsol', 'sunnonlinsol'):
for header in multi_glob(env, 'sundials/include/'+subdir, 'h'):
ext_copies.extend(
copyenv.Command(f"#include/cantera/ext/{subdir}/{header.name}",
f"#ext/sundials/include/{subdir}/{header.name}",
Copy("$TARGET", "$SOURCE"))
)
# Compile Sundials source files. Skip files related to the Sundials Fortran
# interface, which start with 'fsun'.
subdirs = ['sundials', 'nvector/serial', 'cvodes', 'ida', 'sunmatrix/band',
'sunmatrix/dense', 'sunmatrix/sparse', 'sunlinsol/dense',
'sunlinsol/band','sunlinsol/spgmr', 'sunnonlinsol/newton']
if env['use_lapack']:
subdirs.extend(('sunlinsol/lapackdense', 'sunlinsol/lapackband'))
for subdir in subdirs:
libraryTargets.extend(localenv.SharedObject(
[f for f in multi_glob(localenv, 'sundials/src/'+subdir, 'c')
if not f.name.startswith('fsun')]))
if not env['system_yamlcpp']:
localenv = prep_default(env)
localenv.Prepend(CPPPATH=Dir('#include/cantera/ext'))
license_files["YAML-CPP"] = File("#ext/yaml-cpp/LICENSE")
# Copy header files into common include directory
for subdir in ('', 'contrib', 'node', 'node/detail'):
for header in multi_glob(env, 'yaml-cpp/include/yaml-cpp/'+subdir, 'h'):
ext_copies.extend(
localenv.Command(
f"#include/cantera/ext/yaml-cpp/{subdir}/{header.name}",
f"#ext/yaml-cpp/include/yaml-cpp/{subdir}/{header.name}",
Copy("$TARGET", "$SOURCE")
)
)
# Compile yaml-cpp source files
for subdir in ('', 'contrib'):
libraryTargets.extend(localenv.SharedObject(
[f for f in multi_glob(localenv, 'yaml-cpp/src/'+subdir, 'cpp')]))
if not env['system_eigen']:
license_files["Eigen"] = File("#ext/eigen/COPYING.MPL2")
h = build(copyenv.Command('#include/cantera/ext/Eigen', '#ext/eigen/Eigen',
Copy('$TARGET', '$SOURCE')))
copyenv.Depends(copyenv['config_h_target'], h)
ext_copies.extend(h)
# Google Test: Used internally for Cantera unit tests.
if env['googletest'] == 'submodule':
localenv = prep_gtest(env)
gtest = build(localenv.Library('../lib/gtest',
source=['googletest/googletest/src/gtest-all.cc']))
localenv = prep_gmock(env)
gmock = build(localenv.Library('../lib/gmock',
source=['googletest/googlemock/src/gmock-all.cc']))
env["ext_include_copies_target"] = build(ext_copies)
def generate_license(target, source, env):
target = Path(target[0].abspath)
stars = "*" * 50 + "\n" + "*" * 50 + "\n"
tpl = stars + "The following license applies to {}\n" + stars + "\n{}\n"
license = []
for package, license_file in env["license_files"].items():
license_file = Path(license_file.abspath)
license.append(tpl.format(package, license_file.read_text().strip()))
license = "\n".join(license)
if target.suffix == ".rtf":
license = license.replace("\\", "\\\\").replace("{", "\\{").replace("}", "\\}")
license = license.replace("\n", " \\par\n")
license = (r"{\rtf1\ansi{\fonttbl\f0\fswiss Arial;}\f0\pard\fs16 "
+ license + "}")
target.write_text(license)
localenv["license_files"] = license_files
license = build(localenv.Command("LICENSE.txt", license_files.values(),
generate_license))
env["license_target"] = license
install('$inst_docdir', license)
if env['OS'] == 'Windows':
# RTF version is required for Windows installer
build(localenv.Command("LICENSE.rtf", license_files.values(),
generate_license))