Linux下编译生成android ndk需要的头文件和so

1,033 阅读8分钟

Linux下编译生成android ndk需要的头文件和so

我们android做ndk开发,往往c++底层编写c++代码时有依赖于它们所需要的一些第三方开源库,就像我们android经常implement第三方库一样,但是这些c++代码我们是无法直接在android上面使用的,我们需要在我们的jni代码中引入这些第三方库的头文件和so,然后在链接到我们的c++代码中,这样我们的c++代码中引用的这些第三方开源库就不会报错了,最终在生成一个最终的so文件即可。

所以这边文章能教你的就是编译绝大多数的第三方c++库,生成对应的头文件和so库,然后在我们的android中使用。

说明:基本现在所有的项目的构建工具都是使用cmake进行构建的,cmake是一个很强大的软件构建工具,它可以根据cmakelist.txt文件生成对应于不同平台的makefile文件,然后生成对应系统的二进制文件在当前系统进行使用。所以砸门先花一点点时间来学习下cmake相关的知识

CMake

CMake是一个跨平台的编译(Build)工具,可以用简单的语句来描述所有平台的编译过程。

CMake能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。

假如我们有一个深度学习框架的部分工程列表,里面有超过40个互相调用的工程共同组成,一些用于生成库文件,一些用于实现逻辑功能。他们之间的调用关系复杂而严格,如果我想在这样复杂的框架下进行二次开发,显然只拥有它的源码是远远不够的,还需要清楚的明白这几十个项目之间的复杂关系,在没有原作者的帮助下进行这项工作几乎是不可能的。

即使是原作者给出了相关的结构文档,对新手来说建立工程的过程依旧是漫长而艰辛的,因此CMake的作用就凸显出来了。原作者只需要生成一份CMakeLists.txt文档,框架的使用者们只需要在下载源码的同时下载作者提供的CMakeLists.txt,就可以利用CMake,在”原作者的帮助下“进行工程的搭建。

什么是makefile?

或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个专业人士,你还是要了解HTML的标识的含义。特别在Unix下的软件编译,你就不能不自己写makefile了,会不会写makefile,从一个侧面说明了一个人是否具备完成大型工程的能力。因为,makefile关系到了整个工程的编译规则。一个工程中的源文件不计数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。make是一个命令工具,是一个解释makefile中指令的命令工具,一般来说,大多数的IDE都有这个命令,比如:Delphi的make,Visual C++的nmake,Linux下GNU的make。可见,makefile都成为了一种在工程方面的编译方法。

为什么使用makefile

对于一个大型软件,其编译、维护是一个复杂而耗时的过程。它涉及到大量的文件、目录,这些文件可能是在不同的时间、由不同的人、在不同的地方分别写的,其中一些是程序,有些是数据,有些是文档,有些是衍生文件。甚至参与开发的人员也不一定清楚所有文件的细节,包括如何处理它们。此外,构成软件的文件数目可能达到成百上千,甚至成千上万个,开发过程中当修改了少量几个文件后,往往只需要重新编译、生成少数几个文件。有效地描述这些文件之间的依赖关系以及处理命令,当个别文件改动后仅执行必要的处理,而不必重复整个编译过程,可以大大提高软件开发的效率。

CMake和makefile

Cmake是用来makefile的一个工具:读入所有源文件之后,自动生成makefile。

image.png

简单了解了cmake和makefile,下面我们就开始踏入我们的正式编译之旅了...

在这里以我们项目中为例,我们需要编译ceres。Ceres Solver是一个开源 C++ 库,用于建模和解决大型、复杂的优化问题。它可用于求解具有边界约束的非线性最小二乘问题和一般无约束优化问题。

官方链接:ceres-solver.org/

准备

在Linxu环境下进行编译

1.ubuntu16.0.4

2.ubuntu安装ndk,具体可参考blog.csdn.net/qq_38410730…

