MATLAB R2016b - MEX не может скомпилировать код C ++

Мой последний пост был загроможден большим количеством информации. Частично это была проблема, которая, надеюсь, сама по себе с дополнительной информацией будет иметь больше смысла.

Я пытаюсь использовать mex в MATLAB R2016b для компиляции кода C ++ 03 в Windows.

Когда я пытаюсь это сделать, я получаю следующие ошибки:

Error using mex
cpp_mexapi_version.o: In function `mexfilerequiredapiversion':
C:/Progra~1/MATLAB/R2016b/extern/version/cpp_mexapi_version.cpp:4: multiple definition of `mexfilerequiredapiversion'
C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\cpp_mexapi_version.obj:cpp_mexapi_version.cpp:(.text+0x0): first defined here
myclass.o: In function `MyClass::MyClass(int, double*, int, int, int*, double, int, double, double, int, bool, char)':
C:\msys64\home\myName\Desktop\test/myclass.cpp:67: undefined reference to `__imp___acrt_iob_func'
C:\msys64\home\myName\Desktop\test/myclass.cpp:110: undefined reference to `__imp___acrt_iob_func'
C:\msys64\home\myName\Desktop\test/myclass.cpp:121: undefined reference to `__imp___acrt_iob_func'
myclass.o: In function `MyClass::MyClass(int, double*, int, int*, int, double, double, int, char)':
C:\msys64\home\myName\Desktop\test/myclass.cpp:139: undefined reference to `__imp___acrt_iob_func'
C:\msys64\home\myName\Desktop\test/myclass.cpp:178: undefined reference to `__imp___acrt_iob_func'
myclass.o:C:\msys64\home\myName\Desktop\test/myclass.cpp:189: more undefined references to `__imp___acrt_iob_func' follow
myclass.o: In function `MyAssertionClass::MyAssertionClass(char const*, int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
C:\msys64\home\myName\Desktop\test/myclass.cpp:1014: undefined reference to `std::__cxx11::basic_ostringstream<char, std::char_traits<char>, std::allocator<char> >::basic_ostringstream()'
myclass.o: In function `MyAssertionClass::MyAssertionClass(char const*, int, char const*)':
C:\msys64\home\myName\Desktop\test/myclass.cpp:1029: undefined reference to `std::__cxx11::basic_ostringstream<char,
std::char_traits<char>, std::allocator<char> >::basic_ostringstream()'
collect2.exe: error: ld returned 1 exit status

Вот подробный журнал до того, как он потерпел неудачу:

>> mex -v COMPFLAGS='$COMPFLAGS -std=c++03' -IC:\ourLibraryLocation myTargetMex.cpp myclass.o (a few other .o files here) cpp_mexapi_version.o
Verbose mode is on.
Neither -compatibleArrayDims nor -largeArrayDims is selected.
     Using -compatibleArrayDims. In the future, MATLAB will require the use of
     -largeArrayDims and remove the -compatibleArrayDims option.
     For more information:
     http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.
