Android编译Skia库

news2024/11/23 18:54:40

Android编译Skia库

本文档提供两种方法编译Skia库

  1. 使用aosp源码进行编译
  2. 使用skia源码进行编译

两种编译方法都可以编译,并且都可以使用在多个平台中,且可以使用在不同Android版本中

使用aosp源码编译

第一步是拿到aosp的源码.因为写这篇教程,使用的是msm8996的源码,因此,我就直接使用了.

注意:如果是app开发人员,可能无法拿到跟我一样的源码,则可以使用aosp源码.下面是aosp源码下载教程:
https://source.android.com/docs/setup/download/downloading
大部分情况下,可能无法下载,此时可以使用清华镜像站:https://mirrors.tuna.tsinghua.edu.cn/help/AOSP/

拿到aosp之后,切换到一个比较熟悉的版本中,可以切换到跟我一样的Android 奥利奥版本

第二步进入项目根目录,运行:

. build/envsetup.sh
lunch xxx-debug
mmma external/skia

第三步拷贝out/target/product/xxx/system/lib/libskia.so 和 out/target/product/xxx/system/lib64/libskia.so到app中.

第四步修改对应的错误.

  1. 运行在Android 7.1 应该没啥问题
  2. 运行在Android 7.1 以上,会出现xxx.so库未找到的问题.出现这种问题,是因为libskia.so中会加载部分系统内部的so库.现提供两种修改办法
第一种 如果属于定制rom,则可以修改rom的情况下,可以将需要暴露的so库,放入public.libraries.txt文件中

第二种 如果无法修改rom,那么只能将对应的so静态编译进libskia.so中.具体方法如下:
1. 打开external/skia/Android.bp,找到shared_libs和static_libs.将shared_libs中的文件,一个一个添加到static_libs中
2. 举个例子如下:将libdng_sdk移动到static_libs中,然后,重新运行mmma external/skia
3. 部分动态库,无法移植到static_libs的解决办法:
    a. 如libicui18n放入到static_libs之后,编译会出错,大概错误如下:error: external/skia/Android.bp:3:1: dependency "libicui18n" of "libskia" missing variant:
    b. 上面错误的原因是,libicui18n并没有静态库
    c. 接下来就是,编译libicui18n的静态库
    d. 对应步骤如下
    e. 找到libicui18n的编译文件配置文件.使用find . -name "*.mk" -exec grep -rinH --color=auto "LOCAL_MODULE.*libicui18n" {} \;
    f. 本机结果如下:
./out/soong/Android-mini_emulator_x86_64.mk:79473:LOCAL_MODULE := libicui18n
./out/soong/Android-mini_emulator_x86_64.mk:79488:LOCAL_MODULE_STEM := libicui18n
./out/soong/Android-mini_emulator_x86_64.mk:79493:LOCAL_MODULE := libicui18n
./out/soong/Android-mini_emulator_x86_64.mk:79508:LOCAL_MODULE_STEM := libicui18n
./out/soong/Android-mini_emulator_x86_64.mk:79513:LOCAL_MODULE := libicui18n
./out/soong/Android-mini_emulator_x86_64.mk:79528:LOCAL_MODULE_STEM := libicui18n-host
./out/soong/Android-mini_emulator_x86_64.mk:79533:LOCAL_MODULE := libicui18n
./out/soong/Android-mini_emulator_x86_64.mk:79548:LOCAL_MODULE_STEM := libicui18n-host
./out/soong/Android-FindPiano.mk:79034:LOCAL_MODULE := libicui18n
./out/soong/Android-FindPiano.mk:79049:LOCAL_MODULE_STEM := libicui18n
./out/soong/Android-FindPiano.mk:79054:LOCAL_MODULE := libicui18n
./out/soong/Android-FindPiano.mk:79069:LOCAL_MODULE_STEM := libicui18n
./out/soong/Android-FindPiano.mk:79074:LOCAL_MODULE := libicui18n
./out/soong/Android-FindPiano.mk:79089:LOCAL_MODULE_STEM := libicui18n-host
./out/soong/Android-FindPiano.mk:79094:LOCAL_MODULE := libicui18n
./out/soong/Android-FindPiano.mk:79109:LOCAL_MODULE_STEM := libicui18n-host

   g. 打开./out/soong/Android-FindPiano.mk并定位到79034行.可以看到libicui18n的位置为:external/icu/icu4c/source/i18n
   h. 打开对应的编译配置文件,Android.bp或者Android.mk
   i. 添加对应的静态库编译配置,如下
