Skip to content

Commit

Permalink
Remove MATLAB from build system
Browse files Browse the repository at this point in the history
  • Loading branch information
ischoegl committed Feb 21, 2024
1 parent 9d2e630 commit c4c2243
Show file tree
Hide file tree
Showing 4 changed files with 7 additions and 201 deletions.
111 changes: 6 additions & 105 deletions SConstruct
Original file line number Diff line number Diff line change
Expand Up @@ -127,22 +127,12 @@ if "clean" in COMMAND_LINE_TARGETS:
remove_file("src/pch/system.h.gch")
remove_directory("include/cantera/ext")
remove_file("config.log")
remove_directory("doc/sphinx/matlab/examples")
remove_file("doc/sphinx/matlab/examples.rst")
for name in Path("doc/sphinx/matlab/").glob("**/*.rst"):
if name.name != "index.rst":
remove_file(name)
remove_directory("doc/sphinx/cython/examples")
remove_file("doc/sphinx/cython/examples.rst")
for name in Path(".").glob("*.msi"):
remove_file(name)
for name in Path("site_scons").glob("**/*.pyc"):
remove_file(name)
remove_file("interfaces/matlab/toolbox/cantera_shared.dll")
remove_file("interfaces/matlab/Contents.m")
remove_file("interfaces/matlab/ctpath.m")
for name in Path("interfaces/matlab/toolbox").glob("ctmethods.*"):
remove_file(name)

logger.status("Done removing output files.", print_level=False)

