Использование GCC (MinGW) в качестве MEX-компилятора MATLAB - PullRequest
20 голосов
/ 18 декабря 2011

Мне дали проект для запуска на MATLAB R2011a. Поскольку там есть несколько файлов .c, мне нужно настроить GCC в качестве MEX-компилятора для этого проекта. Тем не менее, я не могу найти какое-либо объяснение того, как его настроить. Я пробовал программу-скрипт под названием gnumex, но она не удалась (возможно, для более старой версии MATLAB).

Есть идеи как его настроить?

Ответы [ 13 ]

14 голосов
/ 26 февраля 2012

В Matlab 2011b просто скомпилируйте и создайте ссылку непосредственно в среде mingw64 или 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*

Поместите этот make-файл в каталог с исходным кодом и make.Нет необходимости конвертировать dll файлы.

13 голосов
/ 17 сентября 2012

Почему бы не настроить файл mexopts.bat в вашем каталоге?Таким образом, вы можете прозрачно использовать команду «mex» для компиляции чего-либо, как обычно в MATLAB, так же, как если бы оно было настроено MATLAB с использованием mex -setup.Я удивлен, что никто не делал этого раньше.

Файл ниже для x64 версии Matlab и Mingw.Я использую дистрибутив TDM Mingw64 , который я установил в p:\mingw64-tdm.У меня установлен Matlab в p:\matlab\R2012a - отредактируйте их соответствующим образом.

Это файл mexopts.bat, который я использую, скопируйте и вставьте его в %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%"

Затемвы можете просто попытаться сделать это в Matlab:

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

Должно дать b:\code\m\yprime.mexw64 (или что-то еще в текущей папке).Тогда, если вы сделаете:

yprime(1,1:4)

Вы должны увидеть:

ans =
    2.0000    8.9685    4.0000   -1.0947

Что означает, что вы в бизнесе.Удачи!

РЕДАКТИРОВАТЬ октябрь 2014 г .: Теперь я использую улучшенный файл mexopts.bat, чем приведенный выше, с другим MinGW64 (дает немного более быстрый двоичный код, чем у TDM).Смотрите мою домашнюю страницу для получения подробной информации и загрузок.

8 голосов
/ 13 февраля 2015

Начиная с MATLAB R2015b, официально поддерживается MinGW!

Теперь он находится на вершине списка поддерживаемых компиляторов .

См. здесь для официальных инструкций для загрузки MinGW (они рекомендуют TDB-GCC).

Есть несколько ограничений и предостережений в списке (например, не связывать библиотеки, скомпилированные с другими компиляторами, вы должны перехватывать исключения в файле MEX и т. Д.).

Ниже приведен мой старый способ сделать файл XML для того же.


Прошли годы, и MATLAB (по состоянию на R2014a) перешел на новую систему на основе XML для настройки файлов MEX. MATLAB пока что временно поддерживает устаревшие файлы .bat, но это будет беспокоить вас об этом . Другое изменение состоит в том, что это разные конфигурации C и C ++ (более подробно).

То, что осталось прежним, это то, что вам просто нужно скачать и извлечь дистрибутив MinGW и указать на него MATLAB. все еще нет необходимости в MSYS, cygwin или gnumex. Единственная сложность - указывать на нее MATLAB, но вот решение.

Короткая версия

  • Загрузите и распакуйте дистрибутив MinGW. Выберите один, например, MinGW-w64 (64-разрядный) или TDM-GCC (32-разрядный и 64-разрядный варианты).
  • Настройте файл конфигурации XML, используя этот в качестве шаблона (подробности в длинной версии ниже).
  • Установить MINGWROOT переменная окружения.
  • Выполнить mex -setup:[xmlfile] [C|C++].

Длинная версия