diff --git a/external/icu/icu4c/source/i18n/Android.bp b/external/icu/icu4c/source/i18n/Android.bp
index ef84d97..4c46b16 100644
--- a/external/icu/icu4c/source/i18n/Android.bp
+++ b/external/icu/icu4c/source/i18n/Android.bp
@@ -251,3 +251,16 @@ cc_library_shared {
         "-lpthread",
     ],
 }
+
+cc_library_static {
+    name: "libicui18n_s",
+    vendor_available: true,
+    defaults: ["libicui18n_defaults"],
+    host_supported: true,
+    unique_host_soname: true,
+    shared_libs: ["libicuuc"],
+    host_ldlibs: [
+        "-lm",
+        "-lpthread",
+    ],
+}

  j. 注意,上面已经将静态库的名字改变,将libicui18n改成了libicui18n_s.因此在libskia的静态库中,应该写成libicui18n_s而不是libicui18n
  k. 经过一些列修改之后,skia的编译配置文件,变成如下
     shared_libs: [
         "libEGL",
         "libGLESv2",
-        "libdng_sdk",
-        "libexpat",
-        "libft2",
-        "libheif",
-        "libicui18n",
-        "libicuuc",
-        "libjpeg",
-        "liblog",
-        "libpiex",
-        "libpng",
         "libvulkan",
-        "libz",
-        "libcutils",
-        "libnativewindow",
+        "libnativewindow",  
     ],
     static_libs: [
         "libarect",
         "libsfntly",
         "libwebp-decode",
         "libwebp-encode",
+        "libdng_sdk",
+           "libjpeg",
+           "libpng",
+           "libcutils",
+           "libexpat",
+           "libz",
+           "liblog",
+        "libft2_s",
+        "libpiex_s",
+        "libbinary_parse",
+        "libimage_type_recognition",
+        "libtiff_directory",
+        "libicui18n_s",
+        "libicuuc_s",
+        "libicuuc_stubdata",
     ],
     qti_whole_static_libs: [
         "libqc-skia",
     ],
 }

   l. 从上面的文件可以看到,增加一些以前不存在的库,如libbinary_parse这是因为在编译libpiex时会用到,读者可以在piex的编译配置文件中,找到libbinary_parse的依赖关系
   m. 上述文件中的shared_libs中依然有四个库,并没有编译成静态库,是因为,留下来的四个库:libEGL,libGLESv2,libvulkan,libz属于标准ndk,可以直接加载,而不会出现,诸如:libandroid_runtime.so not found的错误
   n. 使用mmma external/skia再次编译,得到libskia.so.放入APP中,成功运行.

使用skia源码进行编译

第一步, 进入官网下载源码.源码位置
https://github.com/google/skia

第二步,切换到你想要编译的分支上,比如,这次我目标安卓版本是Android 8.1所以我切到了android/o-release分支

第三步,下载NDK,NDK有不同的版本,因此,要下载对应的版本,怎么查找对应的NDK版本呢? 根据时间.Android 8.1 释放的时间在2017年12月左右,因此NDK版本,差不多也在这个附近.

翻看NDK如下:

在这里插入图片描述

可以看到NDK版本应该是r16b.如果不行再试试上下版本的NDK

第四步,开始编译

