xcode 的app工程与ffmpeg 4.4版本的静态库联调,ffmpeg内下的断点无法暂停。

news2024/12/23 13:09:17

        先阐述一下我的业务场景,我有一个iOS的app sdk项目,下面简称 A ,以及运行 A 的 app 项目,简称 A demo 。

        引用关系为 A demo 引用了 A ,而 A 引用了 ffmpeg 的静态库(.a文件)。此时业务出现了 bug ,测试后得知,bug 来自于ffmpeg。现在无法定位ffmpeg的问题出在哪里,需要在程序运行时,断点停在ffmpeg的源码中。而直接拉入ffmpeg是无法下断点的,断点无效(就是代码行数上那个虚线边框中心透明的图标)。经过各种方式研究,现在做出总结。

        代码是公司的,github就不放出来了

        其实对于静态库的源码断点调试可以有三种方式:

        一、如果工程中有可执行文件,可以直接调试源码,例如ffmpeg的ffmpeg_g可执行文件,缺点是与项目脱离,无法从iOS项目中直接进入(也可能是我没找到方法,反正我是没成功)。无法暂停项目的调试真的很难排查问题在哪。本文不讨论该方法

        二、make生成有符号表的静态库文件,项目A引用该文件,并将静态库源码直接拉入工程。通过xcode断点调试。该方法可行,但是不知道ffmpeg为什么不可以,通过nm命令查看符号表,也都正常。但就是不行。然后我选择了第三种方式

        三、直接源码调试,就是新建xcode 的静态库工程,然后生成静态库后由A引用,并在A工程中拉入ffmpeg的源码,利用xcode设置断点。实测可以,缺点就是编译ffmpeg时候会有很多奇怪的问题,需要一一解决。我最后采用的就是这种方式。

   针对第三种方法,这种其实在逻辑上是最简单的,首先需要新建一个xcode工程,因为是我的是iOS项目,所以我选的是 static library。把ffmpeg的文件夹拉入工程,然后清空compile sources 后面会告诉你哪些需要拖入这个地方,这个工程编译成功后就是.a静态库。然后在build configuration中设置为debug 。别忘了在header search中配置好路径,不然会找不到文件,这里很简单,我就不赘述了,不会的可以去百度。

         因为ffmpeg是有多个静态库的,建议一个target对应一个静态库,方便管理和编译,后面往项目A里也只需要拉动ffmpeg的哪个.xcodeproj 文件就行了。也很方便。最后弄好的工程界面应该是这样

那么ffmpeg那么多文件,哪些文件是需要编译的,这才是本文的重点。通常从ffmpeg官方库中下载的源代码,会有一个可执行文件configure,该文件的主要作用是生成一个可以用来make编译ffmpeg的config.h文件,这个config才是最重要的,它里面写了你所需要的配置需要编译哪些文件。他长这样

其实就是一堆宏定义。那么光看他怎么知道哪些文件是需要的还是不够的,你还需要看对应静态库源码文件夹内的makefile文件,因为ffmpeg是通过make编译,而make就是通过config和makefile文件结合来排查那些文件编译的,你需要把make编了哪些文件找到。举个例子,比如我现在想编译libavutil.a这个库,那么你就需要打开libavutil的目录下的makefile文件。见下图

  

 这就很明显了,headers 后面的所有.h文件就是编译静态库后那个Headers文件夹里所有头文件,那么就要把对应的文件拖入这里

 这样就会在生成静态库时生成header文件夹了

        对于.c文件的编译要在ffmpeg的makefile中找 objs 这个变量里有哪些文件,这里每个.o就是对应.c文件编译过来的,可以假装.o就是.c。

        那你会注意到,后面还有很多这样的代码,

 这里就是和config联动的地方,我红色框出来的内容,实际上就是config的宏定义,在config中对应的是0或者1,如果是1,那么该行后面的出现的文件名就是要编译的,如果是0,那么就是不需要的。将上面所有需要的.c文件都拖入到这里,注意,别拖错target了

好有就是,根据不同的平台要拖入对应的平台文件,我是iOS项目,也就是arm64,要把汇编文件拖进去,也就是.s文件,其他的该目录下的.c一般不需要。

 此时就可以 command + b 编译了。但是会有很多报错,我说一下我遇见的

        如果下图报错,那么说明你把不该编译的编译进来了,例如这个tx_template.c,去掉就可以了,注意,不是删除文件啊,文件还在,只是不编译了。 

 

 如果类似出现No matching function for call to 'av_pix_fmt_desc_get' 就是缺少头文件,查一下av_pix_fmt_desc_get 函数在哪个.h文件里,一般都是internal.h 在上面添加#include""就行了,如果已经添加了还是报错,那就说明没编译,要把有av_pix_fmt_desc_get 对应的.c文件放入complie sources里。

