从原理上解决 uniapp (含第三方插件)打包 iOS APP 失败的问题

news2024/9/23 1:38:06

最近一段时间,我的团队基于uniapp开发的平台型APP因平台资金合规的要求,需要对接中金支付,uniapp的插件市场有一个别人做好的中金支付插件,但前端开发同事在引用这个 插件时,出现了 iOS APP 打包不成功的情况,开发花了几天时间也没有解决问题,就上升到我这边处理了。

由于我们的 APP大小已经超过 40MB,每次云打包都要收10元打包费用,让前端开发通过砍代码的方式,写了一个 小于 40MB 可以复现问题的 demo APP,这样我就可能通过多次打包一次一次调整并接近问题的核心。

这个demo APP是使用了 APP分享到微信的功能 和 一个中金支付的插件,也正是这 2 个功能触发了本次的问题。

第一次打包失败,看下面问题的现像,明显就是 Undefined symbols,一看就知道是 链接阶段,链接器找不到库,相关的 symbols自然就链接失败了。

cd [PackagePath]
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -Xlinker -reproducible -target arm64-apple-ios12.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.2.sdk -Os -L[PackagePath]/build/EagerLinkingTBDs/Release-iphoneos -L[PackagePath]/build/Release-iphoneos -L[SourcePath]/libs/UniSDK/Base -L[SourcePath]/libs/UniSDK -L[PackagePath]/utsFrameworks -L[SourcePath]/libs/Universal/DCUniAdWm.xcframework/ios-arm64/ -L[PackagePath]/wgtRoot/__UNI__0278D71/nativeplugins/cpcn-cpcnpay/ios/ -L[SourcePath]/libs/Universal -F[PackagePath]/build/EagerLinkingTBDs/Release-iphoneos -F[PackagePath]/build/Release-iphoneos -F[SourcePath]/libs/UniSDK/Base -F[SourcePath]/libs/UniSDK -F[PackagePath]/utsFrameworks -F[SourcePath]/libs/Universal/DCUniAdWm.xcframework/ios-arm64/ -F[PackagePath]/wgtRoot/__UNI__0278D71/nativeplugins/cpcn-cpcnpay/ios/ -F[SourcePath]/libs/Universal -F[SourcePath]/libs/UniSDK/Base -F[SourcePath]/libs/UniSDK -F[PackagePath]/utsFrameworks -F[SourcePath]/libs/Universal/DCUniAdWm.xcframework/ios-arm64/ -F[PackagePath]/wgtRoot/__UNI__0278D71/nativeplugins/cpcn-cpcnpay/ios/ -F[SourcePath]/libs/Universal -filelist [PackagePath]/build/HBuilder.build/Release-iphoneos/HBuilder.build/Objects-normal/arm64/HBuilder.LinkFileList -Xlinker -rpath -Xlinker @executable_path/Frameworks -dead_strip -Xlinker -object_path_lto -Xlinker [PackagePath]/build/HBuilder.build/Release-iphoneos/HBuilder.build/Objects-normal/arm64/HBuilder_lto.o -fobjc-arc -fobjc-link-runtime -ObjC -ld64 -weak_framework SwiftUI -llibAdSupport -llibLoader -llibAccelerometer -lopencore-amrnb -lmp3lame -llibMedia -llibCache -llibLog -llibIO -llibPGInvocation -llibNativeObj -llibNativeUI -llibNavigator -llibPGProximity -llibStorage -llibUI -llibXHR -llibZip -llibShare -lweixinShare -lWeChatSDK -weak_framework AdSupport -weak_framework AppTrackingTransparency -weak_framework Accelerate -weak_framework AudioToolbox -weak_framework AVFoundation -weak_framework CFNetwork -weak_framework CoreFoundation -weak_framework CoreGraphics -weak_framework CoreMedia -weak_framework CoreTelephony -weak_framework CoreText -weak_framework CoreVideo -weak_framework Foundation -weak_framework ImageIO -weak_framework JavaScriptCore -weak_framework MobileCoreServices -weak_framework MediaPlayer -weak_framework QuartzCore -weak_framework QuickLook -weak_framework Security -weak_framework SystemConfiguration -weak_framework UIKit -weak_framework WebKit -lc++ -lz -lxml2 -lsqlite3 -weak_framework MetalKit -weak_framework GLKit -licucore -liconv -weak_framework DCUniAdWm -weak_framework CoreMotion -weak_framework CPCNWeixinPaySDK -weak_framework CPCNPayUniPlugin -weak_framework CPCNAlipaySDK -weak_framework AlipaySDK -weak_framework DCUniBase -Xlinker -no_adhoc_codesign -Xlinker -dependency_info -Xlinker [PackagePath]/build/HBuilder.build/Release-iphoneos/HBuilder.build/Objects-normal/arm64/HBuilder_dependency_info.dat -o [PackagePath]/build/Release-iphoneos/HBuilder.app/HBuilder
ld: warning: -ld64 is deprecated, use -ld_classic instead
ld: warning: arm64 function not 4-byte aligned: _dc_ffi_call_SYSV from [SourcePath]/libs/UniSDK/liblibPGInvocation.a(sysv_arm64.o)
ld: warning: arm64 function not 4-byte aligned: _ffi_closure_SYSV from [SourcePath]/libs/UniSDK/liblibPGInvocation.a(sysv_arm64.o)
Undefined symbols for architecture arm64:
\"_OBJC_CLASS_$_PayReq\", referenced from:
objc-class-ref in CPCNWeixinPaySDK(CPCNWeixinPay.o)
\"_OBJC_CLASS_$_PayResp\", referenced from:
objc-class-ref in CPCNPayUniPlugin(CPCNPayPluginProxy.o)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)