... Looking for compiler 'MinGW64 Compiler (C++)' ...
... Looking for environment variable 'MW_MINGW64_LOC' ...Yes ('C:\TDM-GCC-64').
... Looking for file 'C:\TDM-GCC-64\bin\g++.exe' ...Yes.
... Looking for folder 'C:\TDM-GCC-64' ...Yes.
Found installed compiler 'MinGW64 Compiler (C++)'.
Set PATH = C:\TDM-GCC-64\bin;C:\Program Files\MATLAB\R2016b\extern\include\win64;C:\Program Files\MATLAB\R2016b\extern\include;C:\Program Files\MATLAB\R2016b\simulink\include;C:\Program Files\MATLAB\R2016b\lib\win64;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\iCLS\;C:\Program Files\Intel\Intel(R) Management Engine Components\iCLS\;C:\Program Files\avs\bin;C:\Program Files\avs\bin32;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files (x86)\Enterprise Vault\EVClient\;C:\Program Files\Intel\WiFi\bin\;C:\Program Files\Common Files\Intel\WirelessCommon\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\MATLAB\R2016b\bin;C:\TDM-GCC-64\bin;C:\Users\myName\AppData\Local\Microsoft\WindowsApps;
Set INCLUDE = C:\TDM-GCC-64\include;C:\TDM-GCC-64\include;
Set LIB = C:\TDM-GCC-64\lib;;C:\TDM-GCC-64\lib;;
Set MW_TARGET_ARCH = win64;win64;
Set LIBPATH = C:\Program Files\MATLAB\R2016b\extern\lib\win64;C:\Program Files\MATLAB\R2016b\extern\lib\win64;
Options file details
-------------------------------------------------------------------
    Compiler location: C:\TDM-GCC-64
    Options file: C:\Users\myName\AppData\Roaming\MathWorks\MATLAB\R2016b\mex_C++_win64.xml
    CMDLINE2 : C:\TDM-GCC-64\bin\g++ -m64 -Wl,--no-undefined -shared -s -Wl,"C:\Program Files\MATLAB\R2016b/extern/lib/win64/mingw64/exportsmexfileversion.def" C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\myTargetMex.obj C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\cpp_mexapi_version.obj myclass.o (a few other .o files here) cpp_mexapi_version.o  -L"C:\Program Files\MATLAB\R2016b\extern\lib\win64\mingw64" -llibmx -llibmex -llibmat -lm -llibmwlapack -llibmwblas -o myTargetMex.mexw64
    CXX : C:\TDM-GCC-64\bin\g++
    COMPILER : C:\TDM-GCC-64\bin\g++
    DEFINES : -DMX_COMPAT_32   -m64 -DMATLAB_MEX_FILE
    MATLABMEX : -DMATLAB_MEX_FILE
    CXXFLAGS : -fexceptions -fno-omit-frame-pointer -std=c++11
    INCLUDE : -IC:\ourLibraryLocation  -I"C:\Program Files\MATLAB\R2016b/extern/include" -I"C:\Program Files\MATLAB\R2016b/simulink/include"
    CXXOPTIMFLAGS : -O -DNDEBUG
    CXXDEBUGFLAGS : -g
    LDXX : C:\TDM-GCC-64\bin\g++
    LINKER : C:\TDM-GCC-64\bin\g++
    LDFLAGS : -m64 -Wl,--no-undefined
    LDTYPE : -shared
    LINKEXPORT : -Wl,"C:\Program Files\MATLAB\R2016b/extern/lib/win64/mingw64/mexFunction.def"
    LINKEXPORTVER : -Wl,"C:\Program Files\MATLAB\R2016b/extern/lib/win64/mingw64/exportsmexfileversion.def"
    LIBLOC : C:\Program Files\MATLAB\R2016b\extern\lib\win64\mingw64
    LINKLIBS : -L"C:\Program Files\MATLAB\R2016b\extern\lib\win64\mingw64" -llibmx -llibmex -llibmat -lm -llibmwlapack -llibmwblas
    LDOPTIMFLAGS : -s
    LDDEBUGFLAGS : -g
    OBJEXT : .obj
    LDEXT : .mexw64
    SETENV : set COMPILER=g++
                set COMPFLAGS=-c -fexceptions -fno-omit-frame-pointer -std=c++11 -DMX_COMPAT_32   -m64 -DMATLAB_MEX_FILE  -DMATLAB_MEX_FILE
                set OPTIMFLAGS=-O -DNDEBUG
                set DEBUGFLAGS=-g
                set LINKER=g++
                set LINKFLAGS=-m64 -Wl,--no-undefined -shared -L"C:\Program Files\MATLAB\R2016b\extern\lib\win64\mingw64" -llibmx -llibmex -llibmat -lm -llibmwlapack -llibmwblas -Wl,"C:\Program Files\MATLAB\R2016b/extern/lib/win64/mingw64/mexFunction.def"
                set LINKDEBUGFLAGS=-g
                set NAME_OUTPUT= -o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    MINGWROOT : C:\TDM-GCC-64
    MATLABROOT : C:\Program Files\MATLAB\R2016b
    ARCH : win64
    SRC : C:\Users\myName\Desktop\test\myTargetMex.cpp;"C:\Program Files\MATLAB\R2016b\extern\version\cpp_mexapi_version.cpp"
    OBJ : C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\myTargetMex.obj;C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\cpp_mexapi_version.obj
    OBJS : C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\myTargetMex.obj C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\cpp_mexapi_version.obj myclass.o (a few other .o files here) cpp_mexapi_version.o
    SRCROOT : C:\Users\myName\Desktop\test\myTargetMex
    DEF : C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\myTargetMex.def
    EXP : myTargetMex.exp
    LIB : myTargetMex.lib
    EXE : myTargetMex.mexw64
    ILK : myTargetMex.ilk
    MANIFEST : myTargetMex.mexw64.manifest
    TEMPNAME : myTargetMex
    EXEDIR :
    EXENAME : myTargetMex
    COMPFLAGS :  -std=c++03
    OPTIM : -O -DNDEBUG
    LINKOPTIM : -s
    CMDLINE1_0 : C:\TDM-GCC-64\bin\g++ -c -DMX_COMPAT_32   -m64 -DMATLAB_MEX_FILE  -IC:\ourLibraryLocation  -I"C:\Program Files\MATLAB\R2016b/extern/include" -I"C:\Program Files\MATLAB\R2016b/simulink/include" -fexceptions -fno-omit-frame-pointer -std=c++11 -O -DNDEBUG C:\Users\myName\Desktop\test\myTargetMex.cpp -o C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\myTargetMex.obj
    CMDLINE1_1 : C:\TDM-GCC-64\bin\g++ -c -DMX_COMPAT_32   -m64 -DMATLAB_MEX_FILE  -IC:\ourLibraryLocation  -I"C:\Program Files\MATLAB\R2016b/extern/include" -I"C:\Program Files\MATLAB\R2016b/simulink/include" -fexceptions -fno-omit-frame-pointer -std=c++11 -O -DNDEBUG "C:\Program Files\MATLAB\R2016b\extern\version\cpp_mexapi_version.cpp" -o C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\cpp_mexapi_version.obj