Expand Down Expand Up @@ -257,7 +247,7 @@ config_options = [
"python_package",
"""If you plan to work in Python, then you need the 'full' Cantera Python
package. If, on the other hand, you will only use Cantera from some
other language (for example, MATLAB or Fortran 90/95) and only need Python
other language (for example, C or Fortran 90/95) and only need Python
to process YAML files, then you only need a 'minimal' subset of the
package and Cython and NumPy are not necessary. The 'none' option
doesn't install any components of the Python interface. The default
Expand Down Expand Up @@ -288,21 +278,6 @@ config_options = [
'python_prefix=USER'.""",
{"default": ""},
PathVariable.PathAccept),
EnumOption(
"matlab_toolbox",
"""This variable controls whether the MATLAB toolbox will be built. If
set to 'y', you will also need to set the value of the 'matlab_path'
variable. If set to 'default', the MATLAB toolbox will be built if
'matlab_path' is set.""",
"default", ("y", "n", "default")),
PathOption(
"matlab_path",
"""Path to the MATLAB install directory. This should be the directory
containing the 'extern', 'bin', etc. subdirectories. Typical values
are: "C:\\Program Files\\MATLAB\\R2021a" on Windows,
"/Applications/MATLAB_R2021a.app" on macOS, or
"/opt/MATLAB/R2021a" on Linux.""",
"", PathVariable.PathAccept),
EnumOption(
"f90_interface",
"""This variable controls whether the Fortran 90/95 interface will be
Expand Down Expand Up @@ -423,9 +398,8 @@ config_options = [
"""Select whether to use BLAS/LAPACK from a system installation ('y'), use
Eigen linear algebra support ('n'), or to decide automatically based on
libraries detected on the system ('default'). Specifying 'blas_lapack_libs'
or 'blas_lapack_dir' changes the default to 'y', whereas installing the
Matlab toolbox changes the default to 'n'. On macOS, the 'default' option
uses the Accelerate framework, whereas on other operating systems the
or 'blas_lapack_dir' changes the default to 'y'. On macOS, the 'default'
option uses the Accelerate framework, whereas on other operating systems the
preferred option depends on the CPU manufacturer. In general, OpenBLAS
('openblas') is prioritized over standard libraries ('lapack,blas'), with
Eigen being used if no suitable BLAS/LAPACK libraries are detected. On Intel
Expand Down Expand Up @@ -816,10 +790,6 @@ if "cygwin" in env["OS"].lower():
if "FRAMEWORKS" not in env:
env["FRAMEWORKS"] = []

# Needed for Matlab to source ~/.matlab7rc.sh
if "HOME" in os.environ:
env["ENV"]["HOME"] = os.environ["HOME"]

if os.name == "nt":
env["INSTALL_MANPAGES"] = False

Expand Down Expand Up @@ -1379,11 +1349,6 @@ elif env["blas_lapack_libs"] or env["blas_lapack_dir"]:
if not conf.CheckLib(lib, autoadd=False):
config_error(f"Library {lib!r} could not be found.")

elif env["matlab_path"] != "" and env["matlab_toolbox"] in {"default", "y"}:
# MATLAB provides the mwlapack and mwblas libraries in matlabroot/extern/lib.
if env["system_blas_lapack"] == "default":
env["system_blas_lapack"] = "n"

elif env["system_blas_lapack"] == "default":
# auto-detect versions
if env["OS"] == "Darwin":
Expand Down Expand Up @@ -1960,43 +1925,6 @@ if env["python_package"] == "full" and env["OS"] == "Darwin":
env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = mac_target
logger.info(f"MACOSX_DEPLOYMENT_TARGET = {mac_target}")

# Matlab Toolbox settings
if env["matlab_path"] != "" and env["matlab_toolbox"] == "default":
env["matlab_toolbox"] = "y"

if env["matlab_toolbox"] == "y":
matlab_path = env["matlab_path"]
if matlab_path == "":
logger.error(
"Unable to build the Matlab toolbox because 'matlab_path' "
"has not been set.")
sys.exit(1)

if env["blas_lapack_libs"] or env["system_blas_lapack"] == "y":
logger.error(
"The Matlab toolbox is incompatible with external BLAS and LAPACK "
"libraries. Unset 'blas_lapack_libs' (for example, 'scons build "
"blas_lapack_libs=') and/or 'system_blas_lapack' in order to build the "
"Matlab toolbox, or set 'matlab_toolbox=n' to use the specified BLAS/"
"LAPACK libraries and skip building the Matlab toolbox.")
sys.exit(1)

if env["system_sundials"] == "y":
logger.error(
"The Matlab toolbox is incompatible with external SUNDIALS "
"libraries. Set system_sundials to no (for example, 'scons build "
"system_sundials=n') in order to build the Matlab "
"toolbox, or set 'matlab_toolbox=n' to use the specified "
"SUNDIALS libraries and skip building the Matlab toolbox.")
sys.exit(1)

matlab_path = Path(matlab_path)
env["matlab_path"] = matlab_path.as_posix()
if not matlab_path.is_dir() and (matlab_path / "extern").is_dir():
logger.error(
f"Path set for 'matlab_path' is not correct. Path was {matlab_path!r}")
sys.exit(1)


# **********************************************
# *** Set additional configuration variables ***
Expand Down Expand Up @@ -2076,18 +2004,11 @@ if env["layout"] == "compact":
env["ct_sampledir"] = (prefix / "samples").as_posix()
env["ct_docdir"] = (prefix / "doc").as_posix()
env["ct_mandir"] = (prefix / "man1").as_posix()
env["ct_matlab_dir"] = (prefix / "matlab" / "toolbox").as_posix()
else:
env["ct_datadir"] = (prefix / "share" / "cantera" / "data").as_posix()
env["ct_sampledir"] = (prefix / "share" / "cantera" / "samples").as_posix()
env["ct_docdir"] = (prefix / "share" / "cantera" / "doc").as_posix()
env["ct_mandir"] = (prefix / "share" / "man" / "man1").as_posix()
if env["layout"] == "conda":
env["ct_matlab_dir"] = (
prefix / "share" / "cantera" / "matlab" / "toolbox").as_posix()
else:
env["ct_matlab_dir"] = (
prefix / env["libdirname"] / "cantera" / "matlab" / "toolbox").as_posix()


addInstallActions = ('install' in COMMAND_LINE_TARGETS or
Expand All @@ -2112,7 +2033,7 @@ if os.path.abspath(instRoot) == Dir('.').abspath:

env["inst_root"] = instRoot
locations = ["libdir", "shlibdir", "bindir", "python_bindir", "incdir", "incroot",
"matlab_dir", "datadir", "sampledir", "docdir", "mandir"]
"datadir", "sampledir", "docdir", "mandir"]
for loc in locations:
if env["prefix"] == ".":
env[f"inst_{loc}"] = (Path(instRoot) / env[f"ct_{loc}"]).as_posix()
Expand Down Expand Up @@ -2309,9 +2230,6 @@ if env['CC'] != 'cl':
VariantDir('build/platform', 'platform/posix', duplicate=0)
SConscript('build/platform/SConscript')

if env['matlab_toolbox'] == 'y':
SConscript('build/src/matlab/SConscript')

if env['doxygen_docs'] or env['sphinx_docs']:
SConscript('doc/SConscript')

Expand Down Expand Up @@ -2397,21 +2315,6 @@ def postInstallMessage(target, source, env):
name="Python examples", location=env_dict["python_example_loc"]
))

