有一个场景如下:
在安卓平台上开发一个软件,语言全部是C/C++,然后编一个可执行文件,使其能够在安卓平台运行。
本文适用对象:初接触安卓,习惯使用C/C++的人群。
开发环境:
编译环境NDK,系统平台:Windows 11
文件结构:
│ Android.mk # 存在未使用
│ Application.mk # 编译指导文件,介绍安卓环境和需要调用的Androd.mk
├─libs # 编译后文件,根据Application声明的平台会有多个文件夹
│ └─armeabi-v7a # 将它们push到安卓,赋予相对应权限就能使用
│ libmq.so
│ myexecutable
│
├─obj # 编译后文件
│ └─local
│ └─armeabi-v7a
│ │ libmq.so
│ │ myexecutable
│ │
│ └─objs
│ ├─mq
│ │ add.o
│ │ add.o.d
│ │
│ └─myexecutable
│ main.o
│ main.o.d
│
├─src # 测试源代码
│ Android.mk # 类似与make文件
│ main.cpp # 主控代码
│
└─third_party # 测试代码,用于生成动态库的
└─mq
add.cpp
add.h
Android.mk # 类似于make文件,用于指导如何编译动态库
对每个需要写的文件进行介绍:假设根目录叫main_mq。
1. main_mq\\Application.mk 这个相当于是根目录,这里不会列出根目录下的Android.mk文件,因为那个文件并未被APP_BUILD_SCRIPT指明。
APP_ABI := armeabi-v7a # 声明需要运行的平台
APP_BUILD_SCRIPT := \ # 声明包含的需要调用的Android.mk文件
src/Android.mk\
third_party/mq/Android.mk
APP_STL := c++_static # 使用静态的c++库
# 允许使用缺失的depend,例如需要mq库,但是当前并没有,需要整个项目编译结束才有,可以将其加上
APP_ALLOW_MISSING_DEPS := true
2. main_mq\\src\\Application.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := myexecutable
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../third_party/mq
LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES := mq
include $(BUILD_EXECUTABLE)
3. main_mq\\src\\main.cpp
#include<iostream>
#include <add.h>
// 功能说明
int main(int argc, char* argv[])
{
std::cout << "Hello, World!" << std::endl;
std::cout << "1 + 2 = " << add(1, 2) << std::endl;
return 0;
}
4. main_mq\\third_party\\mq\\Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mq
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_SRC_FILES := add.cpp
include $(BUILD_SHARED_LIBRARY)
5. main_mq\\third_party\\mq\\*.h.cpp 这个目录下的c++文件
// add.h
int add(int a, int b);
//-------------------------------------------------
// add.cpp
int add(int a, int b)
{return a + b;}
使用的命令:
ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk
这里如果命令我不会使用,安卓开发使用IDE环境相对,,没用过。为了能够快速编译,这些都是在命令行里进行的。
执行:
// 将编译好的文件拷贝到安卓设备上,这里是在main_mq\obj\local\armeabi-v7a> 目录下
adb push .\libmq.so .\myexecutable /data/local/tmp
adb shell
// 增加动态库的环境,否则会提示缺少库
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/data/local/tmp
cd /data/local/tmp
// 增加执行权限
chmod 777 libmq.so myexecutable
./myexecutable
显示:
Hello, World!
1 + 2 = 3
总结:安卓开发NDK不知道怎么介绍,为什么做的不能和cmake那么简单。这样兼容起来更容易。。