Xcode命令列 = Xcode Command Lines Tool
经过深入浅出 Xcode 命令列(1) - 初探的介绍,我们知道一台mac上可能会有多'组'xcode command line tool.
且在xcode-select的帮助下,我们能指定某个特定版本的Command Line Tools,然后整台电脑在不需要设定env变量的前提下,就知道该调那个SDK了.... 听起来很符合直觉,却有点太玄了...😰
--
让我们稍微深追一下这问题
碍于我的知识有限,所以这篇写做加餐,咱们点到为止😅
things we know
复习一下,当我们在终端敲命令(例如: xcodebuild)时,系统都会在 $PATH 这个环境变量里给的路径里寻找你敲的指令的object file。
echo $PATH
所以输入 git, 其实是执行了 /usr/bin/xcodebuild
which git
以上都是我们熟知的原理。
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
结合这两个信息,我们可以得出
- 调用了一个 _xcselect_invoke_xcrun 函数
- 这个函数对 /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的用法,我们下回分晓。
拨云见日
参考文章: