Question

Je suis en train d'écrire une fonction Matlab qui MEX utilise libhdf5; Mon installation de Linux fournit des bibliothèques partagées libhdf5-1.8 et les en-têtes. Cependant, ma version de Matlab, version 2007b, fournit un libhdf5.so du 1.6 version. (Matlab .mat fichiers d'amorçage hdf5, évidemment). Quand je compilez le MEX, il segfaults dans Matlab. Si je passe ma version de libhdf5 à 1,6 (et non une option à long terme), le code compile et fonctionne très bien.

question: comment puis-je résoudre ce problème? comment puis-je dire le processus de compilation pour lier contre MEX /usr/lib64/libhdf5.so.6 au lieu de /opt/matlab/bin/glnxa64/libhdf5.so.0? Lorsque je tente de le faire en utilisant -Wl,-rpath-link,/usr/lib64 dans ma compilation, je reçois des erreurs telles que:

/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../x86_64-pc-linux-gnu/bin/ld: warning: libhdf5.so.0, needed by /opt/matlab/matlab75/bin/glnxa64/libmat.so, may conflict with libhdf5.so.6
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

    mex: link of 'hdf5_read_strings.mexa64' failed.

make: *** [hdf5_read_strings.mexa64] Error 1

ack. le dernier recours serait de télécharger une copie locale des en-têtes hdf5-1.6.5 et être fait avec elle, mais ce n'est pas la preuve future (une version Matlab mise à jour est dans mon avenir.). des idées?

EDIT: par d'excellentes suggestions de Ramashalanka, I

A) appelé mex -v pour obtenir les 3 commandes gcc; la dernière est la commande de liaison;

B) a appelé cette commande de liaison avec un -v pour obtenir la commande collect;

C) appelé que collect2 -v -t et le reste des drapeaux.

Les parties pertinentes de ma sortie:

/usr/bin/ld: mode elf_x86_64
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtbeginS.o
hdf5_read_strings.o
mexversion.o
-lmx (/opt/matlab/matlab75/bin/glnxa64/libmx.so)
-lmex (/opt/matlab/matlab75/bin/glnxa64/libmex.so)
-lhdf5 (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libhdf5.so)
/lib64/libz.so
-lm (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/libm.so)
-lstdc++ (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libstdc++.so)
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so)
/lib64/libpthread.so.0
/lib64/libc.so.6
/lib64/ld-linux-x86-64.so.2
-lgcc_s (/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/libgcc_s.so)
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/crtendS.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.3.4/../../../../lib64/crtn.o

Donc, en fait, est fait référence à la libhdf5.so de /usr/lib64. Cependant, cela est outrepassée, je crois, par l'environnement LD_LIBRARY_PATH variable, ma version de Matlab met automagiquement à l'exécution afin qu'il puisse localiser ses propres versions de par exemple libmex.so, etc.

Je pense que l'exemple de crt_file.c fonctionne soit b / c ne pas utiliser les fonctions que je utilise (H5DOpen, qui a eu un changement de signature dans le passage de 1,6 à 1,8 (oui, je me sers -DH5_USE_16_API)), ou , moins probable, b / c il ne touche pas les parties de Matlab internes qui ont besoin hdf5. ack.

Était-ce utile?

La solution

