dyld: Library not loaded: @rpath/xxx.framework 动态库

目录

错误分析

@rpath

知识点:动态库 vs 静态库。

解决方法

一:在xcode界面中进行设置

 二:使用py脚本进行设置 

其中 add_EmbeedFrames 函数的实现:

其中dstSubfolderSpec=10意思是Frameworks

Xcode工程文件project.pbxproj小结 

三:使用C#进行设置

知识点:@executable_path/Frameworks

命令行工具

otool

file


错误分析

上面的原因就是说:这个库没有被加载,哪个库呢,@rpath/xxx.framework 这个库。

首先看这个路径下这个库是否存在。

@rpath

@rpath是在xcode中设置的RunpathSearchPaths,这里可以设置多个路径,会依次查找(和Windows下的PATH变量差不多了):

所以先看自己的xcode的工程中有没有设置rpath

如果设置,看看这个路径下有没有需要的动态库,比如上面图中设置的是rpath=executable_path/Frameworks,就看看打出的app中点查看包内容里的Frameworks目录中有没有xxx动态库。如果没有需要在BuildPhases中进行设置拷贝进去:

(dyld: Library not loaded这个要加载说明这个是动态库,是需要拷贝到包里的,所以看看build BuildPhases中有没有添加这个库)


知识点:动态库 vs 静态库。

动态库就是动态链接的,是不会生成到可执行文件里面的。

所以如果说可执行文件app的包内容里面,包含了一个framework的,那么他肯定是一个动态库了。

静态库是生成到了包内容里面的那个可执行文件里面去了。


解决方法

一:在xcode界面中进行设置

1.第一步 添加 xxx.framework:

2. 第二步:


 二:使用py脚本进行设置 

把需要设置的 xxx.framework 配置到某个配置文件中

            <key>EmbedFrameworks</key>
            <array>
                <string>xxx</string>
            </array>

在py文件中读取这个配置文件进行处理

    。。。。。    
    elif current_config == 'EmbedFrameworks':
            ref_files = []
            for framwork_need_add in dic_channel_config[current_config]:
                tFiles = proj.get_files_by_name(framwork_need_add + '.framework')
                print 'Embed Frameworks:' + framwork_need_add + '.framework' 
                for f in tFiles:
                    ref_files.append(f)

            proj.add_EmbeedFrames(ref_files,'10',('CodeSignOnCopy', 'RemoveHeadersOnCopy'))
            proj.add_build_config('LD_RUNPATH_SEARCH_PATHS' , '$(inherited) @executable_path/Frameworks')
    。。。。。

其中 add_EmbeedFrames 函数的实现:

    def add_EmbeedFrames(self,refFiles,dstSubfolderSpec,attrs):
        result = []
        targets = self.get_build_phases('PBXNativeTarget') + self.get_build_phases('PBXAggregateTarget')
        if len(targets) != 0 :

            build_fileIds = []
            for file_ref in refFiles:
                build_file = PBXBuildFile.Create(file_ref)
                build_file.set_attributes(attrs)
                self.objects[build_file.id]=build_file
                build_fileIds.append(build_file.id)

            buildActionMask = '0'

            buildPhases = [g for g in self.objects.values() if g.get('isa') == 'PBXCopyFilesBuildPhase']   
                     
            for bp in buildPhases:
                buildActionMask = bp['buildActionMask']

            copy_Files_Build_Phase = PBXCopyFilesBuildPhase.Create("Embed Frameworks",build_fileIds,dstSubfolderSpec,buildActionMask)

            for t in targets:
                for buildPhase in t['buildPhases']:
                    if self.objects[buildPhase].get('isa') == 'PBXCopyFilesBuildPhase':
                        t['buildPhases'].add(copy_Files_Build_Phase.id)
                        self.objects[copy_Files_Build_Phase.id] = copy_Files_Build_Phase
                        result.append(copy_Files_Build_Phase)                        
            
        return result 

其中dstSubfolderSpec=10意思是Frameworks

 Anyone had success with Copy Files build phases in Xcode 4 templates - Stack Overflow

# dstSubfolderSpec property value used in a PBXCopyFilesBuildPhase object.
'BUILT_PRODUCTS_DIR': 16,  # Products Directory
 : 1,                      # Wrapper
 : 6,                      # Executables: 6
 : 7,                      # Resources
 : 15,                     # Java Resources
 : 10,                     # Frameworks
 : 11,                     # Shared Frameworks
 : 12,                     # Shared Support
 : 13,                     # PlugIns

Xcode工程文件project.pbxproj小结 

