cmake使用独立工具链交叉编译可在android中运行的so包

2023-05-16

cmake使用独立工具链交叉编译可在android中运行的so包

在在命令行下用CMake交叉编译可在android中运行的so包一文中说了一下使用NDK自带的工具链来编译so包,当时讲到还有另一种方法来编译so包,即使用独立工具链来编译,现在就来讲一讲这种方式。主要包含以下两个步骤:

  • 编译独立工具链
  • 使用独立工具链编译so包

一、编译独立工具链

编译独立工具链是利用$NDK/tools下的 make-standalone-toolchain.sh 脚本来生成独立的交叉编译工具链,先用 –help 参数来看一下具体用法,我的ndk位置放在/home/hm/android_ndk_r15c

参数不多,有几个还是不再使用的,主要的只有以下几个:

  • –toolchain=<name> 指定toolchain,在 $NDK/toolchains 目录下可以看到所有支持的编译链工具,根据目标cpu架构进行选择。

  • –arch=<name> 指定目标cpu架构
  • –platform=<name> 指定android平台,默认是[android-14]

好,现在来指定一下这几个参数,

  • –toolchain=arm-linux-androideabi-4.9
  • –arch=arm
  • –platform=android-15

然后运行这个脚本,稍等片刻就能看到如下的结果:

接下来我们根据输出的提示进入/tmp/ndk-hm目录下看看有些什么东西

嗯,只有一个压缩包和一个tmp目录,显然tmp目录是个临时目录,可以删除它,然后解压arm-linux-androideabi.tar.bz2,解压出来是这样子的:

这样独立工具链就编译好了,接下来看看怎么使用它。

二、编译so包

新建一个jni工程,目录如下:

内容都非常简单,其中JTest.java文件的内容如下,就一个带native修饰的方法:

package com.jni;

public class JTest{
    public native String getStringFromC();
}

CTest.c文件的内容如下,它是根据JTest.java文件的头文件来编写的,实现了JTest.java中的native方法,打印了一句日志,返回了一个字符串:

 /* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include <android/log.h>
/* Header for class com_jni_JTest */
#ifndef _Included_com_jni_JTest
#define _Included_com_jni_JTest
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_jni_JTest
 * Method:    getStringFromC
 * Signature: ()Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_com_jni_JTest_getStringFromC
  (JNIEnv * env, jobject obj){
__android_log_print(ANDROID_LOG_DEBUG,"CTest.c","Hello World C!\n");
    return (*env)->NewStringUTF(env, "I am from CTest.c");
    }
#ifdef __cplusplus
}
#endif
#endif

CMakeLists.txt中的内容就是重点了,这里面指定了刚刚编译好的独立工具链,内容如下:

cmake_minimum_required(VERSION 3.4.1)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")

# Android 5.0 以上需要在此处设置 PIE
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fPIE -pie")

# 配置使用 NDK Standalone Toolchain 编译
set(NDK_STANDALONE_TOOLCHAIN /tmp/ndk-hm/arm-linux-androideabi)
set(CMAKE_SYSTEM_NAME Android)
set(CMAKE_SYSTEM_VERSION 21)
set(CMAKE_C_COMPILER ${NDK_STANDALONE_TOOLCHAIN}/bin/clang)
set(CMAKE_CXX_COMPILER ${NDK_STANDALONE_TOOLCHAIN}/bin/clang++)
set(CMAKE_FIND_ROOT_PATH ${NDK_STANDALONE_TOOLCHAIN})

# 使用 NDK 提供的头文件
add_definitions("--sysroot=${NDK_STANDALONE_TOOLCHAIN}/sysroot")

add_library(myso SHARED CTest.c)

set_target_properties(myso
                      PROPERTIES
                      LIBRARY_OUTPUT_DIRECTORY
                      "${CMAKE_CURRENT_SOURCE_DIR}/lib")

include_directories(/home/hm/JDK/jdk1.8.0_151/include /home/hm/JDK/jdk1.8.0_151/include/linux)

target_link_libraries(myso
                     log)

进入build目录,执行一下:

~/cmake_sample/cross_for_android/build$ cmake ../c/

~/cmake_sample/cross_for_android/build$ make

进入c/lib目录看一下结果:

嗯,so包已经出来了,接下来建个工程验证一下,看看这个so包能不能用。


三、验证

跟之前一样,建个测试工程,将编译好的so包及JTest.java文件拷到工程中,具体步骤就不多说了,很简单,最后建好的工程目录如下:

在MainActivity.java中调用native方法:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String str = new JTest().getStringFromC();
        System.out.println(str);
        ((TextView)findViewById(R.id.tvHello)).setText(str);
    }
}

跑一下工程,看看有没有输出日志:

没问题,返回值没错,在CTest.c中输出的日志也打出来了,说明这个so包是可用的。

最后,上源码:

demo源码:https://github.com/MingHuang1024/CrossCompileForAndroid

测试工程的源码就不上了,需要的可以联系我。



由于水平有限,如果文中存在错误之处,请大家批评指正,欢迎大家一起来分享、探讨!

博客:http://blog.csdn.net/MingHuang2017

GitHub:https://github.com/MingHuang1024

Email:MingHuang1024@foxmail.com

微信:724360018

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

cmake使用独立工具链交叉编译可在android中运行的so包 的相关文章

