够用的ndk编译系列
- 前置知识
Windows 安装NDK环境
够用的ndk编译(1)-编译一个工程 - github链接https://github.com/cpnyualc/sample_ndk_build_guide.git
- 分支demo2
编译大一点的工程
前面讲了ndk-build的基本目录结构,Application.mk和Android.mk作用。这篇拓展一下,包括调用系统库,调用本地库,调用stl,编译C/C++
Application.mk用于指定stl库,它是Android NDK构建系统使用的一个可选的构建文件,也是一个GNU Makefile片段。主要用于1、设置编译库的类型;2、用于选择STL;3、平台app api版本。
复杂的例子
看看这次的目录结构:
sample_ndk_build_guide
+---jni
| Android.mk
| Application.mk
|
\---project1
| demo.c
|
+---inc1
| fun1.h
|
+---inc2
| fun2.h
| fun3.h
|
+---projectlibs
+---src1
| fun1.c
|
\---src2
fun2.cpp
fun3.c
看看Android.mk,其中包含了
- 1、自定义变量
- 2、打印信息
- 3、判断架构
- 4、包含目录
- 5、包含源文件
- 6、设置c和c++编译参数
- 7、包含系统库
LOCAL_PATH := $(call my-dir) #设置当前目录,当前目录其实是jni
include $(CLEAR_VARS) #清空除LOCAL_PATH之外的所有LOCAL_XX变量的值
LOCAL_MODULE := project_1#工程名字,编译出来的目标名字
#设置一些自己的变量
LOCAL_PATH := $(LOCAL_PATH)/..
PORJECT_INC_PATH := $(LOCAL_PATH)/project1
PORJECT_SRC_PATH := $(LOCAL_PATH)/project1
PORJECT_WILDCARD_PATH := $(LOCAL_PATH)/project1
#打印方法
#$(info Info something. ) #info打印信息
#$(warning "warning! haha!") #打印信息
#$(warning $(PORJECT_PATH)) #打印一个变量
#$(error Fuck!) #打印一个变量
#判断架构
#ifeq ($(TARGET_ARCH), arm)
#$(info Info something. ) #info打印信息
#endif
LOCAL_ARM_MODE := arm #arm mode
#头文件目录
LOCAL_C_INCLUDES := $(PORJECT_INC_PATH)/inc1/ \
$(PORJECT_INC_PATH)/inc2/
#加上一个文件
LOCAL_SRC_FILES := project1/demo.c #包含一个编译文件。
#LOCAL_SRC_FILES := $(LOCAL_PATH)/../../project1/src1/fun1.c #包含一个编译文件。
#再加上一个文件
LOCAL_SRC_FILES += $(PORJECT_SRC_PATH)/src1/fun1.c #包含一个编译文件。
#LOCAL_SRC_FILES += $(LOCAL_PATH)/../../project1/src1/fun1.c #包含一个编译文件。
#加上一堆,注意wildcard目录是运行命令目录
LOCAL_SRC_FILES += $(wildcard $(PORJECT_WILDCARD_PATH)/src2/*.c) \
$(wildcard $(PORJECT_WILDCARD_PATH)/src2/*.cpp)
$(warning $(LOCAL_C_INCLUDES)) #打印信息
$(warning $(LOCAL_SRC_FILES)) #打印信息
#设置c和c++编译参数
#LOCAL_CFLAGS := -mfloat-abi=softfp -mfpu=neon
#LOCAL_CXXFLAGS := -std=c++11
#链接系统库
LOCAL_LDLIBS:= -llog -lm
include $(BUILD_EXECUTABLE) #编译成一个可执行文件
Application.mk,其中了
- 输出平台
- stl选择
- 平台版本
#需要编译的平台代码
APP_ABI := armeabi-v7a arm64-v8a
#链接各种stl库
#APP_STL := stlport_static
APP_STL := c++_static
#平台版本
APP_PLATFORM := 25
demo.c带有注释的代码。
#include <stdio.h>
#include "fun1.h"
#include "fun2.h"
#include "fun3.h"
void main() {
char str_tmp[256] = {0};
printf("Now! Hellow world!\n");
fun1(str_tmp); //调用一个c文件。
printf("%s\n", str_tmp);
fun2(str_tmp); //调用一个cpp,需要调用stl。
/*
数学库需要Application.mk包括
#链接各种stl库
APP_STL := c++_static
*/
printf("%s\n", str_tmp);
fun3(str_tmp); //调用一个含有数学运算的c。
/*
数学库需要Andorid.mk包括
#链接系统库
LOCAL_LDLIBS:= -llog -lm
*/
printf("%s\n", str_tmp);
}
来biu~~biu~~biu~~一下,进入相关目录,biu~~
PS C:\Users\Chaos\Desktop\blog\sample_ndk_build_guide> ndk-build.cmd
jni/Android.mk:33: jni/../project1/inc1/ jni/../project1/inc2/
jni/Android.mk:34: ../project1/demo.c jni/../../project1/src1/fun1.c .././project1/src2/fun3.c .././project1/src2/fun2.cpp
jni/Android.mk:33: jni/../project1/inc1/ jni/../project1/inc2/
jni/Android.mk:34: ../project1/demo.c jni/../../project1/src1/fun1.c .././project1/src2/fun3.c .././project1/src2/fun2.cpp
[armeabi-v7a] Compile arm : project_1 <= demo.c
[armeabi-v7a] Compile arm : project_1 <= fun1.c
[armeabi-v7a] Compile arm : project_1 <= fun3.c
[armeabi-v7a] Compile++ arm : project_1 <= fun2.cpp
[armeabi-v7a] Executable : project_1
[armeabi-v7a] Install : project_1 => libs/armeabi-v7a/project_1
[arm64-v8a] Compile : project_1 <= demo.c
[arm64-v8a] Compile : project_1 <= fun1.c
[arm64-v8a] Compile : project_1 <= fun3.c
[arm64-v8a] Compile++ : project_1 <= fun2.cpp
[arm64-v8a] Executable : project_1
[arm64-v8a] Install : project_1 => libs/arm64-v8a/project_1
可以看到:
sample_ndk_build_guide目录下生成了/libs/和/obj/。libs文件夹里头有arm64-v8a/project_1和armeabi-v7a/project_1文件。
Run一下
root@virgo:/data/tmp # chmod +x project_1
root@virgo:/data/tmp # ls -la
-rwxrwxrwx root root 206272 2020-04-05 12:15 project_1
root@virgo:/data/tmp # ./project_1
Now! Hellow world!
Fun1.
Fun2.
Fun3.