# Backends and Installation
The installation of this crate is slightly more involved than you might be used to: you
need to select a backend. The backend to choose depends on what version of Matlab or
GNU/Octave you are targeting with your library. Rustmex wraps the bindings exposed by
Matlab (pre and post 2017b) and GNU/Octave. The features these bindings provide are all
slightly different. The available backends are:
| `matlab800` | `mex800` | Matlab R2018a or newer | interleaved
| `matlab700` | `mex700` | Matlab R2017b or older | separate
| `octave` | `mexoctave` | GNU/Octave | separate
Once you've selected your target API, put the following in your `Cargo.toml`:
```toml
rustmex = { version = "0.6.4", features = ["<backend>"] }
```
where `"<backend>"` is then one of the options for target APIs.
Furthermore, if want to use rustmex to write a MEX file, you need to add the following to
your `Cargo.toml` file too:
```toml
[lib]
crate-type = ["cdylib"]
```
Compiling your crate then results in a C dynamic library, instead of a Rust library.
## Compilation and linkage
On some platforms with some target API's (in particular Windows with Matlab; your milage
may vary with Octave), you might need to tell the linker where some libraries are
located.
On those platforms, Rustmex's build script unconditionally fails if you don't tell the
linker where the libraries are located. Otherwise you will run into one impenetrable
error, while with the build script failing you get a nice error message.
You tell the linker where the libraries are located by [overriding the build script](https://doc.rust-lang.org/cargo/reference/build-scripts.html#overriding-build-scripts)
in a [`config.toml`](https://doc.rust-lang.org/cargo/reference/config.html) like the
following:
```toml
[target.<triple>.<links-name>]
rustc-link-search = ["<library search path>"]
rustc-link-lib = ["mx", "mex", "mat"] # libraries to link
```
you set the appropriate triplet, library search path, and libraries to link. Substitute
`<triple>` with the triple you are compiling for (the "host" field of the output of
`rustc -vV`). Matlab will print the appropriate search path when you run
`fullfile(matlabroot(), 'bin', computer('arch'))` in your Matlab prompt.
For example, on an x86_64 linux machine, this could be
```toml
[target.x86_64-unknown-linux-gnu.mex800]
rustc-link-search = ["~/bin/R2022a/bin/glnxa64"]
rustc-link-lib = ["mx", "mex", "mat"]
```
If you are on another platform than Matlab on Windows, and the compilation still fails
with a linker error, you might also need to do this process there. Create an empty C file
`test.c` for example, and "dry run" the creation of a mex file from it. For matlab, you
can do this with `mex -n test.c`, for Octave with `mkoctfile -n test.c --mex`. Look, on
the second line, for arguments starting with `-L` and `-l`, and substitute these in the
`config.toml` file for the link search path and link library path respectively.
## MEX file installation
If you've compiled your crate as a `cdylib`, you can then take the resultant dynamic
library (on linux a `.so`), copy it to the target location in your Matlab path, with the
appropriate file extension. (`.mexa64` for MEX on 64 bit Linux, `.mexw64` for MEX on
Windows, and `.mex` for GNU/Octave.)
## Complex data representation note
When Rustmex is compiled for an API which represents complex values with two arrays (so
either `matlab700` or `octave`), slightly different implementations for data conversions
are used. Since most Rust code assumes that complex values are interleaved (i.e., the
real and imaginary parts of the value are stored next to eachother in memory) this might
cause a lot of copying on the interface.
_See also_ <https://nl.mathworks.com/help/matlab/matlab_external/matlab-support-for-interleaved-complex.html>.