一、前言
由于项目中要用到java调用C++的库文件,于是需要在linux下编译连接生成动态库,然后根据Recast官方包要先CMake生成编译,然后在包含到自己实现的文件,网上查了半天,坑爹没有全面的,东拼西凑终于才明白原理,于是总结记录分享如下。
二、CMake生成库文件
总的来说CMake生成过程不复杂,但是查到的资料都坑爹,废话说了半天没有说到要点,咱直奔主题,两个步骤:
1)切到有CMakeList.txt文件的文件夹下,执行CMake .命令(.是当前路径)
2)执行make命令即可
然后就发现生成了libDetour.so文件,这个就是自己的文件依赖的recast库。
当然这中间最重要的就是CMakeList.txt,这个文件剪短,具体如下:
CMAKE_MINIMUM_REQUIRED(VERSION 2.6) SET(detour_SRCS Source/DetourAlloc.cpp Source/DetourCommon.cpp Source/DetourNavMesh.cpp Source/DetourNavMeshBuilder.cpp Source/DetourNavMeshQuery.cpp Source/DetourNode.cpp ) SET(detour_HDRS Include/DetourAlloc.h Include/DetourAssert.h Include/DetourCommon.h Include/DetourNavMesh.h Include/DetourNavMeshBuilder.h Include/DetourNavMeshQuery.h Include/DetourNode.h ) INCLUDE_DIRECTORIES(Include) ADD_LIBRARY(Detour ${detour_SRCS} ${detour_HDRS})
其中ADD_LIBRARY(Detour ${detour_SRCS} ${detour_HDRS})这个是里面的需要加上SHARED表示动态库文件,而不是静态库文件,方便自己的项目中包含进来。(PS昨天弄了好久,就是这个地方没有改过来)
类型有三种: SHARED,动态库STATIC,静态库MODULE,在使用dyld的系统有效,如果不支持dyld,则被当作SHARED对待。EXCLUDE_FROM_ALL参数的意思是这个库不会被默认构建,除非有其他的组件依赖或者手工构建。具体更多参数和CMakeList.txt的编写规范这里就不多说了,可以参考CMake官方文档。
三、G++编译生成最终的动态库文件
闲话少叙,先附上来命令:g++ -I /usr/local/jdk1.7.0_10/include/linux/ -I /usr/local/jdk1.7.0_10/include/ -I ./Include/ -L ./ -l Detour -fPIC -shared -o librecast.so PathFinding.cpp。
注意:要生成的是recast.so需要在java里面加载的,然后是务必命名为librecast
System.load("recast");
还有就记得加上-L ./ -lDetour这个参数,否则就算正常编译,运行的时候会报错can not find symbol 某个函数的错误,不能正常运行。
这样就搞定了。
接下来是具体的参数说明。
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件。
-fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
-L.:表示要连接的库在当前目录中
-l Detour:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
-I 项目中include包含的头文件寻找路径
...更多参数(请参阅G++编译参数)
四、总结
其实还是自己的问题,在学校的时候没有好好学C++编译相关知识和在linux下的编译相关知识,当年就稍微用IDE如微软的Visual Studio随便编译了一下就以为自己会了额,真是年少啊不知天高地厚啊,现在就苦逼了。。其实也还好,弄过一遍就会了。。在此记录提醒自己,学海无涯,多写(学)点东西没啥坏处。。。共勉。。
(全文完)
注:这个是本人原创的,如需转载,请尊重劳动果实,务必保持原链接(http://blog.csdn.net/lufeng20/article/details/18554571)。