对于编译其他库时候,也会需要用到libavutil的internal.h,加入把这个写进去就行了#include "libavutil/internal.h",注意head search目录,得让他找得到

对于libavformat,如果你引用了openssl 或者srt,那么你还得添加依赖到link binary中并在library search配置好目录就行了。

对于avutil 源码编译时,ffmpeg有自己的time.h 和time.c文件,xcode会有可能出现于系统库里的time.c和time.h冲突,导致报错,例如 struct tm 、clock()、nanosleep无法找到,但是头文件#include <time.h>明明添加了,这就说明冲突了,给ffmpeg 的time.c和time.h改名就行了。

如果编译成功了,那么恭喜你,完成了一大半。现在你可以在A中引入生成的静态库了,然后编译A,如果报错 Undefined symbol: _av_gettime 说明 av_gettime这函数、变量或者宏定义没找到,你在ffmpeg中找到这个函数所在的.c文件,然后拖到complie sources里,重新编译就行了

上诉问题解决了,大概率就能用了,这时A工程的workspace中拖入ffmpeg的.xcodeproj文件,然后在对应的位置设置断点就可以直接使用了。

从iOS Ademo 启动,断点停在ffmpeg源码如下图

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

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

相关文章

线程、进程和管程

一、线程 1.1 定义 线程&#xff1a;线程是进程中的实体&#xff0c;一个进程可以拥有多个线程&#xff0c;一个线程必须有一个父进程。线程有时被称为轻量级进程&#xff0c;是程序执行流的最小单元。 线程的组成部分&#xff1a; 1. 线程ID&#xff1a;线程标识符 2. 当前…

【python】python求解矩阵的转置(详细讲解)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

Linux服务器安装JDK20

一、下载安装包 访问官网&#xff0c;找到JDK20&#xff0c;复制下载链接 我复制的链接是&#xff1a;JDK20 二、Linux服务器操作 1.服务器根目录下创建一个新的文件夹 cd /mkdir jdkscd /jdks2.将下载好的jdk-20上传到jdks下 3.解压缩 tar -zxvf jdk-20_linux-x64_bin.tar…

ClickHouse目录结构

默认安装路径&#xff1a;/var/lib/clickhouse/ 目录结构&#xff1a; 主要介绍metadata和data metadata 其中的default、system及相应的数据库&#xff0c;.sql文件即数据库创建相关sql语句 进入default数据库&#xff08;默认数据库&#xff09;&#xff1a; 可以看到数据库…

Java电子招投标采购系统源码-适合于招标代理、政府采购、企业采购、等业务的企业 tbms

&#xfeff;功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&…

明星广告代言指南:遵循行业规范保持诚信

明星广告代言是一种常见的市场营销策略&#xff0c;通过邀请知名明星为品牌或产品代言&#xff0c;以增加品牌曝光和销售额。媒介拥有的3000多位一二线明星的合作资源&#xff0c;包括演员、歌手、主持人等各种类型的明星&#xff0c;可以为企业提供签售会、产品发布会、品牌推…

手写一个锁其实也很easy

懵逼的状态&#xff1a; 面试中经常被问到&#xff0c;如何手写一个锁&#xff0c;很多时候一脸懵逼&#xff0c;不知所措&#xff0c;多少年前深有体会&#xff0c;然而回过头来细细分析&#xff0c;只需使用AtomicReference类 即可以轻松搞定。首先咱们先来了解一下Atomi…

6.s081/6.1810(Fall 2022)Lab2: System calls

文章目录 前言其他篇章参考链接0. 前置准备1. System call tracing (moderate)简单分析Hint 1Hint 2Hint 3Hint 4Hint 5测试 2. Sysinfo (moderate)声明实现框架用户态与内核态交互计算空闲内存的大小计算非UNUSED进程的数量 测试 3. 总测试 前言 这个lab主要介绍了用户态到内…

【Java】Map<String,Object>中解析Object类型数据为数组格式(94)

