On m'a confié un projet à exécuter sur MATLAB R2011a. Comme il y a plusieurs fichiers .c - j'ai besoin de configurer GCC comme compilateur MEX pour ce projet. Cependant, je n'arrive pas à trouver d'explication sur la façon de le configurer. J'ai essayé un programme de script appelé gnumex - mais il a échoué (probablement configuré pour une ancienne version de MATLAB).
Une idée de comment le configurer?
Dans Matlab 2011b, il suffit de compiler et de lier directement dans un environnement mingw64 ou cygwin.
MINGWPATH=c:/MinGW64
CYGPATH=c:/cygwin
MATLABROOT=c:/Progra~1/MATLAB/R2011b
CC=$(MINGWPATH)/bin/x86_64-w64-mingw32-gcc
CFLAG= -Wall -m64 -O3 -I$(MATLABROOT)/extern/include $(SRC) $(LIBS) -o $(EXE)
MEXFLAG=-m64 -shared -DMATLAB_MEX_FILE -I$(MATLABROOT)/extern/include -Wl,--export-all-symbols $(LIBS) $(MEXSRC) -o $(MEXTGT).mexw64
LIBS= -L$(MATLABROOT)/bin/win64 -L$(MATLABROOT)/extern/lib/win64/Microsoft -lmex -lmx -lmwlapack -lmwblas -leng
EXE=../bin/engwindemo.exe
MEXTGT=
SRC=engwindemo.c
MEXSRC=
all:$(EXE)
$(EXE): $(SRC)
$(CC) $(CFLAG) -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex -o $(EXE)
@rm -f *.o*
$(MEXTGT): $(MEXSRC)
$(CC) $(MEXFLAG) -ladvapi32 -luser32 -lgdi32 -lkernel32 -lmingwex
@rm -f *.o*
Placez ce makefile dans le répertoire du code source et make
. Aucune conversion de fichiers dll nécessaire.
Pourquoi ne pas ajuster le fichier mexopts.bat dans votre répertoire? De cette façon, vous pouvez utiliser la commande "mex" de manière transparente pour compiler n'importe quoi, comme d'habitude dans MATLAB, comme s'il avait été configuré par MATLAB en utilisant mex -setup
. Je suis surpris que personne ne l'ait fait auparavant.
Le fichier ci-dessous est pour la version x64 de Matlab et Mingw. J'utilise la distribution TDM Mingw64 , que j'ai installée dans p:\mingw64-tdm
. J'ai Matlab installé dans p:\matlab\R2012a
- modifiez-les en conséquence.
Ceci est le fichier mexopts.bat que j'utilise, copiez-collez-le dans %USERPROFILE%\AppData\Roaming\MathWorks\MATLAB\R2012a\mexopts.bat
:
@echo off
set MINGWPATH=p:\mingw64-tdm
set PATH=%MINGWPATH%\bin;%PATH%
set COMPILER=gcc
set COMPFLAGS=-c -m64 -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE -Wall -std=c99
set OPTIMFLAGS=-O3 -DNDEBUG
set DEBUGFLAGS=-g
set NAME_OBJECT=-o
set LINKER=gcc
set LINKFLAGS=-shared -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\Microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
Ensuite, vous pouvez simplement essayer de faire cela dans Matlab:
mex -v p:\matlab\R2012a\extern\examples\mex\yprime.c
which yprime
Devrait céder b:\code\m\yprime.mexw64
(ou quel que soit le dossier actuel). Alors si vous le faites:
yprime(1,1:4)
Tu devrais voir:
ans =
2.0000 8.9685 4.0000 -1.0947
Ce qui signifie que vous êtes en affaires. Bonne chance!
EDIT Oct 2014: J'utilise maintenant un fichier mexopts.bat amélioré que le précédent avec un MinGW64 différent (donne un code binaire légèrement plus rapide que celui de TDM). Voir ma page d'accueil pour les détails et les téléchargements.
Il est maintenant en haut de la liste des compilateurs pris en charge .
Voir ici pour les instructions officielles pour télécharger MinGW (ils recommandent TDB-GCC).
Il y a plusieurs limitations et mises en garde répertoriées (par exemple, ne liez pas avec les bibliothèques compilées avec d'autres compilateurs, vous devez intercepter vos exceptions dans le fichier MEX, etc.).
Vous trouverez ci-dessous mon ancienne façon de créer un fichier XML pour faire la même chose.
Les années ont passé et MATLAB (à partir de R2014a) est passé à un nouveau système basé sur XML pour configurer les fichiers MEX. MATLAB prend toujours en charge temporairement les fichiers .bat hérités, pour l'instant, mais cela vous dérange . Un autre changement est que ce sont des configurations C et C++ distinctes (plus tard).
Ce qui est resté le même, c'est qu'il vous suffit de télécharger et d'extraire une distribution MinGW et de pointer MATLAB dessus. Il n'y a encore pas besoin de MSYS, cygwin ou gnumex. La seule partie délicate pointe MATLAB dessus, mais voici une solution.
Version courte
MINGWROOT
.mex -setup:[xmlfile] [C|C++]
.Version longue
Pour MinGW-w64, je fais ce qui suit pour le configurer:
C:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1\bin\x86_64-w64-mingw32-g++.exe
. Il n'est pas nécessaire d'utiliser MSYS, cygwin ou tout autre environnement si vous prévoyez de compiler dans MATLAB avec la commande mex
. Vérifiez votre variable d'environnement PATH
pour vous assurer que vous n'avez pas plusieurs compilateurs (g++
) sur votre chemin, de préférence aucun. Vérifiez avec une nouvelle invite de commande.MINGWROOT
. C'est ce qui permet à la commande mex
de localiser le compilateur. Vous pouvez le faire dans MATLAB (et à chaque fois MATLAB commence par un startup.m
script dans userpath
) avec setenv
, ou une seule fois avec boîte de dialogue des propriétés Windows ou Windows 7 natif commande setx.exe .Courir mex -setup:C:\actual\configFilePath.xml C++
. Par exemple, en utilisant le fichier .xml pour configurer la compilation du fichier MEX C++:
setenv('MINGWROOT','H:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1')
mex -setup:H:\building\GitHub\MATLAB\MinGW\mex_C++_mingw-w64.xml C++
La sortie devrait ressembler à ceci:
MEX configuré pour utiliser 'MinGW-w64 GCC 4.9.2 posixthreads seh' pour la compilation du langage C++.
Si nécessaire, configurez le compilateur C de manière similaire avec un nouveau fichier de configuration XML spécifiant le langage C, l'interface du compilateur C (par exemple "x86_64-w64-mingw32-gcc.exe" qui ne liera pas automatiquement la bibliothèque standard C++ ), ajustez les bibliothèques de liens selon vos besoins, les drapeaux du compilateur (par exemple, changez -std=c++11
à -std=c99
), etc.
Remarque sur la liaison statique et dynamique des bibliothèques d'exécution
Les bibliothèques telles qu'un fichier MEX créé avec MinGW-w64 comme ci-dessus peuvent dépendre de quelques DLL (au moment de l'exécution): LIBGCC_S_SEH-1.DLL (pour les distributions d'exceptions seh) et LIBSTDC++ - 6.DLL, et peut-être libwinpthread-1.dll si vous avez choisi une distribution pthreads au lieu de threads Win32. Si vous ne souhaitez pas copier ces fichiers, vous pouvez lier statiquement les bibliothèques d'exécution dans votre fichier MEX en ajoutant les commutateurs suivants:
-static-libgcc -static-libstdc++
Il y a un commentaire dans le modèle XML à ce sujet. Voir ici pour plus d'informations sur libpthread-1.dll.
Avec TDM-GCC, l'inverse est vrai : les temps d'exécution (y compris pthread) sont automatiquement liés statiquement. Pour créer un lien dynamique, qui nécessitera les DLL mais réduira la taille de votre fichier MEX, vous avez besoin de:
-shared-libgcc -shared-libstdc++
EDIT: Il semble y avoir un bien meilleur moyen avec MinGW; voir mon autre réponse.
Vous pouvez compiler un fichier .mex
En utilisant gcc
si vous avez Matlab
installé, à partir de la ligne de commande. Certains pourraient dire que c'est un peu fastidieux la première fois.
Tout d'abord - quel Matlab utilisez-vous? si c'est 64 bits, MinGW
ne vous aidera pas, car c'est 32 bits. Je vais donc montrer comment utiliser MinGW-w64 à la place. Comprendre comment faire cela avec MinGW
32 bits devrait être simple.
C:\MinGW-64\bin\
À votre chemin. Vous ne le regretterez pas :)Compilez vos fichiers .c
En utilisant gcc
:
x86_64-w64-mingw32-c++ -m64 -shared -I"C:\Program Files\MATLAB\R2010b\extern\include" -o bla.mexw64 -DMATLAB_MEX_FILE -Wl,--export-all-symbols *.cpp
Cela entraînera un tas d'erreurs de l'éditeur de liens, telles que
undefined reference to `mexErrMsgTxt'
Pour résoudre ce problème, vous devrez créer une bibliothèque d'importation qui se connecte avec libmex.dll
, libmx.dll
, libmat.dll
Et libeng.dll
(Vous pourriez en avoir d'autres, mais ce sont les principaux)
Énumérez les fonctions qui vous manquent et, bien, devinez de quelle dll
elles proviennent. Astuce: mexErrMsgTxt
vient de libmex.dll
, Car il commence par "mex" ...
Pour chaque dll
que vous devez exporter, créez un fichier .def
Contenant
EXPORTS
... relevant function names go here, such as mexErrMsgTxt, matOpen, etc.
Exécutez la commande suivante pour créer des bibliothèques d'importation:
x86_64-w64-mingw32-dlltool -d libmx.def --dllname libmx.dll -l libmx.a
(Idem pour le reste des fichiers .def
)
Vous êtes maintenant prêt à partir!
x86_64-w64-mingw32-c++ -m64 -shared -I"C:\..." -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.cpp libmex.a libmx.a libmat.a libeng.a
Ce qui peut être mieux fait - au lieu de --export-all-symbol
, Exportez uniquement mexFunction
(nécessite la création d'un autre fichier .def
, Ou l'ajout de "__declspec(dllexport)
" avant void mexFunction(...)
).
MinGW
est capable de liaison directe d'un DLL
; c'est-à-dire qu'il créera une sorte de bibliothèque d'importation à la volée lors de la liaison.
Cela signifie que la compilation peut être effectuée en une seule étape:
x86_64-w64-mingw32-c++ -m64 -shared -I"%MATLAB%/extern/include" -DMATLAB_MEX_FILE -o bla.mexw64 -Wl,--export-all-symbols *.cpp -L"%MATLAB%/bin/win64" -lmex -lmx -leng -lmat
Pourquoi tant d'étapes? Si vous avez Matlab 2016 ou supérieur , faites simplement:
MW_MINGW64_LOC
variable d'environnement pointant vers le dossier d'installation (exactement la même chose que vous avez tapée dans le programme d'installation)mex -setup
dans la console. Il devrait indiquer "configuré pour utiliser MinGW"Je les ai testés sur un nouveau PC Windows 10 et ça marche!
Liens Matlab vers du code externe (C++, Fortran, Java etc) en utilisant des fichiers MEX. ( http://gnumex.sourceforge.net/ )
"C:\MinGW32\bin;"
) À partir de http://tdm-gcc.tdragon.net/downloadcygwingDevel.exe
$MATLABHOME\gnumex
).$MATLABHOME
Serait par exemple (C:\Program Files\MATLAB\R2010a
)$MATLABHOME\gnumex
) Au chemin Matlab (File->Set Path
Dans Matlab).Dans Matlab, tapez gnumex
à l'invite. Remplissez les chemins appropriés comme;
MinGW_Root = C:\MinGW32, Cygwin_Root = C:\cygwin
Faites 'File->Save Config
', Puis cliquez sur 'Make Options file
'. Quittez la fenêtre de configuration de gnumex.
Copiez mexopts.bat (%AppData%\MathWorks\MATLAB\R2010a\mexopts.bat
) Dans le répertoire de travail (%UserProfile%\Documents\MATLAB
) Pour ce test.
Dans matlab, exécutez ce qui suit à l'invite;
mex -f mexopts.bat "C:\Program Files\MATLAB\R2010a\extern\examples\mex\yprime.c"
Vous obtenez (%UserProfile%\Documents\MATLAB\yprime.mexw32
) Lorsque vous tapez;
quel yprime
Exécutez-le en tapant à Matlab Prompt >> yprime(1,1:4)
et voyez si vous obtenez 2.0000 8.9685 4.0000 -1.0947
.
$MATLABHOME\bin
Et cela devrait fonctionner de n'importe où.À l'invite Linux, installez les éléments suivants;
Sudo apt-get install gcc g ++ gfortran
Dans Matlab, exécutez ce qui suit à l'invite;
mex -setup
Les fichiers d'options disponibles pour mex sont: **1**: /usr/local/MATLAB/R2012b/bin/mexopts.sh
: Sélectionnez l'option 1 . Pour tester le fonctionnement, exécutez ce qui suit à Matlab Prompt;
mex "/usr/local/MATLAB/R2012b/extern/examples/mex/yprime.c"
yprime (1,1: 4)
Au cas où vous recevez l'avertissement;
Warning: You are using gcc version "4.6.3-1ubuntu5)". The version
currently supported with MEX is "4.4.6".
For a list of currently supported compilers see:
http://www.mathworks.com/support/compilers/current_release/
À l'invite Linux:
Sudo apt-get install gcc-4.4 g++-4.4 gfortran-4.4
Sudo gedit /usr/local/MATLAB/R2012b/bin/mexopts.sh
'gcc'
Par 'gcc-4.4'
, 'g++'
Par 'g++-4.4'
, 'gfortran'
Par 'gfortran-4.4'
À toutes les instances de CC = 'gcc'
, CXX = 'g++'
Et FC = 'gfortran'
.Ceci est un guide détaillé de cette réponse . Par conséquent, tout le crédit devrait aller à cette réponse .
1 Installez MinGW-w64:
1.1 Téléchargez cette version de MinGW64-w64 et sa mise à jour:
1.2 Installez (décompressez) les archives téléchargées:
1.2.1 Décompressez le fichier de construction et déplacez le mingw64\
dossier dans c:\
1.2.2 Décompressez et copiez (écrasez) le fichier de mise à jour sur c:\mingw64
1.3 Ajouter C:\mingw64\bin
à la variable Path:
set PATH=C:\mingw64\bin;%PATH%
2 Sur une ligne de commande (en dehors de l'environnement Matlab), compilez vos fichiers * .c: Par exemple, CCODEFILE.c
(En supposant que Matlab 2012b est installé dans C:\Program Files\MATLAB\R2012b\
dossier):
"c:\mingw64\bin\x86_64-w64-mingw32-g++.exe" -m64 -shared -I"C:/Program Files/MATLAB/R2012b/extern/include" -DMATLAB_MEX_FILE -o CCODEFILE.mexw64 -Wl,--export-all-symbols CCODEFILE.c -L"C:/Program Files/MATLAB/R2012b/bin/win64" -lmex -lmx -leng -lmat
3 Ensuite, tout code Matlab devrait fonctionner correctement lorsqu'il appelle la fonction CCODEFILE
.
Si vous n'avez pas pu installer Mingw-w64 à l'aide de la barre d'outils des modules complémentaires de Matlab2016b sous Windows , vous pouvez utiliser cette solution de contournement. N'oubliez pas que vous devez modifier les chemins d'accès en fonction de vos chemins d'installation.
C:\Win-builds
.Process
pour installer tous les packages où Mingw-w64 est parmi eux.MW_MINGW64_LOC
Qui Matlab l'utilise pour détecter Mingw-w64 .Panneau de configuration\Système\Paramètres système avancés\Avancé\Variable d'environnement\Variables utilisateur pour $ YOUR_USER_NAME\Nouveau
Variable name = MW_MINGW64_LOC
Et Variable value = C:\Win-builds
. Notez que les builds Win placent tous les exécutables dans C:\Win-builds\bin
Et en définissant cette variable, Matlab analysera automatiquement le dossier bin
du chemin à la recherche de gcc.exe
.MW_MINGW64_LOC
, Il est temps de construire et de tester exemple yprime . Lancez donc Matlab et tapez la commande suivante (N'oubliez pas de modifier le chemin en conséquence): mex -v 'C:\Program Files\MATLAB\R2016b\extern\examples\mex\yprime.c'
MEX s'est terminé avec succès.
yprime(1,1:4)
. La réponse serait: ans = 2.0000 8.9685 4.0000 -1.0947
Dans Windows 64 bits avec R2011a, cela fonctionnait avec http://tdm-gcc.tdragon.net/ et http://gnumex.sourceforge.net/ mais je dois changement maxopt.bat
entrée de ligne GM_ADD_LIBS
comme suit:
rem Add path to where dlls are:
set DLL_PATH="C:\Program Files\MATLAB\R2011a\bin\win64"
rem Add every dll needed:
set GM_ADD_LIBS=%DLL_PATH%\libmx.dll %DLL_PATH%\libmex.dll %DLL_PATH%\libmat.dll
Il m'a fallu beaucoup de temps pour en arriver là, bonne chance.
Au départ, je pensais que cela ressemblait à une forme de torture, mais sur la base de la réponse ci-dessus de @ user10171136, je l'ai trouvé assez simple pour effectuer une compilation croisée pour Windows mex à partir de Fedora Linux. Fedora propose des packages mingw et mingw64, donc:
Sudo yum install mingw64-gcc mingw64-gcc-c++
extern/include
et bin/win64
répertoires (en fait, vous n'avez probablement besoin que d'un sous-ensemble des en-têtes et d'un petit sous-ensemble des DLL; libmat.dll libmex.dll libmx.dll
pourrait être tout ce dont vous avez besoin. J'ai mis ces deux répertoires dans un nouveau R2010a-w64
répertoire sous mon répertoire Linux MATLAB existant; modifiez les commandes ci-dessous en fonction de l'endroit où vous avez caché les en-têtes et les bibliothèques Windows.char16_t
était nécessaire dans matrix.h
et n'a pas été défini. Je suppose matrix.h
oublié d'inclure uchar.h
? J'ai travaillé avec un -include
directive; voir ci-dessous.x86_64-w64-mingw32-gcc -m64 -shared -include uchar.h -I/opt/MATLAB/R2010a-w64/extern/include -DMATLAB_MEX_FILE -L/opt/MATLAB/R2010a-w64/bin/win64 -o bla.mexw64 bla.c -lmx -lmex
Intéressé d'entendre si cela semble raisonnable; Je n'ai pas beaucoup d'expérience avec la compilation croisée.
Celui-ci fonctionne sur Matlab 2012b sous Windows 8:
https://github.com/DynareTeam/dynare/blob/master/windows/mexopts-win64.bat
Modifiez le répertoire cgwin ou remplacez-le par le répertoire mingw s'il est utilisé. Vous pouvez également échanger le compilateur-exe si vous passez à une version 64 bits.