I need to call some Fortran code from within MATLAB. I did some research and read about the mex command and how to use it. Sadly I'm already failing at getting the Fortran compiler to work.
First of all, here's my setup:
macOS Sierra 10.12.1 (latest version)
MATLAB R2016b (latest version)
gfortran 4.9.2 (installed via .dmg from official GNU site)
According to the MATLAB documentation, I can use mex -setup FORTRAN to prepare mex for building a mex-file from Fortran. However, running the command in verbose mode yields the following output: mex -setup -v FORTRAN
Verbose mode is on.
... Looking for compiler 'Intel Fortran Composer XE' ...
... Looking for environment variable 'IFORT_COMPILER16' ...No.
... Looking for environment variable 'IFORT_COMPILER15' ...No.
... Looking for environment variable 'IFORT_COMPILER14' ...No.
... Looking for environment variable 'IFORT_COMPILER13' ...No.
... Executing command 'which ifort' ...No.
Did not find installed compiler 'Intel Fortran Composer XE'.
Error using mex
No supported compiler or SDK was found. For options, visit
http://www.mathworks.com/support/compilers/R2016b/maci64.html.
Following the link, one can see that MATLAB does support GNU gfortran 4.9.x on Linux. On Mac however, only Intel's commercial compilers are listed as supported. That's what mex seems to be looking for as well.
Since Mac can also use gfortran to compile Fortran code I thought it'd be possible to get it to work with MATLAB. I've also googled alot and found questions like this one on the MathWorks forum, which suggests that MATLAB should be able to use gfortran, even on Mac.
That's what I think is strange, my MATLAB isn't even looking for a gfortran compiler. All it does is look for an Intel compiler, can't find one and then throws above stated error message.
Regarding my gfortran installation. It is definitely 4.9.2 (which is listed as supported under Linux), which gfortran returns /usr/local/bin and I can successfully compile programs via Terminal.
By the way, mex -setup ANY successfully lists the compilers for C and C++ but no Fortran.
MEX configured to use 'Xcode with Clang' for C language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB
variables with more than 2^32-1 elements. In the near future
you will be required to update your code to utilize the
new API. You can find more information about this at:
http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.
MEX configured to use 'Xcode Clang++' for C++ language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB
variables with more than 2^32-1 elements. In the near future
you will be required to update your code to utilize the
new API. You can find more information about this at:
http://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:
Xcode with Clang mex -setup:'/Users/Lennart/Library/Application Support/MathWorks/MATLAB/R2016b/mex_C_maci64.xml' C
Xcode Clang++ mex -setup:'/Users/Lennart/Library/Application Support/MathWorks/MATLAB/R2016b/mex_C++_maci64.xml'
I also had a look at those .xml files mentioned at the very end of the last output. There was no file for anything having to do with Fortran and I wasn't able to successfully write one myself. I'm not even sure whether that's the problem...
So simply put my question is: How can I get MATLAB to actually look for and then of course also find my gfortran compiler to use it to compile mex files?
Appreciate your help!
Thanks to hsuyaa and the provided link I was able to resolve my problem. As it needed some more experimenting by myself, I'd like to post how exactly I was able to get gfortran to work.
Look at this link and the accepted answer. Although the MathWorks Team explicitly states that the instructions are specifically written for xCode 7.0 and MATLAB R2015b, I got everything to work with xCode 8.1, MATLAB R2016b and macOS Sierra 10.12.
MATLAB seems to be storing the compiler configuration details in .xml-files as mentioned before. You can find the directory in MATLAB by entering
cd( fullfile( matlabroot, 'bin', 'maci64', 'mexopts' ) );
I did perform a fresh install of MATLAB before but at that location, only three files where located, one for Clang, one for Clang++, one for Intel's Fortran. The gfortran one was simply missing.
The solution author at MathWorks appended all of these .xml-files to his post. I downloaded the files and copied gfortran.xml to the above mentioned folder. This granted partial success in that it made MATLAB actually look for gfortran when running the mex setup.
However, since the files are not up-to-date, I had to add a few lines. I don't exactly understand how the configuration files work, but I noticed that some lines where referring to older macOS versions. Download the file gfortran.xml behind the above link and then add the following:
Wherever you see
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk" />
or
<cmdReturns name="find $$ -name MacOSX10.11.sdk" />
also add
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk" />
or
<cmdReturns name="find $$ -name MacOSX10.12.sdk" />
macOS 10.12 is Sierra. Saving the file and running mex -setup FORTRAN again successfully identified gfortran and set it as the fortran compiler for mex.
Your matlab version is not able to detect the supported compilers. May be this Link can help.
Related
I am patching code into my car's ECU. This has a Motorola MC68376 processor, so I'm using the appropriate CPU32 instruction set.
I want to continue to write in assembly code so that I can explicitly manage control registers, RAM access and allocation, as well as copying code structures which are already in use.
My first patch was successfully compiled in EASy68k, but that program does not support the full instruction set for the CPU32. For example, the DIVS.L command is not supported, so I cannot take a quotient of a 32-bit value.
Thus, before writing my own compiler out of sheer incompetence with available tools, I'm looking for an easier path. I read that gcc has the capability to compile code for the CPU32, but I have failed to get it to work.
I'm using MinGW's gcc (6.3.0) and Eclipse (2020-03). I added the '-mcpu32' or '-march=cpu32' flags to the compiler call, according to:
https://gcc.gnu.org/onlinedocs/gcc/M680x0-Options.html
Unfortunately this returns an error:
gcc: error: unrecognized command line option '-mcpu32'; did you mean '-mcpu='?
or
error: bad value (cpu32) for -march= switch
May I please have some advice for making this work? Does anyone know of a better CPU32 compiler that works with Eclipse?
I did not understand that gcc is conventionally distributed as binary files that are compiled with different functionality to suit the needs of a given user.
There seem to be two paths forward:
1) compile my own cross-compiler version of GCC
2) download a pre-compiled cross-compiler version of GCC
I chose to follow route 2).
I began the process of installing the 'Windows Subsystem for Linux' and Ubuntu 20.04 Focal Fossa, because I found a pre-made compiler that should be capable of performing cross compilation for the m68k processor: "gobjc-10-m68k-linux-gnu"
https://ubuntu.pkgs.org/20.04/ubuntu-universe-i386/gobjc-10-m68k-linux-gnu_10-20200411-0ubuntu1cross1_i386.deb.html
While I was installing that, I also found an m68k-elf gcc toolchain that is pre-compiled for windows 10:
https://gnutoolchains.com/m68k-elf/
I played with the latter for much of today. Although I was unable to get the toolchain integrated well with Eclipse, it works from the command line to compile a *.s assembly code file. This includes compatibility with the '-mcpu32' flag that I wanted at the outset.
There is still a lot for me to figure out, even after floundering through learning gcc's assembler directives (https://www.eecs.umich.edu/courses/eecs373/readings/Assembler.pdf) and the differences in gcc's assembly syntax compared to the MC68k reference manual (https://www.nxp.com/files-static/archives/doc/ref_manual/M68000PRM.pdf).
I can even convert the code section of the output file to be a proper s-record by using objcopy with the '-O srec' and '--only-section=.text' flags. This helps me patch the code into my ECU.
Thus I've answered my original question.
I am running glmnet package on MATLAB 2019a in macOS 10.14.5. I have also installed Xcode in my laptop.
I got the error like the following:
Invalid MEX-file '/Users/Desktop/Research/Paper Code/glmnet/glmnetMex.mexmaci64' : dlopen(/Users/Desktop/Research/Paper Code/glmnet/glmnetMex.mexmaci64,
6): Library not loaded: #loader_path/libmex.dylib
Referenced from: /Users/Desktop/Research/Paper Code/glmnet/glmnetMex.mexmaci64
I have tried the code mex -setup and got
MEX configured to use 'Xcode with Clang' for C language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB variables with more than 2^32-1 elements.
In the near future you will be required to update your code to utilize the new API.
You can find more information about this at: http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.
I've found some advice from mathworks specific to mex but I am not sure whether this can solve my problem. I stopped here since I am not sure if I should follow this answer to delete something.
Any ideas?
The glmnetMex MEX file included with the Glmnet download looks busticated on newer versions of macOS because it was compiled on a much older version of macOS (OS X 10.8, according to their website), and the DLL library loading mechanism has changed since then. (It should be using #rpath instead of #loader_path.) You will need to rebuild the MEX file yourself, or contact the Glmnet maintainers and ask them to provide a new build.
To rebuild the MEX file:
Set up Matlab with mex -setup to use a compiler that can compile Fortran MEX files. (I don't actually know how to do this.)
In Matlab, cd to the glmnet_matlab directory, !rm glmnetMex.mexmaci64, and then run mex glmnetMex.F
I would consider this a bug in the Glmnet distribution; I have reported it upstream to the Glmnet maintainers.
(I can reproduce this issue with a fresh download of Glmnet on my macOS 10.14.6 box running Matlab R2019a, too.)
Here's a similar problem with another Matlab library's pre-built MEX file: Library not loaded: #loader_path/libmex.dylib in matlab. Next time try Googling for various parts of your error message; searching for "Library not loaded: #loader_path/libmex.dylib" will pull up that question.
#Andrew Janke's answer worked well, except for the second step where I needed to compile using
mex FFLAGS='-fdefault-real-8 -ffixed-form -compatibleArrayDims' glmnetMex.F GLMnet.f
See also here: https://github.com/growlix/glmnet_matlab
I am running MATLAB 2019a with MacOS 10.15.3.
I have downloaded Bellhop, which is an underwater acoustic simulator written in Fortran. It can be found here with the Makefile.
Question 1: I would like to know if it is possible to compile Fortran code, including everything needed, so a user without gfortran installed, can run it.
I have read here the following:
static linking
This section does not apply to Windows users, except for Cygwin users with gcc4-4.3.2-2 or later.
gfortran is composed of two main parts: the compiler, which creates the executable program from your code, and the library, which is used when you run your program afterwards. That explains why, if gfortran is installed in a non-standard directory, it may compile your code fine but the executable may fail with an error message like library not found. One way to avoid this (more ideas can be found on the binaries page) is to use the so-called "static linking", available with option -static gfortran then put the library code inside the program created, thus enabling it to run without the library present (like, on a computer where gfortran is not installed). Complete example is:
gfortran -static myfile.f -o program.exe
Reading this, I suppose that it is possible to do what I'm asking but I'm not very familiarized with fortran and makefiles. I don't understand this:
put the library code inside the program created
Question 2: How can I put the library code inside the program? Where can I find the library? What does "inside the program" means?
I'm running OSX 10.9.4 and gfortran
I solved my problem about compiling Fortran code with gfortran using static libraries.
As #M.S.B. said, using static-libgfortran worked for me under MacOS.
If somebody is having issues with linking the libquadmath.0.dylb library, remove libquadmath.0.dylib and libquadmath.dylib from /usr/local/gfortran/lib/
This doest the trick. Further information can be found here
I think the meaning of the bold part is actually
gfortran then puts the library code inside the
program created
That means using -static should be enough, there is no additional step. Just be advised you will need a static version of all the libraries that you link with.
I know this is very old tracker, but maybe somebody will be still interested in the solution that works.
Let's say we have code:
! fort_sample.f90
program main
write (*,*) 'Hello'
stop
end
First, compile the stuff:
gfortran -c -o fort_sample.o fort_sample.f90
Then, link stuff
ld -o ./fort_sample -no_compact_unwind \
-arch x86_64 -macosx_version_min 10.12.0 \
-lSystem \
/usr/local/gfortran/lib/libgfortran.a \
/usr/local/gfortran/lib/libquadmath.a \
/usr/local/gfortran/lib/gcc/x86_64-apple-darwin16/6.3.0/libgcc.a \
fort_sample.o
You can execute it
./fort_sample
Hello
You can notice that quadmath is no longer there
> otool -L fort_sample
fort_sample:
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1238.51.1)
I guess this is what you were looking for in a first place. No removing dylibs, no symbolic links, etc.
The current version of the option is -static-libgfortran. This means that the Fortran specific libraries of gfortran will be included into the executable. These are libraries are automatically found for a good installation of gfortran. This should produce an executable that should run on other computers with the same OS, even if that computer doesn't have gfortran installed. This option likely doesn't statically link all libraries, so there is some risk that some other shared library used on your computer won't be available on the other computer.
I've done everything, and it's payed off.
Trying to compile a mex file from MATLAB using the Windows 7.1 SDK.
~ I've created an compiled my C source code on GCC
~ I've created a MEX file that links and compiles fine via GCC on both Linux and OS X. Does not crash MATLAB, gateway function works fine
~ After much confusion, I switched my dev platform form 64-bit to x86 Win7
~ I've found .dll built files, but they do not link. Linking libs in MATLAB using MATLAB's linker flags will default to .lib, so...
~ I've found--after much googling--simple, pre-compiled x86 GSL .lib's and source files and linked them with MATLAB, eliminating any gsl_blas.h-and-it's-dependencies unrecognized external symbol errors
~ I've re-written every single variable declaration in my source code such that it is C89 standard compatible
~ I've set linker flags appropriately to avoid LIBCMT and any other LIB conflicts
~ I've installed the 2010 and 2012 VC C Runtime libraries
~ I've checked to make sure I have msvcrt.dll and msvcp60.dll in my System files
~ I've followed multiple tutorials online on how supposedly link everything together, most of which had nothing broken links or un-replicable results. I didn't find much to go off of for Cygwin or MinGW.
~ I've tried using the Lcc-win32 2.4.1 compiler
If I was doing basic matrix and vector operations, I'd be set, but unfortunately the various decomposition routines I'm utilizing require parts from the cblas library, which I linked as well, but I get ~30 errors all reporting the same thing...
cblas.lib(ctrsv.obj) : error LNK2001: unresolved external symbol __libm_sse2_sqrt_precise
Here's my MATLAB command.
mex -largeArrayDims -IC:\gsl\include -LC:\gsl\lib -lgsl -lcblas LINKFLAGS="$LINKFLAGS /NODEFAULTLIB:libcmt.lib" file1.c file2.c
So, out of options and frustrated out of my mind, I (naturally) come to stack overflow. Anyone have any idea how to solve this one? The only thing I've foudn on google points to wineHQ errors, not very helpful.
And, if possible, I'd rather not try to compile first on VS201X. I have access to whatever version I need, if necessary, but to me that just seems like a redundant step. Maybe I'm spoiled with Unix-based file system management and linking, though.
It's easy to compile the GSL library under MinGW, in fact the process of compiling from sources is exactly identical to that in Linux. Here are the steps I took:
Setup MinGW for Windows. I am using MinGW-w64 but there is also the popular TDM-GCC distribution which comes with a friendly web-installer.
Obtain GSL sources, and extract the tarball (gsl-1.16.tar.gz is the latest as of now)
Compile as usual, I've used the following commands:
$ ./configure --host=x86_64-w64-mingw32 --prefix=/mingw/local --enable-shared --enable-static
$ make
$ make install
It should take several minutes to finish. Maybe you can enable parallel builds to speed up compilation (make -j)
You'll end up with the necessary files installed in /mingw/local with the usual structure underneath (bin, lib, include).
Finally you can compile an example program with:
$ export PATH=/mingw/local:$PATH
$ gcc `gsl-config --cflags` -o main main.c `gsl-config --libs`
Of course if you prefer using Visual C++ as compiler, people out there have prepared solutions to build GSL using Visual Studio (either manually created project files, or using a build system like CMake and the like). See this question for such projects.
A third option is using Cygwin.
I am trying to run FFTW code in a mex file. This is strictly for the purpose of development and testing. After some googling, I see that others have tried to do something similar and have had related problems, but I have not found any solutions. When attempting to run the mex file, Matlab tells me:
??? Error using ==>
chirpTransform.mxCta Invalid MEX-file
'\removed\my\directory\+chirpTransform\mxCta.mexw32':
The specified procedure could not be
found.
.
I am using gnumex with MinGW to build the mex file because LCC seems to have some issues. I have tried using the 32 bit DLL from the FFTW site (http://www.fftw.org/install/windows.html). I have tried using the fftwf3.dll in the Matlab 2009b bin directory. I built the dll from source using Msys/MinGW. In all cases, the results are the same. In all cases I did the following to generate the lib file.
c:\gnumex\mexdlltool.exe -d
libfftw3f-3.def -D libfftw3f-3.dll -l
libfftw3f.lib --as C:\MinGW\bin\as.exe
I also tried using the visual studio lib.exe tool and experimented with various mexdlltool flags.
It appears that I can directly call functions in the fftwf3-3.dll using Matlab's loadlibrary functionality. Since the DLL appears not to be the problem, I tried building a static version of fftwf3 and linking it directly into the mex file. I got the same results! If I remove the FFTW code, the mex file runs fine. I have just about given up at this point, and I am tyring to come up with alternative methods of testing.
I've run into this issue with other mex functions. In my experience, it typically means that there is a dependency issue. Some dependency is not located.
Here is a link to TMW's documentation on this issue:
Invalid MEX-File Error
Give it a read, and then try using dependency walker to diagnose the problem.
It's been a long time, and my setup has changed, but this works for me now. I suspect hoogamaphone was right. I probably didn't have the fftw dll in the same directory as the mex dll (and it wasn't in my path). In fact, 64 bit Matlab 2016a still gives you a warning about not being able to find the mex file when, in fact, it's a dependency that's missing.
My current setup is using the Visual Studio 2013 C++ compiler by default. As mentioned on the fftw web site, you need to generate a lib file for linking. You can run the Visual Studio command prompt from a regular command prompt like so:
"%VS120COMNTOOLS%VsDevCmd.bat"
Then run the following in the directory with the def file.
lib /machine:x64 /def:libfftw3f-3.def
And compile.
mex mxCta.c cta.c -I../fftw -L../fftw -llibfftw3f-3.lib
Perhaps another possibility is that gnumex introduced some dependency into the mex dll. I no longer recall whether I had used gnumex successfully testing other code. When using cygwin, if you don't use the mingw compiler (x86_64-w64-mingw32-gcc), you'll end up with a dependency on the cygwin1.dll.
Finally, if you use more than one compiler, make sure all the compiler flags are the same (same function calling conventions, ABI, etc). Also, Mathworks has changed the mex build procedure. In a recent project, I copied mexconfig.xml to my local directory from
C:\Users\myuser\AppData\Roaming\MathWorks\MATLAB\R2016a\mex_C_win64.xml
and edited the compiler flags like so:
COMPFLAGS="/Zp8 /GR /W3 /EHs /nologo /MD /Gz /TC"
If you use a custom build file, use the -f option.
mex mxCustom.c custom.lib -f mexconfig.xml