if env["matlab_toolbox"] == "y":
env["matlab_sample_loc"] = (Path(env["ct_sampledir"]) / "matlab").as_posix()
env["matlab_ctpath_loc"] = (Path(env["ct_matlab_dir"]) / "ctpath.m").as_posix()
install_message.append(locations_message.format(
name="Matlab toolbox", location=env_dict["ct_matlab_dir"]
))
install_message.append(locations_message.format(
name="Matlab samples", location=env_dict["matlab_sample_loc"]
))
install_message.append(textwrap.dedent("""
An m-file to set the correct matlab path for Cantera is at:
{matlab_ctpath_loc!s}
""".format(**env_dict)))

status = f" Cantera {env['cantera_version']} has been successfully installed "
install_message = [
f"\n{status:*^80}\n",
Expand Down Expand Up @@ -2479,8 +2382,7 @@ if 'msi' in COMMAND_LINE_TARGETS:
wxs = wxsgen.WxsGenerator(env['stage_dir'],
short_version=env['cantera_short_version'],
full_version=env['cantera_pure_version'],
x64=env['TARGET_ARCH']=='amd64',
includeMatlab=env['matlab_toolbox']=='y')
x64=env['TARGET_ARCH']=='amd64')
wxs.make_wxs(str(target[0]))

wxs_target = env.Command('build/wix/cantera.wxs', [], build_wxs)
Expand Down Expand Up @@ -2518,8 +2420,7 @@ if any(target.startswith('test') for target in COMMAND_LINE_TARGETS):

env['ENV']['PYTHON_CMD'] = env.subst('$python_cmd')

# Tests written using the gtest framework, the Python unittest module,
# or the Matlab xunit package.
# Tests written using the gtest framework or the Python unittest module
VariantDir('build/test', 'test', duplicate=0)
SConscript('build/test/SConscript')

Expand Down
2 changes: 1 addition & 1 deletion interfaces/python_sdist/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def replace_git_hash(target, source, env):
sdist(localenv.RecursiveInstall(
"src",
"#src",
exclude=["fortran", "matlab", "clib", r"global\.cpp", "SCons.*", r"canteraStatic\.cpp"],
exclude=["fortran", "clib", r"global\.cpp", "SCons.*", r"canteraStatic\.cpp"],
))

sdist(localenv.Command("src/base/global.cpp", "#src/base/global.cpp",
Expand Down
10 changes: 0 additions & 10 deletions site_scons/wxsgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,22 +130,12 @@ def make_wxs(self, outFile):
Display='expand',
AllowAdvertise='no'))

if self.includeMatlab:
matlab = et.SubElement(product, 'Feature',
dict(Id='Matlab', Level='1',
Title='Matlab Toolbox',
Description='Cantera Matlab toolbox',
Display='expand',
AllowAdvertise='no'))

# Files
includes = self.addDirectoryContents('include', instdir, devel)
binaries = self.addDirectoryContents('bin', instdir, core)
lib_dir = self.addDirectoryContents('lib', instdir, devel)
data_dir = self.addDirectoryContents('data', instdir, core)
sample_dir = self.addDirectoryContents('samples', instdir, samples)
if self.includeMatlab:
matlab_dir = self.addDirectoryContents('matlab', instdir, matlab)