以下是排查过程的记录汇总:
通过观察插件目录发现有一个 ios-exclude.txt。搜索后了解到 ios-exclude.txt 文件正是用于在 uniapp 云端打包时控制 链接器不链接哪些库的。打开 ios-exclude.txt 看到他 排除了 libWeChatSDK_pay.a 这个库。
前面的报错说 找不到 _OBJC_CLASS_$_PayReq 的定义,直觉判断 这个定义应该在 libWeChatSDK_pay.a 这个库中。使用 llvm-nm 命令证实了我的判断。下一步是 清空 ios-exclude.txt 再打一次包。


这一次仍然打包不成功,但看到的错误如下:
duplicate symbol '_OBJC_IVAR_$_WechatAuthSDK._status' in:
[SourcePath]/libs/Universal/libWeChatSDK.a(WechatAuthSDK.o)
[PackagePath]/wgtRoot/__UNI__0278D71/nativeplugins/cpcn-cpcnpay/ios//libWeChatSDK_pay.a(WechatAuthSDK.o)

意思是,引入了 libWeChatSDK_pay.a后,链接器发现了一些 symbol 重复定义在 2 个库中,如 libWeChatSDK.a、libWeChatSDK_pay.a,观察发现这 2 个库的区别就是 带不带 _pay。现在看来插件的作者是 ios-exclude.txt 中排除 libWeChatSDK_pay.a 这个库一定是有他自己的考虑。

百度搜索 libWeChatSDK.a、libWeChatSDK_pay.a的区别,得到的信息如下:

(1)libWeChatSDK_pay.a 为带支付功能的微信SDK,支持微信分享、微信支付及微信授权登录功能,直接导入libWeChatSDK_pay.a即可,忽略libWeChatSDK.a,不要两个同时导入。
(2)libWeChatSDK.a 为不带支付功能的SDK,仅支持微信分享和授权登录(不要导入此SDK)

意思是 这 2 个 库 除开 支付相关的函数symbol外,其它的功能/函数/symbol 是一样的。


再来能过 vimdiff 看一下 前后 2 次错误的对比,可以看到 第二次 错误是 云端打包时 clang 同时链接了 -lWeChatSDK -lWeChatSDK_pay 这 2 个库,当然会出现 一些 symbol 重复了。


到了这里,解决问题的思路已经清晰了:
1)uniapp 官方一定是 解决了 -lWeChatSDK -lWeChatSDK_pay 这 2 个库 同时引用时应该 改为 只引用 -lWeChatSDK_pay的问题,不然它们都推不出 uniapp这个产品

2)我们只能触发云端打包,不能直接决定云端 clang 的命令行参数,对于这个问题我们手上只有 2 个工具:
2.1 插件目录中的 ios-exclude.txt 文件
2.2 1)中提到的 官方方案。

这时出现了一个小插曲,后面再说。

通过如下组合 2.1、2.2 这 2 个工具成功解决了问题。

