Frage

Ich versuche, eine Matlab mex Funktion zu schreiben, die libhdf5 verwendet; Mein Linux installieren bietet libhdf5-1.8 gemeinsam genutzte Bibliotheken und Header. Allerdings ist meine Version von Matlab, R2007b, bietet eine libhdf5.so von 1.6-Release. (Matlab .mat Dateien Bootstrap hdf5, offenbar). Wenn ich die mex kompilieren, Segfaults es in Matlab. Wenn ich Herabstufung meine Version von libhdf5 auf 1,6 (keine langfristige Option), wird der Code kompiliert und läuft gut.

Frage: Wie löse ich dieses Problem? Wie kann ich feststellen, das mex Übersetzungsvorgang zu Link gegen /usr/lib64/libhdf5.so.6 statt /opt/matlab/bin/glnxa64/libhdf5.so.0? Wenn ich versuche, dies mit -Wl,-rpath-link,/usr/lib64 in meiner Sammlung zu tun, bekomme ich Fehler wie:

/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. der letzte Ausweg wäre eine lokale Kopie der hdf5-1.6.5 Header zum Herunterladen und mit ihm getan werden, aber dies ist nicht zuzukunftssicher (ein Matlab Versions-Upgrade ist in meiner Zukunft.). irgendwelche Ideen?

EDIT: pro Ramashalanka ausgezeichneten Vorschläge, I

A) genannt mex -v die 3 gcc Befehle zu erhalten; der letzte ist der Linker Befehl;

B) genannt, dass Linker-Befehl mit einem -v den collect Befehl zu erhalten;

C) genannt, dass collect2 -v -t und der Rest der Flaggen.

Die relevanten Teile meiner Ausgabe:

/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

So in der Tat die libhdf5.so von /usr/lib64 wird verwiesen wird. Dies wird jedoch außer Kraft gesetzt wird, glaube ich, durch den Umgebungsvariable LD_LIBRARY_PATH, die meine Version von Matlab automagically Sets zur Laufzeit, damit es seine eigenen Versionen von zum Beispiel finden kann libmex.so, etc.

Ich denke, dass das crt_file.c Beispiel entweder b Werke / c es verwendet nicht die Funktionen verwende ich (H5DOpen, die in der Bewegung 1,6-1,8 eine Signatur Änderung hatte (ja, ich bin mit -DH5_USE_16_API)) oder , weniger wahrscheinlich, b / c es nicht, die Teile von Matlab-Interna, dass Bedarf hdf5 anstößt. ack.

War es hilfreich?

Lösung

Das auf meinem System gearbeitet folgende:

  1. Installieren hdf5 Version 1.8.4 (Sie haben dies bereits getan: Ich habe die Quelle installiert und zusammengestellt, um sicherzustellen, es mit meinem System kompatibel ist, dass ich gcc Versionen bekommen und dass ich die statischen Bibliotheken erhalten - zum Beispiel des Binärdateien für mein System sind icc spezifische angeboten).

  2. Erstellen Sie eine Zieldatei. Sie haben bereits eine eigene Datei. Ich benutzte die einfache h5_crtfile.c von hier (eine gute Idee zu starten mit dieser einfachen Datei zuerst ein Blick für Warnungen). Ich änderte main zu mexFunction mit dem üblichen args und enthalten mex.h.

  3. Geben Sie die statisch 1.8.4 Bibliothek Sie explizit laden wollen (den vollständigen Pfad ohne -L dafür erforderlich) und nicht -lhdf5 im LDFLAGS enthalten. Fügen Sie eine -t Option, so können Sie sicherstellen, dass es keine dynamische hdf5 Bibliothek geladen werden. Sie könnten auch -lz benötigen, mit zlib installiert. Für Darwin brauchen wir auch eine -bundle in LDFLAGS:

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

    Für Linux, müssen Sie einen gleichwertigen Position unabhängige Anruf, zum Beispiel fPIC und vielleicht -shared, aber ich weiß nicht ein Linux-System mit einer Matlab-Lizenz habe, so dass ich nicht überprüfen kann:

    mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
    
  4. Führen Sie die h5_crtfile mex-Datei. Dies läuft ohne Probleme auf meinem Rechner. Es tut nur H5Fcreate und H5Fclose „file.h5“ im aktuellen Verzeichnis zu erstellen, und wenn ich file file.h5 ich file.h5: Hierarchical Data Format (version 5) data bekommen nennen.

Beachten Sie, dass, wenn ich einen -lhdf5 oben in Schritt 3 sind, dann Matlab Abbrüche, wenn ich versuche, die Datei auszuführen (weil es dann dynamische Bibliotheken Matlab verwendet, die für mich Version 1.6.5), so dass diese auf jeden Fall ist die Lösung des Problems auf meinem System.

Danke für die Frage. Meine Lösung oben ist auf jeden Fall viel einfacher für mich als das, was ich vorher tat. Hoffentlich werden die oben genannten Arbeiten für Sie.

Andere Tipps

Ich bin zu akzeptieren Ramashalanka Antwort, weil es mich an die exakte Lösung geführt, die ich der Vollständigkeit halber hier posten nur:

  1. Laden Sie die hdf5-1.6.5 Bibliothek aus der hdf5 Website, und installieren Sie die Header-Dateien in einem lokalen Verzeichnis;
  2. sagt mex für "hdf5.h" in diesem lokalen Verzeichnis zu suchen, anstatt in der Standardposition (z /usr/include.)
  3. sagen mex meinen Code zu kompilieren und die gemeinsame Objekt-Bibliothek zur Verfügung gestellt von Matlab , und tut nicht verwenden, um die -ldfh5 Flagge in LDFLAGS.

der Befehl, den ich verwenden, im Wesentlichen:

/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

dies durch mex in die Befehle übersetzt wird:

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++

Diese Lösung sollte auf allen meinen verschiedenen Zielmaschinen arbeiten und zumindest bis ich ein Upgrade R2009a in Matlab, die ich Verwendungen hdf5-1.8 glauben. Danke für all die Hilfe, sorry für mit diesem so dicht ist - die verpackte Version von hdf5 zu verwenden, anstatt eine lokale Gruppe von Header-Dateien Ich glaube, ich übermäßig begangen wurde.

Hinweis: Dies wäre alles andere als trivial gewesen, wenn Mathworks einen Satz der Header-Dateien mit der Matlab Verteilung zur Verfügung gestellt hatte ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top