CMake方式编译生成so库
程序员文章站
2022-06-06 17:07:15
...
在CMake构建工具没有发布之前,都是ndk-build方式来编译生成so库,但是ndk-build比较繁琐且容易出错,我们用CMake方式,比较简单,这样我们就可以专注于我们的开发,细心的哥们可能早就注意到了Android Studio创建项目的时候,可以勾选支持这种方式:
看图:
这样是最省事的,我先看下项目都生成了什么特别的东西:
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过来,如下:
注意:源文件的路径一定要正确
再看下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库了:
上一篇: 学习C语言第一天
推荐阅读