原来 HBuilderX 只勾选了"Share(分享)",云端打包时 clang 会使用 -lWeChatSDK 链接这个库。现在 HBuilderX 再勾选了"Payment(支付)" 云端打包时 clang 会使用 lWeChatSDK_pay 链接这个库。
同时引入这 2 个库会出现  duplicate symbol 符号重复的问题,但上面的 1)中已经猜到了 uniapp 官方一定是 解决了-lWeChatSDK -lWeChatSDK_pay 这 2 个库 同时引用时应该 改为 只引用 -lWeChatSDK_pay,不然它们都推不出 uniapp这个产品。

所以这次解决问题的思路是找到问题的核心,再利用 官方的工具/方式/组合 去解决问题。

-----------------------------------------------------------------

说一下前面的小插曲,文章记录的只是打包 2 次就发现了问题的核心,但实际上我是多点击了几次打包,应该打包了 10次,然后 uniapp的提示时今天免费打包的次数太多,明天再能再次使用免费打包,或者可以选择10元打包一次。当天正好也是晚上 21:00 之后了,就下班回家了,但内心中有一种莫名的高兴,笃定了问题的解决方案就是 : HBuilderX 再勾选了"Payment(支付)" ,利用 官方的工具/方式/组合 去解决问题,坚信明天上班后第一次打包就能解决问题。

对自己知识和方法的确定,是工作中快乐的来源。

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

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

相关文章

通付盾Web3专题 | SharkTeam:Web3常见钓鱼方式分析与安全防范建议

引言 Web3钓鱼是一种针对Web3用户的常见攻击手段,通过各种方式窃取用户的授权、签名,或诱导用户进行误操作,目的是盗窃用户钱包中的加密资产。 近年来,Web3钓鱼事件不断出现,且发展出钓鱼即服务的黑色产业链&#xf…

python+pymysql对数据库进行增、删、改、查操作

一、概述 接口测试中,应用到数据库操作的场景: 1.校验测试数据 接口发送请求后明确会对数据库中的某个字段进行修改(编辑,更新、删除操作),但,响应结果中无该字段数据时。 例如:删…

QML-1- qml简介及项目创建

文章目录 1. QML 简介2. 项目创建3. 目录结构4. CMakeLists.txt 简单介绍5. 运行demo 1. QML 简介 根据官网介绍,qml 为qt一个模块,使用Qml语言开发应用程序和库提供了一个框架。它定义并实现了语言和引擎基础结构,并提供了一个API&#xff…

搭建属于自己的 Git 仓库:GitLab

搭建属于自己的 Git 仓库:使用 GitLab 文章目录 搭建属于自己的 Git 仓库:使用 GitLab什么是 GitLab?准备工作安装 Docker使用Docker Compose 快速构建GitLab1、从docker compose快速搭建GitLab2、部署到服务器并访问3、浏览器访问 在现代软件…

Linux-挂盘-分区-卸盘

Linux-挂盘-分区-卸盘 1. 添加硬盘 2. 查看硬盘 [rootlocalhost /]# lsblk # 查看我们新添加的磁盘 NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sda 8:0 0 80G 0 disk ├─sda1 8:1 0 1G 0 part /boot └─sda2 …

基于JT/T808、JT/T1078、苏标、粤标视频主动安全监控

1.概述 如下图是以实时视频点播与部标机产生了主动安全报警,各个服务之间的交互流程说明。 整个系统有以下几个核心组件组成: 1:系统业务端:车载监控业务系统,给用户提供车载监控整套业务流程与界面呈现;…

蓝海项目揭秘:跨境选品师的崛起与挑战

随着全球化贸易的日益深入和电子商务的蓬勃发展,跨境选品师这一新兴职业逐渐走进人们的视野。跨境选品师,顾名思义,就是专门负责为跨境电商平台挑选和推荐适合海外市场的商品的专业人士。那么,跨境选品师这一职业能否被视为一个蓝…

【算法】排序

排序算法在信息学非常常用。Hello&#xff01;大家好&#xff0c;我是学霸小羊&#xff0c;今天讲几个排序算法。 1.“打擂台”排序 思路&#xff1a;a[ i ]和a[ j ]打擂台&#xff08;i<j&#xff09;。 这个方法简单易懂&#xff0c;只需要看看需不需要交换。按从大到小…

行为设计模式之策略模式

文章目录 概述原理结构图 代码实现小结 概述 策略模式(strategy pattern)的原始定义是&#xff1a;定义一系列算法&#xff0c;将每一个算法封装起来&#xff0c;并使它们可以相互替换。策略模式让算法可以独立于使用它的客户端而变化。 在软件开发中也会遇到相似的情况&…

考研数学|强化跟「张宇」还是「武忠祥」?看这一篇!