Les éléments suivants ont travaillé sur mon système:

  1. Installer la version HDF5 1.8.4 (vous avez déjà fait ceci: Je l'ai installé la source et en garantir le est compatible avec mon système, que je reçois des versions de gcc et que je reçois les bibliothèques statiques - par exemple, la binaires offerts pour mon système sont.

    spécifique icc)
  2. Créez un fichier cible. Vous avez déjà votre propre fichier. Je simple h5_crtfile.c de (une bonne idée de commencer avec ce simple fichier d'abord un regard pour les avertissements). J'ai changé main à mexFunction avec les args habituels et inclus mex.h.

  3. Indiquez le statique Bibliothèque 1.8.4 que vous voulez charger explicitement (le chemin complet sans -L pour nécessaire) et de ne pas inclure dans le -lhdf5 LDFLAGS. Inclure une option -t afin de vous assurer qu'il n'y a pas de bibliothèque hdf5 dynamique en cours de chargement. Vous devez également -lz, avec zlib installé. Pour darwin nous avons aussi besoin d'un -bundle dans LDFLAGS:

    mex CFLAGS='-I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -bundle' h5_crtfile.c -v
    

    Pour linux, vous avez besoin d'une position indépendante équivalente appel, par exemple fPIC et peut-être -shared, mais je n'ai pas un système Linux avec une licence de Matlab, donc je ne peux pas vérifier:

    mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
    
  4. Exécuter le fichier de h5_crtfile MEX. Cela va sans problème sur ma machine. Il fait juste un H5Fcreate et H5Fclose pour créer « file.h5 » dans le répertoire courant, et quand je l'appelle file file.h5 je reçois file.h5: Hierarchical Data Format (version 5) data.

Notez que si j'inclus un -lhdf5 ci-dessus à l'étape 3, puis Matlab avorte lorsque je tente de lancer l'exécutable (car il utilise alors les bibliothèques dynamiques de Matlab qui pour moi sont la version 1.6.5), donc c'est de résoudre définitivement le problème sur mon système.

Merci pour la question. Ma solution ci-dessus est sans aucun doute beaucoup plus facile pour moi que ce que je faisais avant. Espérons que les travaux ci-dessus pour vous.

Autres conseils

j'accepte la réponse de Ramashalanka parce qu'il m'a conduit à la solution exacte que je vais poster ici pour être complet que:

  1. télécharger la bibliothèque hdf5-1.6.5 sur le site Web de hdf5 et installer les fichiers d'en-tête dans un répertoire local;
  2. tell MEx de chercher "hdf5.h" dans ce répertoire local, plutôt que dans l'emplacement standard (par exemple /usr/include.)
  3. dire de compiler mon MEX code et la bibliothèque d'objets partagés fourni par Matlab , et faire pas utiliser le drapeau -ldfh5 dans LDFLAGS.

la commande I utilisé est, pour l'essentiel:

/opt/matlab/matlab_default/bin/mex -v CC#gcc CXX#g++ CFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include" CXXFLAGS#"-Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include " -O -lmwblas -largeArrayDims -L/usr/lib64 hdf5_read_strings.c /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0

se traduit par les commandes dans MEX:

gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG hdf5_read_strings.c
gcc -c -I/opt/matlab/matlab75/extern/include -DMATLAB_MEX_FILE -Wall -O3 -fPIC -I./hdf5_1.6.5/src -I/usr/include -I/opt/matlab/matlab_default/extern/include -O -DNDEBUG /opt/matlab/matlab75/extern/src/mexversion.c
gcc -O -pthread -shared -Wl,--version-script,/opt/matlab/matlab75/extern/lib/glnxa64/mexFunction.map -Wl,--no-undefined -o hdf5_read_strings.mexa64  hdf5_read_strings.o mexversion.o  -lmwblas -L/usr/lib64 /opt/matlab/matlab_default/bin/glnxa64/libhdf5.so.0 -Wl,-rpath-link,/opt/matlab/matlab_default/bin/glnxa64 -L/opt/matlab/matlab_default/bin/glnxa64 -lmx -lmex -lmat -lm -lstdc++

cette solution devrait fonctionner sur tous mes différentes machines cibles et au moins jusqu'à ce que je passe à Matlab R2009a, que je crois utilise hdf5-1.8. merci pour toute l'aide, désolé d'être si dense avec - je pense que je excessivement engagé à utiliser la version packagée de hdf5, plutôt que d'un ensemble local de fichiers d'en-tête.

Notez que ce tout aurait été si trivial Mathworks avait fourni un ensemble de fichiers d'en-tête avec la distribution Matlab ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top