diff --git a/var/spack/repos/builtin/packages/octave/helloworld.cc b/var/spack/repos/builtin/packages/octave/helloworld.cc new file mode 100644 index 0000000000..f2cb6d9c1e --- /dev/null +++ b/var/spack/repos/builtin/packages/octave/helloworld.cc @@ -0,0 +1,11 @@ +#include + +DEFUN_DLD (helloworld, args, nargout, + "Hello World Help String") +{ + octave_stdout << "Hello World has " + << args.length () << " input arguments and " + << nargout << " output arguments.\n"; + + return octave_value_list (); +} diff --git a/var/spack/repos/builtin/packages/octave/package.py b/var/spack/repos/builtin/packages/octave/package.py index b3b9567db4..f70895bfda 100644 --- a/var/spack/repos/builtin/packages/octave/package.py +++ b/var/spack/repos/builtin/packages/octave/package.py @@ -2,17 +2,23 @@ # Spack Project Developers. See the top-level COPYRIGHT file for details. # # SPDX-License-Identifier: (Apache-2.0 OR MIT) - -from spack import * +import os.path +import shutil import sys +import tempfile + +import spack.util.environment class Octave(AutotoolsPackage, GNUMirrorPackage): """GNU Octave is a high-level language, primarily intended for numerical - computations. It provides a convenient command line interface for solving - linear and nonlinear problems numerically, and for performing other - numerical experiments using a language that is mostly compatible with - Matlab. It may also be used as a batch-oriented language.""" + computations. + + It provides a convenient command line interface for solving linear and + nonlinear problems numerically, and for performing other numerical + experiments using a language that is mostly compatible with Matlab. + It may also be used as a batch-oriented language. + """ homepage = "https://www.gnu.org/software/octave/" gnu_mirror_path = "octave/octave-4.0.0.tar.gz" @@ -89,6 +95,57 @@ class Octave(AutotoolsPackage, GNUMirrorPackage): depends_on('suite-sparse', when='+suitesparse') depends_on('zlib', when='+zlib') + def patch(self): + # Filter mkoctfile.in.cc to use underlying compilers and not + # Spack compiler wrappers. We are patching the template file + # and not mkoctfile.cc since the latter is generated as part + # of the build. + mkoctfile_in = os.path.join( + self.stage.source_path, 'src', 'mkoctfile.in.cc' + ) + quote = lambda s: '"' + s + '"' + entries_to_patch = { + r'%OCTAVE_CONF_MKOCTFILE_CC%': quote(self.compiler.cc), + r'%OCTAVE_CONF_MKOCTFILE_CXX%': quote(self.compiler.cxx), + r'%OCTAVE_CONF_MKOCTFILE_F77%': quote(self.compiler.f77), + r'%OCTAVE_CONF_MKOCTFILE_DL_LD%': quote(self.compiler.cxx), + r'%OCTAVE_CONF_MKOCTFILE_LD_CXX%': quote(self.compiler.cxx) + } + + for pattern, subst in entries_to_patch.items(): + filter_file(pattern, subst, mkoctfile_in) + + @run_after('install') + @on_package_attributes(run_tests=True) + def check_mkoctfile_works_outside_of_build_env(self): + # Check that mkoctfile is properly configured and can compile + # Octave extensions outside of the build env + mkoctfile = Executable(os.path.join(self.prefix, 'bin', 'mkoctfile')) + helloworld_cc = os.path.join( + os.path.dirname(__file__), 'helloworld.cc' + ) + tmp_dir = tempfile.mkdtemp() + shutil.copy(helloworld_cc, tmp_dir) + + # We need to unset these variables since we are still within + # Spack's build environment when running tests + vars_to_unset = ['CC', 'CXX', 'F77', 'FC'] + + with spack.util.environment.preserve_environment(*vars_to_unset): + # Delete temporarily the environment variables that point + # to Spack compiler wrappers + for v in vars_to_unset: + del os.environ[v] + # Check that mkoctfile outputs the expected value for CC + cc = mkoctfile('-p', 'CC', output=str) + msg = "mkoctfile didn't output the expected CC compiler" + assert self.compiler.cc in cc, msg + + # Try to compile an Octave extension + shutil.copy(helloworld_cc, tmp_dir) + with working_dir(tmp_dir): + mkoctfile('helloworld.cc') + def configure_args(self): # See # https://github.com/macports/macports-ports/blob/master/math/octave/