3.ubuntu安装cmake,采用源码编译的方式进行安装。具体可参考www.cnblogs.com/yanqingyang…

首先我们需要先看官方介绍,看这个库有没有直接提供android上对应的构建方法。果然这个库是有提供的,

image.png

image.png

因此我们按照相关步骤一步步编译。

说明:一般编译这些都是在linux环境下进行的,我刚开始就是在window上环境下去编译,遇到特别多问题,而Linux天生就是适合环境编译的最底层的环境。因此,最终我还是转到Linux环境下进行编译。所以我们需要熟悉基本的Linux相关的指令和操作,在这里新手的话我建议采用ubuntu进行学习,这个是有界面的,可以进行直接复制粘贴等操作,使用简单。

下面开始一步步介绍我的编译过程

1.安装ndk环境

2.安装cmake环境

3.下载ceres和eigen3相关源代码 放到linux中

4.首先先编译 eigen3,因为ceres需要依赖这个库。其实eigens编译和ceres编译是大同小异的,所有的源码编译都可以参考eigen3的编译流程,都是统一的流程和思路,只不过像ceres这些库还依赖于其他库,所以相对来说会复杂一些。因为eigen3的源文件是只有头文件构成的,所以他是没有so的。所以我们以这个glog这个库进行编译。

下面我就以编译glog这个库为例,来说明绝大多数的库的编译。
1.首先进去我们刚刚复制进来的glog的文件夹

image.png

2.在这个里面新建一个build文件夹,这个文件夹是等下我们编译过程中生成的临时文件,目的是为了不让等下生成的临时文件打乱我们原本的源文件目录。然后进入build文件夹,在这里打开终端开始编译
3.输入:cmake ..

image.png

..的意思是上一级目录,也就是含有cmakelist.txt的源文件目录。cmake.. 的意思就是执行cmakelist.txt文件里面的内容。

4.然后执行命令,make

make命令的意思就是编译生成可执行的二进制文件

5.然后执行命令,sudo make install

这个命令的目的是安装(复制二进制文件到系统,配置应用环境),等下我们生成的头文件还有so文件就是对应生成在/usr/local/include , /usr/local/lib 目录下

6.进入/usr/local文件夹里面,头文件就在include目录下,so就在lib目录下(这里so是采用软连接的方式进行引用的,我们找到我们最终的目的so复制 重命令为.so即可)

image.png

image.png

image.png

glog的编译就是这样。同理我们参照官网的ceres编译android的方式进行编译即可。首先我们需要先编译eigen3,然后DEigen3_DIR输入Eigen3Config.cmake的目录;<PATH_TO_CERES_SOURCE>可以直接输入..即可,表示上一级目录。然后步骤一样即可成功编译ceres-android

cmake \
-DCMAKE_TOOLCHAIN_FILE=\
    $NDK_DIR/build/cmake/android.toolchain.cmake \
-DEigen3_DIR=/path/to/Eigen3Config.cmake \
-DANDROID_ABI=arm64-v8a \
-DANDROID_STL=c++_shared \
-DANDROID_NATIVE_API_LEVEL=android-29 \
-DBUILD_SHARED_LIBS=ON \
-DMINIGLOG=ON \
<PATH_TO_CERES_SOURCE>
至此,我们就完成了glog源文件的编译,这样我们就能复制然后在我们的android项目中采用jni进行引用了。这就是编译各种第三方c++库,生成对应的头文件和so在android上使用的步骤和方法,你学废了嘛?我在这里再次总结下编译的步骤。

1.下载源码(要是cmake构建的项目才能采用这种方式进行编译)

2.在源文件目录下面创建build

3.执行cmake..

4.make

5.sudo make install

6./usr/local复制头文件和so


感谢您的阅读,要是有收获请记得三连点击,别告诉我下次一定!

参考资料

blog.51cto.com/u_15127625/…

blog.csdn.net/Torres_10/a…