前提
在开发静态库的时候,为了方便使用部分自己开发的库(也就是库A依赖于库B),于是将库B的工程拖入到库A的工程,并通过 Target Dependencies
的方式,加入到库A的编译环境中。
Bomb
在环境配置好后,满心欢喜的使用 xcodebuild 命令进行编译,BOMB,报错?? 立马切换到工程中使用 Xcode 进行编译,结果发现 Xcode 正常编译,不会报错。 思索了一番,感觉会不会是因为加入了其他工程的原因,所以需要使用 workspace 的方式才能编译? 于是命令执行代码从
xcodebuild -project $PROJECT_PATH -configuration Release -target $TARGET_NAME
变成
xcodebuild -workspace $WORKSPACE_PATH -configuration Release -scheme $SCHEME_NAME
运行,果然可以正常编译。然而这才是坑的开始。。。
坑
由于我是进行库的开发,所以是没法用 exportArchive 等这些做一个指定的输出的,而 -workspace
的编译将会把编译好的库直接保存在 DerivedData
中,或者如果有做额外设置,则在下图的路径处。而作为横向对比, 普通的 -project
编译将会把编译好的库保存在目录下的 build
文件夹中,或者可以通过以下路径查看。


而由于是库的开发,为了保证同时支持模拟器与真机,且也需要对生成的库做一些额外处理,所以需要让文件夹指定到对应的文件夹中才行。
幸好,百度到了相关资料,设置对应的 SYMROOT=build 即可,此时代码应该是长成这样
xcodebuild -workspace $WORKSPACE_PATH -configuration Release -scheme $SCHEME_NAME SYMROOT=build
然而不幸再次发生,编译错误,又炸了一次,这个的原因,我预估还是跟 Target Dependencies 有关,因为是对应的类报的错误,可是由于功能牵扯的比较多,不能一点点的屏蔽调试。
转机
在同一篇文章中发现有这么一个命令-showBuildSettings
,可以来显示所有的配置,于是将配置打印出来,并遍寻找所有对应保存路径的变量,并对其中的变量一一做测试。但是。。。并没有什么用,此时已经耗费了好几个小时了。
于是我便放弃挣扎,转而考虑直接获取到对应的保存路径,幸好,之前发现了 -showBuildSettings
这个命令,于是使用
xcodebuild -workspace $PROJECT_PATH -scheme $SCHEME_NAME -showBuildSettings | grep " BUILD_DIR"
获取到对应的路径。 此时再将路径做一个保存、截取与添加处理,即可得到想要的真机与模拟器的库的位置。
BUILD_PATH=$(xcodebuild -workspace $PROJECT_PATH -scheme $SCHEME_NAME -showBuildSettings | grep " BUILD_DIR")
BUILD_PATH=${BUILD_PATH##*= }
DEV_BUILD_FRAMEWORK_PATH="$BUILD_PATH/Release-iphoneos/$FRAMEWORK_NAME"
SIM_BUILD_FRAMEWORK_PATH="$BUILD_PATH/Release-iphonesimulator/$FRAMEWORK_NAME"
最后,再将 DEV_BUILD_FRAMEWORK_PATH
与 SIM_BUILD_FRAMEWORK_PATH
进行 lipo
合并处理即可。
部分未解之谜
剩下部分问题,需要在进行思考
xcodebuild -proj
会将库保存到BUILT_PRODUCTS_DIR
而-workspace
不会的原因是什么?本身机制不同?- 加入
Target Dependencies
之后,xcodebuild 为何会编译失败?而直接用 Xcode 编译是没问题的? SYMROOT
、BUILD_ROOT
这些变量,具体的含义是什么,xcodebuild
在什么场景下使用到他们?