欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

CMake方式编译生成so库

程序员文章站 2022-06-06 17:07:15
...

在CMake构建工具没有发布之前,都是ndk-build方式来编译生成so库,但是ndk-build比较繁琐且容易出错,我们用CMake方式,比较简单,这样我们就可以专注于我们的开发,细心的哥们可能早就注意到了Android Studio创建项目的时候,可以勾选支持这种方式:

看图:
CMake方式编译生成so库

这样是最省事的,我先看下项目都生成了什么特别的东西:
CMakeLists.txt 这个是最显眼的文件,没错,系统帮助我们完成了所有的东西,最重要的就是这个文件,文件内容如下:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html

# Sets the minimum version of CMake required to build the native library.
#最低要求版本号
cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.

add_library( # Sets the name of the library. 设置so库的名字,这里叫native-lib
             native-lib

             # Sets the library as a shared library.动态库,会被动态链接,在运行时被加载
             SHARED

             # Provides a relative path to your source file(s).要编译的源代码文件的路径,如果你的不是cpp下的,这里记得同步改下
             src/main/cpp/native-lib.cpp )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.

find_library( # Sets the name of the path variable.日志支持库并将其路径存储在 log-lib 中
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log )

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.

target_link_libraries( # Specifies the target library.为了确保您的原生库可以在 log 库中调用函数
                       native-lib

                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib} )

接着看模块下的build.gradle文件(记住不是工程下):

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.administrator.myapplication"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }

    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

这是默认生成的。到这里基本上就没了,所以很简单。不过这是新建项目的时候就选择支持CMake,但是这不符合我们正常开发,好多都是中途要引入Jni\Ndk开发的,怎么办?我觉得我们可以新建一个项目,然后把CMakeLists.txt文件copy到我们现有项目中,然后修改配置,重新编辑即可,是不是很机智QAQ。

大家坐好,看我表演~
首先,新建c文件夹(其实无所谓,因为我待会在文件夹下写c语言,所以取名为c)
然后,新建C文件,C的后缀是.c而C++是.cpp
native-lib.c 代码:

#include <jni.h>

jstring Java_com_example_administrator_kotlinapp_ui_JniActivity_sayHello(JNIEnv* env,jobject jobj){
          char* text="I am from C";
          return (*env)->NewStringUTF(env,text);
 }

看不懂的朋友要去补补C语言咯T^T

接着我们把CMakeLists.txt文件copy过来,如下:
CMake方式编译生成so库

注意:源文件的路径一定要正确

再看下build.gradle:

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.example.administrator.kotlinapp"
        minSdkVersion 15
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }

        ndk {
            // Specifies the ABI configurations of your native
            // libraries Gradle should build and package with your APK.
            abiFilters 'armeabi', 'x86'
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}

这样我们就可以用Java调用C语言了:

public class JniActivity extends AppCompatActivity {

     {
        System.loadLibrary("native-lib");
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_jni);
        ((TextView)findViewById(R.id.textView)).setText(sayHello());
    }

    public native String sayHello();
}

这时候rebuild下,就可以看到生成的so库了:
CMake方式编译生成so库

相关标签: CMake JNINdk