专栏首页24K纯开源XCode日常使用备忘录

XCode日常使用备忘录

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • macOS下利用dSYM文件将crash文件中的内存地址转换为可读符号

    一、使用流程     Windows下的程序运行崩溃时,往往可以利用pdb文件快速解析出程序崩溃的具体位置,甚至可以对应到源代码的具体行数。macOS下的sym...

    24K纯开源
  • macOS上实现Qt应用程序做文件关联打开

    用Qt开发的应用程序要实现文件关联,双击时用默认关联的程序打开文件,在Windows上这个功能非常容易实现。Windows应用程序在安装的时候可以在注册...

    24K纯开源
  • macOS平台下虚拟摄像头的研发总结

    一、背景介绍     虚拟摄像头,顾名思义,就是利用软件技术虚拟出一个摄像头硬件设备供用户使用。当我们需要对视频图像进行处理再输出时,虚拟摄像头就具备非常大的价...

    24K纯开源
  • Django-Docker容器化部署:

    上一章我们成功搭建了容器化的 Django 项目,用到的数据库为默认的 Sqlite。Sqlite 虽然简单易用,但是线上部署时通常会选择更高效、更可靠的数据库...

    py3study
  • Elasticsearch【快速入门】

    Elasticsearch 是一个分布式、RESTful 风格的搜索和数据分析引擎,能够解决不断涌现出的各种用例。作为 Elastic Stack 的核心,它集...

    我没有三颗心脏
  • Java程序员必须搞懂的 Linux 知识大全!

    学习Linux的重要性相信不用我多说大家也明白,以下是小编总结的常用Linux基础知识以及面试常问的Linux命令,希望能帮助大家更规范地理解和使用~

    Java技术栈
  • Flask内置命令行工具—CLI

    flask命令在Flask库安装后可使用,使用前需要正确配置FLASK_APP环境变量以告知用户程序所在位置。不同平台设置方式有所不同。

    枇杷李子橙橘柚
  • TVP访谈 | 腾讯云最具价值专家李文强:割裂的云计算服务与其发展理念相悖

    |受访者简介:李文强,心莱科技CEO/CTO,长沙.NET技术社区执行主席,腾讯云最具价值专家(TVP),荣获“2019 TVP社区突出贡献奖”。加入腾讯云TV...

    TVP官方团队
  • docker基础

    重点:volumes:将主机的数据卷或者文件挂载到容器里。(使得容器内目录与主机内目录完全同步)

    用户3258338
  • 微服务革命:应用,数据的容器化

    近几年来,微服务架构和基于容器的虚拟化技术已经越来越多地在软件开发社区中被提及。Adrian Cockcroft就是这方面公认的极有远见者之一,他在2014年欧...

    ArrayZoneYour

扫码关注云+社区

领取腾讯云代金券