0. Introduction

XCode是macOS上开发app不可缺少的开发者工具,不管是开发macOS上的应用,还是iOS上的应用,都离不开XCode环境。尽管其易用性广受诟病,但由于苹果app开发的封闭性,众多开发者也不有苦不能言。近年来微软针对macOS平台发布了Visual Studio Code和Visual Studio for Mac这两款开发工具,但是其目的显然只是作为XCode的一种补充,要全盘替代XCode目前还不太现实。平时工作中由于负责开发维护Windows和Mac两个平台的应用,因此常常需要用到XCode。但由于macOS系统本来就比较逆反,用惯了Winodws陡然切换到macOS,根本无所适从。对于XCode的使用更是如此。在此记录下平时开发过程中经常用的操作,以免自己再次切换到macOS上时一脸懵逼。

1. Install name and Runpath

      install name是个什么玩意儿?简单的说,是便于加载器dyld找到程序链接的库文件。一般情况下dyld在加载程序的时候,会去一些固定的路径(如/usr/local/lib/usr/lib)下寻找需要的库文件。如果没有找到库文件,程序就会加载失败并报错。install name的出现就是为了解决这种问题,允许用户把库文件放到其他位置,通过install name告诉dylb到哪去寻找这个库文件。
      在XCode中用好install name需要设置两个地方:
(1)Build Settings->Linking,设置了Dynamic Library Install NameDynamic Library Install Name Base两项。这里用到了@rpath变量,其含义和用法在前面的博客中有细说过。@rpath其实是“runpath”的缩写,其值在第二步中设置。
 
     (2)Build Settings->Runpath Search Paths,设置了runpath的搜索路径。在这一项里面可以设置多个路径。这里设置的每个项都会替换@rpath,从而达到灵活设置多个位置的目的。可以在下图中看到,我们使用了@loader_path这个变量,其值实际上是可执行程序的所在位置。因此,假设可执行程序所在路径为:/Users/zhangzhongke/Library/bin/test,@loader_path/../Resources”把上面设置的@rpath替换了之后就变成了:/Users/zhangzhongke/Library/bin/test/../Resources,实际也就是:/Users/zhangzhongke/Library/Resources/。我们这里runpath只设置了一个值,实际上有需要可以设置多个值。
 
      通过命令otool -L可查看dylib文件的install name确实已经设置成了我们需要的值。其中:-L选项打印dylib所使用到的库,-D打印dylib文件的ID名。如果是修改其他动态库,则可使用install_name_tool命令来修改。

2. Header, Compiler and Build Locations

       Build Settings->Build Locations可以修改编译输出位置。
 
      Build Settings->Search Paths可设置编译时头文件和库文件的搜索路径。
 
      Build Settings->Apple LLVM8.0-Language C++设置C++运行时库。有的项目中需要在libstdc++和libc++之间切换,否则编译过程各种错误。
 

3. dSYM and App crashes

dSYM是Debug Symbols的缩写,也就是说dSYM里面存储的都是可执行程序的调试符号,对于Windows下Visual Studio生成的pdb文件。保存Release版的dSYM文件对于程序崩溃时的调试可以说极为重要。调试符号文件在调试中的作用其实非常简单,就是把那些16进制值转换为我们源代码中对应的符号变量。这样能够帮助开发者快速定位到程序崩溃的地方,极大的提高调试效率。

      那么怎么利用调试符号文件来调试程序崩溃呢?顺便记录下Windows的调试方法:
(1)Windows下利用pdb文件调试崩溃程序。首先要注意的是,要保存好Release版的pdb文件。最好发布程序时,把pdb文件也一起打包进去。
  • 调试时使用windbg,需要设置好调试符号文件和源代码文件(如果有)路径:
  • Attach to a Process适用于动态库等不能直接运行的程序,Open Executable则适用于exe可执行程序。程序起来后,直接输入g命令开始执行。在出现异常的地方运行命令:!analyze -v进行分析。windbg就能给出具体的崩溃的位置了。

(2)macOS下利用dSYM文件调试崩溃程序。首先解释下dSYM和DWARF的关系:

  • DWARF是一种被众多编译器和调试器使用的用于支持源代码级别调试的调试文件格式。它满足了许多程序语言的需求,比如C,C++和Fortran,而且被设计成可拓展到其它语言。DWARF是平台独立的且适用于任何处理器任何操作系统。 DWARF广泛应用于Unix,Linux和其它操作系统,以及独立的环境中。
  • 为了避免进行stripping操作后调试符号的丢失,你可以使用dwarf-with-dsym选项. DWARF with dSYM 选项在标准的DWARF之外执行一个额外的步骤:创建一个单独的MyApp.app.dSYM文件,这个文件包含你的程序的所有调试符号(这个文件其实是一个包,可以通过右键->显示包内容进行查看)。事实上,DWARF with dSYM选项允许你对你进行单步调试而不管可执行程序是否被剥离了调试信息(stripped)。这是可能的,这是因为gdb将会在你的程序的目录下查找.dSYM文件。它不需要知道对象文件(object files)的名字或者路径。

利用dSYM解析crash log的主要步骤如下:

(1)在调试之前,把xxx.crash、xxx.dSYM、symbolicatecrash三个文件放到一个同一个文件夹中。这里symbolicatecrash是XCode命令行工具中的一个命令,可以把它拷贝过来,也可以建立符号链接。

ln -s /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash /usr/bin/symbolicatecrash
在我的电脑上装的是XCode8,symbolicatecrash的路径为:/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash。如果找不到,可以使用命令:
find /Applications/Xcode.app/ -name symbolicatecrash -type f

(2)验证app和dSYM的UUID是否一致:

dwarfdump --uuid YourApp.app/YourApp
dwarfdump --uuid YourApp.app.dSYM

(3)解析Crash Log

./symbolicatecrash ./*.crash ./*.app.dSYM > symbol.crash

生成的symbol.crash就是解析后的崩溃日志文件了,里面的符号经过了转换,阅读上变得更加友好。另外,macOS系统上的日志通常存放在如下几个地方:

~/Library/Logs/DiagnosticReports/ (where ~ refers to your Home directory).
~/Library/Logs/CrashReporter/MobileDevice are the crashlogs for your iOS devices (if any).
~/Library/Logs/CrashReporter also has links to items in ~/Library/Logs/DiagnosticReports/
/var/log/system.log

  注意:Build Settings -> Build Options -> Debug Information Format中, 置成 DWARF是不会产生dSYM文件的,必须选择DWARF with dSYM File才会生成符号表文件。

4. Target, Scheme and Group

XCode中的Target类似Visual Studio中的Project,也就是说一个target可以单独进行编译,生成可执行程序。通常在XCode中创建一个项目时,默认会创建一个同名的Target。如果需要新增一个Target,在XCode的工具栏选择:File->New->Target即可。如下图:

创建Target的时候选择需要的项目类型即可。然后,在下图所示位置切换不同的Targets进行编译。

注意:如果要编译不同的Targets一定要记得切换,这个功能如果Visual Studio中的“设置为启动项目”:

如果需要设置不同Targets的项目属性,也需要进行Targets的切换:

编辑Scheme,其实就是设置编译类型:Debug或者Release,以及一些编译动作。XCode里面有Build, Run, Test, Profile, Analysis, Archive这几个编译动作,每个动作都有Debug和Release模式。在这两种模式下设置不同的编译参数。最常用的就是Run和Archive了。

Group在XCode里面的作用非常明确,就是用来在逻辑上对源文件进行分类管理。逻辑上的意思是,它并不会创建物理上的分组,而仅仅是视觉上、逻辑上的划分。所以有时候我们虽然在XCode中看到工程组织的井井有条,可是工程文件夹中的文件实际上是散落一片的。这个功能对于大型的项目功能划分、文件组织非常重要。下图中的New Group和New Group from Selection都是用来创建Group的,后者可以对选中的工程文件创建Group。

5. Misc

  • xcode-select:用于选择不同版本的开发者工具
  • xcodebuild和xcrun是打包时常用的两个命令,xcodebuild负责编译,xcrun负责将app打成ipa。

6. References

XCode日常使用备忘录的更多相关文章

  1. Caffe和py-faster-rcnn日常使用备忘录

    罗列日常使用中遇到的问题和解决办法.包括: { caffe使用中的疑惑和解释: 无法正常执行 train/inference 的情况: Caffe基础工具的微小调整,比如绘loss曲线图: 调试pyt ...

  2. Xcode日常使用

    1.构建输出目录(Preferences->Locations->Locations)当选择为Default时,Derived Data的目录为~/Library/Developer/Xc ...

  3. iOS日常学习 - 每个Xcode开发者应该知道的七个使用技巧

    本文为转载学习使用原文链接 工欲善其事,必先利其器.对一个iOS开发者来说,这就意味着对Xcode的熟练掌握程度.Xcode是一个学习起来有点难度的软件,下面的这些技巧或许可以显著的提高你的编程效率. ...

  4. Xcode插件优缺点对比(推荐20款插件)

    本文大致整理了自己用过的一些插件的使用感想(就是好不好用). 在那之前先简单贴两条插件须知,知道的可以忽略. 1.Alcatraz 类似于管理第三方库的cocoapods,管理插件也有个Alcatra ...

  5. 高效使用你的Xcode

    (via:VongLo's Dev Space  原文:Supercharging Your Xcode Efficiency)   好莱坞电影里经常看到黑客们手指在键盘上飞速跳跃,同时终端上的代码也 ...

  6. Xcode 8 的 Debug 新特性

    Contents OverView Static Analyzer Localizability Instance Cleanup Nullablility Runtime Issue View De ...

  7. Xcode 的正确打开方式——Debugging(转载)

    Xcode 的正确打开方式——Debugging   程序员日常开发中有大量时间都会花费在 debug 上,从事 iOS 开发不可避免地需要使用 Xcode.这篇博客就主要介绍了 Xcode 中几种能 ...

  8. 【转】Xcode 插件优缺点对比(推荐 20 款插件)

    [转自]http://www.cnblogs.com/dsxniubility/p/5099191.html 1.Alcatraz 类似于管理第三方库的cocoapods,管理插件也有个Alcatra ...

  9. Xcode 的正确打开方式——Debugging

    程序员日常开发中有大量时间都会花费在 debug 上,从事 iOS 开发不可避免地需要使用 Xcode.这篇博客就主要介绍了 Xcode 中几种能够大幅提升代码调试效率的方式. “If debuggi ...

随机推荐

  1. sqlserver 连接mysql

    配置与电脑相对应的odbc   http://dev.mysql.com/downloads/connector/odbc/

  2. 编译链接 C++

    预处理之后的源文件被称为一个编译单位,也即编译器的工作对象.为了使编译能够进行,程序员必须提供各种程序其他部分的声明来孤立分析一个编译单位.所有名字空间,类,函数都应该在他们所在的编译单位中有声明,所 ...

  3. java学习笔记(2)

    上篇讲了一些概念之类的知识点,现在继续总结知识点: 1.用户自己在控制面板输入内容是如何实现的:java中有一个类可实现这个功能 类Scanner: import java.util.Scanner; ...

  4. Sort简单排序

    List<T> 类型排序: public List<ProductionMaterialModel> OrderBybom(List<ProductionMaterial ...

  5. 体验phonegap3.0

    网上有各种各样的phonegap环境搭建资料,鉴于学习和整理的考虑,我还是把我搭建的过程整理出来 这篇文章中将涉及到的内容 PhoneGap环境需要的组件 Node环境 JDK Android SDK ...

  6. Visual Studio 2015 CTP6 发布

    微软发布ASP.NET 5 支持在Windows.Mac和Linux上构建程序,Visual Studio 2015 CTP6(社区预览版)现已发布了.感兴趣的朋友们可以登录官网下载[http://w ...

  7. 编译可在Android上运行的qemu user mode

    前言 本文在Ubuntu 64位系统上对qemu项目进行交叉编译,并且只编译与qemu user mode有关的代码. 下文中的”NDK”若无特殊说明均指”Android NDK”. 下文中”$NDK ...

  8. ABP理论学习之OWIN集成

    返回总目录 如果你的应用中使用了OWIN,那么需要在主项目(一般来说是指Web项目)中添加Abp.Owin的nuget包,然后像下面那样在OWIN的 Startup文件中调用 UseAbp()扩展方法 ...

  9. windows下 安装Kali Linux到 U盘的方法

    作者:玄魂工作室 \ 2016年10月20日 把Kali Linux安装到U盘好处很多,可以从U盘启动使用整个电脑的硬件资源, 可以随身携带,减少对自己电脑的影响. 今天要给大家讲的是如何在windo ...

  10. [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能

    [.net 面向对象程序设计进阶] (15) 缓存(Cache)(二) 利用缓存提升程序性能 本节导读: 上节说了缓存是以空间来换取时间的技术,介绍了客户端缓存和两种常用服务器缓布,本节主要介绍一种. ...