编译SO库/可执行程序
编译so库/可执行程序
前面我们了解Android.mk的文件结构,我们也尝试编译了jar包,app,接下来我们看看C++程序的编译和库的打包
前面我们完成了java的编译,编译成jar包,编译成apk。
接下来我们看看C/C++的编译,编译成静态库/动态库,编译成可执行文件。
静态库和动态库(共享库)的说明在前面已经和大家讲了。
编译so库
先给大家表演编译so库,后面的编译可执行程序时,我们可以依赖so库,这样子比较全。
所以就先学习一下如何编译库吧。
库也一样,我们分动态库和静态库。
先写个库吧,我写个简单的,比如说log输出。
头文件:log.h
#define TAG "SOB-LOG"
#include <string>
using namespace std;
namespace sob{
void log(const string msg);
}
c++文件log.cpp
#include <iostream>
#include <string>
#include "log.h"
using namespace std;
namespace sob {
void log(const string msg)
{
cout << TAG << " : " << msg << endl;
}
}
就这么简单,现在,我们把它编译成共享库
编写Android.mk文件
还记得前面我们的Android.mk的结构吗?
于是,我们的脚本这样写了:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
#放到vender目录下
LOCAL_VENDOR_MODULE = true
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= libsoblog
LOCAL_C_INCLUDES := external/libcxx/include
LOCAL_SHARED_LIBRARIES := \
libc++
LOCAL_SRC_FILES:= \
log.cpp
include $(BUILD_SHARED_LIBRARY)
编译结果
hdc@ubuntu:~/Android5.1/packages/apps/HardwearTest/loglib$ mm
make: Entering directory '/home/hdc/Android5.1'
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=5.1
TARGET_PRODUCT=aosp_x86
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=x86
TARGET_ARCH_VARIANT=x86
TARGET_CPU_VARIANT=
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.11.0-40-generic-x86_64-with-Ubuntu-20.04-focal
HOST_BUILD_TYPE=release
BUILD_ID=LMY47D
OUT_DIR=out
============================================
make: Circular out/target/product/generic_x86/obj/SHARED_LIBRARIES/liblog_intermediates/LINKED/liblog.so <- out/target/product/generic_x86/obj/lib/liblog.so dependency dropped.
make: Circular out/target/product/generic_x86/system/lib/liblog.so <- out/target/product/generic_x86/system/lib/liblog.so dependency dropped.
make: Nothing to be done for 'all_modules'.
make: Leaving directory '/home/hdc/Android5.1'
#### make completed successfully (1 seconds) ####
hdc@ubuntu:~/Android5.1/packages/apps/HardwearTest/loglib$
也就是在这个out/target/product/generic_x86/system/lib/liblog.so目录下有生成。
接下来我们编译一下可执行文件,然后依赖我们的log库。
编译成可执行文件
比如说最近写的一个程序,去查询是否有GSensor的,当然,这个是模拟器,就不是真的能测试,只是模拟给大家看如何编译一个可执行程序。
#include "loglib/log.h"
#include <string>
using namespace std;
using namespace sob;
void printHelp(void)
{
log("帮助内容:");
log("checkGyroscope 检查是否支持陀螺仪,1表示支持,-1表示不支持");
log("getGsensorType 检查是否支持重力传感器,0-不支持,1-QMA7981,2-SC7A21,3-DA217");
log("使用示例:hardwaretest checkGyroscope");
}
void handleCmd(char* cmd)
{
//对命令进行判断和执行
log("参数内容:");
string cmdStr;
cmdStr = cmd;
//log("cmdStr ==> "+ cmdStr);
if("checkGyroscope"==cmdStr)
{
log("测试是否有陀螺仪");
//TODO:去检查是否有陀螺仪
}else if("getGsensorType"==cmdStr)
{
log("检查重力传感器的类型");
//TODO:去检查是否有重力传感器
}else
{
printHelp();
}
}
//argc是参数个数,argv[]是参数内容
int main(int argc, char *argv[]){
log("do hardware test...");
int i = 0;
for(;i<argc;i++)
{
if(argc==1)
{
//打开帮助
printHelp();
}
if(i>0){
handleCmd(argv[i]);
}
}
}
按前面的套路,我们这样写Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
# 编译出来的名称
LOCAL_MODULE := hardweartest
#源代码
LOCAL_SRC_FILES := \
hardwaretest.cpp
#添加头部依赖
LOCAL_C_INCLUDES := external/libcxx/include
#添加依赖库
LOCAL_SHARED_LIBRARIES := \
libsoblog \
libc \
libc++
include $(BUILD_EXECUTABLE)
编译结果:
hdc@ubuntu:~/Android5.1/packages/apps/HardwearTest$ mm
make: Entering directory '/home/hdc/Android5.1'
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=5.1
TARGET_PRODUCT=aosp_x86
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=x86
TARGET_ARCH_VARIANT=x86
TARGET_CPU_VARIANT=
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.11.0-40-generic-x86_64-with-Ubuntu-20.04-focal
HOST_BUILD_TYPE=release
BUILD_ID=LMY47D
OUT_DIR=out
============================================
Import includes file: out/target/product/generic_x86/obj/EXECUTABLES/hardweartest_intermediates/import_includes
target C++: hardweartest <= packages/apps/HardwearTest/hardwaretest.cpp
target Executable: hardweartest (out/target/product/generic_x86/obj/EXECUTABLES/hardweartest_intermediates/LINKED/hardweartest)
target Symbolic: hardweartest (out/target/product/generic_x86/symbols/system/bin/hardweartest)
Export includes file: packages/apps/HardwearTest/Android.mk -- out/target/product/generic_x86/obj/EXECUTABLES/hardweartest_intermediates/export_includes
target Strip: hardweartest (out/target/product/generic_x86/obj/EXECUTABLES/hardweartest_intermediates/hardweartest)
Install: out/target/product/generic_x86/system/bin/hardweartest
make: Leaving directory '/home/hdc/Android5.1'
#### make completed successfully (1 seconds) ####
从输出的Log上看,我们可以知道它在这里:out/target/product/generic_x86/system/bin/hardweartest
编译到system/bin目录下,可是,我们现在的镜像并没有这个程序
所以我们要重新打包镜像
怎么打包叫经?
make snod
执行结果
hdc@ubuntu:~/Android5.1$ make snod
============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=5.1
TARGET_PRODUCT=aosp_x86
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_BUILD_APPS=
TARGET_ARCH=x86
TARGET_ARCH_VARIANT=x86
TARGET_CPU_VARIANT=
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.11.0-40-generic-x86_64-with-Ubuntu-20.04-focal
HOST_BUILD_TYPE=release
BUILD_ID=LMY47D
OUT_DIR=out
============================================
build/core/Makefile:1013: Warning: with dexpreopt enabled, you may need a full rebuild.
make snod: ignoring dependencies
Target system fs image: out/target/product/generic_x86/system.img
Running: mkuserimg.sh out/target/product/generic_x86/system out/target/product/generic_x86/system.img ext4 system 786432000 out/target/product/generic_x86/root/file_contexts
make_ext4fs -T -1 -S out/target/product/generic_x86/root/file_contexts -l 786432000 -a system out/target/product/generic_x86/system.img out/target/product/generic_x86/system
Creating filesystem with parameters:
Size: 786432000
Block size: 4096
Blocks per group: 32768
Inodes per group: 8000
Inode size: 256
Journal blocks: 3000
Label:
Blocks: 192000
Block groups: 6
Reserved block group size: 47
Created filesystem with 1463/48000 inodes and 130394/192000 blocks
out/target/product/generic_x86/system.img maxsize=802897920 blocksize=2112 total=786432000 reserve=8110080
#### make completed successfully (2 seconds) ####
运行结果
运行模拟器
emulator
把模拟器启动起来以后,我们adb shell
进去android系统里
进入到system/bin
目录下,查看是否有我们的程序hardweartest
如果有直接执行即可:
到次,就和大家了解完了可执行程序的编译和库的编译了
如何添加到系统遍中
以上我们只是手动编译出来的,然后打包镜像。
如果我们直接从无到有,如果告诉系统我们的库是需要编译的呢?
这个请看我们后面的产品创建了