Для MinGW-w64 я настраиваю его следующим образом:

  1. Получите последнюю версию для w64 от Sourceforge (или используйте установщик , чтобы выбрать нужный набор инструментов, выбирая версию потоков pthread или Win32 в зависимости от ваших потребностей).
  2. Распакуйте его, чтобы у вас был путь к компилятору, например C:\mingw-w64\x86_64-4.9.2-release-posix-seh-rt_v3-rev1\bin\x86_64-w64-mingw32-g++.exe. Нет необходимости в MSYS, cygwin или любой другой среде, если вы планируете компилировать в MATLAB с помощью команды mex . Проверьте переменную окружения PATH, чтобы убедиться, что на вашем пути нет нескольких компиляторов (g++), предпочтительно ни одного. Проверьте с помощью новой командной строки.
  3. Настройте его с помощью пользовательского XML-файла конфигурации. В моем репозитории GitHub я разместил конфигурации C ++ для MinGW-w64 в обоих типах файлов: mex_C ++ _ mingw-w64.xml и устаревших mingw_mexopts.bat . Начните с этого как шаблона и (необязательно) отредактируйте файл XML с описательным именем и версией загруженного и извлеченного вами дистрибутива MinGW .
  4. Установите (или создайте) переменную окружения MINGWROOT. Это то, что позволяет команде mex найти компилятор. Вы можете сделать это в MATLAB (и каждый раз, когда MATLAB запускается со сценария startup.m в userpath) с setenv или только один раз со свойствами Windows диалоговое окно или собственная команда Windows 7 setx.exe .
  5. Выполнить mex -setup:C:\actual\configFilePath.xml C++. Например, используя файл .xml для настройки компиляции файла 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++
    

    Вывод должен выглядеть так:

    MEX настроен для использования 'MinGW-w64 GCC 4.9.2 posixthreads seh' для компиляции языка C ++.

При необходимости настройте компилятор C аналогичным образом с новым XML-файлом конфигурации с указанием языка C, внешнего интерфейса компилятора C (например, «x86_64-w64-mingw32-gcc.exe», который не будет автоматически связывать Стандартная библиотека C ++), при необходимости настройте библиотеки ссылок, флаги компилятора (например, измените -std=c++11 на -std=c99) и т. Д.


Замечание о статическом и динамическом связывании библиотек времени выполнения

Библиотеки, такие как MEX-файл, созданный с помощью MinGW-w64, как указано выше, могут зависеть от нескольких библиотек DLL (во время выполнения): LIBGCC_S_SEH-1.DLL (для распределений исключений seh) и LIBSTDC ++ - 6.DLL и, возможно, libwinpthread- 1.dll, если вы выбрали дистрибутив pthreads вместо потоков Win32. Если вы не хотите копировать эти файлы, вы можете статически связать библиотеки времени выполнения с вашим MEX-файлом, добавив следующие параметры:

-static-libgcc -static-libstdc++

В шаблоне XML есть комментарий по этому поводу. См. здесь для получения информации о libpthread-1.dll.

С TDM-GCC, верно обратное : среды выполнения (включая pthread) статически связаны автоматически. Для динамического связывания, которое потребует DLL, но уменьшит размер вашего файла MEX, вам необходимо:

-shared-libgcc -shared-libstdc++
6 голосов
/ 18 декабря 2011

РЕДАКТИРОВАТЬ: Кажется, что гораздо лучше с MinGW; см. мой другой ответ.

Вы можете скомпилировать файл .mex, используя gcc, если у вас установлено Matlab, из командной строки. Кто-то скажет, что в первый раз это немного утомительно.