背景&#xff1a; 前端&#xff1a;入参为字符串和数组类型&#xff1b;通过json字符串传给后台&#xff0c; 后台&#xff1a;后台通过工具解析为Map<String&#xff0c;Object>&#xff0c;然后需要解析出Map里面的数组值做操作&#xff1b; 需求&#xff1a; 入参&…

Vue源码学习 - 模版编译 和 组件渲染/更新过程

目录 前言一、什么是 模板编译&#xff1f;二、模板编译 到 render 函数字符串的流程三、深入模板编译源码baseCompile ()parse() - 解析阶段optimize() - 优化阶段generate() - 生成阶段&#xff08;1&#xff09;了解 render函数字符串 和 with 语法&#xff08;2&#xff09…

PHP手术麻醉信息系统的功能作用

手术麻醉信息系统源码 手术麻醉信息系统的使用&#xff0c;很大程度上方便了麻醉科医生的日常工作&#xff0c;使麻醉工作流程更规范&#xff0c;为麻醉医生工作提供了一个新平台。下面简述一下该系统在日常麻醉工作中的作用。 (一) 及时合理地安排手术 麻醉信息系统与医院现…

初识C++:类与对象

前言&#xff08;类的引入&#xff09; C语言结构体中只能定义变量&#xff0c;在C中&#xff0c;结构体内不仅可以定义变量&#xff0c;也可以定义函数。比如&#xff1a; 之前在C语言中&#xff0c;用C语言方式实现的栈&#xff0c;结构体中只能定义变量&#xff1b;现在以C方…

【第一阶段】编译时常量

1.编译时常量只能是常用的基本数据类型 String Double Int Float Long Short Byte Char Boolean 2.const用于定义编译时常量类似final,如果我们用在局部变量中将会报错&#xff0c;代码示例 fun main() {//使用const修饰为常量,编译时常量只能是常用的基本数据类型 String Dou…

学习C语言第三天 :分支语句(if - else if - else)

1.C语言语句结构 C语言是结构化的程序设计语言&#xff0c;这里的结构指的是顺序结构、选择结构、循环结构&#xff0c;C语言是能够实现这三种结构的&#xff0c;其实我们如果仔细分析&#xff0c;我们日常所见的事情都可以拆分为这三种结构或者这三种结构的组合。 我们可以使用…

python爬虫 获取简单的get请求

打印结果&#xff1a; 原博主写的很厉害额&#xff0c;写的比较全面&#xff0c;大家可以去学习看看 参考原文&#xff1a; Python调用get或post请求外部接口_python调用post接口_纯洁的小魔鬼的博客-CSDN博客

封装动态SQL的插件

最近根据公司的业务需要封装了一个简单的动态SQL的插件&#xff0c;要求是允许用户在页面添加SQL的where条件&#xff0c;然后开发者只需要给某个接口写查询对应的表&#xff0c;参数全部由插件进行拼接完成。下面是最终实现&#xff1a; 开发人员只需要在接口写上下面的查询SQ…

从零构建深度学习推理框架-3 手写算子relu

Relu介绍&#xff1a; relu是一个非线性激活函数&#xff0c;可以避免梯度消失&#xff0c;过拟合等情况。我们一般将thresh设为0。 operator类&#xff1a; #ifndef KUIPER_COURSE_INCLUDE_OPS_OP_HPP_ #define KUIPER_COURSE_INCLUDE_OPS_OP_HPP_ namespace kuiper_infer {…

websocket服务端大报文发送连接自动断开分析

概述 当前springboot版本&#xff1a;2.7.4 使用依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-websocket</artifactId> </dependency>现象概述&#xff1a; 客户端和服务端已经有心跳…

拿捏--->杨辉三角

文章目录 题目描述算法思路代码示例精简版优化版 题目描述 在屏幕上面打印杨辉三角。 算法思路 杨辉三角&#xff0c;是二项式系数在三角形中的一种几何排列。在欧洲&#xff0c;这个表叫做帕斯卡三角形。帕斯卡&#xff08;1623----1662&#xff09;是在1654年发现这一规律…

《金融数据保护治理白皮书》发布(137页)

温馨提示&#xff1a;文末附完整PDF下载链接 导读 目前业界已出台数据保护方面的治理模型&#xff0c;但围绕金融数据保护治理的实践指导等尚不成熟&#xff0c;本课题围绕数据保护治理的金融实践、发展现状&#xff0c;探索和标准化相关能力要求&#xff0c;归纳总结相关建…