这一期我们继续学习
Android.mk
的一些语法,主要讲的是如何引入系统库、如何引入第三方库、如何引入静态库、如何进入头文件
首先呢,我们先进入我们的
Android
目录,配置我们的环境变量
.build/envsetup.sh
配置
lunch
,我们这里依然选择的是
19
(这里不再细说)
然后进入我们的代码目录,
cd external/test/
然后用
tree
命令看一下代码目录,这个目录下有一个
Android.mk
,两个源文件
main.cpp
和
test1.cpp
我们来看一下我们的main.cpp
使用命令
vi src/main.cpp
,
在
main.cpp
中我们除了引入了
stdio.h
,我们还使用了
utils/Log.h
,这个呢,是安卓系统打印
log
的一个头文件,我们在这里使用的是他的
ALOGE
来做一个打印,我们在
C++
层一般都是使用
ALOGE/ALOGD
来做一些调试打印信息,我们既然引入了
ALOGE
那么我们就需要在编译的时候引入他所需要的库,那么我们来看一下我们的
Android.mk
,首先我们编译的是一个
libtest
动态库,这个暂时我们先不看,我们先来看一下我们的
test
,在这里
test
是编译生成一个可执行的二进制文件,文件名称是
test
,文件源码是
src/main.cpp
现在呢,我们还没有导入log
的库,我们现在来编译看一下 使用
mm
命令进行编译
在这里我们看到有一个错误信息,是说在我们的main.cpp
中的第七行,没有定义
_android_log_print ,
我们打开
main.cpp
来看一下
ALOGE
包含在
log
那个库文件中,我们并没有导入我们的
log
库,所以会有报错信息,那我们应该怎么解决呢?我们可以在
Android.mk
中加一个选项,来把我们的库加上,这样我们在编译的时候就能找到我们的库,我们需要加的选项是
LOCAL_SHARE LIBRARIES += libxxxx
,这样当我们的
Android
编译的时候,就会自动的去我们系统下去寻找我们所添加的库,下面我们将
Android.mk
做一个修改,我们在里面
22
行加上一个选项
因为ALOGE
包含在
log
里面,所以我们在这里使用的是
log
这个库,然后我们再来进行编译,我们会看到在这里生成了一个
test
程序
接下来我们看一下,我们在编译的时候我们的库是放在哪里呢?我们退回到
Android
的目录,然后查找一下这个库,看看他究竟在哪里。输入命令
find out/target/product/ -name liblog.so
可以看到这里有好多相同的库,我们来看一下,他具体的链接的是哪个库,下面我们把第一个库的名字改一下
然后退回到刚才的目录,代码不改变,然后touch src/main.cpp
然后我们重新编译一下
mm
我们可以看到编译是没有问题的,所以不是这个库
我们再把这个库的名字改回来
然后我们再来查找这个库,如此重复,直到编译的时候有错误出现,那么我们就可以肯定,我们所用到的就是这个库文件了,当我们对第二个库进行编译的时候就报了一个错误信息,
那么我们就可以肯定,第二个就是我们要找的链接路径,由此我们可以看出他真正链接的库并不是在我们生成的文件系统那个文件目录下,而是他中间会有一个缓存的库,他的库就会放在这里,这就是如何在安卓下导入系统的库
下面我们来看第二种情况,在当前的Android.mk
中,我们自己生成了一个
libtest
,如果我想在我的
main.cpp
里面使用
src/test1.cpp
里面的函数,那么我们应该怎么做呢?下面我们来修改一下代码
vi main.cpp
我们再来看一下
test1.cpp
中的函数
我们想要调用这个函数,就需要用extern
声明出来,然后再在主函数中调用
call_test();
的函数
我想在这里不以源码的形式,而是以库的形式来导入,我们现在来编译一下
现在报错是找不到这个库,那么现在我们来看一下如何加入第三方库,我们可以使用LOCAL_LDFLAGS := -LPath -lxxx
来添加,其中
-L
加的是库的路径,
-l
加的是库的名字,下面我们来添加一下,打开
Android.mk
进行添加
我们是添加到了这里,现在我们的库还需要编译一下,编译的过程呢,首先是生成一个libtest.so
,这个
.so
会放在我们的
LOCAL_PATH/lib
目录下,然后会编译生成一个
test
的二进制程序,下面我们来做一下编译,首先把
bin
下面的内容清空掉,再把
lib
下面的内容清空掉,在
touch
我们的
src/main.cpp
,
touch src/test1.cpp
然后我们在来进行编译 使用
mm
命令进行编译,这个编译过程呢是没有问题的,这样就
可以在我们
lib
下生成
libtest.so
,在
bin
目录下生成
test
二进制程序
这就是使用Android.mk
导入第三方的库
下面我们来看一下我们的
main.cpp vi src/main.cpp
在这里我们是以
extern
的形式来导入我们的函数的,正规方式呢,应该是使用头文件的形式
现在我们来看一下,我们当前目录下有一个inc
的文件,他就指定了我们的头文件,头文件就是
test1.h
,然后我们打开这个头文件
如果没有test1.h
我们就定义这个
test1.h
,是为了防止重定义,把函数在这里面进行了声明
然后在进入main.cpp
,在上边用
include
进行声明,因为
test1.h
是在
inc
目录下所以应该添加
#include
“
./inc/test1.h
”
现在我们来进行一下编译,看能否找到我们的头文件
mm
可以看到这样是完全没有问题的,那么说如果我们的test1.h
他在一个其他目录,或者说
inc
在往上几个目录,这时候这个办法肯定是不行的,我们就没有办法指定了,此时我们可以添加一个关键字
LOCAL_C_INCLUDES := path
,现在我们返回我们的
main.cpp
文件中进行一下修改,我们将
#include
“
./inc/test1.h
”修改成
#include <test1.h>
现在我们来进行编译 mm
这样是肯定不行的,有错误,现在我们来改一下我们的
Android.mk
,在里边呢加上一个选项
LOCAL_C_INCLUDES := ./inc
现在我们再来进行编译,但是当我们编译的时候他还是会报错,因为是绝对路径,所以呢,我们加的时候要加上我们的LOCAL_PATH
这时我们在进行编译就没问题了
下面我们来看一下我们如何使用我们的静态库,我们先来看一下我们的静态库在哪里,我们首先touch src/test1.cpp
然后
mm
进行编译
这样我们就看到了我们静态库的目录,我们返回我们的Android
目录,然后将静态库的目录拷贝到
external/test/lib/
目录下,这样我们就有了一个静态库
我们来修改一下Android.mk
我们把
LOCAL_LDFLAGS
修改一下,把它改成我们的静态库
然后我们来做编译 mm
他会报一个错,说编译器找不到我们的
./lib/libtest1.a
,这是因为我们需要在刚才修改的地方添加一个绝对路径,也就是我们的
LOCAL_PATH
我们修改完之后在进行编译,这时就可以编译过去了
|