it-swarm-pt.tech

Usando o GCC (MinGW) como compilador MEX do MATLAB

Foi-me dado um projeto para rodar no MATLAB R2011a. Como existem vários arquivos .c - preciso configurar o GCC como o compilador MEX para esse projeto. No entanto, não consigo encontrar nenhuma explicação sobre como configurá-lo. Eu tentei um programa de script chamado gnumex - mas ele falhou (provavelmente configurado para uma versão mais antiga do MATLAB).

Alguma idéia de como configurá-lo?

20
Menyh

No Matlab 2011b, basta compilar e vincular diretamente no ambiente 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*

Coloque este makefile no diretório do código-fonte e make. Nenhuma conversão de arquivo dll necessária.

14
Richard Dualmann

Por que não ajustar o arquivo mexopts.bat no seu diretório? Dessa forma, você pode usar o comando "mex" de forma transparente para compilar qualquer coisa, como sempre no MATLAB, da mesma forma que se tivesse sido configurado pelo MATLAB usando mex -setup. Estou surpreso que ninguém tenha feito isso antes.

O arquivo abaixo é para a versão x64 do Matlab e Mingw. Estou usando a distribuição TDM Mingw64 , instalada em p:\mingw64-tdm. Eu tenho o Matlab instalado em p:\matlab\R2012a - edite-os adequadamente.

Este é o arquivo mexopts.bat que estou usando, copie e cole-o em %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%"

Então você pode apenas tentar fazer isso no Matlab:

mex -v p:\matlab\R2012a\extern\examples\mex\yprime.c
which yprime

Deve render b:\code\m\yprime.mexw64 (ou qualquer que seja a pasta atual). Então, se você fizer:

yprime(1,1:4)

Você deveria ver:

ans =
    2.0000    8.9685    4.0000   -1.0947

O que significa que você está no negócio. Boa sorte!

EDIT, outubro de 2014: Agora, uso um arquivo mexopts.bat aprimorado que o acima com um MinGW64 diferente (gera código binário um pouco mais rápido que o do TDM). Consulte minha página inicial para obter detalhes e downloads.

13
Bogdan

A partir do MATLAB R2015b, o MinGW é oficialmente suportado!

Agora está no topo da lista lista de compiladores suportados .

Veja aqui para as instruções oficiais para baixar o MinGW (eles recomendam o TDB-GCC).

Existem várias limitações e advertências listadas (por exemplo, não vincule a bibliotecas compiladas com outros compiladores, você deve capturar suas exceções no arquivo MEX, etc.).

Abaixo está minha maneira antiga de criar um arquivo XML para fazer a mesma coisa.


Os anos se passaram e MATLAB (a partir de R2014a) mudou-se para um novo sistema baseado em XML para configurar arquivos MEX. O MATLAB ainda suporta temporariamente os arquivos .bat herdados, por enquanto, mas irá incomodá-lo . Outra mudança é que são configurações distintas de C e C++ (mais tarde).

O que permaneceu o mesmo é que você só precisa baixar e extrair uma distribuição MinGW e apontar o MATLAB para ela. Ainda não há MSYS, cygwin ou gnumex. A única parte complicada é apontar o MATLAB para ele, mas aqui está uma solução.

Versão curta

  • Baixe e extraia uma distribuição MinGW. Escolha um, como MinGW-w64 (64 bits) ou TDM-GCC (opções de 32 e 64 bits).
  • Personalize o arquivo de configuração XML, usando este como modelo (detalhes na versão longa abaixo).
  • Defina a variável de ambiente MINGWROOT.
  • Corre mex -setup:[xmlfile] [C|C++].

Versão Longa

Para MinGW-w64, faça o seguinte para configurá-lo:

  1. Pegue a última revisão para w64 do Sourceforge (ou use o instalador para escolher a cadeia de ferramentas desejada, escolhendo uma versão de threads pthread ou Win32, dependendo de suas necessidades).
  2. Extraia-o para que você tenha um caminho para o compilador como C:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1\bin\x86_64-w64-mingw32-g++.exe. Não há necessidade de MSYS, cygwin ou qualquer outro ambiente se você planeja compilar no MATLAB com o comando mex. Verifique sua variável de ambiente PATH para garantir que você não tenha vários compiladores (g++) no seu caminho, de preferência nenhum. Verifique com um novo prompt de comando.
  3. Configure-o com um arquivo de configuração XML personalizado. No meu repositório GitHub, publiquei configurações de C++ para MinGW-w64 nos dois tipos de arquivo: mex_C++ _ mingw-w64.xml e legado mingw_mexopts.bat . Comece com isso como modelo e (opcionalmente) edite o arquivo XML com um nome descritivo e uma versão da distribuição MinGW que você baixou e extraiu .
  4. Defina (ou crie) a variável de ambiente MINGWROOT. É isso que permite ao comando mex localizar o compilador. Você pode fazer isso no MATLAB (e toda vez o MATLAB começa com um startup.m script em userpath) com setenv ou apenas uma vez com o caixa de diálogo de propriedades do Windows ou o Windows 7 nativo comando setx.exe .
  5. Corre mex -setup:C:\actual\configFilePath.xml C++. Por exemplo, usando o arquivo .xml para configurar a compilação do arquivo C++ MEX:

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

    A saída deve ficar assim:

    MEX configurado para usar 'MinGW-w64 GCC 4.9.2 posixthreads seh' para compilação de linguagem C++.

