Multi-platform Matlab compiling
Multi-platform Matlab compiling
When trying to compile a matlab code, I faced and solved many errors either on the Windows platform and the MacOS platform. Here I note some prominent difference across platform and how to debug the compiling process.
Concept
There are 2 types of compilation in matlab.
- Matlab compiler is compiling matlab code
*.minto standalone executive files, like.exesuch that it can run on its own. mexis compiling code written in other languages intomexfile such that it can interact with matlab code, through someMatlab data API
Prerequisites
- If they use
mcc, needs MCC (matlab compiler) add-on for matlab mexuses some compiler to compile the foreign code.- Choose the c compiler for by checking
mex -setupormex -setup c++You will see.
MEX configured to use ‘Microsoft Visual C++ 2017 (C)’ for C language compilation. Warning: The MATLAB C and Fortran API has changed to support MATLAB variables with more than 2^32-1 elements. You will be required to update your code to utilize the new API. You can find more information about this at: https://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html. To choose a different C compiler, select one from the following: MinGW64 Compiler (C) mex -setup:‘C:\Program Files\MATLAB\R2019a\bin\win64\mexopts\mingw64.xml’ C Microsoft Visual C++ 2017 (C) mex -setup:C:\Users\binxu\AppData\Roaming\MathWorks\MATLAB\R2019a\mex_C_win64.xml C To choose a different language, select one from the following:
mex -setup C++mex -setup FORTRAN
- On windows, you can change the compiler just by clicking the link!
- On macOS you cannot. The gcc it use is usually the
Clangcompiler coming withXcode. Thus it’s different fromgccand some options are not supported byClanglikegcc -fopenmp.- If you want to use authentic
gccinstead, you have to install it yourself. Likehomebrew install gccorhomebrew update gcc - And then change the
mexcommand likemex CC="/usr/local/bin/gcc-9 -fopenmp" LD="/usr/local/bin/gcc-9 -fopenmp" xxx.c. Using the path to realgccto substitute! (Note MacOS automatically aliasgccwith the Clang compiler, so we have to usegcc-9for the real one.)
- If you want to use authentic
- For official reference see Change Default Compiler
Debugging Notes for multi-platform compiling
- Some library may have different names on different platforms like
winsock2.his used instead of - The pre-compiling flags are used to choose which lib / header to use
#if !defined(WIN32) && !defined(_WIN64)so some win32 flag may not be identified in win64 machine. Needs to modify that to make it work.- Note
WIN32may not be recognized, so use_WIN32or__WIN32__instead - Look into this table for the difference
- Note
- The language and command in terminal is different in linux, mac and windows, should change for that. like
rm -rfin unix andDEL -rfin windows - The midfile generated in C code compilation differs in unix and windows.
.ovs.obj - Note if some external function is not found. It normally means some library is not linked or imported properly. So find the target library (which the function resides). and to include it!
Error using mex Creating library mslisten.lib and object mslisten.exp mslisten.obj : error LNK2019: unresolved external symbol __imp_bind referenced in function mexFunction mslisten.obj : error LNK2019: unresolved external symbol __imp_closesocket referenced in function mexFunction
Only #include <winsock2.h> will cause the error above. And we should import the corresponding library as well.
#pragma comment(lib, "Ws2_32.lib")
(the meaning of #pragma comment is to add an additional dependent library to the object file, before going into linker. MSDN Doc, Q&A)
So the final debugged C code header looks like, and it can be compiled via mex -I. msconnect.c
#if !defined(_WIN32) && !defined(_WIN64)
#include <sys/socket.h>
#include <unistd.h>
#include <sys/select.h>
#include <netdb.h>
#include <arpa/inet.h>
#else
#include <winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
#endif