# Registry entries
reg_options = dict(ForceCreateOnInstall="yes", ForceDeleteOnUninstall="yes",
Expand Down
85 changes: 0 additions & 85 deletions test/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -204,85 +204,6 @@ def addPythonTest(testname, subset):
return run_program


def addMatlabTest(script, testName, dependencies=None, env_vars=()):
def matlabRunner(target, source, env):
passedFile = target[0]
del test_results.tests[passedFile.name]
workDir = Dir('#test/work').abspath
if not os.path.isdir(workDir):
os.mkdir(workDir)
outfile = pjoin(workDir, 'matlab-results.txt')
runCommand = "%s('%s'); exit" % (source[0].name[:-2], outfile)
if os.name == 'nt':
matlabOptions = ['-nojvm','-nosplash','-wait']
else:
matlabOptions = ['-nojvm','-nodisplay']
if os.path.exists(outfile):
os.remove(outfile)

environ = dict(os.environ)
environ.update(env['ENV'])
environ.update(env_vars)
code = subprocess.call([pjoin(env['matlab_path'], 'bin', 'matlab')] +
matlabOptions + ['-r', runCommand],
env=environ, cwd=Dir('#test/matlab').abspath)
if code and env["fast_fail_tests"]:
sys.exit(1)
try:
with open(outfile, "r") as output_file:
results = output_file.read()
except EnvironmentError: # TODO: replace with 'FileNotFoundError' after end of Python 2.7 support
test_results.failed['Matlab' +
' ***no results for entire test suite***'] = 100
return

matlab_test_message = [
f"{' Matlab test results ':-^88}",
results,
f"{' end Matlab test results ':-^88}",
]
logger.info("\n".join(matlab_test_message))

passed = True
for line in results.split('\n'):
line = line.strip()
if not line:
continue
label = line.split()[0]
if 'seconds' not in line: # Headers for test suite sections
section = line
elif 'test' in line and 'matlab' in line: # skip overall summary line
continue
elif label == section: # skip summary line for each section
continue
elif 'FAILED' in line:
test_results.failed['.'.join(['Matlab', section, label])] = 1
passed = False
elif 'passed' in line:
test_results.passed['.'.join(['Matlab', section, label])] = 1

if passed:
open(target[0].path, 'w').write(time.asctime()+'\n')

testenv = localenv.Clone()
passedFile = File('matlab/%s.passed' % (script))
PASSED_FILES[testName] = str(passedFile)
test_results.tests[passedFile.name] = True
run_program = testenv.Command(passedFile, pjoin('matlab', script), matlabRunner)

dependencies = (dependencies or []) + localenv['matlab_extension']
for dep in dependencies:
if isinstance(dep, str):
dep = File(pjoin('matlab', dep))
testenv.Depends(run_program, dep)

testenv.Depends(testenv['test_results'], run_program)
if os.path.exists(passedFile.abspath):
Alias('test-reset', testenv.Command('reset-%s%s' % ('matlab', script),
[], [Delete(passedFile.abspath)]))

return run_program

# Instantiate tests
addTestProgram('clib', 'clib')
addTestProgram('equil', 'equil')
Expand Down Expand Up @@ -310,12 +231,6 @@ if localenv['python_package'] == 'full':
localenv.Alias('test-' + name, pyTest)
env['testNames'].append(name)

if localenv['matlab_toolbox'] == 'y':
matlabTest = addMatlabTest('runCanteraTests.m', 'matlab',
dependencies=multi_glob(localenv, 'matlab', 'm'))
localenv.Alias('test-matlab', matlabTest)
env['testNames'].append('matlab')

# Force explicitly-named tests to run even if SCons thinks they're up to date
for command in COMMAND_LINE_TARGETS:
if command.startswith('test-'):
Expand Down

0 comments on commit c4c2243

Please sign in to comment.