diff --git a/README.md b/README.md index 87ca89f..6f0ab41 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Generally, this package is comprised of two aspects: **Important**: The procedure to setup this package consists of the following steps. -By default, `MATLAB.jl` uses the MATLAB installation with the greatest version number. To specify that a specific MATLAB installation should be used, set the environment variable `MATLAB_HOME`. +By default, `MATLAB.jl` uses the MATLAB installation with the greatest version number. To specify that a specific MATLAB installation should be used, set the environment variable `MATLAB_ROOT`. ### Windows @@ -34,12 +34,12 @@ By default, `MATLAB.jl` uses the MATLAB installation with the greatest version n ### Linux -1. Make sure ``matlab`` is in executable path. +1. Make sure ``matlab`` is in executable path. + +2. Make sure ``csh`` is installed. (Note: MATLAB for Linux relies on ``csh`` to open an engine session.) -2. Make sure ``csh`` is installed. (Note: MATLAB for Linux relies on ``csh`` to open an engine session.) - To install ``csh`` in Debian/Ubuntu/Linux Mint, you may type in the following command in terminal: - + ```bash sudo apt-get install csh ``` @@ -66,7 +66,7 @@ One can use the function ``mxarray`` to create MATLAB variables (of type ``MxArr ```julia mxarray(Float64, n) # creates an n-by-1 MATLAB zero array of double valued type -mxarray(Int32, m, n) # creates an m-by-n MATLAB zero array of int32 valued type +mxarray(Int32, m, n) # creates an m-by-n MATLAB zero array of int32 valued type mxarray(Bool, m, n) # creates a MATLAB logical array of size m-by-n mxarray(Float64, (n1, n2, n3)) # creates a MATLAB array of size n1-by-n2-by-n3 @@ -126,7 +126,7 @@ You may access attributes and data of a MATLAB variable through the functions pr ```julia # suppose x is of type MxArray nrows(x) # returns number of rows in x -ncols(x) # returns number of columns in x +ncols(x) # returns number of columns in x nelems(x) # returns number of elements in x ndims(x) # returns number of dimensions in x size(x) # returns the size of x as a tuple @@ -198,7 +198,7 @@ read_matfile(filename) # returns a dictionary that maps each variable name write_matfile(filename; name1=v1, name2=v2, ...) # writes all variables given in the # keyword argument list to a MAT file ``` -Both ``read_matfile`` and ``write_matfile`` will close the MAT file handle before returning. +Both ``read_matfile`` and ``write_matfile`` will close the MAT file handle before returning. **Examples:** @@ -209,11 +209,11 @@ struct S z::Vector{Float64} end -write_matfile("test.mat"; - a = Int32[1 2 3; 4 5 6], - b = [1.2, 3.4, 5.6, 7.8], - c = [[0.0, 1.0], [1.0, 2.0], [1.0, 2.0, 3.0]], - d = Dict("name"=>"MATLAB", "score"=>100.0), +write_matfile("test.mat"; + a = Int32[1 2 3; 4 5 6], + b = [1.2, 3.4, 5.6, 7.8], + c = [[0.0, 1.0], [1.0, 2.0], [1.0, 2.0, 3.0]], + d = Dict("name"=>"MATLAB", "score"=>100.0), s = "abcde", ss = [S(1.0, true, [1., 2.]), S(2.0, false, [3., 4.])] ) ``` @@ -264,7 +264,7 @@ As with ordinary string literals, you can also interpolate whole Julia expressio ##### `eval_string` -You may also use the `eval_string` function to evaluate MATLAB code as follows +You may also use the `eval_string` function to evaluate MATLAB code as follows ```julia eval_string("a = sum([1,2,3])") ``` @@ -292,7 +292,7 @@ xx, yy = mxcall(:meshgrid, 2, x, y) ##### `@mget` and `@mput` -The macro `@mget` can be used to extract the value of a MATLAB variable into Julia +The macro `@mget` can be used to extract the value of a MATLAB variable into Julia ```julia julia> mat"a = 6" julia> @mget a @@ -360,4 +360,3 @@ r2 = jarray(r2_mx) close(s1) # close session s1 close(s2) # close session s2 ``` - diff --git a/deps/build.jl b/deps/build.jl index b778398..3e5cb8e 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -2,22 +2,22 @@ import Libdl const depsfile = joinpath(@__DIR__, "deps.jl") -# Determine MATLAB library path and provide facilities to load libraries with -# this path - -function find_matlab_homepath() - matlab_home = get(ENV, "MATLAB_HOME", nothing) - if isnothing(matlab_home) +function find_matlab_root() + # Determine MATLAB library path and provide facilities to load libraries with this path + matlab_root = get(ENV, "MATLAB_ROOT", + get(ENV, "MATLAB_HOME", nothing)) + if isnothing(matlab_root) matlab_exe = Sys.which("matlab") - matlab_home = !isnothing(matlab_exe) ? dirname(dirname(matlab_exe)) : nothing - if isnothing(matlab_home) + if !isnothing(matlab_exe) + matlab_root = dirname(dirname(matlab_exe)) + else if Sys.isapple() default_dir = "/Applications" if isdir(default_dir) dirs = readdir(default_dir) filter!(app -> occursin(r"^MATLAB_R[0-9]+[ab]\.app$", app), dirs) if !isempty(dirs) - matlab_home = joinpath(default_dir, maximum(dirs)) + matlab_root = joinpath(default_dir, maximum(dirs)) end end elseif Sys.iswindows() @@ -26,57 +26,47 @@ function find_matlab_homepath() dirs = readdir(default_dir) filter!(dir -> occursin(r"^R[0-9]+[ab]$", dir), dirs) if !isempty(dirs) - matlab_home = joinpath(default_dir, maximum(dirs)) + matlab_root = joinpath(default_dir, maximum(dirs)) end end end end end - if isnothing(matlab_home) - return nothing - else - @info("Found MATLAB home path at $matlab_home") - return matlab_home - end + !isnothing(matlab_root) && isdir(matlab_root) && @info("Detected MATLAB root folder at \"$matlab_root\"") + return matlab_root end -function find_matlab_libpath(matlab_home) +function find_matlab_libpath(matlab_root) # get path to MATLAB libraries - matlab_lib_dir = if Sys.islinux() + matlab_libdir = if Sys.islinux() Sys.WORD_SIZE == 32 ? "glnx86" : "glnxa64" elseif Sys.isapple() Sys.WORD_SIZE == 32 ? "maci" : "maci64" elseif Sys.iswindows() Sys.WORD_SIZE == 32 ? "win32" : "win64" end - matlab_libpath = joinpath(matlab_home, "bin", matlab_lib_dir) - if !isdir(matlab_libpath) - @warn("The MATLAB library path could not be found.") - end + matlab_libpath = joinpath(matlab_root, "bin", matlab_libdir) + isdir(matlab_libpath) && @info("Detected MATLAB library path at \"$matlab_libpath\"") return matlab_libpath end -function find_matlab_cmd(matlab_home) - if !Sys.iswindows() - matlab_cmd = joinpath(matlab_home, "bin", "matlab") - if !isfile(matlab_cmd) - @warn("The MATLAB path is invalid. Ensure the \"MATLAB_HOME\" evironmental variable to the MATLAB root directory.") - end - matlab_cmd = "exec $(Base.shell_escape(matlab_cmd))" - elseif Sys.iswindows() - matlab_cmd = joinpath(matlab_home, "bin", (Sys.WORD_SIZE == 32 ? "win32" : "win64"), "MATLAB.exe") - if !isfile(matlab_cmd) - error("The MATLAB path is invalid. Ensure the \"MATLAB_HOME\" evironmental variable to the MATLAB root directory.") - end +function find_matlab_cmd(matlab_root) + if Sys.iswindows() + matlab_cmd = joinpath(matlab_root, "bin", (Sys.WORD_SIZE == 32 ? "win32" : "win64"), "matlab.exe") + isfile(matlab_cmd) && @info("Detected MATLAB executable at \"$matlab_cmd\"") + else + matlab_exe = joinpath(matlab_root, "bin", "matlab") + isfile(matlab_exe) && @info("Detected MATLAB executable at \"$matlab_exe\"") + matlab_cmd = "exec $(Base.shell_escape(matlab_exe))" end return matlab_cmd end -matlab_homepath = find_matlab_homepath() +matlab_root = find_matlab_root() -if !isnothing(matlab_homepath) - matlab_libpath = find_matlab_libpath(matlab_homepath) - matlab_cmd = find_matlab_cmd(matlab_homepath) +if !isnothing(matlab_root) + matlab_libpath = find_matlab_libpath(matlab_root) + matlab_cmd = find_matlab_cmd(matlab_root) libmx_size = filesize(Libdl.dlpath(joinpath(matlab_libpath, "libmx"))) open(depsfile, "w") do io println(io, @@ -115,5 +105,5 @@ elseif get(ENV, "JULIA_REGISTRYCI_AUTOMERGE", nothing) == "true" || get(ENV, "CI println(io, "const libmx_size = $libmx_size") end else - error("MATLAB cannot be found. Set the \"MATLAB_HOME\" environment variable to the MATLAB root directory and re-run Pkg.build(\"MATLAB\").") + error("MATLAB cannot be found. Set the \"MATLAB_ROOT\" environment variable to the MATLAB root directory and re-run Pkg.build(\"MATLAB\").") end diff --git a/src/engine.jl b/src/engine.jl index 16371db..0e83b7c 100644 --- a/src/engine.jl +++ b/src/engine.jl @@ -9,7 +9,7 @@ const default_startflag = "" # no additional flags const default_matlabcmd = matlab_cmd * " -nosplash" # pass matlab flags directly or as a Vector of flags, i.e. "-a" or ["-a", "-b", "-c"] startcmd(flag::AbstractString = default_startflag) = isempty(flag) ? default_matlabcmd : default_matlabcmd * " " * flag -startcmd(flags::AbstractVector{T}) where {T<:AbstractString} = isempty(flags) ? default_matlabcmd : default_matlabcmd * " " * join(flags, " ") +startcmd(flags::AbstractVector{<:AbstractString}) = isempty(flags) ? default_matlabcmd : default_matlabcmd * " " * join(flags, " ") # 64 K buffer should be sufficient to store the output text in most cases const default_output_buffer_size = 64 * 1024