今天花了多半天的功夫在解决生成mex文件的问题,源代码是c/c++。本来的代码实在windows环境下的,c/c++是通过visual studio编译生成的.mexw64的文件,然后再matlab环境下面,添加路径就可以直接调用。而现在的环境是,linux,unix,一个之前很少接触的环境。由于熟悉这个环境,这个mex应用的同学很少,所以,自己一个人折腾了好多时间。现在分享记录一下。
编译mex文件的话,一种方式是在matlab内部调用mex指令编译;另一种是在外部shell环境下直接调用mex指令。参数命令貌似几乎是一致的。由于希望在运行matlab代码的时候,所有的mex文件都是编译好的。所以选择了在外部环境下编译的方式。又由于源代码的文件比较多,还有可能使用一些动态链接库,所以把命令打包了一下。得需要写一个makefile文件。那么makefile文件怎么写,mex指令又是如何调用的呢。下面是最后写出来的一个makefile文件,我们一条一条的分析一下。
CXX = mex # 编译器,这个没什么好说的,就是说我们要用mex编译所有的源代码。
RM = rm -f # 这个主要适用于清除文件的,一般的makefile也都有这样的指令
TARGET = ../bin/file_name # 这个是我们希望生成的文件,代表是上一个目录下面的bin文件夹下面,文件名是file_name
SRCS = $(wildcard *.cpp) # 这个代表了,我们要包括当前目录下面所有的cpp文件
INCLUDE_PATH = ../utilitydll/ #这个是第三方库的目录,主要用于在编译的时候,让编译器能够找到.h文件的声明在哪儿
LIB_PATH = ../bin/ #这个是动态链接库所在的目录
LIBS = utility #这个是动态链接库的名字,注意,文件名需要时libutility.so. 有一个前缀lib还有一个后缀.so
CXXFLAGS += $(foreach dir, $(INCLUDE_PATH), -I$(dir)) #这个代表了我们要把所有的包含文件夹的目录都加上去。
CXXFLAGS += CXXFLAGS="\$$CXXFLAGS -fopenmp" #这个指令稍微有点儿特色,这个是告诉mex,我们要用openmp。如果是c++代码的话,注意,一定要用cxxflags,千万不能用cflags这个c语言的参数。
LDFLAGS += -Wl,-rpath,./ #这个是告诉生成的文件,那个动态链接库是当前目录下面寻找。这个命令去掉的话,通过其他方式也可以搞定。
LDFLAGS += $(foreach dir, $(LIB_PATH), -L$(dir)) #这个就是要包含所有 的动态链接库的文件夹。
LDFLAGS += $(foreach lib, $(LIBS), -l$(lib)) #这个就是动态链接库的名称
LDFLAGS += LDFLAGS="\$$LDFLAGS -fopenmp" #这个是告诉mex在连接的时候,注意OMP是要的。注意,编译OMP的时候,在compile和lingk的阶段都是需要的。
OBJS = $(SRCS:.cpp=.o) #所有的目标文件。
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) -o $(TARGET) $(OBJS) $(LDFLAGS)
$(OBJS) : %.o : %.cpp
$(CXX) -c $(CXXFLAGS) $< -o $@
.PHONY: clean
clean:
${RM} ${TARGET} ${OBJS} $(SRCS:.cpp=.d)
最后的几条命令,基本上就比较容易理解,不做解释了。