Android Studio利用CMake生成.so文件并且可供其他项目引用

这篇具有很好参考价值的文章主要介绍了Android Studio利用CMake生成.so文件并且可供其他项目引用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、CMake工具

1.1、CMake是什么

  • CMake是一个主要用于CPP的构建工具。
  • CMake语言是平台无关的中间编译工具。同一个CMake编译规则在不同系统平台构建出不同的可执行构建文件,所有操作都是通过编译CMakeLists.txt来完成的。在Linux产生MakeFile,在Windows平台产生Visual Studio工程等。
  • CMake旨在解决各平台的不同Make工具的产生的差异(比如GNU Make, QT的qmake,微软的nmake, BSD的pmake)。

1.2、CMake原理

CMake有两个阶段:配置、生成。

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 1.3、CMake常用命令介绍

(1)cmake_minimum_required

  • 用于设定需要的最低版本的CMake
cmake_minimum_required
(
    VERSION <min>[...<policy_max>] [FATAL_ERROR]
)

(2)project

  • 用于指定cmake工程的名称,并将其存储在变量PROJECT_NAME中
project
(
    <PROJECT-NAME> 

    [<language-name>...]
)

或

project
(
    <PROJECT-NAME>

    [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]

    [DESCRIPTION <project-description-string>]

    [HOMEPAGE_URL <url-string>]

    [LANGUAGES <language-name>...]
)
VERSION cmake工程的版本号
DESCRIPTION cmake工程的简短的描述
HOMEPAGE_URL cmake工程的主页URL
LANGUAGES cmake工程的编译工程使用的语言

(3)add_library

使用该命令可以在:

  • Linux下生成(静态/动态)库so或者.a文件
  • Windows下就是dll与lib文件

它有两种命令格式

  • 第一种
add_library
(
    <name>

    [STATIC | SHARED | MODULE]
           
    [EXCLUDE_FROM_ALL]
            
    [source1] [source2] [...]
)
<name> 库文件的名字,该库文件会根据命令里列出的源文件来创建
[STATIC | SHARED | MODULE]

作用是指定生成的库文件的类型

  • STATIC库:生成obj文件后,将其链接成静态库,用于链接到其他targets
  • SHARED库:生成obj文件后,将其链接成动态库,用于运行时加载
  • MODULE库:不能链接到其他targets,但是可以用dlopen之类的方法在运行时动态加载

注:如果没有明确指定要生成的library的类型到底是STATIC,SHARED还是MODULE。则查看BUILD_SHARED_LIBS变量,如果值为ON,则默认是SHARED,否则默认STATIC

[EXCLUDE_FROM_ALL] 表明该target是否从默认构建target中排除
[source1] [source2] [...] source1 source2分别表示各个源文件
  •  第二种

生成一个obj文件对象,该对象库只编译源文件,但不链接

add_library
(
    <name> OBJECT [<source>...]
)

(4)find_library

  • 该命令用来查找一个库文件
find_library
(
    <VAR> name1 [path1 path2 ...]
)
<VAR>
  • 一个名为<VAR>的cache条目会被创建来存储该命令的结果。
  • 如果找到了该库文件,那么结果会存储在该变量里,并且搜索过程将不再重复,除非该变量被清空。
  • 如果没有找到,结果变量将会是<VAR>-NOTFOUND,并且在下次使用相同变量调用find_library命令时,搜索过程会再次尝试
NAMES 在NAMES参数后列出的文件名是要被搜索的库名
PATHS 附加的搜索位置在PATHS参数后指定

(5)target_link_libraries

  • 该指令的作用为将目标文件与库文件进行链接
target_link_libraries
(
    <target>

    [item1] [item2] [...][[debug|optimized|general] <item>] ...
)
  • 上述指令中的是指通过add_executable()和add_library()指令生成已经创建的目标文件。而[item]表示库文件没有后缀的名字。
  • 默认情况下,库依赖项是传递的。当这个目标链接到另一个目标时,链接到这个目标的库也会出现在另一个目标的连接线上。这个传递的接口存储在interface_link_libraries的目标属性中,可以通过设置该属性直接重写传递接口。

2、Android Studio生成.so

  • Android Studio版本:Android Studio Flamingo | 2022.2.1 Patch 2
  • 开发语言:Kotlin

2.1、新建C++项目

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

  • 可以选择C++版本,我选择的是默认

 Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

新建项目中会有CMakeLists.txt和native-lib.cpp两个文件

  • CMakeLists.txt:CMake工具会根据其中的命令编译生成.so文件
  • native-lib.cpp:C++文件

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 CMakeLists.txt中的内容

# 指定需要的 CMake 最低版本为 3.22.1
cmake_minimum_required(VERSION 3.22.1)