1. 第一步产生编译文件:bin/gn out/arm64 --args='ndk="ndk路径" target_cpu="arm64"'
2. 在--args中还可以使用的参数有:is_debug表示是否是debug编译 is_component_build表示生成静态库还是动态库.
3. 开始编译  sudo ninja -C out/arm64 -j 8 -v
4. 下面给出本机的运行命令
skia$ bin/gn gen out/arm64 --args='ndk="/media/wanbiao/disk1t/root/SDK/android-ndk-r18b" target_cpu="arm64" is_component_build=true is_debug=false'
skia$ sudo ninja -C out/arm64 -j 8 -v
5. 如果出现部分头文件缺失,则运行tools/install_dependencies.sh 安装相对应的依赖
6. 如要生成32位的库,则将上面命令中的64取掉即可
7. 如果出现编译不通过,大概率是因为NDK的版本不对,我在本机测试过从13到24这几个版本的NDK,都无法正确的编译,只有r16b可以正确编译.
8. 如果将对应的库,放入Android studio的工程之中,进行编译,报出了诸如:__end,__start之类的错误,是因为libskia.so使用的是r16b,而Android studio的工程使用的更高版本的NDK,解决办法就是:在编译libskia.so时,手动指定ld程序.例子如下:
skia$ bin/gn gen out/arm64 --args='ndk="/media/wanbiao/disk1t/root/SDK/android-ndk-r16b" target_cpu="arm64" is_component_build=true is_debug=false extra_ldflags=["-fuse-ld=gold"]'
可以看见,在最后,加入了extra_ldflags参数.
9. 再次重新编译,生成相应的动/静态库

第五步,因为本笔记,写于skia编译之后很久,部分错误处理,可能会忘记,因此,我将本次编译的关于skia的源码,一并上传.


发现CSDN无法上传大于1000MB的文件,因此将其传入百度网盘.
链接: https://pan.baidu.com/s/1ISZ62Pead577zWNbPWcSyg 提取码: 8888 复制这段内容后打开百度网盘手机App,操作更方便哦

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/158330.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Armitage图形化前端

开源免费图形前端 ● 作者自称是众多不会使用metasploit的安全专家之一(命令行) ● MSF基于命令行,缺少直观的GUI图形用户接口 Armitage只是调用MSF的漏洞利用能力 ● Armitage的每一个GUI操作都可以对应MSF中的一条命令 红队团队合作模拟…

OSCP vulhub LORD OF THE ROOT: 1.0.1

vulhub LORD OF THE ROOT: 1.0.1靶场信息&安装Description一、信息收集第一种ssh爆破第二种猜二、漏洞探测三、漏洞利用四、提权第二种方法:udf提权第三种缓冲区溢出提权靶场信息&安装 地址:https://www.vulnhub.com/entry/lord-of-the-root-10…

APSIM练习:向管理组件添加额外规则

“标准”作物管理组件没有提供很多选项来决定何时播种作物——很可能应该考虑一系列额外的种植规则(例如,土壤是否足够干燥以驱动拖拉机过去?),并且在播种时应采取额外措施(例如添加一些肥料)。…

Tofu目标识别跟踪模块介绍

1.简介Tofu3 是多波段视频物体识别跟踪模块,支持可见光视频与红外视频的输入,支持激光补光变焦自适应控制,支持视频下的多类型物体检测、识别、跟踪等功能。产品支持视频编码、设备管理、目标检测、深度学习识别、跟踪等功能,提供…

服务器防勒索病毒场景分析经验分享

服务器防勒索病毒 l 场景描述 互联网飞速发展,各企业均搭建了自己的服务器。包括文件服务器、代码服务器、业务系统服务器、数据库服务器等。目前大多数企业使用的服务器系统以Windows Server和Linux(Centos)居多,但随着国产操作…

python从入门到实践————图形界面(上)

系列文章目录 文章目录系列文章目录前言窗体组件窗体显示显示窗体文本显示项目实践总结前言 图形用户接口(Graphical User Interface,GUI)是人机交互的重要技术手段,在Python中利用tkinter模块就可以方便地实现图形界面。 在你p…

每日一题:Leetcode203 移除链表元素

文章目录 系列:链表专练 语言:java & go 题目来源:Leetcode203 移除链表元素 难度:简单 考点:头结点 && 虚拟头结点 思路和参考答案文章目录题目描述思路java参考代码go参考代码:题目描述 给…

xcelium——重要特性——提高编译仿真性能

以下图片来自于CadenceTECHTALK研讨会 解决编译仿真的瓶颈问题,提高整体性能 影响performance的因素 xcelium版本access rwccoverage收集snapshot过大,加载时间过长,可通过Zlib加快加快snapshot加载 编译/仿真添加选项: -new…

如何检查自己电脑是否被攻击了?

数据来源 本文仅用于信息安全的学习,请遵守相关法律法规,严禁用于非法途径。若观众因此作出任何危害网络安全的行为,后果自负,与本人无关。 通过系统命令排查账户安全 query user # 查看当前登录账户 lo…