考研数学强化阶段是备考过程中非常关键的一环&#xff0c;它不仅要求学生巩固和深化基础知识&#xff0c;还要求学生能够灵活运用所学知识解决复杂问题。 在选择张宇老师或武忠祥老师的高数强化课时&#xff0c;你可以考虑以下几个方面。 首先每位学生都有自己独特的学习风格…

问题记录_stm32“No target connected“

问题描述&#xff1a; 基于HAL库和stm32cubeMX生成的代码&#xff0c;烧录时出现如下报错窗口&#xff1a; 问题原因&#xff1a; stm32cubeMX生成代码时关闭了SWJ调试功能 解决方法&#xff1a; 在项目中找到__HAL_AFIO_REMAP_SWJ_DISABLE();并注释掉 然后短按复位键的…

通用代码生成器应用场景二,快速原型

通用代码生成器应用场景二&#xff0c;快速原型 对项目经理&#xff0c;产品经理和售前工程师而言&#xff0c;开发快速原型是一种常见的需求。使用通用代码生成器&#xff0c;您可以更好&#xff0c;更快的开发系统的快速原型。通用代码生成器对完成CRUD和登录系统阶段的快速…

新手必看!TikTok视频0播放的5大原因及解决方法

很多刚起步的TikTok卖家常会遇到一个烦心事&#xff1a;发布的视频播放量少得可怜&#xff0c;甚至有时是0播放。这确实让人挺沮丧的。到底如何突破TikTok视频总是播放量为0的瓶颈&#xff1f;别担心&#xff0c;今天为大家总结了tiktok视频播放量上不去的5种原因和相应的解决方…

【leetcode2028. 找出缺失的观测数据(自己写出来了)】

给你一个长度为 m 的整数数组 rolls &#xff0c;其中 rolls[i] 是第 i 次观测的值。同时给你两个整数 mean 和 n 。返回一个长度为 n 的数组&#xff0c;包含所有缺失的观测数据&#xff0c;且满足这 n m 次投掷的 平均值 是 mean 。如果存在多组符合要求的答案&#xff0c;只…

山东大学软件学院项目实训-创新实训-基于大模型的旅游平台(二十一)- 微服务(1)

微服务 1.认识微服务 SpringCloud底层是依赖于SpringBoot的&#xff0c;并且有版本的兼容关系&#xff0c;如下&#xff1a; 2. 服务拆分 需求 &#xff1a; 把订单信息和用户信息一起返回 从订单模块向用户模块发起远程调用 &#xff0c; 把查到的结果一起返回 步骤 &…

ubuntu切换CUDA版本

查询版本 cd /usr/local在此目录下进行 ls 命令可以查看自己安装了哪些版本 使用stat cuda命令可以查看当前软连接(符号)为哪个版本&#xff0c;即使用的是哪个版本 若要修改使用的CUDA&#xff0c;只需要删除此软连接&#xff0c;再创建一个新的软连接&#xff0c;指向自己…

最新!!2024年上半年软考【中级】网络工程师 综合知识真题解析

2024上半年软考考试已经结束了&#xff0c;为大家整理了网友回忆版的网络工程师真题及答案&#xff0c;总共41道题。 上半年考试的宝子们可以对答案预估分数&#xff01;准备下半年考的宝子可以提前把握考试知识点和出题方向&#xff0c;说不定会遇到相同考点的题目&#xff01…

python九九乘法表的打印思考及实现

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、问题引入 九九乘法表的显示需求 二、问题分析 嵌套循环的概念 屏幕宽度与换行的考虑…

【NumPy】关于numpy.multiply()函数,看这一篇文章就够了

&#x1f9d1; 博主简介&#xff1a;阿里巴巴嵌入式技术专家&#xff0c;深耕嵌入式人工智能领域&#xff0c;具备多年的嵌入式硬件产品研发管理经验。 &#x1f4d2; 博客介绍&#xff1a;分享嵌入式开发领域的相关知识、经验、思考和感悟&#xff0c;欢迎关注。提供嵌入式方向…

艾体宝干货 | 用于故障排除的最佳 Wireshark 过滤器

在网络故障排除过程中&#xff0c;Wireshark是一款非常强大的工具&#xff0c;它可以用来分析网络数据包并解决各种问题。本文将介绍一些好用的Wireshark过滤器&#xff0c;以便更有效地进行故障排除。 分析网络行为和排除网络故障就像用漏斗过滤渣滓。因此&#xff0c;网络协…