解决在macOS Sierra(10.12)上MATLAB的mex问题

最近设计滑模控制器需要用MATLAB Simulink中的User-Defined Function,写好Function后编译报错。报错信息为:

1
No supported compiler or SDK was found.

MathWorks论坛上有这个问题的解决方案。大致就是去App Store上安装Xcode就可以了,然而我并不想安装臃肿的Xcode且我已经安装了Xcode command line tool。这篇文章将教你如何花式配置mex。

更改mex的XML配置

打开MATLAB,并在其Command Line下输入:

1
cd( fullfile( matlabroot, 'bin', 'maci64', 'mexopts' ) );

这里MATLAB左侧的Current Folder中应有三个文件,分别是clang_maci64.xmlclang++_maci64.xmlgfortan.xml,分别对应了c文件,cpp文件和fortan的编译配置。由于Simulink只需要编译c文件,所以仅更改clang_maci64.xml就可以了。clang++_maci64.xml的修改方法与clang_maci64.xml类似,就不多加说明了。
直接使用MATLAB打开clang_maci64.xml,找到以下部分,并将其用<!--> <-->注释掉。这将会使编译器在/usr/include中搜索头文件,而非Xcode的路径。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<ISYSROOT>
<and>
<cmdReturns name="xcode-select -print-path"/>
<or>
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" />
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk" />
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk" />
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk" />
<cmdReturns name="find $$ -name MacOSX10.9.sdk" />
<cmdReturns name="find $$ -name MacOSX10.10.sdk" />
<cmdReturns name="find $$ -name MacOSX10.11.sdk" />
<cmdReturns name="find $$ -name MacOSX10.12.sdk" />
</or>
</and>
</ISYSROOT>
<SDKVER>
<and>
<and>
<cmdReturns name="xcode-select -print-path"/>
<or>
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk" />
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.10.sdk" />
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk" />
<dirExists name="$$/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk" />
<cmdReturns name="find $$ -name MacOSX10.9.sdk" />
<cmdReturns name="find $$ -name MacOSX10.10.sdk" />
<cmdReturns name="find $$ -name MacOSX10.11.sdk" />
<cmdReturns name="find $$ -name MacOSX10.12.sdk" />
</or>
</and>
<cmdReturns name="echo $$ | rev | cut -c1-10 | rev | egrep -oh '[0-9]+\.[0-9]+'" />
</and>
</SDKVER>

回到MATLAB的Command Window,并输入

1
mex --setup

此时应该输出

1
2
3
4
5
6
MEX configured to use 'Xcode with Clang' for C language compilation.
Warning: The MATLAB C and Fortran API has changed to support MATLAB
variables with more than 2^32-1 elements. In the near future
you will be required to update your code to utilize the
new API. You can find more information about this at:
http://www.mathworks.com/help/matlab/matlab_external/upgrading-mex-files-to-use-64-bit-api.html.

这表明此时mex已经找到并使用gcc了,但是Simulink编译仍然会报以下错误:

1
invalid version number in '-mmacosx-version-min='

这是因为在clang_maci64.xml33行处,还有其他的一些行

1
CFLAGS="-fno-common -arch x86_64 -mmacosx-version-min=$SDKVER -fexceptions -isysroot $ISYSROOT"

引用了我们刚才注释掉的内容$SDKVER$ISYSROOT
需要注意的是此时并不应该再修改这个文件,需要在Command Window中输入

1
cd( prefdir );

打开mex_C_maci64.xml继续修改。需要将文件中所有的$SDKVER更改为10.11,并将ISYSROOT更改为/usr/bin
至此XML文件修改完毕,然而打开Simulink还是不能编译通过。

复制头文件

Simulink报错的内容大概是在simulink/include/文件夹下找不到头文件,手动将/usr/include/中的所有文件复制到/Applications/MATLAB_R2014a.app/simulink/include/下即可。现在重新编译Simulink的model应该就可以顺利通过了。

总结

之前在解决mex问题的时候搜索到stackoverflow上的这个答案,不过按照回答者提出的方案仍然报错,于是自己动手修改了一些细节上的内容,希望可以帮助到被这个问题困扰的朋友们。