Se necessário, configure o compilador C de maneira semelhante com um novo arquivo de configuração XML especificando a linguagem C, o front-end do compilador C (por exemplo, "x86_64-w64-mingw32-gcc.exe" que não vinculará automaticamente a biblioteca padrão do C++ ), ajuste as bibliotecas de links conforme necessário, sinalizadores do compilador (por exemplo, altere -std=c++11 para -std=c99) etc.


Nota sobre a vinculação estática vs. dinâmica das bibliotecas de tempo de execução

Bibliotecas como um arquivo MEX criado com MinGW-w64 como acima podem depender de algumas DLLs (em tempo de execução): LIBGCC_S_SEH-1.DLL (para as distribuições de exceção seh) e LIBSTDC++ - 6.DLL e, possivelmente, libwinpthread-1.dll se você escolheu uma distribuição pthreads em vez de threads do Win32. Se você não deseja copiar esses arquivos, é possível vincular estaticamente as bibliotecas de tempo de execução ao seu arquivo MEX adicionando as seguintes opções:

-static-libgcc -static-libstdc++

Há um comentário no modelo XML sobre isso. Veja aqui para obter informações sobre libpthread-1.dll.

Com TDM-GCC, o oposto é verdadeiro : os tempos de execução (incluindo pthread) são estaticamente vinculados automaticamente. Para vincular dinamicamente, o que exigirá as DLLs, mas reduzirá o tamanho do arquivo MEX, você precisará:

-shared-libgcc -shared-libstdc++
8
chappjc

EDIT: Parece haver uma maneira muito melhor com o MinGW; veja minha outra resposta.

Você pode compilar um arquivo .mex Usando gcc se tiver Matlab instalado, na linha de comando. Alguns podem dizer que é um pouco tedioso pela primeira vez.

