Pergunta

Estou tentando escrever uma função Matlab Mex que usa libhdf5; Minha instalação do Linux fornece bibliotecas e cabeçalhos compartilhados libhdf5-1.8. No entanto, minha versão do MATLAB, R2007B, fornece um libhdf5.so a partir da versão 1.6. (Matlab .mat arquivos bootstrap hdf5, evidentemente). Quando eu compilar o MEX, ele se usa no MATLAB. Se eu rebaixar minha versão do libhdf5 para 1.6 (não uma opção de longo prazo), o código compila e funciona bem.

Pergunta: Como resolvo esse problema? Como digo ao processo de compilação do MEX para vincular /usr/lib64/libhdf5.so.6 em vez de /opt/matlab/bin/glnxa64/libhdf5.so.0? Quando tento fazer isso usando -Wl,-rpath-link,/usr/lib64 Na minha compilação, recebo erros como:

/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. O último recurso seria baixar uma cópia local dos cabeçalhos HDF5-1.6.5 e terminar com ela, mas isso não é uma prova futura (uma atualização da versão do MATLAB está no meu futuro.). alguma ideia?

Editar: De acordo com as excelentes sugestões de Ramashalanka, eu

A) chamado mex -v Para conseguir o 3 gcc comandos; O último é o comando vinculador;

B) chamado aquele comando vinculativo com um -v Para obter o collect comando;

C) chamado assim collect2 -v -t e o resto das bandeiras.

As partes relevantes da minha saída:

/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

Então, de fato o libhdf5.so a partir de /usr/lib64 está sendo referenciado. No entanto, isso está sendo substituído, acredito, pela variável ambiente LD_LIBRARY_PATH, que minha versão do MATLAB configura automaticamente em tempo de execução para que possa localizar suas próprias versões de por exemplo libmex.so, etc.

Estou pensando que o crt_file.c Exemplo funciona b/c não usa as funções que estou usando (H5DOpen, que teve uma mudança de assinatura na mudança de 1,6 para 1,8 (sim, estou usando -DH5_USE_16_API)), ou, menos provável, b/c não atinge as partes dos internos do MATLAB que precisam de HDF5. ack.

Foi útil?

Solução

O seguinte funcionou no meu sistema:

  1. Instale o HDF5 versão 1.8.4 (você já fez isso: instalei a fonte e compilou para garantir que ela seja compatível com o meu sistema, que recebo versões GCC e que recebo as bibliotecas estáticas - por exemplo, os binários oferecidos para o meu sistema são icc específico).

  2. Faça um arquivo de destino. Você já tem seu próprio arquivo. Eu usei o simples h5_crtfile.c a partir de aqui (Uma boa ideia para começar com este arquivo simples primeiro um visual de avisos). eu mudei main para mexFunction com os args habituais e incluídos mex.h.

  3. Especifique o estático 1.8.4 Biblioteca que você deseja carregar explicitamente (o caminho completo sem -l para ser necessário) e não inclua -lhdf5 no LDFLAGS. Inclua um -t Opção para garantir que não haja biblioteca HDF5 dinâmica sendo carregada. Você também precisa -lz, com zlib instalado. Para Darwin, também precisamos de um -bundle dentro LDFLAGS:

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

    Para Linux, você precisa de uma chamada independente de posição equivalente, por exemplo, fPIC e talvez -shared, mas não tenho um sistema Linux com uma licença MATLAB, então não posso verificar:

    mex CFLAGS='-fPIC -I/usr/local/hdf5/include' LDFLAGS='-t /usr/local/hdf5/lib/libhdf5.a -lz -shared' h5_crtfile.c -v
    
  4. Execute o h5_crtfile arquivo mex. Isso funciona sem problemas na minha máquina. Ele apenas faz um H5fcreate e H5fclose para criar "file.h5" no diretório atual e quando eu ligo file file.h5 eu recebo file.h5: Hierarchical Data Format (version 5) data.

Observe que se eu incluir um -lhdf5 Acima na etapa 3, o Matlab aborta quando tento executar o executável (porque ele usa as bibliotecas dinâmicas do MATLAB que para mim são a versão 1.6.5), então isso está definitivamente resolvendo o problema no meu sistema.

Obrigado pela pergunta. Minha solução acima é definitivamente muito mais fácil para mim do que o que eu estava fazendo antes. Espero que o acima funcione para você.

Outras dicas

Estou aceitando a resposta de Ramashalanka porque isso me levou à solução exata que postarei aqui apenas para completar:

  1. Faça o download da biblioteca HDF5-1.6.5 no site HDF5 e instale os arquivos de cabeçalho em um diretório local;
  2. Diga a Mex para procurar "hdf5.h" neste diretório local, e não no local padrão (por exemplo /usr/include.)
  3. Diga a Mex para compilar meu código e a biblioteca de objetos compartilhados fornecida pelo MATLAB, e fazer não use o -ldfh5 sinalize LDFLAGS.

O comando que usei é essencialmente:

/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

Isso é traduzido pelo MEX para os comandos:

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

Esta solução deve funcionar em todas as minhas várias máquinas de destino e pelo menos até que eu atualize para o MATLAB R2009A, que acredito que usa o HDF5-1.8. Obrigado por toda a ajuda, desculpe por ser tão denso com isso-acho que fui compensado demais para usar a versão embalada do HDF5, em vez de um conjunto local de arquivos de cabeçalho.

Observe que tudo isso teria sido trivial se o Mathworks tivesse fornecido um conjunto de arquivos de cabeçalho com a distribuição do MATLAB ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top