背景
计算机领域有这静态库和动态链接库的概念
windows系统
动态链接库:windows编程里是 *.dll及其引入库
静态库:*.lib
类unix系统
动态链接库:*.so
静态库:*.a
为什么要静态库?
1. 模块化及代码复用
2. 可执行文件在链接的过程中只会打包使用到的函数,这样可以减小包的大小。举个例子,有这么个场景,我要使用计算md5的功能,openssl库中有这么个功能,那么我是否需要把整个openssl打包到自己的工程中,显然这是不需要的。
从老外的博客(引用1)搬来张图,说的非常清楚
文件结构
project /
+ module
+ src
+ main
+ jni # JNI source files here and other native sources here
| Android.mk
| Application.mk
| Xjni.c
+ x86 # target x86 ABI directory
| libX.a # x86 precompiled static library
+ armeabi
| libX.a
+ armeabi-v7a # and so forth
+ mips
Android.mk配置要这么写
LOCAL_PATH := $(call my-dir)
# prepare libX
include $(CLEAR_VARS)
LOCAL_MODULE := libX
LOCAL_SRC_FILES := $(TARGET_ARCH_ABI)/libX.a
include $(PREBUILT_STATIC_LIBRARY)
# build JNI
include $(CLEAR_VARS)
LOCAL_STATIC_LIBRARIES := X
LOCAL_MODULE := Xjni
LOCAL_SRC_FILES := Xjni.c
include $(BUILD_SHARED_LIBRARY)
我自己编译openssl是这样的
我将openssl整个工程放到jni目录底下,jni目录如下,这里省略了很多文件
.
├── Android.mk
├── Application.mk
├── caculateMd5.c
├── openssl
│ ├── android-config.mk
│ ├── Android.mk
│ └── include
│ └── openssl
├── prebuilt
│ ├── armeabi
│ │ └── libcrypto_static.a
│ ├── armeabi-v7a
│ │ └── libcrypto_static.a
│ ├── mips
│ │ └── libcrypto_static.a
│ └── x86
│ └── libcrypto_static.a
└── util
└── printerr.c
编译openssl成静态库,放到 jni/prebuilt 目录,这样的话就不需要重复编译
修改 jni/Android.mk
================================
LOCAL_PATH := $(call my-dir)
#对静态库的声明
# prepare pre-built static library
include $(CLEAR_VARS)
LOCAL_MODULE := libcrypto_static
LOCAL_SRC_FILES := ./prebuilt/$(TARGET_ARCH_ABI)/libcrypto_static.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := testMd5
LOCAL_SRC_FILES :=
caculateMd5.c \
util/printerr.c
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
# 静态库的头文件
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) \
$(LOCAL_PATH)/openssl/include
#表明该模块依赖于上面声明的crypto_static静态库
LOCAL_STATIC_LIBRARIES := crypto_static
include $(BUILD_EXECUTABLE)