在Xcode中手动创建通用Framework及静态库文件
发布时间: 2013-03-28 10:20:24 作者: rapoo
在Xcode中手动创建通用Framework及静态库文件
Step 2: 添加库代码,或者编写之这个具体想写什么就随意了,这里偷懒,就把之前写的 UIView (ParticalCurl) 贴进去
Step3: 确保库相关的代码能够编译通过我觉得这是一句废话…好吧,但这确实是很重要的一步,在你的项目中使用库相关的代码,并且确保都能编译通过以及能够正常的工作。 Step4: 建立新Target, 创建适合iPhone真机使用的静态库终于到了关键核心步骤了,各位看官久等了!选择 File -> New -> Target, 如下图:
在新建对话框中,选择 Framework & Library -> Cocoa Touch Static Library,如图
将Target命名为 [library-name].iphoneos,比如 blogguide.iphoneos,如图
随后,选中刚刚建立的blogguide.iphoneos这个target,切换到 Build Phases这个Tab,点开Compile Sources结点,删掉里面所有的东西,将库相关的 *.m 文件拖拽进去,然后点开Copy Headers,将库相关的 *.h 头文件拖到public下,如下图:
随后,选择 Product -> Edit Schema,将编译配置设置为 Release,如图
至此,一个可以在iphone真机上使用的静态链接库的工程就算搞定了,接下来,只要选择 Device 编译就好,如图:
选择 Target 和对应的 Platform,按下 CMD+B 编译就好了 Step 5: 重复Step4,建立可以在模拟器下使用的静态链接库第五步的操作和第四步完全相同,但是注意新建的Target的命名还是得改下,可以叫做blogguide.iphonesimulator。如图:
同样,选择 对应的 Target和Platform进行编译。 Step 6: 合并两个平台的静态链接库,使用lipo命令好吧,这并不是最激动人心的时刻,因为这一步其实是可以省略的,不过如果不怕麻烦要多搞几个不同的二进制文件,其实就随意了…我只是给点建议,合并在一起比较容易管理,并且最终产物是一个通用的静态链接库,最终用户并不用操心这个库是使用在哪个平台上的,用就可以了,配置起来也很方便。操作如下:建立新的Aggregate类型的target,如图:
名字这种东西就是个代号,所以随意了…在右下角选择 Add Build Phase -> Add Run Script
贴进去如下代码: DESKTOP_DIR="/Users/$(whoami)/Desktop/libblogguide"mkdir -p $DESKTOP_DIRcp -r "${BUILT_PRODUCTS_DIR}/usr/local/include" "${DESKTOP_DIR}/include/"#create the liblipo -create "${BUILT_PRODUCTS_DIR}/../Release-iphonesimulator/libblogguide.iphonesimulator.a" \ "${BUILT_PRODUCTS_DIR}/libblogguide.iphoneos.a" \ -output "${DESKTOP_DIR}/libblogguide.a" 选择blogguide->iOS Device编译,如果之前的步骤都正常,那么如上的脚本在执行之后,将会在你的桌面上创建一个libblogguide的目录,并且其中会有一个libblogguide.a的静态链接库,以及一个include文件夹,包含了这个库的头文件。 Xcode在编译新工程时,会在 ~/Library/Developer/Xcode/DerivedData/下,创建 [工程名]-xxxxxxx 的目录,用来存放编译出的临时文件和对应的打包文件,当然,这个目录我们可以通过Xcode的环境变量获得,就是 $BUILT_PRODUCTS_DIR,指向的是该target的目录。在一个target目录的上层,存在 [BuildConfig]-[Platform] 格式的若干目录,分别存放了对应平台编译的结果。lipo命令的作用,就是创建通用文件,具体说明可以直接在命令行中 man lipo 查看。 Step 7: 创建Framework激动人心的时刻终于来了!一个Framework的基本目录结构为: Name.framework -| -|- Headers -|- Name(bin)只要按照这个目录结构存放我们的库,那么,在Xcode中就能以Framework的形式载入。于是按照Step 6的方式,再创建一个Aggregate Target,命名为install-lib,添加一个Run Script。之后,且慢。由于我们需要把我们的framework放到 Xcode 本身的目录中去,而这个目录是/Application目录中的一个子目录,所以需要管理员权限才能写入,虽然sudo命令支持通过CR模式传入密码,可以用另一个脚本echo密码,然后设置SUDO_ASKPASS环境变量为密码脚本,但始终不太美观,尤其是别的使用者要安装在自己的电脑上,还要改密码脚本。 于是,我们可以用Apple Script来执行,Apple Script中有do shell script *** with administrator privileges的指令,可以弹出输入密码的对话框。在工程中添加新的Shell Script文件,叫做 install.sh,在install-lib的Run Script中,贴入如下代码:
osascript -e "set shellScript to \"/bin/sh install.sh $whoami $XCODE_APP_SUPPORT_DIR\"" \ -e "do shell script shellScript with administrator privileges"该段脚本使用osascript命令执行Apple Script,并通过Apple Script,使用管理员权限执行install.sh脚本。 注意我们在Apple Script所执行的脚本中给install.sh传入了一个 $XCODE_APP_SUPPORT_DIR 的参数,以此来获得Xcode的安装路径。 随后,我们就来编写install.sh,来达到安装Framework的目的。在install.sh中写下如下代码:
#! /bin/sh# Install BlogGuide after buildUSERNAME=$1SUPPORT_LIBRARY=$2DESKTOP_DIR="/Users/${USERNAME}/Desktop/libblogguide"# change the head file include typeINCLUDEPATH="${DESKTOP_DIR}/include"includeFiles=$(ls $INCLUDEPATH)for headfile in $includeFiles; do filePath="${INCLUDEPATH}/${headfile}" #echo "process file: $filePath" >> /tmp/aggtarget.log includes=$(grep "#import \"" ${filePath} | awk -F"#import \"" '{print $2}' | awk -F "\"" '{print $1}') #echo "Find import head: $includes" >> /tmp/aggtarget.log for includePiece in $includes; do filename=$(echo $includePiece | awk -F"." '{print $1}') extension=$(echo $includePiece | awk -F"." '{print $2}') #echo "file: $filename, extension: $extension" >> /tmp/aggtarget.log sed -i "" "s/#import \"${filename}.${extension}\"/#import \<PYUtility/${filename}.${extension}\>/g" $filePath donedone# install to each SDKPLATFORM_ROOT_DIR=${SUPPORT_LIBRARY}/../../PlatformsPLATFORM_LIST=$(ls $PLATFORM_ROOT_DIR)#echo $PLATFORM_LIST >> /tmp/aggtarget.logfor platform in $PLATFORM_LIST; do SDK_ROOT_DIR=${PLATFORM_ROOT_DIR}/$platform/Developer/SDKs SDK_LIST=$(ls $SDK_ROOT_DIR) for sdk in $SDK_LIST; do FRAMEWORKS_ROOT_DIR=${SDK_ROOT_DIR}/$sdk/System/Library/Frameworks BLOGGUIDE_FRAMEWORK_DIR=${FRAMEWORKS_ROOT_DIR}/BlogGuide.framework rm -rf ${BLOGGUIDE_FRAMEWORK_DIR} mkdir ${BLOGGUIDE_FRAMEWORK_DIR} mkdir ${BLOGGUIDE_FRAMEWORK_DIR}/Headers cp -r "${INCLUDEPATH}""${BLOGGUIDE_FRAMEWORK_DIR}/Headers" cp "${DESKTOP_DIR}/libblogguide.a""${BLOGGUIDE_FRAMEWORK_DIR}/BlogGuide" donedone 然后就编译吧~编译时,会弹出输入密码的对话框:
编译成功后,重启Xcode,就可以在 Link Binary With Libraries里搜到之前创建的BlogGuide.framework了
至此,大功搞成!按此方法创建的framework,由于是使用的静态链接库,因而不会别苹果拒绝,同时,这样的framework给自定义库的使用、分享、传播带来了很多便利之处,虽然麻烦了一点,其实我只是想说我比较蛋疼而已。