Matlab requires
compatible compilers
to run compiled code and even to run itself.
Trying to use Matlab on a non-supported just-released OS version can sometimes encounter difficulty.
libc, libstdc++, or libgfortran incompatible with Matlab and cause failure to run MEX code.
The workaround below assumes Linux.
Example error messages:
MATLAB/R*/sys/os/glnxa64/libstdc++.so.6: version `GLIBCXX_3.4.29’ not found (myfun.mexa64)
Workaround by having the system libraries take priority by using environment variable
LD_PRELOAD.
In certain cases, such as defining multiple classes or templates in a single header or source file in C or C++, it may be useful to include inline source code files to reduce code duplication.
This can be achieved by using the #include directive with a file containing the inline code.
This technique is distinct from the use of
header files,
which are typically used to declare functions, classes, and other entities that are defined in a separate source file.
This technique is also distinct from the use of the
inline specifier on functions.
A traditional file suffix for include code files is .inc or .inl, but any suffix can be used.
Build systems detect changes to these included inline code files and rebuild the source file if necessary.
For example, CMake
detects
include dependencies (header, inline code) based on its own source parser, or some modern compilers manage dependencies themselves.
Makefiles with CMake uses the compiler itself or depend.make in each target build directory to track dependencies.
Ninja (with CMake or other build system such as Meson) specifies include dependencies via
depfiles
per source file, which may be observed for debugging with option ninja -d keepdepfile
The Fortran include statement inserts source code from the specified file into the Fortran source code file at the location of the include statement.
The include file can contain any valid Fortran syntax, including procedures, modules, variable definitions, operations, etc.
This concept is similar to the C/C++ #include preprocessor directive that can also be used for
inlining code,
but Fortran include does not require a preprocessor.
include statements are frequently used to reuse code like defining constants or Fortran 77 common blocks.
Generated code from build systems like CMake and Meson can be consumed with include statements.
The file suffix “.inc” is often used, but is arbitrary.
One example of a Fortran-only project extensively using CMake-generated Fortran source with include is
h5fortran
to allow polymorphic (type and rank) HDF5 I/O in Fortran.
The source code deduplication thus achieved is significant and the code is easier to maintain.
Build systems scan Fortran source files for dependencies to detect the include statements and track the included files.
Makefiles with CMake uses the compiler itself or depend.make in each target build directory to track dependencies.
Ninja (with CMake or other build system such as Meson) specifies include dependencies via
depfiles
per source file, which may be observed for debugging with option ninja -d keepdepfile
In the example below, the dependency of main.f90 on const.inc is tracked by:
If importing Python modules or trying to run an Anaconda Python program like Spyder gives CXXABI errors, it can be due to a conflict between the system libstdc++ and the Anaconda libstdc++.
Assuming Anaconda / Miniconda Python on Linux, try specifying the libstdc++ library in the
conda environment
by LD_PRELOAD.
Find the system libstdc++:
find /usr -name libstdc++.so.6
Suppose “/usr/lib64/libstdc++.so.6”.
Set LD_PRELOAD environment variable in the conda environment:
conda env config vars set LD_PRELOAD=/usr/lib64/libstdc++.so.6
conda activate
Matlab
codeIssues()
command recursively lints Matlab .m code files.
The output is a neat table.
The Matlab build system has a built-in
CodeIssuesTask
for use via
buildtool
to validate an entire Matlab project from a single command.
Used from CI, this is a quick first step check of a project to help ensure compatibility of code syntax across Matlab versions.
Of course, the Matlab version checked is only the currently-running Matlab, so the CI system would need to fan out running across the desired Matlab versions.
Matlab
Git operations
are a first-class part of the Matlab environment, without need for
system()
calls.
The Matlab Desktop GUI or Matlab factory functions allow most common Git operations to be directly performed.
For example,
Git clone
is a plain Matlab function that can be called from the command line or script.
For research reproducibility, a Docker image gives a known software state that should be usable for many years.
It isn’t strictly necessary to make a custom image as described below, but it can be useful for a known software state.
FROM alpine:latest# example for CMake project using Fortran with OpenMPI.RUN apk add --no-cache ninja-build cmake gfortran openmpi-devENV CMAKE_GENERATOR=Ninja
Create the file above named Dockerfile in the Git repo.
Once the configured Docker container is ready, share this container.
This can be done with
Docker Hub.
Once ready to upload the image, note the “container ID”, which is the hexadecimal number at the terminal prompt of the Docker container, under docker ps.
The container hex ID must appear under docker ps, just being in docker images is not enough.
The changes to the image the container made are gathered into a new image.
It may take a minute or two for a large image.
Ideally with a small image it will take only a couple seconds.
The new image has not yet left the computer, it will show up under
docker images
Once uploaded, the Docker image is visible to the world by default.
Login to Docker Hub
docker login -u dockerhub_username
Push (upload) this image to Docker Hub.
This image is world-visible by default!
docker push dockerhub_username/openmpi-fortran
If the image is very large > 1 GB, be aware it will take a while to upload, and for the host to download.
This is a telltale that it’s important to keep Docker images small.
Docker images are useful for reproducibility and ease of setup and for software binary distribution on platforms not natively available.
For example, it may be desired to distribute a statically-linked binary that will run on any Linux system with compatible CPU architecture and kernel system calls.
To setup and maintain Docker images, it’s useful to have
Docker Desktop
available on the developer laptop to debug and test Dockerfiles.
Read the install instructions particular to the laptop OS to understand OS-specific caveats and features.
For example, on Linux laptops, to avoid the need for “sudo” in every command, follow the
post-install.
Docker commands can be run from the system terminal if desired–all commands in this article assume this.
Docker images by default will be downloaded to run locally.
Try the Hello World images, which should auto-download and print a welcome message
docker run hello-world
Search for a desired image using Docker Desktop or docker search.
Consider the “Official” images first.
Let’s use
Alpine Linux.
docker search alpine
Get the desired image
docker pull alpine
Verify the images:
docker images
Start the Docker container:
docker run -it alpine
-it
interactive session
Verify the Alpine version running in the container.
It will have a # superuser prompt.
cat /etc/os-release
Search for desired APK packages from within the container: