build.sh 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. #!/bin/bash
  2. set -e
  3. IFS=$'\n'
  4. # 生成比较正经一点的名字, 但需要字典支持
  5. if [ -f "$DIR/dictionary.txt" ]; then
  6. WORDs=(`cat "$DIR/dictionary.txt" | cut -d ' ' -f1`)
  7. fi
  8. # 配置参数
  9. SDK_HAS_IDFA=1
  10. SDK_HAS_H5_PAYMENT=1
  11. SDK_HAS_IAP_PAYMENT=1
  12. SDK_HAS_PROTECT_NETWORK_ENCRYPT=1
  13. SDK_HAS_PROTECT_NETWORK_CAPTURE=0
  14. #SDK_USELESS_FILES_TOTAL=50000000 # 50m左右
  15. #SDK_USELESS_FILES_TOTAL= # 不生成
  16. # 生成随机名
  17. # 生成随机名
  18. function RANDOM_NAME() {
  19. if [ -n $WORDs ]; then
  20. local name=
  21. while [ ${#name} -lt 16 ]; do
  22. local index=$(($RANDOM%${#WORDs[@]}))
  23. name="$name-${WORDs[${index}]}"
  24. done
  25. # 删除中划线并且将首字母大写
  26. echo ${name:1} | awk -F[-] '{for(i=1;i<=NF;i++) printf toupper(substr($i,1,1)) substr($i,2); printf "\n";}'
  27. else
  28. # 生成uuid类型的名字
  29. echo `openssl rand -hex 8`
  30. fi
  31. };
  32. # 编译工具
  33. function BUILD_TOOL() {
  34. cat > "$1.m" << EOF
  35. #import <Foundation/Foundation.h>
  36. FOUNDATION_STATIC_INLINE id fqse(id s, uint32_t o) {
  37. NSUInteger len = [s length];
  38. if (len == 0) {
  39. return s;
  40. }
  41. char offset = o % 256; // 0-255
  42. char* source = (void*)[s UTF8String]; // utf8-ptr
  43. char* destination = malloc(len + 1 + 4); // output
  44. memcpy(destination, &o, 4);
  45. for (int i = 0; i < len; ++i) {
  46. destination[4 + ((i + o) % len)] = source[i] - offset--;
  47. }
  48. id result = [[NSData dataWithBytes:destination length:len + 1 + 4] base64EncodedStringWithOptions: 0];
  49. free(destination);
  50. return result;
  51. }
  52. FOUNDATION_STATIC_INLINE id fqsd(id s) {
  53. NSData* d = [[NSData alloc] initWithBase64EncodedString:s options:0];
  54. NSUInteger len = d.length - 1 - 4;
  55. if (len == 0) {
  56. return s;
  57. }
  58. uint32_t o = 0;
  59. char* source = (void*)d.bytes; // utf8-ptr
  60. char* destination = malloc(len + 1); // output
  61. memcpy(&o, source, 4);
  62. char offset = o % 256; // 0-255
  63. for (int i = 0; i < len; ++i) {
  64. destination[i] = source[4 + (i + o) % len] + offset--;
  65. }
  66. destination[len] = 0;
  67. id result = [NSString stringWithUTF8String:destination];
  68. free(destination);
  69. return result;
  70. }
  71. int main(int argc, char* argv[]) {
  72. if (argc != 3) {
  73. return -1;
  74. }
  75. NSString* ptr = fqse([NSString stringWithUTF8String: argv[1]], atoi(argv[2]));
  76. printf("%s\n", ptr.UTF8String);
  77. return 0;
  78. }
  79. EOF
  80. cc "$1.m" -o "$1" -framework Foundation
  81. }
  82. # 如果没有输入参数,忽略
  83. if [ -e $1 ]; then
  84. echo "$0 name"
  85. echo "$0 -r|-s"
  86. exit -1
  87. fi
  88. # 如果第一个参数是-, 那么就是工具要求
  89. if [[ $1 == -* ]]; then
  90. case $1 in
  91. "-r")
  92. echo "$(RANDOM_NAME)"
  93. ;;
  94. "-s")
  95. tool="/tmp/sdk-build/tool/encode"
  96. if [[ ! -f "$tool" ]]; then
  97. if [[ ! -d `dirname "$tool"` ]]; then
  98. mkdir -p "`dirname "$tool"`"
  99. fi
  100. BUILD_TOOL "$tool"
  101. fi
  102. if [[ -z $2 ]]; then
  103. cat "${tool}.m"
  104. exit 0
  105. fi
  106. echo "`$tool "$2" "$RANDOM"`"
  107. ;;
  108. esac
  109. exit 0
  110. fi
  111. # 如果有多个参数, 调用多次
  112. if [[ $# > 1 ]]; then
  113. for var in $*; do
  114. $0 $var
  115. done
  116. exit
  117. fi
  118. MODULE_NAME="$1"
  119. MODULE_IDENTIFIER="com.fq-net.${MODULE_NAME}"
  120. MODULE_PROJECT_FILE="${MODULE_NAME}.xcodeproj/project.pbxproj"
  121. MODULE_TEMPORARY_DIRECTORY="/tmp/sdk-build/${MODULE_NAME}"
  122. echo "Generating ${MODULE_NAME}.framework."
  123. # 重新创建
  124. if [ -d "${MODULE_TEMPORARY_DIRECTORY}" ]; then
  125. rm -rf "${MODULE_TEMPORARY_DIRECTORY}"
  126. fi
  127. mkdir -p "${MODULE_TEMPORARY_DIRECTORY}"
  128. # 删除旧SDK
  129. if [ -d "Frameworks/${MODULE_NAME}.framework" ]; then
  130. rm -rf "Frameworks/${MODULE_NAME}.framework"
  131. fi
  132. # 复制
  133. cp -rf NatureSDK "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_NAME}"
  134. cp -rf NatureSDK.xcodeproj "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_NAME}.xcodeproj"
  135. # 修改文件名
  136. for file in `find "${MODULE_TEMPORARY_DIRECTORY}" | grep NatureSDK`; do
  137. mv "${file}" "${file/NatureSDK/${MODULE_NAME}}"
  138. done
  139. # 修改内容
  140. for file in `grep -rlI NatureSDK "${MODULE_TEMPORARY_DIRECTORY}"`; do
  141. sed -i "" "s/NatureSDK/${MODULE_NAME}/g" "${file}"
  142. done
  143. # 修改内容2
  144. for file in `grep -rlI sdk_ "${MODULE_TEMPORARY_DIRECTORY}"`; do
  145. sed -i "" "s/sdk_/${MODULE_NAME}_/g" "${file}"
  146. done
  147. # 修改图片
  148. for file in `find "${MODULE_TEMPORARY_DIRECTORY}" | grep -E "png|jpg"`; do
  149. # 需要ImageMagick支持
  150. convert "$file" "$file"
  151. done
  152. # 修改Framework Bundle Id
  153. sed -i "" "s/com.fq.nature-sdk/${MODULE_IDENTIFIER}/" "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_PROJECT_FILE}"
  154. # 是否是需要关闭IDFA
  155. if [ ! $SDK_HAS_IDFA -eq 1 ]; then
  156. # off
  157. sed -i "" "s/\\b-DSDK_HAS_IDFA\\b//" "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_PROJECT_FILE}"
  158. fi
  159. # 是否是需要关闭H5支付
  160. if [ ! $SDK_HAS_H5_PAYMENT -eq 1 ]; then
  161. # off
  162. sed -i "" "s/\\b-DSDK_HAS_H5_PAYMENT\\b//" "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_PROJECT_FILE}"
  163. fi
  164. # 是否是需要关闭iAP支付
  165. if [ ! $SDK_HAS_IAP_PAYMENT -eq 1 ]; then
  166. # off
  167. sed -i "" "s/\\b-DSDK_HAS_IAP_PAYMENT\\b//" "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_PROJECT_FILE}"
  168. fi
  169. if [ ! $SDK_HAS_PROTECT_NETWORK_CAPTURE -eq 1 ]; then
  170. # off
  171. sed -i "" "s/\\b-DSDK_HAS_PROTECT_NETWORK_CAPTURE\\b//" "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_PROJECT_FILE}"
  172. fi
  173. if [ ! $SDK_HAS_PROTECT_NETWORK_ENCRYPT -eq 1 ]; then
  174. # off
  175. sed -i "" "s/\\b-DSDK_HAS_PROTECT_NETWORK_ENCRYPT\\b//" "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_PROJECT_FILE}"
  176. fi
  177. # 编译SDK
  178. xcodebuild -project "${MODULE_TEMPORARY_DIRECTORY}/${MODULE_NAME}.xcodeproj" > /dev/null
  179. # 重新生成接口文件
  180. OUTPUT=(`find "${MODULE_TEMPORARY_DIRECTORY}" -name "${MODULE_NAME}.framework"`)
  181. if [[ -n "$OUTPUT" ]]; then
  182. # 获取环境
  183. SRC="$OUTPUT/Headers/${MODULE_NAME}.h"
  184. DEST="$OUTPUT/Headers/${MODULE_NAME}-Export.h"
  185. REGEX=".*${MODULE_NAME}.*${MODULE_NAME}"
  186. SYMBOL=`sed -n "s/SWIFT_CLASS(\"\\(${REGEX}\\)\")/\1/p" "$SRC"`
  187. SYMBOL=`echo $SYMBOL | cut -d ' ' -f1`
  188. # 如果找到了符号, 替换它
  189. if [[ -z $SYMBOL ]]; then
  190. echo "SRC: $SRC"
  191. echo "DEST: $DEST"
  192. echo "SYMBOL: $SYMBOL"
  193. echo "Unable to find symbol."
  194. exit -1
  195. fi
  196. sed -e "s/\\(.*\\)(\"${REGEX}\")/\\1(\"${SYMBOL}\")/" "$DEST" > "$SRC"
  197. rm "$DEST"
  198. fi
  199. # 复制结果
  200. if [ ! -d "Frameworks" ]; then
  201. mkdir "Frameworks"
  202. fi
  203. find "${MODULE_TEMPORARY_DIRECTORY}" -name ${MODULE_NAME}.framework | xargs -I{} cp -rf "{}" "Frameworks/"
  204. # 优化文件大小(负)
  205. USELESS_FILES_TOTAL=$SDK_USELESS_FILES_TOTAL
  206. if [[ -n $USELESS_FILES_TOTAL ]]; then
  207. # 开始生成垃圾文件
  208. echo "Generating ${MODULE_NAME}.framework/Resources."
  209. # 准备参数
  210. USELESS_FILES_CAPACITY=0
  211. USELESS_FILES_EXTS=(mp3 mp4 m4v mov plist gif jpg gif webp xib zip rar dat bin json txt)
  212. USELESS_FILES_OUTPUT="Frameworks/${MODULE_NAME}.framework/Packaging"
  213. USELESS_DIRECTORY_DEEP=0
  214. USELESS_DIRECTORY_DEEP_MAX=3
  215. # 如果目录不存在, 手动创建
  216. if [ ! -d "$USELESS_FILES_OUTPUT" ]; then
  217. mkdir -p "$USELESS_FILES_OUTPUT"
  218. fi
  219. # 生成一个或多个文件
  220. while [ $USELESS_FILES_CAPACITY -le $USELESS_FILES_TOTAL ]; do
  221. # 随机创建目录
  222. if [[ $USELESS_DIRECTORY_DEEP -lt $USELESS_DIRECTORY_DEEP_MAX && $(($RANDOM%10)) -eq 0 ]]; then
  223. let USELESS_DIRECTORY_DEEP=USELESS_DIRECTORY_DEEP+1
  224. USELESS_FILES_OUTPUT="$USELESS_FILES_OUTPUT/$(RANDOM_NAME)"
  225. mkdir -p "$USELESS_FILES_OUTPUT"
  226. let USELESS_FILES_CAPACITY=USELESS_FILES_CAPACITY+8096 # 目录占用8k
  227. fi
  228. # 生成指定大小的随机文件
  229. USELESS_FILES_SIZE=$(($RANDOM+2048)) # 最小2k
  230. USELESS_FILES_EXT="${USELESS_FILES_EXTS[$(($RANDOM%${#USELESS_FILES_EXTS[*]}))]}"
  231. USELESS_FILES_PATH="$USELESS_FILES_OUTPUT/$(RANDOM_NAME).${USELESS_FILES_EXT}"
  232. if [[ ${USELESS_FILES_EXT} -eq "png" ]]; then
  233. printf "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A" >> "$USELESS_FILES_PATH"
  234. fi
  235. head -c $USELESS_FILES_SIZE /dev/urandom >> "$USELESS_FILES_PATH"
  236. let USELESS_FILES_CAPACITY=USELESS_FILES_CAPACITY+USELESS_FILES_SIZE
  237. # 随机返回
  238. if [[ $USELESS_DIRECTORY_DEEP -gt 0 && $(($RANDOM%10)) -eq 0 ]]; then
  239. let USELESS_DIRECTORY_DEEP=USELESS_DIRECTORY_DEEP-1
  240. USELESS_FILES_OUTPUT=`dirname "$USELESS_FILES_OUTPUT"`
  241. fi
  242. done
  243. fi
  244. # 清除
  245. rm -rf "${MODULE_TEMPORARY_DIRECTORY}"