ios – 在构建时更改子例程名称以避免Xcode中的冲突

背景

我正在构建一个iOS应用程序(我将从这里调用MyApp),它将依赖于几个独立的静态库(我称之为Lib1,Lib2,Lib3,…)的计算.每个库都在其自己的项目中构建,然后导入到单个工作区(因此工作区将包含MyApp,Lib1,…).有关如何设置的详细信息here.这些库由其他独立于MyApp的产品使用,因此我希望尽可能减少库中的任何更改.这些库也是用(普通)C编写的,因此没有头文件.

某些函数名称由多个库使用(因此Lib1和Lib2都可能都有DoStuff方法).具有相同名称的函数通常做同样的事情,但是有一些细节关于如何在库之间做出不同的事情,因此Lib1上的DoStuff中的实际代码可能与Lib2上的DoStuff中的代码完全不同.编写一个在每个库中完全相同的通用DoStuff是非常困难的.

问题

在应用程序运行时,它没有从正确的库中调用正确的DoStuff.我发现了这一点,因为在调试会话期间调用了错误的函数(由于DoStuff函数的细微差别,最终导致应用程序崩溃).

我在寻找什么

每个库只有一个来自MyApp的入口点,每个入口点都是唯一命名的.如果从Lib1的入口点方法(或者Lib1上的任何其他方法)调用DoStuff,那么我希望它在Lib1上调用DoStuff方法.实现这一目标的最佳方法是什么?

有没有办法(可能通过XCode中的某个设置)我可以这样做,以便每个库都是它自己的命名空间?这将是我解决问题的首选方法.我想我可以通过重命名重复的函数,使它们都是唯一的(所以Lib1上的DoStuff方法可以重命名为Lib1DoStuff,或类似的东西),但有数百个函数可能有重复的名称,我们是将要向项目中添加数百个库,因此必须手动重命名所有函数并修复所有调用它们需要花费大量时间,而我的老板并不认为这是一个可行的选择.

UPDATE

在查看Josh Caswell的评论以及他提供的一些链接之后,看起来可能在编译库时自动重命名所有函数,这将是尝试修复上述问题的最佳方法.从我所看到的,在评论中的几个链接中提到的objcopy不支持iOS.我最终遇到了this博客文章,其中讨论了为Xcode目标创建自定义构建规则,以及this博客,其中讨论了自定义构建设置和构建阶段.

我是否正确地假设我可以在构建过程中的某个时刻使用脚本自动附加到我的每个库中的所有函数的名称,而不是像我在WHAT I’的最后一段中所描述的那样手动执行. M寻找以上部分?如果是这样,那么构建过程的正确部分是进行这些更改的?最后,做这样的事情的语法是什么样的?在构建过程的不同部分中使用的“脚本”当然看起来不像Obj-C.我之前从未使用过这些“剧本”,所以我完全不知道如何使用它们,这就是我正在寻求帮助的地方.

我试着尽可能地清楚,但如果对我要问的问题有任何疑问,请告诉我.

解决方法

为什么xcode没有调用正确的库函数?

假设我提到了3个C库.假设它有以下代码.

库1 – test1lib.a,代码:

#include <stdio.h>

void doStuff()
{
  printf("\nDoing stuff for lib1\n");
}

void uniqueEntryPoint1()
{
  printf("\nUnique entry point for lib1\n");
  doStuff();
}

库2 – test2lib.a,代码:

#include <stdio.h>

void doStuff()
{
  printf("\nDoing stuff for lib2\n");
}

void uniqueEntryPoint2()
{
  printf("\nUnique entry point for lib2\n");
  doStuff();
}

库3 – test3lib.a,代码:

#include <stdio.h>

void doStuff()
{
  printf("\nDoing stuff for lib3\n");
}

void uniqueEntryPoint3()
{
  printf("\nUnique entry point for lib3\n");
  doStuff();
}

这里每个库都有一个独特的函数和一个常用函数doStuff()

当我们将这3个库添加到xcode并链接它们时. xcode链接但不加载所有对象文件.让我们说客观的C代码是这样的:

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view,typically from a nib.
    uniqueEntryPoint1();

}

输出是

Unique entry point for lib1

Doing stuff for lib1

在这种情况下,xcode将仅加载被引用的符号(库1对象).

如果您阅读了链接器标志/选项,例如-all_load,-force_load和-objC,您将更好地理解.

如果我们添加-all_load链接器选项,它将强制链接器加载库的所有对象,因此我们将在xcode中获得以下错误

ld: 2 duplicate symbols for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

这是因为链接器检测到多次重新定义doStuff()而失败的原因.

解决此问题的唯一方法是更改​​链接器输入,即这3个库中存在的符号. Josh在评论中已经提到过这一点.我要加0.02美元.

可能的解决方案

解决方案1:

最好的解决方案(自解释)是在有权访问源代码的情况下更改源代码.

解决方案2:

使用objcopy重命名或添加函数前缀,如How to deal with symbol collisions between statically linked libraries?的答案中所提供

现在你怀疑如何找到objcopy.