随机推荐

  • Usart 串口发送数据包 两种方式(遍历结构体,指针数组)

    Usart 串口发送数据包 两种方式 xff08 结构体 xff0c 指针数组 xff09 1 结构体指针 1 1 结构体和联合体 叙述 xff1a 这种直观性比较 xff0c 利用联合体和结构体的形式组成数据包 xff0c 通过结构体指针
  • netfilter 讲解 ,讲的很好

    Netfilter为多种网络协议 xff08 IPv4 IPv6 ARP等 xff09 各提供了一套钩子函数 在IPv4中定义了5个钩子函数 xff0c 这些钩子函数在数据包流经协议栈的5个关键点被调用 这就像有5个钓鱼台 xff0c 在每
  • python字典添加元素和删除元素

    1 添加字典元素 方法一 xff1a 直接添加 xff0c 给定键值对 pycharm aa 61 39 人才 39 60 39 英语 39 39 english 39 39 adress 39 39 here 39 print aa 39
  • Verilog中奇偶校验位的计算方法

    偶校验 xff1a 数据和校验位中1的总数为偶数 xff0c 则认为数据无误 xff0c 否则标识数据有误 xff1b 奇校验 xff1a 数据和校验位中1的总数为奇数 xff0c 则认为数据无误 xff0c 否则标识数据有误 xff1b
  • Ubuntu下进行Socket编程

    龙云尧个人博客 xff0c 转载请注明出处 CSDN地址 xff1a http blog csdn net Michael753951 article details 72553287 个人blog地址 xff1a http yaoyl c
  • add_library,target_link_libraries,set_target_properties,target_link_libraries使用联系

    折腾了半下午 xff0c 终于知道这个货是怎么个关系了 在此写下记录 xff0c 希望遇到同样问题的同学 xff0c 不要再次浪费时间了 首先我是在Linux环境下 先列出我的CmakeLists txt 注意 xff0c 在CmakeLi
  • strpbrk

    头文件 xff1a include lt include h gt strpbrk 函数检索两个字符串中首个相同字符的位置 xff0c 其原型为 xff1a char strpbrk char s1 char s2 参数说明 s1 s2要检
  • Ubuntu中在命令行如何打开图形界面的文件夹、文件、网页等

    方法一 xff08 nautilus open terminal 打开文件夹 xff09 xff1a 安装nautilus open terminal span class token function sudo span span cla
  • 3.4迭代器介绍

    文章目录 使用迭代器迭代器运算符将迭代器从一个元素移动到另外一个元素迭代器类型begin和end运算符结合解引用和成员访问操作某些对vector对象的操作会使迭代器失效 迭代器运算迭代器的算术运算使用迭代器运算 我们已经知道可以使用下标运算
  • CAN报文格式简析

    Date xff1a 2022 5 11 Author xff1a MJQ Meta xff1a CAN CAN基础篇 CAN报文格式简析 1 Motornala和Intel格式 建议直接看图 xff0c 小白也能秒懂 xff01 注 xf
  • 【C++】头文件声明变量总结

    类外变量 span class token comment 1 直接声明定义 span span class token comment 如果被多个 cpp 包含 xff0c 则链接报错 multiple definition span s
  • C语言 如何用http post方式 上传json数据

    What C语言 如何用post方式 上传json数据 Piont C语言Socket实现HTTP协议 xff0c json格式数据组包 1 xff0c C语言Socket实现HTTP POST 43 json格式数据 按照HTTP协议发送
  • UDP组播调试(使用TCP&UDP调试工具)

    如何使用调试工具进行UDP组播调试 一 下载UDP amp TCP调试工具 二 双击打开调试工具并建立端口 2 1 创建组播客户端1 类型 xff1a UDP xff08 组播模式 xff09 xff1b 目标IP xff1a 225 0
  • python字典遍历的几种方法

    xff08 1 xff09 遍历key值 gt gt gt a 39 a 39 39 1 39 39 b 39 39 2 39 39 c 39 39 3 39 gt gt gt for key in a print key 43 39 39
  • 基于寄存器与基于固件库的stm32差异

    一 简介 STM32标准外设库之前的版本也称固件函数库或简称固件库 xff0c 是一个固件函数包 xff0c 它由程序 数据结构和宏组成 xff0c 包括了微控制器所有外设的性能特征 寄存器是中央处理器内的组成部分 寄存器是有限存贮容量的高
  • Ublox F9P通过NTRIP实现实时RTK定位

    现在开一个新坑 xff0c 后面慢慢填 2022 07 23更新 xff1a 测试视频 NTRIP ROS测试 一 前言 首先 xff0c 什么RTK呀 NTRIP呀 xff0c RTKLIB呀 xff0c 我都还是新手不是很懂 xff0c
  • 接口测试工具--Postman安装

    想用汉化版的Postman xff0c 需要有两样东西 xff1a 一是英文版安装包 xff1b 一是汉化包 xff1b 需注意的是中 英文版本号必须一致 xff0c 才可以 但是官网的汉化包 xff0c 现在还没更新到最新版本 xff0c
  • 05c语言——宏定义、带参宏、带参宏函数

    提示 xff1a 文章写完后 xff0c 目录可以自动生成 xff0c 如何生成可参考右边的帮助文档 文章目录 一 宏定义1 使用规则2 注意 二 带参宏1 定义2 注意 三 带参函数1 带参函数的宏与带参宏的区别2 带参宏函数和普通函数区
  • Makefile 和 CMake 入门

    Makefile Reference Makefile 20分钟入门 xff0c 简简单单 xff0c 展示如何使用Makefile管理和编译C 43 43 代码 简介 Makefile 是一个用于构建 xff08 Build xff09
  • cmake使用独立工具链交叉编译可在android中运行的so包

    cmake使用独立工具链交叉编译可在android中运行的so包 在在命令行下用CMake交叉编译可在android中运行的so包一文中说了一下使用NDK自带的工具链来编译so包 xff0c 当时讲到还有另一种方法来编译so包 xff0c