# 指定项目名称为 "mysocreatefile"
project("mysocreatefile")

# 添加一个名为 "mysocreatefile" 的共享库,并将 "native-lib.cpp" 源文件添加到库中
# 这里使用 SHARED 标志表示这是一个共享库(动态链接库)
add_library(
        mysocreatefile

        SHARED

        native-lib.cpp
)

# 查找名为 "log" 的库,并将其路径保存在变量 log-lib 中
# 这是为了在后面的步骤中将这个库链接到目标库
find_library(
        log-lib

        log
)

# 将目标库 "mysocreatefile" 与 log-lib 变量中的库链接起来。
# 这意味着在编译和链接过程中,将使用 "log" 库提供的功能和符号
target_link_libraries(
        mysocreatefile

        ${log-lib}
)

native-lib.cpp中的内容,即C++要执行的代码

#include <jni.h>
#include <string>

extern "C" JNIEXPORT jstring JNICALL
Java_com_leon_mysocreatefile_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";
    return env->NewStringUTF(hello.c_str());
}

MainActivity中的内容

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        binding.sampleText.text = stringFromJNI()
    }

    external fun stringFromJNI(): String

    companion object {
        init {
            System.loadLibrary("mysocreatefile")
        }
    }
}
  • 可以看到程序已经为我们自动生成了一个动态生成.so文件的示例
  • 其中生成的.so文件的库的名称叫做"mysocreatefile"
  • 库中的C++方法Java_com_leon_mysocreatefile_MainActivity_stringFromJNI(),其中com_leon_mysocreatefile对应的是包名,MainActivity_stringFromJNI()对应的是类名和方法名,在Java中调用该方法时,必须使包名类名方法名与此处的保持一致,下面会示例讲解。
  • 想要在MainActivity中调用C++方法,需要先加载库System.loadLibrary("mysocreatefile"),然后声明native方法stringFromJNI(),这个方法名要与C++中的方法名对应
  • external对应Java中的public static native

build.gradle(:app)中,android{}目录中会有cmake的配置

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

我们可以Make一下项目,看一下示例生成的.so

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

 2.2、生成自定义功能的.so文件

  • 比如,我们想在.so中实现一个分数评定的功能,大于90分优秀,大于70分良好,小于60分不及格。

(1)创建一个Kotlin类

定义一个external方法

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

(2)创建cpp文件,用C++实现功能

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

  • 注:C++中方法名中的包名前缀、类名前缀、方法名前缀要与定义的Kotlin类的一致。
  • 如,Kotlin类的包名是com.leon.score,类名是ScoreTool,方法名是evaluateLevel
  • 则C++中的方法名就是Java_com_leon_score_ScoreTool_evaluateLevel

(3)修改CMakeList.txt

  • 可以将库名换一个myscorelib
  • 替换cpp文件
# 指定需要的 CMake 最低版本为 3.22.1
cmake_minimum_required(VERSION 3.22.1)

# 指定项目名称为 "myscorelib"
project("myscorelib")

# 添加一个名为 "myscorelib" 的共享库,并将 "score-lib.cpp" 源文件添加到库中
# 这里使用 SHARED 标志表示这是一个共享库(动态链接库)
add_library(
        myscorelib

        SHARED

        score-lib.cpp
)

# 查找名为 "log" 的库,并将其路径保存在变量 log-lib 中
# 这是为了在后面的步骤中将这个库链接到目标库
find_library(
        log-lib

        log
)

# 将目标库 "myscorelib" 与 log-lib 变量中的库链接起来。
# 这意味着在编译和链接过程中,将使用 "log" 库提供的功能和符号
target_link_libraries(
        myscorelib

        ${log-lib}
)

(4).so文件加载和使用

  • 需要通过System.loadLibrary来加载库myscorelib
package com.leon.score

class ScoreTool {

    companion object{
        init {
            System.loadLibrary("myscorelib")
        }
    }

    external fun evaluateLevel(score: Int): String
}
  • Make Project以生成.so文件(把之前.so的缓存全部删除再make)

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

  • 在MainActivity中调用该方法
class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)


        //评定分数等级
        val score = 50
        val level = ScoreTool().evaluateLevel(score)


        //展示结果
        binding.sampleText.text = "得分:$score\n等级:$level"
    }
}

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

3、在其他项目中使用自定义的.so文件

  • 将cmake目录下动态生成的.so文件复制一份备用

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

3.1、新建一个Android项目

  • 将刚才复制的.so文件放置app下的libs中

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

  • 配置build.gradle(:app)中的sourceSets和ndk
android {
	...
    sourceSets{
        main{
            jniLibs.srcDirs = ['libs']
        }
    }

    defaultConfig {
		...
        ndk {
            // 设置支持的SO库架构
            abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86', 'x86_64'
        }
        
    }  
}