选项1:
你可以使用这个项目https://github.com/RodAtDISA/llvm-objcopy.这将与llvm一起构建时很难编译.您必须按照http://llvm.org/docs/GettingStarted.htmlhttp://llvm.org/docs/CMake.html的说明进行操作.

如果重写https://github.com/RodAtDISA/llvm-objcopy/blob/master/llvm-objcopy.cpp,则可以重用解析和对象重写逻辑,而不依赖于llvm.

选项2:

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;a=blob;f=binutils/objcopy.c;h=2636ab4bcb34cf1e1e54db9933018a805b366727;hb=HEAD编译并重用binutils objcopy

解决方案3:

您可以按照理查德在此链接Rewriting symbols in static iOS libraries中提供的答案进行操作.这更像是一个黑客,但如果使用十六进制编辑器,您可以重写符号,如果它们的长度保持不变.如果您有更多符号及其大型库,则可以考虑使用https://sourceforge.net/projects/bbe-/和nm编写脚本.

所有这一切都是相当大的努力,但显然没有捷径.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


在有效期内的苹果开发者账号(类型为个人或者公司账号)。还有一种情况,就是你的Apple ID被添加到公司开发者账号团队里面,这样也是可以的,但是需要叫管理员给你开通相应的账号权限,如下截图:这里可能有些同学会问,苹果开发者账号是什么?如何申请?那么可以看看我的上一篇文章:iOS苹果开发者账号(公司账号)申请流程详解能正常编译打包的iOS工程项目(都不能正常编译谈何出包上架
Appuploader官网--IOS ipa上传发布工具,证书制作工具跨平台版,windows,linux,mac系统都可用 (applicationloader.net)第一步:注册苹果开发者账号,访问以下网址,按照提示注册即可,因为不需要支付688认证苹果开发者,所以没什么好讲的。证书部分:主要是通过工具生成.p12证书文件,后面这个证书要导入mac系统。描述文件:这个文件主要包含了证书,公钥,设备信息等,具体可以百度了解详情。第三步:使用xcode打包导出ipa文件,供其他人内测。..........
苹果在9月13号凌晨(北京时间)发布 iOS 16,该系统的设备可能会因为各种原因,导致功能不可用和UI错乱等问题,我们需要做好适配iOS 16。
计算机图形学--OpenGL递归实现光线追踪
Xcode 14打出来的包在低版本系统运行时会崩溃,报错信息是Library not loaded: /usr/lib/swift/libswiftCoreGraphics.dylib,在苹果开发者论坛搜索报错信息,可以看到会闪退的最高版本是iOS12.1(不敢肯定,毕竟我没测过,不过肯定低于iOS 12.4
iOS16手机开启开发者模式 "developer mode disable"Pod工程中的Bundle target签名报错
【计算机图形学】【实验报告】DDA画线算法、Bresenham中点画线算法、多边形填充算法(附代码)
iOS 16 满载全新的个性化功能、更具深度的智能技术,以及更多无缝的沟通与共享方式,让 iPhone 的体验更进一步。13、隐私权限增强,如通过 UIDevice 获取设备名称时,无法获取用户的信息,只能获取设备对应的名称。
3、回到苹果开发者中心,如下图,点击certificates,点蓝色小加号,就可以开始创建证书,创建证书的时候无论测试还是上传app store打包,都要选ios distribution app store and adhoc,不要选apple和develpment类型的证书。2、如下图,点左边的profiles菜单,点击蓝色加号,创建描述文件,创建过程中会要求我们选择描述文件的类型,假如你想发布app到app store,则选择app store,假如你想真机测试,则选择ad hoc类型。
需要:Unity,IOS平台模块,Xcode,IOS_SDk,MAC电脑,Iphone手机
最近下载安装 xcode 并解压安装,遇到一些问题误以为是错误,记录在此。从百度和谷歌上搜了很多帖子,发现并没有靠谱的 xcode 国内的镜像,这里提供一个可以跳转到官网的下载方式。xcode 不同版本的列表,下载时注意不同 macOs 不同的系统和 Xcode 版本的对应关系。如 要求 及其以上版本。https://xcodereleases.com/注意点击后会跳到官方下载地址,需要登录苹果账号。xcode 文件很大,通常要 10G 以上,下载速度很慢。可以考虑使用 Free Downlo
使用苹果登录作为第三方登录
missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun解决方法
Xcode14 正式版编译报错' does not contain bitcode.You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. file 'xxx' for architecture arm64解决方案
那应该和升级Xcode 14有关系。但是官方还没有给出解决方案。应该后续会有兼容的cocoapods 新版本。
项目中需要用到Xcode将C++代码输出的Mac版本的DLL文件即DYLIB文件,并能够使用C#代码调用。Unity与 DLL文件 ☀️| 怎样使用VC++生成一个DLL文件并调用!这次来看一下在Mac使用Xcode生成的方法吧!本文介绍了在Mac中怎样使用 Xcode项目使用C++生成 .dylib文件的方法。相对于在Windows中使用AndroidStudio创建动态链接库的方法来说,使用Xcode创建.dylib文件确实简单了很多。