深入浅出 Xcode 命令列 - libxcselect.dylib

2,251 阅读2分钟

Xcode命令列 = Xcode Command Lines Tool

经过深入浅出 Xcode 命令列(1) - 初探的介绍,我们知道一台mac上可能会有多'组'xcode command line tool.

多组xcode command line tool

且在xcode-select的帮助下,我们能指定某个特定版本的Command Line Tools,然后整台电脑在不需要设定env变量的前提下,就知道该调那个SDK了.... 听起来很符合直觉,却有点太玄了...😰

giphy -1-

--

让我们稍微深追一下这问题

碍于我的知识有限,所以这篇写做加餐,咱们点到为止😅

things we know

复习一下,当我们在终端敲命令(例如: xcodebuild)时,系统都会在 $PATH 这个环境变量里给的路径里寻找你敲的指令的object file。

echo $PATH

所以输入 git, 其实是执行了 /usr/bin/xcodebuild

which git

以上都是我们熟知的原理。

llibSelect1

things we don't know

我们现在已xcodebuild为例,来看看后面有关xcode command line tools的流程。

我对详细的逆向函数还不是很熟悉,所以统整了一些参考文章,想要深入暸解的可以点击文章底部链接。

看看/usr/bin/xcodebuild 下的指令是怎么配合xcode-select , 找到 /Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild

首先我们就对 /usr/bin/xcodebuild 动手

列出 /usr/bin/xcodebuild 的 textsection

再打印 /usr/bin/xcodebuild 的 name list

结合这两个信息,我们可以得出

  1. 调用了一个 _xcselect_invoke_xcrun 函数
  2. 这个函数对 /usr/bin/xcodebuild 来说是一个外部符号,来自另一个动态库,交给动态链接去做了。

接着

打印 /usr/bin/xcodebuild依赖的库

可以看到有 libxcselect.dylib, libSystem.B.dylib,

打印 libxcselect.dylib 的 name list 看看 _xcselect_invoke_xcrun这symbol 在不在这

bingo! 找到了

跟着 Swift-Swiftc 作者的追踪,可以得到如下

libxcselect.dylib
->
_xcselect_invoke_xcrun
-> 
libxcrun.dylib
->
xcrun_main

而最后的 xcrun_main -> 指向的就是 指令 xcrun

xcrun

截至目前,我们能把上面的所有堆栈,抽象大概浓缩成一行函数,类似于

xcrun('xcodebuild')

而xcrun 就会引领我们到

/Applications/Xcode.app/Contents/Developer/usr/bin/xcodebuild

至于xcrun的用法,我们下回分晓。

拨云见日

llibSelect

giphy -2-

参考文章: