合并真机模拟器静态库(转载)

文章目录
  1. 1. 合成脚本
  2. 2. 铺路
    1. 2.1. xcodebuild
    2. 2.2. cp “源文件路径” “目标文件路径”
    3. 2.3. lipo
    4. 2.4. 用到的一些shell脚本基础命令
      1. 2.4.1. echo “你要写的东西”
      2. 2.4.2. 赋值命令。 变量名=变量值
      3. 2.4.3. ${变量名}
      4. 2.4.4. 判断语句
      5. 2.4.5. 本脚本中用到的判断语句:
  3. 3. 脚本结构解释
    1. 3.1. 执行条件– 编译
    2. 3.2. 工程名称定义
    3. 3.3. build 路径
    4. 3.4. build目录的位置
    5. 3.5. 文件状态判断
    6. 3.6. 编译
    7. 3.7. 合并
    8. 3.8. 打开目标文件夹
  4. 4. shell脚本基础知识
  5. 5. xcworkspace 工程对应的脚本
  6. 6. iOS设备架构
  7. 7. 参考

这篇文章解释合并真机模拟器静态库的脚本

合成脚本

合并的脚本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
if [ "${ACTION}" = "build" ]
then
#要build的target名
target_Name=${PROJECT_NAME}
echo "target_Name=${target_Name}"

#build之后的文件夹路径
build_DIR=${SRCROOT}/build
echo "build_DIR=${build_DIR}"
#真机build生成的头文件的文件夹路径
DEVICE_DIR_INCLUDE=${build_DIR}/Release-iphoneos/include/${PROJECT_NAME}
echo "DEVICE_DIR_INCLUDE=${DEVICE_DIR_INCLUDE}"
#真机build生成的.a文件路径
DEVICE_DIR_A=${build_DIR}/Release-iphoneos/lib${PROJECT_NAME}.a
echo "DEVICE_DIR_A=${DEVICE_DIR_A}"
#模拟器build生成的.a文件路径
SIMULATOR_DIR_A=${build_DIR}/Release-iphonesimulator/lib${PROJECT_NAME}.a
echo "SIMULATOR_DIR_A=${SIMULATOR_DIR_A}"

#目标文件夹路径
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}
echo "INSTALL_DIR=${INSTALL_DIR}"
#目标头文件文件夹路径
INSTALL_DIR_Headers=${SRCROOT}/Products/${PROJECT_NAME}/Headers
echo "INSTALL_DIR_Headers=${INSTALL_DIR_Headers}"
#目标.a路径
INSTALL_DIR_A=${SRCROOT}/Products/${PROJECT_NAME}/lib${PROJECT_NAME}.a
echo "INSTALL_DIR_A=${INSTALL_DIR_A}"

#判断build文件夹是否存在,存在则删除
if [ -d "${build_DIR}" ]
then
rm -rf "${build_DIR}"
fi
#判断目标文件夹是否存在,存在则删除该文件夹
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
#创建目标文件夹
mkdir -p "${INSTALL_DIR}"

#build之前clean一下
xcodebuild -target ${target_Name} clean

#模拟器build
xcodebuild -target ${target_Name} -configuration Release -sdk iphonesimulator
#真机build
xcodebuild -target ${target_Name} -configuration Release -sdk iphoneos
#复制头文件到目标文件夹
cp -R "${DEVICE_DIR_INCLUDE}" "${INSTALL_DIR_Headers}"
#合成模拟器和真机.a包
lipo -create "${DEVICE_DIR_A}" "${SIMULATOR_DIR_A}" -output "${INSTALL_DIR_A}"

#打开目标文件夹
open "${INSTALL_DIR}"
fi

铺路

本代码中用到的核心命令:

xcodebuild

苹果给的一个命令。主要用来编译Xcode的工程。
可以在终端中输入xcodebuild -h来查看命令的详情,介绍一下本脚本中用到的几个参数

  • clean:clean一下工程
  • -configuration Release
    使用Release方式编译,还可以使用Debug
  • -sdk iphoneos
    真机编译,还可以使用-sdk iphonesimulator模拟器编译

cp “源文件路径” “目标文件路径”

复制”源文件路径”的文件到 “目标文件路径”

lipo

lipo -create “模拟器.a文件路径” “真机.a文件路径” -output “目标.a文件路径”

将模拟器和真机的.a包合成。

用到的一些shell脚本基础命令

echo “你要写的东西”

打印的log,将”你要写的东西”打印出来,相当于OC中的NSLog
Xcode的话,运行脚本后,可以在这里找到log

赋值命令。 变量名=变量值

比如将”CrazyStone”赋值给MyName变量

MyName=CrazyStone

${变量名}

取出变量名的内容。
比如:取出变量MyName中的内容
${MyName}

判断语句

if [ 条件语句 ]then

fi
条件语句为真就执行then后面的语句,不成立就结束判断语句

本脚本中用到的判断语句:

[ -d “文件夹路径” ] :判断是否为文件夹

脚本结构解释

看完上面,我想你再看一下代码应该就能理解脚本,然后可以做一些简单的改动了。下面再介绍一下脚本的结构。

执行条件– 编译

1
2
3
4
if [ "${ACTION}" = "build" ]
then
#我们的大部分脚本代码
fi

执行脚本的时候做个判断,在Xcode里面build这个工程的时候就执行then后面的脚本

工程名称定义

1
2
3
#要build的target名
target_Name=${PROJECT_NAME}
echo "target_Name=${target_Name}"

变量target_Name是我们要编译的target的名字,在这里指的是工程的名字${PROJECT_NAME},也就是MySDK。

顺便说一下,ACTION和PROJECT_NAME都是Xcode里面定义的,这是在Xcode里面写脚本的一个好处。

build 路径

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#build之后的文件夹路径
build_DIR=${SRCROOT}/build
echo "build_DIR=${build_DIR}"

#真机build生成的头文件的文件夹路径
DEVICE_DIR_INCLUDE=${build_DIR}/Release-iphoneos/include/${PROJECT_NAME}
echo "DEVICE_DIR_INCLUDE=${DEVICE_DIR_INCLUDE}"

#真机build生成的.a文件路径
DEVICE_DIR_A=${build_DIR}/Release-iphoneos/lib${PROJECT_NAME}.a
echo "DEVICE_DIR_A=${DEVICE_DIR_A}"

#模拟器build生成的.a文件路径
SIMULATOR_DIR_A=${build_DIR}/Release-iphonesimulator/lib${PROJECT_NAME}.a
echo "SIMULATOR_DIR_A=${SIMULATOR_DIR_A}"

这里是定义的build之后各个文件的路径。我们执行了xcodebuild命令之后,会在工程目录生成一个build文件夹,里面有build之后生成的文件。打开Finder看看就知道各个文件的路径了。

build目录的位置

1
2
3
4
5
6
7
8
9
10
11
#目标文件夹路径
INSTALL_DIR=${SRCROOT}/Products/${PROJECT_NAME}
echo "INSTALL_DIR=${INSTALL_DIR}"

#目标头文件文件夹路径
INSTALL_DIR_Headers=${SRCROOT}/Products/${PROJECT_NAME}/Headers
echo "INSTALL_DIR_Headers=${INSTALL_DIR_Headers}"

#目标.a路径
INSTALL_DIR_A=${SRCROOT}/Products/${PROJECT_NAME}/lib${PROJECT_NAME}.a
echo "INSTALL_DIR_A=${INSTALL_DIR_A}"

这里就是定义目标变量的路径了。你想把文件放在哪里?在这里定义咯。${SRCROOT}表示工程的根目录。用了这么久的Xcode,这个有用过吧(全局头文件配置过吧?)?

文件状态判断

1
2
3
4
5
6
7
8
9
10
11
12
13
#判断build文件夹是否存在,存在则删除
if [ -d "${build_DIR}" ]
then
rm -rf "${build_DIR}"
fi

#判断目标文件夹是否存在,存在则删除该文件夹
if [ -d "${INSTALL_DIR}" ]
then
rm -rf "${INSTALL_DIR}"
fi
#创建目标文件夹
mkdir -p "${INSTALL_DIR}"

这里就是文件的操作了。如果有这两个文件夹,就删除掉。为什么?为了保证我们工程的纯净啊。

编译

1
2
3
4
5
6
7
8
#build之前clean一下
xcodebuild -target ${target_Name} clean

#模拟器build
xcodebuild -target ${target_Name} -configuration Release -sdk iphonesimulator

#真机build
xcodebuild -target ${target_Name} -configuration Release -sdk iphoneos

这里就跟平常操作一样了。先clean一下工程,然后模拟器编译一次,真机编译一次。

合并

1
2
3
4
5
#复制头文件到目标文件夹
cp -R "${DEVICE_DIR_INCLUDE}" "${INSTALL_DIR_Headers}"

#合成模拟器和真机.a包
lipo -create "${DEVICE_DIR_A}" "${SIMULATOR_DIR_A}" -output "${INSTALL_DIR_A}"

关键代码。拷贝头文件到我们的目标位置去。合成.a包。大功告成。

打开目标文件夹

1
2
#打开目标文件夹
open "${INSTALL_DIR}"

最后,打开文件夹。检查一下文件是否真正生成了。

shell脚本基础知识

如果你想了解更多关于shell脚本的知识,可以看看这篇文章:Linux shell脚本基础学习详细介绍

xcworkspace 工程对应的脚本

1
2
3
4
5
#模拟器build
xcodebuild -workspace ${target_Name}.xcworkspace -scheme ${target_Name} -configuration ${build_model} -sdk iphonesimulator

#真机build
xcodebuild -workspace ${target_Name}.xcworkspace -scheme ${target_Name} -configuration ${build_model} -sdk iphoneos

对于xcworkspace工程,需要将编译的脚本替换 ,其中–workspace、-scheme是必须的 ,scheme 可以通过xcodebuild -list 查看。

iOS设备架构

模拟器:
iPhone4s-iPnone5:i386
iPhone5s-iPhone7 Plus:x86_64

真机:
iPhone3gs-iPhone4s: armv7
iPhone5-iPhone5c: armv7s
iPhone5s-iPhone7 Plus: arm64

参考

【iOS开发】静态库.a文件合成脚本解释