Xcode工程文件project.pbxproj小结 - 简书

blog.csdn.net/bobbob32/article/details/84648848

https://github.com/kronenthaler/mod-pbxproj

ps:

将脚本加入到xcode工程中某个文件中
group的添加(xcode中文件夹的概念就是组的概念)
https://github.com/kronenthaler/mod-pbxproj/wiki

获取最上层的Frameworks,然后一层一层的往下加

frameworks=proj.get_or_create_group('Frameworks')
plugins=proj.get_or_create_group('Plugins',parent=frameworks)
ios=proj.get_or_create_group('IOS',parent=plugins)
aaaasdk_ios=proj.get_or_create_group('AAAASDK_iOS',parent=ios)           
thirdpartyImport=proj.get_or_create_group('ThirdPartyImport',parent=aaaasdk_ios)
xxxxsdk=proj.get_or_create_group('XXXXSDK',parent=thirdpartyImport)
proj.add_file(current_project_path + '/Frameworks/Plugins/IOS/AAAASDK_iOS/ThirdPartyImport/XXXXSDK/' + framwork_need_add + '.framework', parent=xxxxsdk, tree='SOURCE_ROOT')


三:使用C#进行设置

如何在C#中设置xcode工程的设置
https://docs.unity3d.com/ScriptReference/iOS.Xcode.Extensions.PBXProjectExtensions.AddAppExtension.html


知识点:@executable_path/Frameworks

@executable_path 指的是可执行程序所在的路径 ,可执行程序就是可以运行的经过了编译链接以后生成的那个文件,直观的看的话windows下就是exe后缀的,linux下之前说过是.out或者没有后缀的。在动态库中基本上不使用这个path。

@loader_path 这个变量表示每一个被加载的 binary (包括App, dylib, framework,plugin等) 所在的目录。如果是应用程序的loader_path,则和@executable_path一样,如果是Framework或者plugin的,则和Framework或者plugin相关。

比如对于一个插件,这个插件需要加载依赖其他的动态库-A库,当加载这个插件的时候,loader_path就变成了这个插件所在的位置,而动态库设置的installpath如果设置的是相对于@loader_path来说的,那么无论这个插件在哪里都没有关系。但是如果这个动态库设置的是相对于@executable_path的话,插件的位置就只能固定了。

install name:开发动态库时候设置的一个值,推荐中rpath来设置install name ——mac上可执行文件加载动态库是依照动态库的install name(是一个路径)来查找动态库,找到加载,找不到报错,因为rpath可以设置多个值灵活。具体是在程序链接的时候install name 会被拷贝到应用程序中,当程序运行过程中需要动态链接器去加载libfoo.dylib的时候,动态链接器将会从应用程序中找到这个install Name,根据install name去查找这个库,找不到就报错。

   使用Xcode开发动态库及Framework时,需要为其设置Install path。在设置Install path时,可能会使用到以下几个路径:

  •     1)绝对路径:               绝对路径,通常用于设置固定目录下的Framework、动态库。
  •     2)@executable_path:执行路径,通常用于设置直接在Application中加载的FrameWork、动态库。
  •     3)@loader_path:        加载路径,通常用于设置需要在插件中加载的FrameWork、动态库。
  •     4)@rpath:                 运行路径,通常用于设置动态库的Install Name,需要同时在调用应用中设置好rpath。

设置成@rpath的好处:

比如 XPSSO.dylib 被两个 .app 使用, 且被包含的路径不同。比如:
softA.app/Contents/MacOS/dylib/XPSSO.dylib
softB.app/Contents/MacOS/Frameworks/XPSSO.dylib
将 XPSSO.dylib 的 INSTALL_PATH 设置成 @loader_path/../dylib 或 @loader_path/../Frameworks 都只能满足其中一个 .app 的需求. 要解决这个问题, 就可以用 @rpath. 将 XPSSO.dylib 的 INSTALL_PATH 设置成 @rpath, 然后在编译 softA.app, softB.app 时分别指定 @rpath 为 @loader_path/../dylib, @loader_path/../Frameworks, 问题得到了解决

命令行工具

otool

otool -L xxx:查看使用的动态库有哪些,依赖了哪些动态库

otool -D xxx:查看其install name

其他参数直接键入otool 回车查看

file

Framework是动态库还是静态库

file xxx

使用命令查看

如果是动态库就会遇到上面的错误,需要进行设置。如果是静态库就不需要了。

http://www.tanhao.me/pieces/1361.html/

Xcode 动态库及Framework 安装路径设置 - !--! - 博客园

  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ivy_0709

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值