Перво-наперво - какой Matlab вы используете? если он 64-битный, MinGW вам не поможет, потому что он 32-битный. Поэтому я покажу, как использовать MinGW-w64 . Понимание того, как сделать это с 32-битным MinGW, должно быть простым.

  1. Добавьте C:\MinGW-64\bin\ на свой путь. Вы не пожалеете об этом:)
  2. Скомпилируйте .c файлы, используя 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. Это приведет к множеству ошибок компоновщика, таких как

    undefined reference to `mexErrMsgTxt'
    

    Чтобы решить эту проблему, вам нужно создать библиотеку импорта, которая соединяется с libmex.dll, libmx.dll, libmat.dll и libeng.dll (у вас могут быть другие, но это основные)

  4. Перечислите функции, которые вам не хватает, и, ну, угадайте, откуда они dll. Подсказка: mexErrMsgTxt от libmex.dll, потому что начинается с "mex" ...

  5. Для каждого dll, необходимого для экспорта, создайте файл .def, содержащий

    EXPORTS
    ... relevant function names go here, such as mexErrMsgTxt, matOpen, etc.
    
  6. Выполните следующую команду, чтобы создать библиотеки импорта:

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

    (То же самое для остальных файлов .def)

  7. Теперь все готово!

    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
    

Вещи, которые можно сделать лучше - вместо --export-all-symbol только экспорт mexFunction (требуется создать другой файл .def или добавить "__declspec(dllexport)" перед void mexFunction(...)).

3 голосов
/ 26 февраля 2012

MinGW способен к прямой связи DLL; то есть он создаст своего рода библиотеку импорта на лету при компоновке.

Это означает, что компиляция может быть выполнена за один шаг:

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
1 голос
/ 11 марта 2017

Почему так много шагов?Если у вас Matlab 2016 или выше , просто выполните:

  1. Загрузите mingw и установите в папку без пробелов (т.е. не в «Program Files»))
  2. Добавьте переменную окружения MW_MINGW64_LOC, указывающую на папку установки (то же самое, что вы ввели в установщик)
  3. Перезагрузите компьютер
  4. Откройте MATLAB и введите mex -setup в консоль.Должно быть написано: «настроено на использование MinGW»
  5. Запустите / скомпилируйте вашу программу MATLAB

Я протестировал их на новом ПК с Windows 10, и он работает!*

1 голос
/ 23 декабря 2016

Если вам не удалось установить Mingw-w64 с помощью панели инструментов дополнений Matlab2016b в Windows , вы можете использовать этот обходной путь. Имейте в виду, что вам нужно изменить пути в соответствии с вашими путями установки.

  1. Официальный сайт Mingw-w64 перенаправляет вас на Win-builds проект, который является менеджером пакетов для пакета инструментов разработки с открытым исходным кодом. Итак, сначала вам нужно установить Win-builds.
  2. При установке Win-сборок убедитесь, что вы вводите путь , который не содержит пробелов например. C:\Win-builds.
  3. После установки Win-build просто нажмите кнопку Process, чтобы установить все пакеты, среди которых Mingw-w64.
  4. Теперь, когда вы установили Mingw-w64, вам нужно определить переменную окружения MW_MINGW64_LOC, которую Matlab использует для обнаружения Mingw-w64 .
  5. Чтобы определить переменную среды, выполните следующие шаги:

    Панель управления \ Система \ Расширенные настройки системы \ Дополнительно \ Переменная среды \ Пользовательские переменные для $ YOUR_USER_NAME \ New

  6. Положите Variable name = MW_MINGW64_LOC и Variable value = C:\Win-builds. Обратите внимание, что Win-builds помещает все исполняемые файлы в C:\Win-builds\bin, и, определив эту переменную, Matlab автоматически просканирует папку bin пути в поисках gcc.exe.
  7. Теперь, когда вы установили Mingw-w64 и определили переменную среды MW_MINGW64_LOC, пришло время собрать и протестировать пример yprime . Запустите Matlab и введите следующую команду (не забудьте изменить путь соответствующим образом):

    mex -v 'C: \ Program Files \ MATLAB \ R2016b \ extern \ examples \ mex \ yprime.c'

  8. При успешной установке появится следующее сообщение:

    MEX завершен успешно.

  9. Наконец, вы можете проверить вашу установку, набрав yprime(1,1:4). Ответ будет:

    ans = 2.0000 8.9685 4.0000 -1.0947

1 голос
/ 20 декабря 2013

Это подробное описание этого ответа .Следовательно, вся заслуга должна идти на , который отвечает .

1. Установка MinGW-w64:

1.1 Загрузите эту сборку MinGW64-w64 и ее обновление:

(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) Установить (разархивировать) загруженные архивы:

1.2.1Разархивируйте файл сборки и переместите получившуюся папку mingw64\ в c:\

1.2.2. Распакуйте и скопируйте (перезаписайте) файл обновления в c:\mingw64

1.3. Добавьте C:\mingw64\bin впеременная Path:

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

2 В командной строке (вне среды Matlab) скомпилируйте файлы * .c: например, CCODEFILE.c (при условии, что Matlab 2012b установлен в папке 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 Тогда любой код Matlab должен нормально работать, когда он вызывает функцию CCODEFILE.

1 голос
/ 09 января 2013

Matlab ссылается на внешний код (C ++, Fortran, Java и т. Д.) С использованием MEX-файлов.(http://gnumex.sourceforge.net/)

Настройка компилятора:

  1. Установка TDM-GCC (компилятор C ++ "C:\MinGW32\bin;") из http://tdm -gcc.tdragon.net/download
  2. Установка Cygwin (инструментарий предоставляет инструменты Unix на платформе Windows) из (http://ptolemy.eecs.berkeley.edu/ptolemyII/ptII4.0/cygwin.htm).
    Загрузка и установка cygwingDevel.exe
  3. Получить архив gnumex через (https://sourceforge.net/projects/gnumex) и извлечь gnumex в ($MATLABHOME\gnumex).
    Где, например, $MATLABHOME (C:\Program Files\MATLAB\R2010a)
  4. Добавьте этот каталог ($MATLABHOME\gnumex) к пути Matlab (File->Set Path в Matlab).
    Примечание. Запустите Matlab с привилегиями администратора.
  5. В Matlab введитеgnumex в приглашении. Введите соответствующие пути, как;

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

  6. Выполните «File->Save Config», затем нажмите «Make Options file». Выход из окна конфигурации gnumex.

Тестирование:

Копирование mexopts.bat (%AppData%\MathWorks\MATLAB\R2010a\mexopts.bat) в рабочий каталог (%UserProfile%\Documents\MATLAB) для этого теста.

  1. В Matlab выполните следующее по подсказке;

    mex -f mexopts.bat "C: \ Program Files \ MATLAB \ R2010a \ extern \ examples \ mex \ yprime.c"

  2. Вы получаете (%UserProfile%\Documents\MATLAB\yprime.mexw32) при вводе;

    который yprime

  3. Запустите его, набрав в приглашении Matlab >> yprime(1,1:4) и увидитеесли вы получите 2.0000 8.9685 4.0000 -1.0947.

  4. Теперь просто скопируйте mexopts.bat в $MATLABHOME\bin и он должен работать из любого места.

Matlab наПлатформа Linux:

  1. В командной строке Linux установите следующее:

    sudo apt-get install gcc g ++ gfortran

  2. В Matlab выполните в командной строке следующее:

    mex -setup

  3. Файлы опций, доступные для mex: **1**: /usr/local/MATLAB/R2012b/bin/mexopts.sh: выберите опцию 1 .Чтобы проверить работоспособность, выполните в приглашении Matlab следующее:

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

    yprime (1,1: 4)

Если вы получаете предупреждение;

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/

В приглашении 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. Измените 'gcc' на 'gcc-4.4', 'g++' на 'g++-4.4', 'gfortran' на 'gfortran-4.4' во всех случаях CC = 'gcc',CXX = 'g++' и FC = 'gfortran'.
  4. Сохраните файл и выйдите.
0 голосов
/ 08 декабря 2013

Первоначально я думал, что это звучит как пытка, но, основываясь на приведенном выше ответе @ user10171136, я на самом деле нашел довольно простым кросс-компиляцию для Windows mex из Fedora Linux.В Fedora есть пакеты mingw и mingw64, поэтому:

  1. sudo yum install mingw64-gcc mingw64-gcc-c++
  2. Скопируйте из Windows Matlab и установите каталоги extern/include и bin/win64 (на самом деле вам, вероятно, нужно толькоподмножество заголовков и небольшое подмножество dll; libmat.dll libmex.dll libmx.dll может быть всем, что вам нужно. Я поместил эти два каталога в новый каталог R2010a-w64 в моем существующем каталоге Linux MATLAB; измените приведенные ниже команды в соответствии с тем, где вы спрятализаголовки и библиотеки Windows.
  3. Была одна проблема, с которой я столкнулся, это то, что char16_t был необходим в matrix.h и не был определен. Я думаю, matrix.h забыл включить uchar.h?Я работал с директивой -include, см. Ниже.
  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. (вам могут понадобиться дополнительные библиотеки для ссылок, например -lmat -leng -lm и т. Д.)
  6. Это успешно генерирует mex-файл, который исполняется под Windows Matlab для моей установки. До сих пор я проверял это только с довольно простыми программами на Си.

Интересно узнать, звучит ли это разумно?ле;У меня нет большого опыта кросс-компиляции.

...