21.字符串的概念,字符串的可修改性

字符串和指针 字符串的概念: 字符串就是以 ‘\0’ 结尾的若干字符的集合。字符串的地址,是第一个字符的地址。可以定义一个字符指针变量保存字符串的地址。比如: char* shelloworld"; 字符串的存储形式:数组、文字常量区、…

靶机测试haclabs-no_name

靶机地址https://www.vulnhub.com/entry/haclabs-no_name,429/靶机测试nmap扫描└─$ nmap -T5 -A 192.168.1.100 -oA hl-portsStarting Nmap 7.92 ( https://nmap.org ) at 2023-01-12 11:16 CST Nmap scan report for 192.168.1.100 Host is up (0.00040s latency). Not show…

获工信部认可!腾讯牵头的《零信任系统技术规范》入选工信部百项团标应用示范

近日,工信部发布《关于公布2022年团体标准应用示范项目的通告》,由腾讯安全牵头起草,公安部第三研究所、国家计算机网络应急技术处理协调中心、中国移动设计院等业内16家零信任厂商、测评机构及用户联合编制的中国第一部《零信任系统技术规范…

Webpack搭建本地服务器

1、开启本地服务器 1.1、为什么要搭建本地服务器? 目前我们开发的代码,为了运行需要有两个操作: 操作一:npm run build,编译相关的代码;操作二:通过live server或者直接通过浏览器&#xff0…

【ROS】—— 机器人系统仿真 —URDF语法 (十三)

文章目录前言1. 概述1.1 概念1.2 作用1.3 相关组件1.3.1 URDF1.3.2 RViz1.3.3 gazebo1.4 准备2. URDF集成Rviz基本流程2.1 创建功能包,导入依赖2.2 编写 URDF 文件2.3 在 launch 文件中集成 URDF 与 Rviz3. URDF语法详解3.1 robot3.2 link3.3 joint3.4 URDF练习3.5 …

Lock锁原理解析【Android进阶】

Lock锁原理解析【Android进阶】 Lock简介 Lock接口位于J.U.C下locks包内,其定义了Lock应该具备的方法。 Lock 方法签名: void lock():获取锁(不死不休,拿不到就一直等)boolean tryLock():获…

13.0、Linux-安装Tomcat、以及防火墙常用命令

13.0、Linux-安装Tomcat、以及防火墙常用命令 防火墙常用命令在本文最下方-> 安装 Tomcat -> 第一步:进入官网下载 Tomcat8 -> Apache Tomcat - Apache Tomcat 8 Software Downloads 第二步:将下载好的文件 通过 Xshell 和 Xftp 工具上传到 L…

前端面试题——React重点

文章目录React相关问题1. 函数式组件与Class组件有什么不同?2. 说说React的fiber架构?3. 协调4. 虚拟DOM (Virtual DOM)React相关问题 1. 函数式组件与Class组件有什么不同? 答: ① 函数式组件不需要继承,直接 “fun…

YUV 文件读取、显示、缩放、裁剪等操作教程

系列文章目录 文章目录系列文章目录前言一、Chroma subsampling二、读取 YUV 文件2.1 准备工作2.2 Planar 模式2.2.1 YUV420P 格式读取2.2.2 YUV422P 格式读取2.2.3 NV21 格式读取2.2.4 NV12 格式读取2.2.5 小结2.3 Packed 模式2.3.1 YUYV 格式读取2.3.2 小结三、SDL 显示 YUV …

自动化测试是什么?为什么要做自动化测试?

自动化测试是什么?相信对软件测试有一定了解的朋友都不会感到陌生。自动化测试正如字面上理解得那样,是一种自动完成测试工作的测试方式。虽然是说的自动化,但是也是需要测试员手动编写代码去完成测试工作。那么,为什么要做自动化…

【链表】leetcode19.删除链表的倒数第N个节点(C/C++/Java/Js)

leetcode19.删除链表的倒数第N个节点1 题目2 思路3 代码3.1 C版本3.2 C版本3.3 Java版本3.4 JavaScript版本4 总结1 题目 题源链接 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 示例 1: 输入:head [1,2…