Primeiras coisas primeiro - que Matlab você usa? se for de 64 bits, MinGW não o ajudará, porque é de 32 bits. Portanto, mostrarei como usar MinGW-w64 . Entender como fazer isso com MinGW de 32 bits deve ser simples.

  1. Adicione C:\MinGW-64\bin\ Ao seu caminho. Você não vai se arrepender disso :)
  2. Compile seus arquivos .c Usando 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
    
  3. Isso resultará em vários erros de vinculador, como

    undefined reference to `mexErrMsgTxt'
    

    Para resolver esse problema, você precisará criar uma biblioteca de importação que se conecte com libmex.dll, libmx.dll, libmat.dll E libeng.dll (Você pode ter outros, mas esses são os principais)

  4. Liste as funções que estão faltando e, bem, adivinhe de onde elas vêm dll. Dica: mexErrMsgTxt é de libmex.dll, Porque começa com "mex" ...

  5. Para cada dll que você precisa exportar, crie um arquivo .def Contendo

    EXPORTS
    ... relevant function names go here, such as mexErrMsgTxt, matOpen, etc.
    
  6. Execute o seguinte comando, para criar bibliotecas de importação:

    x86_64-w64-mingw32-dlltool -d libmx.def --dllname libmx.dll -l libmx.a
    

    (O mesmo para os demais arquivos .def)

  7. Agora você está pronto para ir!

    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
    

Coisas que podem ser feitas melhor - em vez de --export-all-symbol, Exporte apenas mexFunction (requer a criação de outro arquivo .def Ou a adição de "__declspec(dllexport)" antes de void mexFunction(...)).

6
user1071136

MinGW é capaz de vincular diretamente um DLL ; isto é, criará uma espécie de biblioteca de importação em tempo real ao vincular.

Isso significa que a compilação pode ser realizada em uma etapa:

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
3
user1071136

Por que tantos passos? Se você possui Matlab 2016 ou superior , basta:

  1. Faça o download mingw e instale em uma pasta sem espaços (ou seja, não em "Arquivos de Programas")
  2. Adicione o MW_MINGW64_LOC variável de ambiente apontando para a pasta de instalação (exatamente a mesma coisa que você digitou no instalador)
  3. Reinicie seu PC
  4. Abra o MATLAB e digite mex -setup no console. Deveria dizer "configurado para usar MinGW"
  5. Execute/compile seu programa MATLAB

Testei-os em um novo PC com Windows 10 e funciona!

1
Robinicks

Os links do Matlab para código externo (C++, Fortran, Java etc) usando arquivos MEX. ( http://gnumex.sourceforge.net/ )

Configurando o Compilador:

  1. Instale TDM-GCC (Compilador C++ "C:\MinGW32\bin;") De http://tdm-gcc.tdragon.net/download
  2. Instale Cygwin (o kit de ferramentas fornece ferramentas Unix na plataforma Windows) em ( http://ptolemy.eecs.berkeley.edu/ptolemyII/ ptII4.0/cygwin.htm ).
    Baixe e instale cygwingDevel.exe
  3. Obtenha o arquivo gnumex via ( https://sourceforge.net/projects/gnumex ) e extraia o gnumex para ($MATLABHOME\gnumex).
    Onde $MATLABHOME Seria, por exemplo (C:\Program Files\MATLAB\R2010a)
  4. Adicione este diretório ($MATLABHOME\gnumex) Ao caminho do Matlab (File->Set Path No Matlab).
    Nota: Execute o Matlab com privilégios de administrador.
  5. No Matlab, digite gnumex no prompt. Preencha os caminhos apropriados como;

    MinGW_Root = C:\MinGW32, Cygwin_Root = C:\cygwin

  6. Faça 'File->Save Config' E clique em 'Make Options file'. Saia da janela de configuração do gnumex.

Teste:

Copie mexopts.bat (%AppData%\MathWorks\MATLAB\R2010a\mexopts.bat) Para o diretório de trabalho (%UserProfile%\Documents\MATLAB) Para este teste.

  1. No matlab, execute o seguinte em Prompt;

    mex -f mexopts.bat "C:\Arquivos de programas\MATLAB\R2010a\extern\examples\mex\yprime.c"

  2. Você recebe (%UserProfile%\Documents\MATLAB\yprime.mexw32) Quando digita;

    qual yprime

  3. Execute-o digitando no prompt do Matlab >> yprime(1,1:4) e veja se você recebe 2.0000 8.9685 4.0000 -1.0947.

  4. Agora basta copiar mexopts.bat para $MATLABHOME\bin E deve funcionar de qualquer lugar.

Matlab na plataforma Linux:

  1. No prompt do Linux, instale o seguinte;

    Sudo apt-get install gcc g ++ gfortran

  2. No Matlab, execute o seguinte em Prompt;

    mex -setup

  3. Os arquivos de opções disponíveis para o mex são: **1**: /usr/local/MATLAB/R2012b/bin/mexopts.sh: Selecione a opção 1 . Para testar o trabalho, execute o seguinte no Prompt do Matlab;

    mex "/usr/local/MATLAB/R2012b/extern/examples/mex/yprime.c"

    yprime (1,1: 4)

Caso você receba o aviso;

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/

No prompt do Linux:

  1. Sudo apt-get install gcc-4.4 g++-4.4 gfortran-4.4
  2. Sudo gedit /usr/local/MATLAB/R2012b/bin/mexopts.sh
  3. Altere 'gcc' Para 'gcc-4.4', 'g++' Para 'g++-4.4', 'gfortran' Para 'gfortran-4.4' Em todas as instâncias de CC = 'gcc', CXX = 'g++' E FC = 'gfortran'.
  4. Salve o arquivo e saia.
1
Faheem

Esta é uma descrição detalhada de esta resposta . Portanto, todo o crédito deve ir para essa resposta .

1 Instale o MinGW-w64:

1.1 Baixe esta compilação MinGW64-w64 e sua atualização:

( http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/mingw-w64-bin_x86_64-mingw_20111101_sezero.Zip/download )

( http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/sezero_20111101-w64-update-rev.5747.Zip/download =)

( http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/sezero_4.5_20111101/README-mingw-w64-20111101_sezero.txt/download )

1.2 Instale (descompacte) os arquivos baixados:

1.2.1 Descompacte o arquivo de compilação e mova a pasta mingw64\ Resultante em c:\

1.2.2 Descompacte e copie (substitua) o arquivo de atualização em c:\mingw64

1.3 Adicione C:\mingw64\bin À variável Path:

set PATH=C:\mingw64\bin;%PATH%

2 Em uma linha de comando (fora do ambiente Matlab), compile seus arquivos * .c: Por exemplo, CCODEFILE.c (Assumindo o Matlab 2012b instalado na pasta C:\Program Files\MATLAB\R2012b\):

"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 Então, qualquer código Matlab deve funcionar bem quando chamar a função CCODEFILE.

1
imriss

Se você não pôde instalar Mingw-w64 usando a barra de ferramentas Complementos do Matlab2016b no Windows , você pode usar esta solução alternativa. Lembre-se de que você precisa alterar os caminhos de acordo com seus caminhos de instalação.

  1. O site oficial Mingw-w64 o redireciona para o projeto Win-builds , que é um gerenciador de pacotes para um pacote de ferramentas de desenvolvimento de código aberto. Então, primeiro você precisa instalar o Win-builds.
  2. Ao instalar o Win-builds, verifique se você está inserindo um caminho que não contém espaços p. C:\Win-builds.
  3. Após instalar o Win-builds, basta pressionar o botão Process para instalar todos os pacotes em que o Mingw-w64 está entre eles.
  4. Agora que você instalou o Mingw-w64, é necessário definir a variável de ambiente MW_MINGW64_LOC Que o Matlab a utiliza para detectar o Mingw-w64 .
  5. Para definir a variável de ambiente, execute as seguintes etapas:

    Painel de controle\Sistema\Configurações avançadas do sistema\Avançado\Variável de ambiente\Variáveis ​​de usuário para $ YOUR_USER_NAME\Novo

  6. Coloque Variable name = MW_MINGW64_LOC E Variable value = C:\Win-builds. Observe que o Win-builds coloca todos os executáveis ​​em C:\Win-builds\bin E, ao definir essa variável, o Matlab verifica automaticamente a pasta bin do caminho procurando por gcc.exe.
  7. Agora que você instalou o Mingw-w64 e definiu a variável de ambiente MW_MINGW64_LOC, É hora de criar e testar o exemplo do yprime . Portanto, inicie o Matlab e digite o seguinte comando (Não se esqueça de modificar o caminho adequadamente):

    mex -v 'C:\Arquivos de programas\MATLAB\R2016b\extern\examples\mex\yprime.c'

  8. Uma instalação bem-sucedida mostrará a seguinte mensagem:

    MEX concluído com sucesso.

  9. Por fim, você pode testar sua instalação digitando yprime(1,1:4). A resposta seria:

    ans = 2.0000 8.9685 4.0000 -1.0947

1
hmofrad

No Windows 64 bits com o R2011a, ele trabalhou com http://tdm-gcc.tdragon.net/ e http://gnumex.sourceforge.net/ mas eu tenho que mudança maxopt.bat entrada de linha GM_ADD_LIBS do seguinte modo:

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 

Levei muito tempo para chegar a esse ponto, boa sorte.

0
rarias

Originalmente, pensei que isso soasse como uma forma de tortura, mas, com base na resposta acima de @ user10171136, achei bastante simples compilar o Windows mex a partir do Fedora Linux. O Fedora possui pacotes mingw e mingw64, então:

  1. Sudo yum install mingw64-gcc mingw64-gcc-c++
  2. Copie de um Windows Matlab e instale os arquivos extern/include e bin/win64 diretórios (na verdade você provavelmente só precisa de um subconjunto dos cabeçalhos e de um pequeno subconjunto das DLLs; libmat.dll libmex.dll libmx.dll pode ser tudo o que você precisa. Eu coloquei esses dois diretórios em um novo R2010a-w64 diretório no meu diretório Linux MATLAB existente; altere os comandos abaixo apropriados para onde você escondeu os cabeçalhos e bibliotecas do Windows.
  3. Houve um problema que encontrei: char16_t era necessário em matrix.h e não foi definido. Eu acho matrix.h esqueceu de incluir uchar.h? Eu trabalhei com um -include diretiva; ver abaixo.
  4. 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
  5. (Você pode precisar de bibliotecas adicionais para vincular, por exemplo, -lmat -leng -lm, etc.)
  6. Isso gera com êxito um arquivo mex que é executável no Windows Matlab para minha instalação. Até agora, eu só testei isso com programas C bastante simples.

Interessado em saber se isso soa razoável; Não tenho muita experiência com compilação cruzada.

0
Chinasaur

Este funciona no Matlab 2012b no Windows 8:

https://github.com/DynareTeam/dynare/blob/master/windows/mexopts-win64.bat

Modifique o diretório cgwin ou substitua-o pelo diretório mingw, se usado. Você também pode alterar o compilador-exe se mudar para uma versão de 64 bits.

0
pete