-------------------------------------------------------------------
Building with 'MinGW64 Compiler (C++)'.
C:\TDM-GCC-64\bin\g++ -c -DMX_COMPAT_32   -m64 -DMATLAB_MEX_FILE  -IC:\ourLibraryLocation  -I"C:\Program Files\MATLAB\R2016b/extern/include" -I"C:\Program Files\MATLAB\R2016b/simulink/include" -fexceptions -fno-omit-frame-pointer -std=c++11 -O -DNDEBUG C:\Users\myName\Desktop\test\myTargetMex.cpp -o C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\myTargetMex.obj
C:\TDM-GCC-64\bin\g++ -c -DMX_COMPAT_32   -m64 -DMATLAB_MEX_FILE  -IC:\ourLibraryLocation  -I"C:\Program Files\MATLAB\R2016b/extern/include" -I"C:\Program Files\MATLAB\R2016b/simulink/include" -fexceptions -fno-omit-frame-pointer -std=c++11 -O -DNDEBUG "C:\Program Files\MATLAB\R2016b\extern\version\cpp_mexapi_version.cpp" -o C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\cpp_mexapi_version.obj
C:\TDM-GCC-64\bin\g++ -m64 -Wl,--no-undefined -shared -s -Wl,"C:\Program Files\MATLAB\R2016b/extern/lib/win64/mingw64/exportsmexfileversion.def" C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\myTargetMex.obj C:\Users\myName\AppData\Local\Temp\2\mex_53351148310745_8852\cpp_mexapi_version.obj myclass.o (a few other .o files here) cpp_mexapi_version.o  -L"C:\Program Files\MATLAB\R2016b\extern\lib\win64\mingw64" -llibmx -llibmex -llibmat -lm -llibmwlapack -llibmwblas -o myTargetMex.mexw64

Чтобы было ясно, MyClass - это просто еще один класс, включенный в myTargetMex. Так уж получилось, что он первый, поэтому, естественно, это первое, что терпит неудачу при попытке компиляции. (Насколько мне известно)

Спасибо за любую помощь!


