I am working on getting gfortran working with MATLAB on Windows. As far as I understand, the main issue is related to the name mangling; however, my understanding is naive, and there may be more to it than this. I would love it if you could explain it to me. I want gfortran and MATLAB to work on windows to keep using Fortran mex functionality of libraries that I have come across over the years. For instance, Glmnet is an example of a great library that once provided a mex binary that worked. As of the last couple releases of MATLAB, the Glmnet binary no longer works and therefore needs to be recompiled on Windows; For Linux, the recompile is trivially simple. I have contacted the author and received no response. Several years ago, I actually got gfortran to compile and link to MATLAB dll’s, but the mex function didn’t work. Now I am back again, trying to learn enough to see if what I have described is even possible.
The main method I use to get gfortran to compile and link against MATLAB is
- Generate a Module-Definition (.def) File using gendef for libmex.dll and libmx.dll (main dll’s needed for basic mex files). Modify the .def file mapping what gfortran is looking for in function name to what libmex.dll and libmx.dll provide. For example:
... mexatexit_=MEXATEXIT mexatexit800_=MEXATEXIT800 mexcallmatlab_=MEXCALLMATLAB mexcallmatlab800_=MEXCALLMATLAB800 mexcallmatlabwithtrap_=MEXCALLMATLABWITHTRAP mexcallmatlabwithtrap800_=MEXCALLMATLABWITHTRAP800 mexerrmsgidandtxt_=MEXERRMSGIDANDTXT mexerrmsgidandtxt800_=MEXERRMSGIDANDTXT800 mexerrmsgtxt_=MEXERRMSGTXT mexerrmsgtxt800_=MEXERRMSGTXT800 mexevalstring_=MEXEVALSTRING mexevalstring800_=MEXEVALSTRING800 mexevalstringwithtrap_=MEXEVALSTRINGWITHTRAP mexevalstringwithtrap800_=MEXEVALSTRINGWITHTRAP800 mexfunctionname_=MEXFUNCTIONNAME mexfunctionname800_=MEXFUNCTIONNAME800 mexgetvariable_=MEXGETVARIABLE mexgetvariable800_=MEXGETVARIABLE800 mexgetvariableptr_=MEXGETVARIABLEPTR mexgetvariableptr800_=MEXGETVARIABLEPTR800 mexisglobal_=MEXISGLOBAL mexisglobal800_=MEXISGLOBAL800 mexislocked_=MEXISLOCKED mexislocked800_=MEXISLOCKED800 mexlock_=MEXLOCK mexlock800_=MEXLOCK800 mexmakearraypersistent_=MEXMAKEARRAYPERSISTENT mexmakearraypersistent800_=MEXMAKEARRAYPERSISTENT800 mexmakememorypersistent_=MEXMAKEMEMORYPERSISTENT mexmakememorypersistent800_=MEXMAKEMEMORYPERSISTENT800 mexprintf_=MEXPRINTF mexprintf800_=MEXPRINTF800 mexputvariable_=MEXPUTVARIABLE mexputvariable800_=MEXPUTVARIABLE800 mexsettrapflag_=MEXSETTRAPFLAG mexunlock_=MEXUNLOCK mexunlock800_=MEXUNLOCK800 mexwarnmsgidandtxt_=MEXWARNMSGIDANDTXT mexwarnmsgidandtxt800_=MEXWARNMSGIDANDTXT800 mexwarnmsgtxt_=MEXWARNMSGTXT mexwarnmsgtxt800_=MEXWARNMSGTXT800 and more...
- Use dlltool to generate an Import Library as follows. I have tried dllwrap but haven’t been able to get it to work yet.
dlltool --def libmex.def --dllname libmex.dll --output-lib libmex.a dlltool --def libmx.def --dllname libmx.dll --output-lib libmx.a
- Compile Fortran mex function.
gfortran -c -m64 -DMATLAB_DEFAULT_RELEASE=R2017b -DUSE_MEX_CMD -I"C:\Program Files\MATLAB\R2020b/extern/include" -I"C:\Program Files\MATLAB\R2020b/extern/include" -fexceptions -fbackslash -fPIC -fno-omit-frame-pointer -fdefault-integer-8 -O2 timestwo.F gfortran -c -m64 -DMATLAB_DEFAULT_RELEASE=R2017b -DUSE_MEX_CMD -I"C:\Program Files\MATLAB\R2020b\extern\include" -fexceptions -fbackslash -fPIC -fno-omit-frame-pointer -fdefault-integer-8 -O2 fortran_mexapi_version.F
- Link the objects and Import Libraries:
gfortran -m64 -static -shared timestwo.o timestwo.def fortran_mexapi_version.o libmex.a libmx.a libgfortran-3.dll -o timestwo.mexw64
The previous 4 steps complete without error. However, the mex library doesn’t work. I am missing a few things. If you can provide some explanation, that would be helpful. If I can’t get this figured out in the next couple of months, I will probably post a job and get some help on this. I really would love to compile Open Source Software and provide it for free on GitHub; many will benefit.
The calling conventions are a little different between gfortran and libmex.dll and libmx.dll. What I am really asking is can gfortran/GCC generate binaries that are compatible with libmex.dll, libmx.dll, etc. I hope so.