網上可以找到很多應用Visual Studio編寫、編譯mex文件,並與MATLAB聯合調試的文章。但這只限於Win平台,網上許多源碼都是.mexa64的文件,它們的作者是怎麼調試的呢?這裡我介紹一下我的方式。
利用Qt的IDE,建立CMake工程,從而實現一次編碼,多平台復用;而且CMake還可以自動設置Matlab的Include和Lib目錄,免去很多麻煩;再者,IDE的GUI能讓調試直觀不少,比直接用gdb調試mex方便。
一、實現平台:
操作系統:Linux Mint 17.3, Ubuntu 14.04, Linux Mint 18, Ubuntu 16.04.
編程工具:CMake 3.7, 系統自帶的gcc, 系統自帶的gdb, Matlab 2016b, Qt 5.7
二、建立CMake工程:
在Qt中新建CMake工程,其結構可以參見此處
http://cn.mathworks.com/matlabcentral/fileexchange/45522-mex-cmake
這裡有它的中文說明
http://blog.csdn.net/kxuehen/article/details/45851651
其中注意幾點:
1) Matlabdef.def文件的內容是
EXPORTS mexFunction
2) FindMatlab.cmake文件是用於查找本地Matlab的Include和Lib路徑的。CMake通過將其加入CMAKE_MODULE_PATH變量,實現了此查找功能。這裡一定要把環境變量MATLAB_ROOT設為Matlab根目錄,例如,我在~/.bashrc下加入
export MATLAB_ROOT=/usr/local/MATLAB/R2016b
3) 編譯生成的mex文件可以指定位置(即make後,mex文件的生成位置,並不是指定make install之後的安裝位置),在生成mex文件用的CMakeList.txt中設置LIBRARY_OUTPUT_PATH變量即可。例如,我在add_library()後面加上
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
就可把mex文件生成到構建目錄(通常是build目錄)的lib文件夾下了。
三、編譯CMake工程:
用Qt Creator編譯CMake工程,一定要安裝CMake 3.3.2以上版本。
Qt Creator要引入bash的環境變量,比如上面提到的MATLAB_ROOT就在這些變量中,方法是更改Qt Creator快捷方式裡的Exec,(即.desktop文件,一般是~/.local/share/applications/DigiaQtOpenSource-qtcreator.desktop或/usr/share/applications/DigiaQtOpenSource-qtcreator.desktop)。例如我改成這樣,加入了bash -i -c
Exec=bash -i -c /opt/Qt5.7.0/Tools/QtCreator/bin/qtcreator
同時注意把Qt Creator裡的CMake生成器設置為CodeBlocks - Unix Makefiles (默認就是這個設置),如下圖所示
如果Edit裡沒有源碼顯示,別忘了點開左側的Project;然後菜單Build->Run CMake,或者右鍵工程名,然後點右鍵菜單中的Run CMake,如圖所示
針對CMake工程,詳細的Qt Creator設置可以參考
http://doc.qt.io/qtcreator/creator-project-cmake.html
四、與Matlab聯合調試:
編譯完成之後就可以打開Matlab,讓Qt Creator使用gdb進行聯合調試。在Qt Creator中設置斷點,然後菜單Debug->Start Debuging->Attach to Running Application...
但我在聯合調試時遇到2個錯誤:
1) 第一種可能出現的錯誤,如下圖所示
可以用以下命令暫時解決問題,
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scop
若要徹底地解決這個問題,可以修改文件/etc/sysctl.d/10-ptrace.conf 將其中的
kernel.yama.ptrace_scope = 1
改為
kernel.yama.ptrace_scope = 0
2) 第二種可能出現的錯誤,如下圖所示
這裡的solib-search-path是gdb搜索動態鏈接庫文件(或者叫共享庫文件,即Linux裡的.so文件或Win中的.dll文件)的目錄,當然gdb也會在其工作的當前目錄進行搜索。那麼這個錯誤其實是說gdb找不到我們的mex文件了,所以我這裡直接設置調試時的Working directory為mex所在目錄,就可以讓gdb直接找到mex文件了,設置方法如圖所示
注:這裡有個小技巧,我喜歡把Matlab代碼和C++分開存放,所以想要在Matlab中調用新生成的mex文件,可以用Matlab裡addpath命令,把mex文件所在的文件夾包含進去,如
addpath('~/mex/build/lib');