Bonjour à tous,
Je suis confronté à un problème de compilation ou link sous Matlab.
Tout d'abord, pour introduire un peu mon soucis, voici quelques explications :
- j'ai un fichier fortran 'algo.f' dans lequel j'ai une subroutine TOTO. Cette subroutine fait appel à différentes fonctions que l'on retrouve dans ce même fichier.
- l'objectif est d'intégrer ce code fortran dans un modèle Simulink, pour au final générer une S-Fonction de ce modèle via RTW de Matlab
Après quelques tâtonnements, j'ai compris que pour générer une S-Fonction sous RTW, il faut lui donner du code C : RTW n'accepte pas directement du Fortran, il faut donc créer un fichier C 'interface.c' dans lequel il faut définir les fonctions "d'interfaçage" entre Simulink et Fortran (avec par exemple la fonction mdlOutput...). On parle aussi de S-Fonction "inline".
Je dispose maintenant de 2 fichiers : 'algo.f' et 'interface.c' ; il ne reste plus qu'à les compiler et les linker pour obtenir ma dll que j'intégrerai ensuite dans mon modèle Simulink.
Cette complation s'effectue en 2 étapes :
- création du fichier 'algo.obj' à partir du fichier Fortran. J'utilise la commande mex avec le compilateur fortran Intel Visual studio Fortran 10.1.
- création de la dll à partir du fichier C et du fichier 'algo.obj'. J'utilise également la commande mex avec le compilateur C de base sous Matlab : lcc.
Pour faciliter la compilation, je commence avec une subroutine fortran vide ou avec un algo très simple du style sorties=entrees. De cette manière, tout est ok : création des objets, link de ces objets et création de la dll, puis enfin génération de la S-Fonction finale sous RTW incluant cette dll et le reste du modèle.
Après ce succès, je décide de mettre les algo voulus dans mon code Fortran : la compilation du code fortran se déroule bien, l'objet 'algo.obj' est créé sans soucis.
Le problème intervient lors de la seconde compilation, et à mon avis lors du link... Puisque j'ai comme infos des messages du type "algo.obj .text: undefined reference to '_expf'", ce qui me laisse penser qu'il manque une ou plusieurs librairies à passer au linker. Ce besoin de ces librairies étant directement aux fonctions appelées dans mon algo Fortran.
Dès lors, je rajoute diverses librairies mais derrière c'est l'effet cascade : pour une "undefined refrence" de résolue j'en récupère 10...
Bref tout ça pour en arriver à ma question : comment configurer mon linker, ou comment utiliser la fonction mex pour compiler correctement et surtout linker mes objets ensemble ?
Ci-dessous un aperçu de ce que Matlab me renvoie lors de ces compilations, avec l'option -v de la commande mex pour voir les options de compilation et de link :
- Ici la première compilation
>> mex -v -f mexopts_fortran.bat -c algo.f
This is mex, Copyright 1984-2007 The MathWorks, Inc.
-> Options file specified on command line
----------------------------------------------------------------
-> Options file = mexopts_fortran.bat
MATLAB = C:\PROGRA~1\MATLAB\R2008a
-> COMPILER = ifort
-> Compiler flags:
COMPFLAGS = /fpp /Qprec "/IC:\PROGRA~1\MATLAB\R2008a/extern/include" -c -nologo -DMATLAB_MEX_FILE /fixed
OPTIMFLAGS = /MD -Ox -DNDEBUG
DEBUGFLAGS = /MD -Zi /PDB:"algo.mexw32.pdb"
arguments =
Name switch = /Fo
-> Pre-linking commands =
-> LINKER = link
-> Link directives:
LINKFLAGS = /DLL /EXPORT:MEXFUNCTION /MAP /LIBPATH:"C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\microsoft" libmx.lib libmex.lib libmat.lib /implib:C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_uZE9e1\templib.lib /NOLOGO
LINKDEBUGFLAGS = /debug /PDB:"algo.mexw32.pdb"
LINKFLAGSPOST =
Name directive = "/out:algo.mexw32"
File link directive =
Lib. link directive =
Rsp file indicator = @
-> Resource Compiler = rc /fo "mexversion.res"
-> Resource Linker =
----------------------------------------------------------------
--> ifort /fpp /Qprec "/IC:\PROGRA~1\MATLAB\R2008a/extern/include" -c -nologo -DMATLAB_MEX_FILE /fixed /Foalgo.obj /MD -Ox -DNDEBUG -DMX_COMPAT_32 "X:\algo.f"
>>
- Ici la seconde compilation
>> mex -v -f mexopts_lcc.bat interface.c algo.obj
This is mex, Copyright 1984-2007 The MathWorks, Inc.
-> Options file specified on command line
----------------------------------------------------------------
-> Options file = mexopts_lcc.bat
MATLAB = C:\PROGRA~1\MATLAB\R2008a
-> COMPILER = lcc
-> Compiler flags:
COMPFLAGS = -c -Zp8 -I"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\include" -DMATLAB_MEX_FILE -noregistrylookup
OPTIMFLAGS = -DNDEBUG
DEBUGFLAGS = -g4
arguments =
Name switch = -Fo
-> Pre-linking commands =
-> LINKER = lcclnk
-> Link directives:
LINKFLAGS = -tmpdir "." -dll "C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\lcc\mexFunction.def" -L"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\lib" -libpath "C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\lcc" C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\templib2.obj
LINKDEBUGFLAGS =
LINKFLAGSPOST = libmx.lib libmex.lib libmat.lib
Name directive = -o "interface.mexw32"
File link directive =
Lib. link directive =
Rsp file indicator = @
-> Resource Compiler = lrc -I"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\include" -noregistrylookup -fo"mexversion.res"
-> Resource Linker =
----------------------------------------------------------------
--> lcc -c -Zp8 -I"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\include" -DMATLAB_MEX_FILE -noregistrylookup -FoC:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\interface.obj -IC:\PROGRA~1\MATLAB\R2008a\extern\include -IC:\PROGRA~1\MATLAB\R2008a\simulink\include -DNDEBUG -DMX_COMPAT_32 "X:\interface.c"
--> lcc -c -Zp8 -I"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\include" -DMATLAB_MEX_FILE -noregistrylookup "C:\PROGRA~1\MATLAB\R2008a\sys\lcc\mex\lccstub.c" -FoC:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\templib2.obj
Contents of C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\mex_tmp.rsp:
C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\interface.obj algo.obj
--> lcclnk -o "interface.mexw32" -tmpdir "." -dll "C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\lcc\mexFunction.def" -L"C:\PROGRA~1\MATLAB\R2008a\sys\lcc\lib" -libpath "C:\PROGRA~1\MATLAB\R2008a\extern\lib\win32\lcc" C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\templib2.obj -s @C:\DOCUME~1\wt0t1123\LOCALS~1\Temp\mex_pL7KD9\mex_tmp.rsp libmx.lib libmex.lib libmat.lib
Writing library for interface.mexw32
algo.obj .text: undefined reference to '_expf'
algo.obj .text: undefined reference to '___powr4i4'
algo.obj .text: undefined reference to '_powf'
algo.obj .text: undefined reference to '_tanf'
algo.obj .text: undefined reference to '_for_stop_core'
algo.obj .text: undefined reference to '_for_cpystr'
algo.obj .text: undefined reference to '_for_close'
algo.obj .text: undefined reference to '_logf'
C:\PROGRA~1\MATLAB\R2008A\BIN\MEX.PL: Error: Link of 'interface.mexw32' failed.
??? Error using ==> mex at 207
Unable to complete successfully.
>>
Pour info j'ai rajouter la librairie libm.lib qui se trouve dans un répertoire du compilateur Fortran, en utilisant les options -L et -l de la commande mex, et c'est ainsi qu'apparaissent par la suite d'autre "undefined reference"...
Voilà désolé pour la tartine mais je voulais donner le plus d'infos possible.
En espérant que quelqu'un aura une idée pour résoudre mon problème, que ce soit une erreur de configuration du linker, ou même une mauvaise façon de compiler...
Pour toute autre question n'hésitez pas...
Dans l'attente de votre aide,
Merci d'avance !
Philippe
Partager