Compiling C++ MEX-functions for Matlab on Linux
May 292020Even 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