person Tyler Shellberg    schedule 20.08.2019    source источник
comment
-std=c++03 в командной строке не очень хорошо сочетается с std::__cxx11::basic_string в некоторых сообщениях об ошибках и -std=c++11 позже в выводе сборки. Плохая цепочка инструментов может запутаться.   -  person user4581301    schedule 20.08.2019
comment
Я так думаю, но не знаю, как это исправить. В нашем коде нет ничего из C ++ 11. Обе строки, в которых он запутался, просто std::ostringstream s;. Дело в том, что эта проблема действительно возникла до того, как я поставил флаг c++03. Это была моя попытка исправить это, но, очевидно, мне все равно удается установить его на C ++ 11.   -  person Tyler Shellberg    schedule 20.08.2019
comment
Ваша первая ошибка исчезнет, ​​если вы удалите cpp_mexapi_version.o из команды mex. Позвольте mex выяснить, что ему нужно сделать, чтобы скомпилировать ваш файл, просто дайте ему свой файл плюс любые библиотеки, не относящиеся к MATLAB, которые вы явно используете.   -  person Cris Luengo    schedule 20.08.2019
comment
@CrisLuengo Это позаботилось об этой проблеме. Большое спасибо! Есть какие-нибудь мысли по поводу того, где COMPFLAGS='$COMPFLAGS -std=c++03', похоже, ничего не делает?   -  person Tyler Shellberg    schedule 20.08.2019
comment
В качестве примечания, я хотел бы узнать больше о cpp_mexapi_version в какой-то момент. Мне любопытно, как мы использовали его при работе вручную, в отличие от того, что делает mex. Но это отвлекающий маневр и не очень важный для решения оставшихся проблем.   -  person Tyler Shellberg    schedule 20.08.2019
comment
mex добавляет этот файл. Добавляя его вручную, вы добавляете его дважды, получая повторяющиеся символы. При компиляции MEX-файла без использования команды mex вам нужно сделать много дополнительных вещей, которые команда mex делает за вас.   -  person Cris Luengo    schedule 20.08.2019
comment
Попробуйте вместо этого установить CXXFLAGS?   -  person Cris Luengo    schedule 20.08.2019
comment
@CrisLuengo Кажется, это правильно изменило. Вики предложили вместо этого в приглашении MATLAB использовать COMPFLAGS, но, возможно, я неправильно это понял. К сожалению, похоже, что это не устранило эти ошибки. Как странно. Он по-прежнему бросает неопределенные ссылки на методы C ++ 11.   -  person Tyler Shellberg    schedule 20.08.2019
comment
Отображает ли теперь подробный вывод команды mex правильный CXXFLAGS? Он имеет -std=c++11 на выходе, который у вас есть в настоящее время. Может быть, еще добавить строгий флаг?   -  person Cris Luengo    schedule 21.08.2019
comment
Ничего! Вроде снова работает. Спасибо еще раз! :)   -  person Tyler Shellberg    schedule 21.08.2019
comment
@CrisLuengo Ну, может быть, не совсем. Это действительно работает, хотя в аргументах указано следующее: -fno-omit-frame-pointer -std=c++11 -std=c++03 -O. Странно, но ... работает. Я возьму это.   -  person Tyler Shellberg    schedule 21.08.2019
comment
@CrisLuengo Я слежу за происходящим. Я пишу в CXXFLAGS просто добавляя дополнительный флаг. Я могу напрямую записывать его содержимое, а не добавлять к нему.   -  person Tyler Shellberg    schedule 21.08.2019
comment
В самом деле, вы можете это сделать. В любом случае учитывается последний из стандартных флагов. Флаги читаются по порядку, а более поздние заменяют более ранние в случае противоречия.   -  person Cris Luengo    schedule 21.08.2019
comment
@CrisLuengo И последнее. Есть ли способ сделать сборку в стиле makefile-esque с помощью сценария MATLAB? IE, прямо сейчас, если я хочу внести изменения в CXXFLAGS и CXXOPTIMFLAGS, мне нужно изменить строку, которая компилирует каждый файл MEX. Есть ли способ установить их заранее, а не в строке, вызываемой MEX?   -  person Tyler Shellberg    schedule 21.08.2019
comment
Вы можете делать mex(arg1,arg2,...) с переменными arg1 и arg2, которые содержат строку. Каждая строка является одним из входных аргументов команды mex.   -  person Cris Luengo    schedule 21.08.2019


Ответы (1)


Вот к чему это привело:

  1. Мне нужно было использовать $ CXXFLAGS вместо $ COMPFLAGS (подробный вывод показывает, что COMPFLAGS здесь никогда не отображается, а CXXFLAGS есть)

  2. Выполнение CXXFLAGS='$CXXFLAGS -std=c++03' просто добавляет флаги к существующему набору флагов. (Да, но я это пропустил) Существующий набор флагов по умолчанию включает -std=c++11. Технически последний просто перезаписывает старый, но выглядит все равно странно. Лучше сделать: CXXFLAGS='-fexceptions -fno-omit-frame-pointer -std=c++03', поэтому я включил все, что уже было, но просто заменил стандартную часть C ++. Вы можете сделать то же самое со всем, что хотите изменить. Например, CXXOPTIMFLAGS='-O0 -DNDEBUG' просто заменит -O на -O0

  3. В качестве примечания: если в вашем проекте смешаны C и CPP, это беспорядок. Просто сделайте себе одолжение и измените все свои файлы .C на .CPP. У нас это было, и когда MEX попытался скомпилировать файлы .C, он использовал GCC вместо G ++ и плохо себя чувствовал. Лучше этого избежать. Напоминаем, что старая точка входа mexFunction () отлично работает в файлах .C. mexFunction () не обязательно должна быть в файле .C!

Большое спасибо Крису Луенго, который еще раз спас меня своими знаниями MATLAB и MEX-файлов. :) Я бы отметил его решение как ответ, если бы он его поставил.

person Tyler Shellberg    schedule 20.08.2019