您的位置:首页 > 运维架构 > Linux

Linux下GNU多文件编译方法

2016-11-21 23:18 225 查看

Linux下GNU多文件编译方法

1. 准备工作

1.1. 安装GNU编译器

首先使用以下命令进行更新:

apt-get update


然后输入以下命令安装编译环境:

apt-get install make gcc g++


1.2. 复制文件至指定目录

将需要编译的源文件放入指定目录,这里本例涉及到的文件为
MatlabEngine.h
MatlabEngine.cpp
main.cpp
。放入的目录为
/home/xwy


2. 编写MakeFile文件

2.1. MakeFile的内容

MakeFile文件主要包含了五样东西:

显式规则:显式规则说明了,如何生成一个或多的的目标文件。这是由MakeFile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。

隐晦规则:由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。

变量定义。在Makefile中我们要定义一系列的变量,变量一般都是字符串,这个有点你C语言中的宏,当Makefile被执行时,其中的变量都会被扩展到相应的引用位置上。

文件指示。其包括了三个部分,一个是在一个MakeFile中引用另一个MakeFile,就像C语言中的include一样;另一个是指根据某些情况指定MakeFile中的有效部分,就像C语言中的预编译#if一样;还有就是定义一个多行的命令。有关这一部分的内容,我会在后续的部分中讲述。

注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用“#”字符,这个就像C/C++中的“//”一样。如果你要在你的Makefile中使用“#”字符,可以用反斜框进行转义,如:“\#”。

最后,还值得一提的是,在Makefile中的命令,必须要以[Tab]键开始。

2.2. MakeFile的文件名

默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,找到了解释这个文件。在这三个文件名中,最好使用“Makefile”这个文件名,因为,这个文件名第一个字符为大写,这样有一种显目的感觉。最好不要用“GNUmakefile”,这个文件是GNU的make识别的。有另外一些make只对全小写的“makefile”文件名敏感,但是基本上来说,大多数的make都支持“makefile”和“Makefile”这两种默认文件名。

2.3. 定义变量&引用变量

变量的定义和应用与Linux环境变量一样,变量名要大写,变量一旦定义后,就可以通过将变量名用圆括号括起来,并在前面加上“$”符号来进行引用。

变量的主要作用:

保存文件名列表

保存可执行命令名,如编译器

保存编译器的参数

变量一般都在makefile的头部定义。

e.g.

cc = g++
exe = main
obj = main.o
$(cc) -o $(exe) $(obj)


2.4. MakeFile的规则

命令格式:

target ... : dependencies ...
command
...


其中:

target
也就是一个目标文件,可以是Object File,也可以是执行文件。还可以是一个标签(Label)。

dependencies
就是,要生成那个
target
所需要的文件或是目标。

command
也就是make需要执行的命令。(任意的Shell命令,可以有若干行)

command
必须以[Tab]键开头。否则,make就会显示出错信息。如果某一命令行太长可以分作两行,用反斜杠(\)连接

本例中MakeFile文件内容如下:

2.4.1 可执行文件的编译

cc = g++
exe = main
obj = main.o MatlabEngine.o
matlab_include = /usr/local/matlab/2015b/extern/include
matlab_lib = /usr/local/matlab/2015b/bin/glnxa64/

$(exe):$(obj)
$(cc) -o $(exe) $(obj) -L $(matlab_lib) -leng -lmx -lmex
main.o:main.cpp
$(cc) -c main.cpp -std=c++11 -I $(matlab_include) -L $(matlab_lib) -leng -lmx -lmex
MatlabEngine.o:MatlabEngine.cpp
$(cc) -c MatlabEngine.cpp -std=c++11 -I $(matlab_include) -L $(matlab_lib) -leng -lmx -lmex
clean:
rm -rf *.o main


其中,

*
/usr/local/matlab/2015b/extern/include
/usr/local/matlab/2015b/bin/glnxa64/
分别为头文件目录与链接库目录 。

*
-std=c++11
为编译参数,指示使用C++11标准

2.4.2 .so动态链接库的编译

CC = g++
LD = ld
EXE = main
OBJ = MatlabEngine.o callEngineFunctions.o
SHARED = -shared -o
LIB_OBJ = libcallEngineFunctions.so
BIN_OBJ = callEngineFunctions
MATLAB_INCLUDE_DIR = /usr/local/matlab/2015b/extern/include
MATLAB_LIB_DIR = /usr/local/matlab/2015b/bin/glnxa64/

all:$(LIB_OBJ)

$(LIB_OBJ):$(OBJ)
$(CC) -fPIC $(SHARED) $(LIB_OBJ) $(OBJ) -L $(MATLAB_LIB_DIR) -leng -lmx -lmex
callEngineFunctions.o:callEngineFunctions.cpp
$(CC) -fPIC -c callEngineFunctions.cpp -std=c++11 -I $(MATLAB_INCLUDE_DIR) -L $(MATLAB_LIB_DIR) -leng -lmx -lmex
MatlabEngine.o:MatlabEngine.cpp
$(CC) -fPIC -c MatlabEngine.cpp -std=c++11 -I $(MATLAB_INCLUDE_DIR) -L $(MATLAB_LIB_DIR) -leng -lmx -lmex
clean:
rm -rf *.o


在编译过程中,需要添加
-fPIC
参数,该参数的作用如下:

告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任意位置,都可以正确的执行。


详细说明参见

makefile知识点《一》

3. 使用make指令进行编译

在MakeFile文件的路径下,输入以下指令进行编译链接即可生成可执行文件

make -f MakeFile


最后说明一点,MakeFile功能较为强大,本文只介绍了一些简单的MakeFile使用方法。如需用到其他高级功能,可以在Google上进行检索,相关资料非常多。

4. 一些遇到的问题

4.1. 在程序链接时提示找不到so文件的错误

在编译调用Matlab计算引擎的程序时,遇到了以下这样的问题:



猜测该问题是因为没有在指定路径下寻找so文件所造成的,在网上搜索之后,找到了以下的解决方案:

修改
/etc/ld.so.conf
文件,将so文件所在的路径添加至这个文件中,文件中的一行表示一个路径,修改后的文件如下所示:



在修改完文件之后,问题解决!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux gnu make
相关文章推荐