iOS "Warning" No such file or directory详解、解决方案和原理

IOS  "Warning" No such file or directory



1.为什么工程中会出现“No such file or directory”的警告。


当我们仔细看我们的工程“Warning”,会发现这个警告不是一个,是一个Framework中很多文件,但是通过在项目中查找,以及根据对应的Warning的路径查找警告文件和文件夹,根本找不到。
这个问题根本原因是:“加载的静态库的设置”



2.出现“No such file or directory”的警告解决方案

解决方法1:

如果是自己公司的静态库,或者是自己写的静态库。通过在XCode里面将使用的静态库的Generate Debug Symbol的值设为NO,重新编译一下生成静态库,这次编译出来的静态库再也不会产生已经警告了。

解决方法2:(存在两种方法)

方案1: 如果使用的是第三方的库,需要联系第三方的作者。更新一些对应的库文件。

方案2:  如果以上的情况都无法实现,就只能简单处理(详细步骤如下图:)


第一步.修改前工程的配置




第二步:修改“Debug Information Format”


   

第三步:运行工程,No such file or directory 的警告就消失了


3.出现“No such file or directory”的根本原因 和 原理


最近用XCode做了一个静态库,在自己电脑上别的App project中编译使用没有任何问题,但是传给别的同事使用在编译的时候就会出现类似于下面警告。
warning: (i386) /UsersLibrary/Developer/Xcode/DerivedData/ProjectName-ebyadedaazwurqcvfzmyzzacvlbg/Build/Intermediates/  ProjectName.build/Debug-iphonesimulator/ ProjectName.build/Objects-normal/i386/ClassName.o unable to open object file
通过在Google里面搜索,终于弄明白了,通过在XCode里面将Generate Debug Symbol的值设为NO,重新编译一下生成静态库,这次编译出来的静态库再也不会产生已经警告了。这是为什么呢?

在开始解释原因之前,我们需要看一下什么是   Debug Symbol / Debug Information

1) Debug Symbol(调试符号)

首先来看看维基百科上的解释: http://en.wikipedia.org/wiki/Debug_symbol

debug symbol is information that expresses which programming-language constructs generated a specific piece of machine code in a given executable module. Sometimes the symbolic information is compiled together with the module's binary file, or distributed in separate file, or simply discarded during the compilation and/or linking. This information enables a person using a symbolic debugger to gain additional information about the binary, such as the names of variables and routines from the original source code. This information can be extremely helpful while trying to investigate and fix a crashing application or any other fault.

When debug symbols are embedded in the binary itself, the file can then grow significantly larger (sometimes by several megabytes). To avoid this extra size, modern compilers and early mainframe debugging systems output the symbolic information into a separate file; for Microsoft compilers, this file is called a PDB file. Some companies ship the PDB on their CD/DVD to enable troubleshooting and other companies (like Microsoft, and the Mozilla Corporation) have special online servers from which it's possible to download the debug symbols separately. 

我简单翻译下上面两段话

调试符号(debug symbol)是代表在给定的可执行的模块中由编程语言产生的一段特定的机器码的信息。有时这些符号信息被编译进模块的二进制文件中,或者以单独的文件的形式进行分发,或者在编译/链接的时候直接丢弃。这些信息使得人们可以一种符号调试程序来获取关于二进制文件的额外信息,比如变量的名称和来自于源代码的routines(不知道怎么翻译比较好)。这些信息在我们研究和修复程序的崩溃问题或者别的错误的时候非常有用。

-----------------------为什么会非常有用呢?----------------------------

因为借助符号调试程序可以将类似

Thread 0 Crashed:
0 libobjc.A.dylib 0×300c87ec 0×300bb000 + 55276
1 MobileLines 0×00006434 0×1000 + 21556
2 MobileLines 0×000064c2 0×1000 + 21698
3 UIKit 0×30a740ac 0×30a54000 + 131244

的log信息转换成

Thread 0 Crashed:
0 libobjc.A.dylib 0×300c87ec objc_msgSend + 20
1 MobileLines 0×00006434 -[BoardView setSelectedPiece:] (BoardView.m:321)
2 MobileLines 0×000064c2 -[BoardView touchesBegan:withEvent:] (BoardView.m:349)
3 UIKit 0×30a740ac -[UIWindow sendEvent:] + 264

-------------------这样应该能非常明了地指出问题所在吧?-------------------

