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

最近一段时间,我的团队基于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.mzph.cn/bicheng/14119.shtml

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

相关文章

Pantera 合伙人简谈 Morpho:更高效、适应性更强的 DeFi 解决方案

原文标题:《Pioneering Peer-to-Peer Lending in the DeFi Revolution》撰文:Pantera Capital 合伙人 Paul Veradittakit编译:Chris,Techub News 文章来源:香港Web3媒体Techub News Morpho 正在超越 Compound 等传统…

Redis主从、哨兵、cluster集群的部署和细节

目录 1. 主从模式 为什么需要主从? 搭建主从架构 2. Sentinel(哨兵)模式 为什么需要哨兵模式? 搭建哨兵集群 哨兵集群 Go语言编程redis哨兵模式 有了哨兵,客户端连接谁? test1:redis节点主从切换 test2&am…

webgl入门-矩阵变换

矩阵变换 前言 变换有三种状态:平移、旋转、缩放。 当我们变换一个图形时,实际上就是在移动这个图形的所有顶点。 课堂目标 掌握图形变换的三种方式。可以对图像进行复合变换。 知识点 平移旋转缩放 第一章 平移 对图形的平移就是对图形所有顶点…

如何快速从手动测试转向自动化测试

寻求具有无缝持续集成和持续交付 (CI/CD) 的高效 DevOps 管道比以往任何时候都更加重要。想象一下这样一个场景:您的软件组织显著减少了人工工作量、降低了成本,并更加自信地发布了软件更新。换句话说,通过将 Web UI 和 API 测试结合在一起&a…

【小白课程】如何在openKylin上个性化定制开关机动画

开关机动画是Linux系统的重要组成部分,其主要功能是在Linux内核启动的早期遮盖内核打印日志,并在内核刷新屏幕分辨率时保证屏幕显示的流畅性。 其中,openKylin操作系统使用plymouth组件作为开关机动画显示程序。Linux系统在启动时&#xff0…

计算机SCI期刊,中科院2区,收稿范围非常广泛!

一、期刊名称 Journal of Web Semantics 二、期刊简介概况 期刊类型:SCI 学科领域:计算机科学 影响因子:2.5 中科院分区:2区 出版方式:开放出版 版面费:$1600 三、期刊征稿范围 《网络语义学杂志》…

【软件测试】5.测试用例

目录 1.测试用例 1.1概念 1.2测试的要素 2.测试用例的万能公式 2.1常规思考逆向思维发散性思维 2.2万能公式 2.2.1功能测试 2.2.2界面测试 2.2.3性能测试 2.2.4兼容性测试 2.2.5易用性测试 2.2.6安全测试 2.3弱网测试 1.测试用例 1.1概念 什么是测试用例&#xf…

Jenkins 构建 Web 项目:构建服务器和部署服务器分离的情况

构建命令 #!/bin/bash node -v pnpm -v pnpm install pnpm build:prod # 将dist打包成dist.zip zip -r dist.zip dist

软件项目运维方案-word原件2024

1. 文档介绍 1.1 文档目的 1.2 文档范围 1.3 读者对象 1.4 参考文献 1.5 术语与缩写解释 2. 人员与责任 2.1 项目建设管理机构 2.2 驻场人员工作时间 2.3 人员培训 2.3.1. 培训需求管理 2.3.2. 培训内容管理 2.4 绩效考核 3. 运维过程内容 3.1. 运维模型 3.2. P…

LangChain - 概念指南

文章目录 一、Architecture1、langchain-core2、partner-packages3、langchain4、langchain-community5、langgraph6、langserve7、langsmith 二、浪链表达语言(LCEL )可运行界面 runnable-interface 三、组件 components1、聊天模型 chat-models2、 LLM…

工程机械租赁平台数字化平台系统油耗与排放管理创新与应用

在快速发展的城市建设和基础设施项目中,工程机械扮演着举足轻重的角色。随着工程规模的扩大和施工技术的不断进步,工程机械租赁平台应运而生,为建设项目提供了灵活高效的解决方案。然而,随着租赁机械数量的增加,如何有…

【GO基础】GO基础语法一

GO基础语法一 一、编写第一个Go程序1、基本程序结构2、应用程序入口3、退出返回值4、获取命令行参数 二、变量,常量以及与其他语言的差异1、编写测试程序2、实现Fibonacci数列3、变量赋值4、常量定义 三、数据类型1、类型转化2、类型的预定义值3、指针类型 四、运算…

微信小程序仿胖东来轮播和背景效果(有效果图)

效果图 .wxml <view class"swiper-index" style"--width--:{{windowWidth}}px;"><image src"{{swiperList[(cardCur bgIndex -1?swiperList.length - 1:cardCur bgIndex > swiperList.length -1?0:cardCur bgIndex)]}}" clas…

【四数之和】python,排序+双指针

四层循环&#xff1f;&#xff08;doge) 和【三数之和】题目很类似 class Solution:def fourSum(self, nums: List[int], target: int) -> List[List[int]]:nums.sort()#a,b,c,d四个数&#xff0c;先固定两个数&#xff0c;那就是双指针问题了&#xff0c;令ba1&#xff…

关于搜索引擎链路

一、搜索引擎的的链路 简单流程如下&#xff0c;一般都包括query理解&#xff0c;召回&#xff0c;粗排&#xff0c;精排&#xff0c;重排。 二、query理解&#xff0c;查询词处理 对于进来的query需要有很多道工序做处理。才能让搜索引擎的效果更好、更智能。 2.1 分词 分词…

Ubuntu18.04 OpenSSH升级

升级前版本&#xff1a; rootecs-m2eqyb:/opt# ll total 20912 drwxr-xr-x 2 root root 4096 May 10 16:23 ./ drwxr-xr-x 24 root root 4096 May 10 14:38 ../ -rw-r--r-- 1 root root 1848766 May 10 16:23 openssh-9.7p1.tar.gz -rw-r--r-- 1 root root 18038…

离散数学--图论

目录 1.简单概念 2.握手定理 3.点割集 4.边割集 5.点连通度和边连通度 6.Dijstra算法&&最短路径 7.有向图的连通性 8.图的矩阵表示 9.欧拉图问题 10.哈密尔顿图 1.简单概念 &#xff08;1&#xff09;这个里面的完全图比较重要&#xff0c;完全图是例如k3,k5这…

JMETER工具:以录制手机app为例

JMETER工具&#xff1a;以录制手机app为例子 JMETER安装和环境配置 pc需要安装jdk&#xff0c;并进行jdk的环境配置&#xff0c;安装好jdk并配置好后&#xff0c;通过命令行输入java –version出现以下界面就表示安装成功&#xff1a; &#xff08;对应的jdk版本不可太低&…

selenium环境安装和web自动化基础

webUI自动化背景 因为web页面经常会变化&#xff0c;所以UI自动化测试的维护成本很高。不如接口的适用面广&#xff0c;所以大部分公司会做接口自动化测试&#xff0c;但是未必会做UI自动化测试&#xff1b; UI自动化测试要做也是覆盖冒烟测试&#xff0c;不会到很高的覆盖率&a…

Flink常见面试题总结

文章目录 1. 简单介绍一下Flink2. Flink 的运行必须依赖Hadoop组件吗?3. Flink 和 Spark Streaming 的区别&#xff1f;4. Flink集群角色5. Flink核心概念5.1 并行度5.2 算子链&#xff08;Operator Chain&#xff09;5.3 任务槽&#xff08;Task Slots&#xff09;5.4 任务槽…