NDK01-打包静态库 动态库在mk和cmake环境配置使用

动态库和静态库

动态库: libxxx.so
运行的时候,才会去加载,加载一次就在内存中存在副本,其他地方使用就都是公用的。使用场景就是 高德百度sdk对外开房
静态库: libxxx.a
编译期把静态库完整的copy一份去执行,使用场景是如果不需要对外开放就使用静态库

编译静态库、动态库

先编写一个get.c 和 get.h文件
localhost:test01 dsh$ cat test_get.h

#include <stdio.h>

int test_get();

localhost:test01 dsh$ cat test_get.c

#include "test_get.h"

int test_get(){
	return 1991;
}

cat是一个linux查看文件内容的命令

ndk编译动态库:

$NDK_GCC_arm $NDK_CFIG_arm -fPIC -shared get.c -o libget.so

ndk编译静态库: 必须使用 arm-linux-androideabi-ar

必须先,用交叉编译打出来的 .o,不能使用gcc

$NDK_GCC_arm $NDK_CFIG_arm -fPIC -c get.c -o get.o

NDK_AR_arm="/root/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-ar"

$NDK_AR_arm rcs -o  libget.a *.o

$NDK_GCC_arm $NDK_CFIG_arm $NDK_AR_arm 是自己配置的环境变量名字,根据自己的喜好定义

下面是我的定义

#NDK 交叉编译 环境配置
export NDK_GCC_arm="/Users/xxx/Downloads/android/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc"

export NDK_CFIG_arm="--sysroot=/Users/xxx/Downloads/android/NDK/android-ndk-r17c/platforms/android-21/arch-arm -isystem /Users/xxx/Downloads/android/NDK/android-ndk-r17c/sysroot/usr/include -isystem /Users/xxx/Downloads/android/NDK/android-ndk-r17c/sysroot/usr/include/arm-linux-androideabi"

export NDK_AR_arm="/Users/xxx/Downloads/android/NDK/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-ar"

mk环境动态库 和 静态库使用

1、创建mk环境AS项目
创建一个普通的AS项目,然后在build.gradle 文件上中添加下面注释部分的代码

android {
    compileSdkVersion 28
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.ndk_mk_01"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        //设置NDK支持的环境
        externalNativeBuild{
            ndkBuild{
                abiFilters 'armeabi-v7a'
            }
        }

        ndk {
            //设置支持的SO库架构
            //abiFilters 'armeabi', 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
            abiFilters "armeabi-v7a"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    //指定mk文件的位置
    externalNativeBuild{
        ndkBuild{
            path 'src/main/ndkDir/Android.mk'
        }
    }
}

2、编写Android.mk文件

标准的配置 1 2 3 4步

# 1、 源文件路径在哪
# LOCAL_PATH 其实就是Android.mk文件的位置
LOCAL_PATH := $(call my-dir)

$(info "LOCAL_PATH:======== ${LOCAL_PATH}")

# 2、清理
include $(CLEAR_VARS)

# todo 预编译库的引入 提前编译好的库
LOCAL_MODULE := test_get
LOCAL_SRC_FILES := libtest_get.a
#LOCAL_SRC_FILES := libtest_get.so

#告诉构建工具是静态库
include $(PREBUILT_STATIC_LIBRARY)
#include $(PREBUILT_SHARED_LIBRARY)

# 清理自己的库
include $(CLEAR_VARS)

# 3、指定库的名字
LOCAL_MODULE := test_get_jar

LOCAL_SRC_FILES := test01.c \
test02.c

# todo 链接进来
# 静态库链接
LOCAL_STATIC_LIBRARIES := test_get
# 动态库的链接
# LOCAL_SHARED_LIBRARIES := test_get

# 导入log
LOCAL_LDLIBS    := -lm -llog

# 4、构建库
include $(BUILD_SHARED_LIBRARY)

引入静态库或者动态库的步骤
第一步、引入预编译库 上面我们使用ndk环境编译处理 .a 或者 .so 文件

LOCAL_MODULE := test_get
LOCAL_SRC_FILES := libtest_get.a
#LOCAL_SRC_FILES := libtest_get.so

第二步、告诉构建工具使用的是静态库还是动态库

include $(PREBUILT_STATIC_LIBRARY)
#include $(PREBUILT_SHARED_LIBRARY)

第三步、清理(必须步骤)

include $(CLEAR_VARS)

第四步、把静态库或者动态库链接进来 跟谁链接 就是LOCAL_MODULE(test_get_jar)

# 静态库链接
LOCAL_STATIC_LIBRARIES := test_get
# 动态库的链接
# LOCAL_SHARED_LIBRARIES := test_get

3、静态库 动态库调用
编一个c文件 叫test01.c

#include <jni.h>
#include <android/log.h>

#define TAG "dsh"
#define LOGD(...)__android_log_print(ANDROID_LOG_DEBUG,TAG,__VA_ARGS__)

extern int test_get();

//extern "C"
JNIEXPORT void JNICALL
Java_com_example_ndk_1mk_101_MainActivity_testGet(JNIEnv * env,jobject instance) {
    LOGD("Java_com_example_ndk_1mk_101_MainActivity_testGet %d",test_get());
}

在MainActivity中调用

static {
    System.loadLibrary("test_get_jar");
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    testGet();
}

public native void testGet();

cmake环境动态库静态库使用
1、新建一个c++的as项目。一定要是c++
2、配置cmake的gradle配置文件

android {
    compileSdkVersion 28
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.ndk_cmake_01"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                //cppFlags "" 默认支持四大平台
                abiFilters 'armeabi-v7a'
            }
        }

        ndk{
            abiFilter 'armeabi-v7a'
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }

}

3、配置CMakeLists.txt文件

cmake_minimum_required(VERSION 3.4.1)

message("Camke 路径地址 ${CMAKE_SOURCE_DIR}")

file(GLOB allcpp *.cpp)


add_library(
        native-lib

        SHARED

        ${allcpp}
)
#[[# 导入静态库
add_library(test_get STATIC IMPORTED)
set_target_properties(test_get PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/libtest_get.a)]]

# 导入动态库
add_library(test_get SHARED IMPORTED)
set_target_properties(test_get PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libtest_get.so)
#${CMAKE_SOURCE_DIR}/../jniLibs/${CMAKE_ANDROID_ARCH_ABI}/libget.so
find_library(
        log-lib

        log)

target_link_libraries(
        native-lib

        ${log-lib}

        test_get
)

4、调用静态 或者动态库方法

    static {
        //如果是动态库 必须添加加一次
        System.loadLibrary("test_get");
        System.loadLibrary("native-lib");
    }
发布了58 篇原创文章 · 获赞 16 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/dingshuhong_/article/details/103946004
今日推荐