3.2、适配工具类

  • 创建的工具类必须和.so文件中方法的包名,类名,方法名一致,才能引用到.so库中的C++方法

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

3.3、使用.so方法

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

Android Studio利用CMake生成.so文件并且可供其他项目引用,Android Learning,android,StableDiffusion

 

CMake概念

CMake命令

OOM文章来源地址https://www.toymoban.com/news/detail-522571.html

到了这里,关于Android Studio利用CMake生成.so文件并且可供其他项目引用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android so库开发——Android Studio生成so库(一)

    1)新建项目          选择最下面的 Native C++ 下一步即可 2)填写项目信息  3)选择C++版本可以直接选择默认 1)进入Studio 设置 SDK 设置界面         这里选择需要的 NDK 和 CMake 版本进行下载。 2)加载 ndk         通过 File - Project Structure 或 点击 图标进入设置界面。

    2024年02月09日
    浏览(43)
  • Android中的SDK以及利用Android Studio生成aar

    广义上的SDK: 指的是为特定的软件包、软件框架、硬件平台、操作系统等建立应用程序时所使用的开发工具的集合。 比如你在编辑器里敲代码的时候它会自动补全代码,自动错误检查,你点一下Run,它会调用编译器来自动编译,编译完它会调用iPhone的模拟器来运行,这就是

    2024年02月12日
    浏览(47)
  • NDK编译C++源码生成Android平台so文件(opencv_android)

     1.准备CPP文件  编写CMakeLists.txt 编写 mk文件   android-8 is unsupported. Using minimum supported version android-16  APP_PLATFORM android-16 is higher than android:minSdkVersion 1 in ./AndroidManifest.xml 修改Application.mk中的APP_PLATFORM为 android-21  builg.gradle添加原生编译路径     出现gnustl_static不支持错误  修改

    2024年02月10日
    浏览(43)
  • Cmake学习记录(九)--使用Cmake交叉编译Android .so库

    注意:本教程没有关于JNI接口的写法,只是把C代码编译成适合android平台的so库,想查看完整代码可以参考文末的第9条参考链接 目前Android编译.so的话使用Android Studio比较简单,但是有时候时候Android Studio的话还需要创建一个Android的项目,这里记录下脱离Android Studio单纯使用Cma

    2024年02月12日
    浏览(42)
  • OpenCV开发之——人脸识别库生成so文件(1),通宵都要看完这个Android关键技术点

    ifneq (“”,“$(wildcard $(OPENCV_ANDROID_SDK)/OpenCV.mk)”) include ${OPENCV_ANDROID_SDK}/OpenCV.mk else include ${OPENCV_ANDROID_SDK}/sdk/native/jni/OpenCV.mk endif else include …/…/sdk/native/jni/OpenCV.mk endif LOCAL_SRC_FILES := DetectionBasedTracker_jni.cpp LOCAL_C_INCLUDES += $(LOCAL_PATH) LOCAL_LDLIBS += -llog -ldl LOCAL_MODULE := detection_b

    2024年04月16日
    浏览(129)
  • Android Studio生成.jks文件

    字面意思可以理解为java的密钥库,是一个用来存放密钥和证书的仓库。而keytool就是密钥和证书的管理工具,它把key(密钥)和certificate(证书)存放在一个叫keystore的文件中。具体内容可以参考JKS_密钥对生成与读取方法。 1、打开android studio软件,点击上方Build - Generate Signe

    2024年02月02日
    浏览(38)
  • Android so库开发——Android Studio调用so库(二)

            在 Android Studio生成自己的so库 中已经创建了自己的so库,这是一个JNI规范的so库,可以直接将so库放到libs中,并按照上面文章中MainActivity中的调用方法使用。 1、build.gradle(app)配置 2、加载so库中方法         在Sudio中方法名虽然显示红色,但不影响使用。 3、

    2024年02月09日
    浏览(44)
  • Android studio打包生成jar包文件

    将应用模块application转换成库模块library后生成jar包 1、首先打开build.gradle文件,注意这里是module目录下的,在这个文件我们需要做两个操作: 将com.android.application改成com.android.library 注释掉applicationId 2、打开清单文件AndroidManifest.xml 首先将application配置的属性去掉 然后再去掉

    2024年02月01日
    浏览(40)
  • Android Studio 创建项目不自动生成BuildConfig文件

    今天在AS上新建项目发现找不到BuildConfig文件,怎么clear都不行。通过多方面查找发现原来gradle版本不同造成的,Gradle 8.0默认不生成 BuildConfig 文件。 如上图,8.0版本是没有source文件夹 上图是低于8.0版本有source文件夹 针对这个问题,有两种解决办法        方法一:降低Gr

    2024年01月22日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包