Xcode Toolchain

0x00 前言

这篇文章是自己在学习 CFHipsterRef Chapter 14 Xcode Toolchain 时做的笔记。

0x01 Xcode Toolchain

从 Mavericks 开始,作为一个开发者在 Mac 上开始只需要一个命令:

1
xcode-select -- install

这将会安装命令行工具,这是编译 Objective-C 代码所必要的。

0x02 xcrun

xcrun 是 Xcode 命令行工具的基础。有了它,所有其他的工具都可以被调用。

1
$ xcrun xcodebuild

除了运行命令,xcrun 可以找到二进制文件并显示 SDK 的路径:

1
2
3
$ xcrun --find clang
$ xcrun --sdk iphoneos --find pngcrush
$ xcrun --sdk macosx --show-sdk-path

由于 xcrun 是执行在活动的 Xcode 版本(由 xcode-select 设置)的上下文中,所以在单系统上很容易共存多个版本的 Xcode 工具链(toolchain)。

在脚本和其他外部工具中使用 xcrun 具有确保跨不同环境的统一性的优点。例如,Xcode 附带了一个 Git 的自定义分布(custom distribution)。通过调用 $ xcrun git 而不只是 $ git,构建系统可以保证运行正确的分布。

0x03 xcodebuild

第二个最重要的 Xcode 工具是 xcodebuild,顾名思义,构建 Xcode 项目(projects)和工作空间(workspaces)。

不需要传递任何构建设置,xcodebuild 默认使用 Xcode.app 最近使用的方案(scheme)和配置。

1
$ xcodebuild

然而,从方案,targets,配置(configuration),目标地址(destination),SDK 和 derived data 位置的一切都可以配置:

1
2
$ xcodebuild -workspace NSHipster.xcworkspace \
-scheme "NSHipster"

这里有 7 个可以按照顺序被调用的构建动作:

build 在构建根目录(build root,SYMROOT)中构建目标(target)。这是默认的构建动作。
analyze 从构建根目录中构建并分析一个目标或方案。需要指定一个方案。
archive 从构建根目录中归档(Archive)一个方案。需要指定一个方案。
test 从构建根目录中测试一个方案。需要指定一个方案和可选的目标地址。
installsrc 复制项目的源到源根目录(source root,SRCROOT)。
install 构建目标并且安装到目标在分发根目录(distribution root,DSTROOT)的安装目录中。
clean 从构建根目录移除构建的产品(products)和中间文件。

0x04 genstrings

genstrings 工具从指定的 C 或 Objective-C 源文件生成一个 .strings 文件。.strings 文件用于在不同语言环境中本地化一个应用程序,在 Apple 的 Cocoa Core Competencies 中的 “Internationalization” 下有描述。

1
2
$ genstrings -a \
/path/to/source/files/*.m

对于在源文件中每次使用的 NSLocalizedString 宏,genstrings 都会将 key 和注释附加到目标文件中。然后由开发者为每个目标语言环境创建一个该文件的副本,并翻译该文件。

fr.lproj/Localizable.strings

1
2
3
4
/* No comment provided by engineer. */
"Username"="nom d'utilisateur";
/* {User First Name}'s Profile */
"%@'s Profile"="profil de %1$@";

0x05 ibtool

genstrings 是用于源代码,而 ibtool 是用于 XIB 文件。

1
2
3
$ ibtool --generate-strings-file \
Localizable.strings \
en.lpoj/Interface.xib

虽然本地化是它的主要用例,ibtool 有用于跟 Interface Builder 文档工作的几个其他功能。可以使用 --convert 标记来改变对一个类名的所有引用。可以使用 --upgrade 标记将一个文档升级到最新版本。甚至可以分别使用 --enable-auto-layout--update-frames--update-constraints 标记来启动 Auto Layout,以及更新 frames & constraints(约束)。

0x06 iprofiler

iprofiler 不需要启动 Instruments.app 测算一个 app 的性能:

1
2
3
4
5
$ iprofiler -allocations \
-leaks \
-T 15s \
-o perf \
-a NSHipster

上面的命令将附加到 NSHipster.app 上,运行 15 秒,仪器分配和泄露,然后将结果写入 pref 中。然后这个输出可以通过 Instruments.app 读取和显示。

0x07 xed

这个命令简单地打开 Xcode。

1
$ xed NSHipster.xcworkspace

通过传递 -w 标记,xed 会等待直到所有一打开的窗口都关闭。这个对于脚本化用户交互非常有用,例如提示用户编辑一个文件,一旦完成就继续。

0x08 agvtool

通过在 Info.plist 文件中读写一个适当的值, agvtool 可以用于修改 Xcode 项目的版本。

1
$ agvtool what-version

…返回当前项目的版本。

1
$ agvtool next-version

…增加 当前项目的版本当前 DYLIB 的版本。传递 -all 选项也会更新 Info.plist 中的 CFBundleVersion key。

0x09 Other Tools

除了上述的 Xcode tools,还有一些其他可执行文件可以被 xcrun 调用。

0x0901 Compilation & Assembly

  • clang:Compiles C,C,Objective-C 和 Objective-C 源文件。
  • lldb:Debugs C,C,Objective-C 和 Objective-C 程序。
  • nasm:汇编文件。
  • ndisasm:反汇编文件。
  • symbols:显示一个文件或过程(process)的符号信息。
  • strip:删除或修改附加到汇编器和链接编辑器输出的符号表。
  • atos:将数字地址转换为二进制映像或进程的符号。

0x0902 Processors

  • unifdef:从代码中删除条件的 #ifdef 宏。
  • ifnames:在 C++ 文件中查找条件。

0x0903 Libraries

  • ld:将对象文件和库组合到单个文件中。
  • otool:显示对象文件或库的指定部分。
  • ar:创建和维护库归档。
  • libtool:创建一个用于链接编辑器 ld 的库。
  • ranlib:更新归档库的内容目录。
  • mksdk:制作和更新 SDK。
  • lorder:列出对象文件的依赖关系。

0x0904 Scripting

  • sdef:脚本定义提取器。
  • sdp:脚本定义处理器。
  • amlint:Checks Automator actions for problems.

0x0905 Packages

  • installer:安装 OS X 包(packages)。
  • pkgutil:读取和操作 OS X 包。
  • lsbom:列出一个 bom(Bill of Materials) 的内容。

0x0906 Documentation

  • headerdoc:进程头文档。
  • gatherheaderdoc:编译和链接 headerdoc 输出。
  • headerdoc2html:从 headerdoc 输出生成 HTML。
  • hdxml2manxml:从 headerdoc XML 输出翻译为使用 xml2man 的文件。
  • xml2man:将 Man Page Generation Language(MPGL)XML 文件转换为 manual pages。

0x0907 Core Data

  • momc:编译 Managed Object Model(.mom)文件
  • mapc:编译 Core Data Mapping Model(.xcmappingmodel)文件