diff --git a/SConstruct b/SConstruct index 932a3fa27..6aba2c265 100644 --- a/SConstruct +++ b/SConstruct @@ -253,17 +253,18 @@ opts.AddVariables( EnumVariable( 'matlab_toolbox', """This variable controls whether the Matlab toolbox will be - built. If it is set to 'default', the Matlab toolbox will - be built if Matlab can be found in the $PATH. Note that you - may need to run 'mex -setup' within Matlab to configure it - for your C++ compiler before building Cantera.""", + 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')), PathVariable( - 'matlab_cmd', - """Path to the Matlab executable. In Windows, this is probably - something like "C:/Program Files/MATLAB/R2009a/bin/win64/MATLAB.exe" - """, - 'matlab', PathVariable.PathAccept), + '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/R2011a" on Windows, + "/Applications/MATLAB_R2011a.app" on OS X, or + "/opt/MATLAB/R2011a" on Linux.""", + '', PathVariable.PathAccept), EnumVariable( 'f90_interface', """This variable controls whether the Fortran 90/95 interface @@ -728,18 +729,24 @@ else: env['python_array_include'] = '' -if env['matlab_toolbox'] == 'y' and which(env['matlab_cmd']) is None: - print """ERROR: Unable to find the Matlab executable '%s'""" % env['matlab_cmd'] - sys.exit(1) -elif env['matlab_toolbox'] == 'default': - cmd = which(env['matlab_cmd']) - if cmd is not None: - env['matlab_toolbox'] = 'y' - print """INFO: Building the Matlab toolbox using '%s'""" % cmd - else: - print """INFO: Skipping compilation of the Matlab toolbox. """ +# Matlab Toolbox settings +if env['matlab_path'] != '' and env['matlab_toolbox'] == 'default': + env['matlab_toolbox'] = 'y' + +if env['matlab_toolbox'] == 'y': + matPath = env['matlab_path'] + if matPath == '': + print """ERROR: Unable to build the Matlab toolbox because 'matlab_path' has not been set.""" + sys.exit(1) + + if not (os.path.isdir(matPath) and + os.path.isdir(pjoin(matPath, 'extern'))): + print """ERROR: Path set for 'matlab_path' is not correct.""" + print """ERROR: Path was: '%s'""" % matPath + sys.exit(1) +# Sundials Settings if env['use_sundials'] == 'default': if env['HAS_SUNDIALS']: env['use_sundials'] = 'y' @@ -1040,7 +1047,7 @@ if env['python_package'] in ('full','minimal'): SConscript('src/python/SConscript') if env['matlab_toolbox'] == 'y': - SConscript('src/matlab/SConscript') + SConscript('build/src/matlab/SConscript') SConscript('build/src/apps/SConscript') diff --git a/interfaces/matlab/testpath.m b/interfaces/matlab/testpath.m new file mode 100644 index 000000000..7e773dacf --- /dev/null +++ b/interfaces/matlab/testpath.m @@ -0,0 +1,20 @@ +% get list of directories +% dirs = strread(path, '%s', 'delimiter', pathsep); +dirs = regexp(path, ['([^' pathsep ']*)'], 'match'); + +% if 'cantera' is already in the path, we want to remove it +for i = 1:length(dirs) + if strfind(dirs{i}, 'Cantera') + rmpath(dirs{i}); + continue; + end + if strfind(dirs{i}, 'cantera') + rmpath(dirs{i}); + end +end + +path(path, [pwd filesep 'toolbox']); +path(path, [pwd filesep 'toolbox' filesep '1D']); + +% Set path to Python module +%setenv('PYTHONPATH', [pwd filesep 'interfaces' filesep 'python']) diff --git a/src/matlab/SConscript b/src/matlab/SConscript index f9a8c84d9..74456c7d7 100644 --- a/src/matlab/SConscript +++ b/src/matlab/SConscript @@ -2,69 +2,68 @@ from buildutils import * Import('env', 'build', 'install') -class MatlabBuilder(object): - def __init__(self, libs): - self.libs = libs - - def __call__(self, target, source, env): - filenames = [os.path.split(node.path)[1] for node in source] - sourcestr = ' '.join(filenames) - includes = ' '.join('-I%s' % quoted(Dir(s).abspath) for s in env['CPPPATH']) - libdir = ' '.join('-L%s' % quoted(Dir(s).abspath) for s in env['LIBPATH']) - libs = ' '.join('-l'+s for s in self.libs) - extraFlag = '-cxx' if os.name == 'posix' else '' - debugFlag = '-g' if not env['optimize'] else '' - outdir = "'%s'" % Dir('#interfaces/matlab/toolbox').abspath - - text = ("disp('building Cantera...');\n" - "mex %(debugFlag)s %(extraFlag)s -v -output ctmethods " - "-outdir %(outdir)s " - "%(includes)s %(libdir)s " - "%(libs)s %(sourcestr)s\n" - "disp('done.');\n" - "pause(2)\n" - "exit\n") % locals() - - with open(str(target[0]), 'w') as f: - f.write(text) - - localenv = env.Clone() -localenv.Append(CPPPATH=['#include', '#src']) +linkflags = [] -cantera_libname = 'cantera_shared' if os.name=='nt' else 'cantera' -libs = [cantera_libname] + env['sundials_libs'] +matlab_include = pjoin(localenv['matlab_path'], 'extern', 'include') -localenv.Command('build_cantera.m', - mglob(localenv, '.', 'cpp'), - MatlabBuilder(libs)) - -localenv['ENV']['PATH'] = os.environ['PATH'] -if 'TEMP' in os.environ: - localenv['ENV']['TEMP'] = os.environ['TEMP'] - -build_cmd = 'cd ${SOURCE.dir} && "%(matlab_cmd)s" -nojvm -nosplash -r build_cantera' - -if os.name == 'posix': - mexPlatform = 'a' -elif os.name == 'nt': +if localenv['OS'] == 'Windows': mexPlatform = 'w' - if localenv['OS_BITS'] == 64: - localenv['ENV']['PROCESSOR_ARCHITECTURE'] = "AMD64" + linklibs = ['cantera_shared'] + linklibs += ['libmx', 'libmex', 'libmat'] + if localenv['OS_BITS'] == 32: + matlab_libs = pjoin(localenv['matlab_path'], 'extern', + 'lib' ,'win32', 'microsoft') else: - localenv['ENV']['PROCESSOR_ARCHITECTURE'] = "x86" + matlab_libs = pjoin(localenv['matlab_path'], 'extern', + 'lib' ,'win64', 'microsoft') -mexFile = ('#interfaces/matlab/toolbox/ctmethods.mex%s%i' % - (mexPlatform, localenv['OS_BITS'])) + if localenv['CC'] == 'cl': + linkflags.append('/export:mexFunction') + linkflags.append('/MACHINE:X%i' % localenv['OS_BITS']) -target = build(localenv.Command(mexFile, 'build_cantera.m', - build_cmd % localenv)) -localenv.Depends(target, localenv['cantera_shlib']) +elif localenv['OS'] == 'Darwin': + linklibs = ['cantera'] + linklibs += ['mx', 'mex', 'mat'] + env['LIBM'] + mexPlatform = 'maci' + linkflags.extend(['-Wl,-exported_symbol,_mexFunction']) + localenv.Append(FRAMEWORKS=['Accelerate']) + + if localenv['OS_BITS'] == 64: + matlab_libs = pjoin(localenv['matlab_path'], 'bin', 'maci64') + else: + matlab_libs = pjoin(localenv['matlab_path'], 'bin', 'macx86') + +elif os.name == 'posix': + linklibs = ['cantera'] + linklibs += ['mx', 'mex', 'mat'] + env['LIBM'] + mexPlatform = 'a' + + if localenv['OS_BITS'] == 64: + matlab_libs = pjoin(localenv['matlab_path'], 'bin', 'glnxa64') + else: + matlab_libs = pjoin(localenv['matlab_path'], 'bin', 'glnx86') + +mexSuffix = '.mex%s%i' % (mexPlatform, localenv['OS_BITS']) + +localenv.Append(CPPPATH=['#include', '#src', matlab_include], + CPPDEFINES=['MATLAB_MEX_FILE'], + LIBPATH=[matlab_libs]) + +linklibs += env['sundials_libs'] + +ctmethods = build(localenv.SharedLibrary('#interfaces/matlab/toolbox/ctmethods', + mglob(localenv, '.', 'cpp'), + SHLIBPREFIX='', + SHLIBSUFFIX=mexSuffix, + LIBS=linklibs, + LINKFLAGS=linkflags)) ### Install the Matlab toolbox ### # 'ctpath.m' -target = build(localenv.SubstFile('ctpath.m', '#interfaces/matlab/ctpath.m.in')) +target = build(localenv.SubstFile('#interfaces/matlab/ctpath.m', + '#interfaces/matlab/ctpath.m.in')) install('$inst_matlab_dir', target) # 'cantera_demos.m'