N0dev

Ladislav Dobrovský

Compiling C++ MEX-functions for Matlab on Linux

May 292020

Even the newest Matlab 2020a requires GCC 6.3 from 2016 to compile custom MEX functions in C++. That is quite a problem in modern Ubuntu (based) distros, which do not have this version of GCC in the repository and also compiling the GCC 6.3 does not work smoothly because of different version of Glib and such.
I am using Linux Mint 19.3 Tricia based on Ubuntu 18.04 Bionic Beaver, so this is what I tried and successfully managed to get it working.

Virtualization to the rescue

Inside Virtualbox I have installed 64bit Ubuntu 16.04.6 Xenial. It might ask after installation to upgrade, don’t do it… https://releases.ubuntu.com/16.04/

I had no luck installing gcc-6.3 from a PPA, so I decided to compile it from the sources:
https://ftp.gnu.org/gnu/gcc/gcc-6.3.0/gcc-6.3.0.tar.bz2

You need packages: build-essential, libgmp-dev, libmpfr-dev, libmpc-dev:

sudo apt install build-essential libgmp-dev libmpfr-dev libmpc-dev

extract the tar.bz2 and inside the directory, create a build directory:

mkdir build
cd build
../configure --enable-languages=c,c++ \
--disable-multilib \
--program-suffix=-6.3
make -j 8 # change the number according to your virtual CPU core count

 

Back to the main system

Copy the whole gcc folder (you can use mounting a local folder from host) to the host system.
Also copy from /usr/lib/x86_64-linux-gnu/ the files libmpfr.so.4 and libmpfr.so.4.1.4 to host system. Other libraries were compatible in my case, you might need to copy also libgmp and libmpc shared objects if versions differ.

In the build directory run:

sudo make install

It shoud work now as gcc-6.3 !

With matlab mex inside Matlab

mex GCC='/usr/local/bin/gcc-6.3' arrayProduct.cpp

With a Makefile

In my case I need to use NVIDIA’s nvcc, so I use a Makefile to compile everything like this:

SRC = ../src
SRC_MEX = ../src_mex
NVCC_FLAGS = -std c++14 -Xcompiler -std=c++14 -Xcompiler -Wall
DEPLOY_MEX = ../deploy_mex

all: test_hc12 test_hc12_taboo mex

MATLAB_INCLUDE = -I/usr/local/MATLAB/R2019b/extern/include
MATLAB_LIBS = /usr/local/MATLAB/R2019b/sys/os/glnxa64/libstdc++.so.6 -pthread \
-Wl,--no-undefined -shared -Wl,--as-needed \
-Wl,-rpath-link,/usr/local/MATLAB/R2019b/bin/glnxa64 \
-L"/usr/local/MATLAB/R2019b/bin/glnxa64" \
-Wl,-rpath-link,/usr/local/MATLAB/R2019b/extern/bin/glnxa64 \
-L"/usr/local/MATLAB/R2019b/extern/bin/glnxa64" \
-lMatlabDataArray -lmx -lmex -lmat -lm -lstdc++ \
-Wl,--version-script,"/usr/local/MATLAB/R2019b/extern/lib/glnxa64/mexFunction.map"
MATLAB_NV_LIBS = -L/usr/local/cuda/lib64 -lcudart
MATLAB_NVCC_FLAGS = -Xcompiler -fexceptions \
-Xcompiler -fPIC \
-Xcompiler -fno-omit-frame-pointer \
-Xcompiler -pthread -Xcompiler -O2 \
-Xcompiler -fwrapv -Xcompiler -DNDEBUG \
-Xcompiler -D_GNU_SOURCE -Xcompiler -DMATLAB_MEX_FILE

mex_function.o: $(SRC_MEX)/mex_function.cu
nvcc -ccbin gcc-6.3 -v -c $(SRC_MEX)/mex_function.cu \
-o mex_function.o $(MATLAB_INCLUDE) $(MATLAB_NVCC_FLAGS)

mex: mex_function.o
g++-6.3 mex_function.o -o hc12qs2_v2.mexa64 \
$(MATLAB_LIBS) $(MATLAB_NV_LIBS) \
&& cp hc12qs2_v2.mexa64 $(DEPLOY_MEX)

test_hc12: $(SRC)/test_hc12.cu
nvcc -ccbin gcc-6.3 -v $(SRC)/test_hc12.cu \
-o test_hc12 $(NVCC_FLAGS)

test_hc12_taboo: $(SRC)/test_hc12_taboo.cu
nvcc -ccbin gcc-6.3 -v $(SRC)/test_hc12_taboo.cu \
-o test_hc12_taboo $(NVCC_FLAGS)

.PHONY: clean
clean:
rm -f test_hc12 test_hc12_taboo hc12qs2_v2.mexa64 mex_function.o

rebuild: clean all

Atom

Powered by Nibbleblog