当调试符号被嵌入进二进制文件本身的时候,文件的尺寸会显著地增长(不难理解吧?文件中放入了额外的信息,自然就大了)。为了避免这个额外的文件尺寸(为什么要避免,应该不难理解吧),现在的编译器(新的,和老旧的相对)和早期的大型机调试系统将符号信息输出到单独的文件中(为什么要输出到单独的文件中?调试符号信息对于普通的用户是没有用的,它只对开发人员追踪问题有用,嵌入到二进制文件中只会增大文件尺寸,延长用户下载的时间,而且也会暴露你程序的内部信息,如果你想保护你的代码不被别人猜到,你应该考虑不要在二进制文件中包含调试信息)。比如微软的编译器,这个文件叫做PDB文件,有的公司通过CD/DVD的方式来传输,有的公司提供在线的服务器单独进行下载,通过PDB文件,你可以进行程序故障诊断(发现程序出错的地方)。

通过上面简单的介绍,我想大家应该对Debug Symbol应该已经有了个大概的认识了。


2)DWARF


接下来我们看看DWARF是什么。  官方网站:http://dwarfstd.org/

官方网站对DWARF的简单介绍:

DWARF is a debugging file format used by many compilers and debuggers to support source level debugging. It addresses the requirements of a number of procedural languages, such as C, C++, and Fortran, and is designed to be extensible to other languages. DWARF is architecture independent and applicable to any processor or operating system. It is widely used on Unix, Linux and other operating systems, as well as in stand-alone environments.  

DWARF是一种被众多编译器和调试器使用的用于支持源代码级别调试的调试文件格式。它满足了许多程序语言的需求,比如C,C++和Fortran,而且被设计成可拓展到其它语言。DWARF是平台独立的且适用于任何处理器任何操作系统。 DWARF广泛应用于Unix,Linux和其它操作系统,以及独立的环境中。

为了更好地理解DWARF,可以阅读下这篇文章:http://lapcatsoftware.com/blog/2008/03/09/stabs-is-deprecated/  由于篇幅的原因原文就不贴过来了,直接简单翻译下。

2008-02-27开始, STABS(一种调试数据格式)被苹果Apple弃用。XCode项目build setting中DEBUG_INFORMATION_FORMAT默认的STABS被取代。

通过STABS, 你可以创建带有调试符号(debugging symbols)的程序的release版本,拷贝一份可执行程序MyApp.app/Contents/MacOS/MyApp保存起来, 而把此可执行文件除去调试符号用于分发(strip the executable for shipping), 然后用未除去调试符号的可执行程序来进行崩溃分析。和STABS不同, DWARF不将调试符号包含到可执行文件自身里面,而是仅在可执行文件里包含对中间对象文件的引用( references to the intermediate object files),而这些中间对象文件中则包含着调试符号。通常你可以在build/MyApp.build目录的子目录下找到这些中间对象文件(.o files,如果你使用XCode,这些文件则通常在/Developer/XCode/DerivedData/MyApp-****/Build/Intermediates目录下)。如果你在使用DWARF编译后删除这些对象文件,你将不能对你的代码进行单步调试。 (如果你使用stabs, 这些对象文件则是完全无用的.) 如果你把调试符号从你的程序中除去(strip debugging symbols from your app),你也不能进行单步调试,因为可执行文件中已经不存在对中间对象文件的引用了。


3)dSYM


为了避免进行stripping操作后调试符号的丢失,你可以使用dwarf-with-dsym选项. DWARF with dSYM 选项在标准的DWARF之外执行一个额外的步骤:创建一个单独的MyApp.app.dSYM文件,这个文件包含你的程序的所有调试符号(这个文件其实是一个包,可以通过右键->显示包内容进行查看)。事实上,DWARF with dSYM选项允许你对你进行单步调试而不管可执行程序是否被剥离了调试信息(stripped)。这是可能的,这是因为gdb将会在你的程序的目录下查找.dSYM文件。它不需要知道对象文件(object files)的名字或者路径。如果你不除去调试符号 (strip debugging symbols), 你可以使用.o或者.dSYM文件来调试。


4.其它

其实如果,你想跟深入的了解,你可以更深入的了解 DWARF调试格式 ”, 如果有什么不同的见解,可以留言相互学习


猜你喜欢

转载自blog.csdn.net/Future_One/article/details/67640955