extract.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387
  1. #! /bin/bash
  2. # LOCK_PATTERN=bash_lock
  3. # LOCK_FILE=${LOCK_PATTERN}.$$
  4. # cleanup ()
  5. # {
  6. # rm -f ${LOCK_FILE}
  7. # }
  8. # trap cleanup EXIT
  9. # if [ "$(ls ${LOCK_PATTERN}.* 2>/dev/null)" = "" ];then
  10. # echo "LOCK" > ${LOCK_FILE}
  11. # else
  12. # echo "Another Extract Script Is Running, Exit..."
  13. # exit
  14. # fi
  15. env_check()
  16. {
  17. if [ "${OS}" = "Linux" ]; then
  18. export PATH=tools/prebuilt/ubuntu/bin:${PATH}
  19. fi
  20. gawk --help > /dev/null 2>&1
  21. if [ "$?" != "0" ];then
  22. echo "Please install gawk, using sudo apt-get install gawk for ubuntu 16.04"
  23. exit
  24. fi
  25. }
  26. extract_from_cloud()
  27. {
  28. OS=$(uname)
  29. EXTRACT_ID=$(curl --connect-timeout 5 -sF "file=@make.settings" --url https://linkkit.aliyuncs.com/upload/config?pk=a1AuWIoEr4Z\&os=${OS})
  30. # echo ${EXTRACT_ID}
  31. RETRY_COUNT=0
  32. if [ "${EXTRACT_ID}" != "" ];then
  33. echo ". Download request sent, waiting respond ..."
  34. sleep 2
  35. while :
  36. do
  37. DOWNLOAD_FILE=$(curl -s --connect-timeout 5 https://linkkit.aliyuncs.com/get/linkkit?extractId=${EXTRACT_ID})
  38. # echo ${DOWNLOAD_FILE}
  39. if [ "${DOWNLOAD_FILE}" = "404" ] || [ "${DOWNLOAD_FILE}" = "" ];then
  40. break
  41. elif [ "${DOWNLOAD_FILE}" = "406" ];then
  42. echo ". Respond generating, wait longer"
  43. if [ "${RETRY_COUNT}" = "20" ];then
  44. break
  45. fi
  46. RETRY_COUNT=$[RETRY_COUNT+1]
  47. echo ". Retried ${RETRY_COUNT}/20"
  48. sleep 2
  49. else
  50. echo ""
  51. curl ${DOWNLOAD_FILE} > output.zip
  52. rm -rf output
  53. unzip -q output.zip
  54. rm -rf output.zip
  55. echo ""
  56. echo "Please pick up extracted source files in [${PWD}/${OUTPUT_DIR}]"
  57. echo ""
  58. # rm -rf ${LOCK_FILE}
  59. exit
  60. fi
  61. done
  62. fi
  63. }
  64. OS="$(uname)"
  65. if [ "${OS}" = "Linux" ]; then
  66. FIND="find -L"
  67. else
  68. FIND="find"
  69. fi
  70. OUTPUT_DIR=output
  71. INFRA_DIR=${OUTPUT_DIR}/eng/infra
  72. WRAPPERS_DIR=${OUTPUT_DIR}/eng/wrappers
  73. XTRC_FILE_RULS=./tools/misc/xtrc_file_rules
  74. TEMP_FILE_RULS="${PWD}/.temp_file_rule_filter"
  75. XTRC_WRAPPER_RULS=./tools/misc/xtrc_wrapper_rules
  76. TEMP_WRAPPER_RULS="${PWD}/.temp_wrapper_rule_filter"
  77. WRAPPER_DOC=./tools/misc/wrapper
  78. # Try Extract Linkkit From Cloud
  79. #
  80. if [ "$1" = "" ] || ( [ "$1" != "test" ] && [ "$1" != "local" ] ) then
  81. extract_from_cloud
  82. fi
  83. # environment check
  84. env_check
  85. # Prepare Config Macro In make.settings
  86. MACRO_LIST=$(sed -n '/#/!{/=y/p}' make.settings | sed -n 's/=y//gp' | sed -n 's/FEATURE_//gp')
  87. mkdir -p ${OUTPUT_DIR} ${OUTPUT_DIR}/examples
  88. rm -rf $(${FIND} ${OUTPUT_DIR} -mindepth 1 -maxdepth 1|grep -v release)
  89. # Generate infra_config.h and extract necessary infra files
  90. mkdir -p ${INFRA_DIR}
  91. echo "#ifndef _INFRA_CONFIG_H_" > ${INFRA_DIR}/infra_config.h
  92. echo -e "#define _INFRA_CONFIG_H_\n" >> ${INFRA_DIR}/infra_config.h
  93. echo "${MACRO_LIST}" | sed -n 's/^/#define /p' >> ${INFRA_DIR}/infra_config.h
  94. echo -e "\n#endif" >> ${INFRA_DIR}/infra_config.h
  95. ${FIND} ./src -name "infra_types.h" | xargs -i cp -f {} ${INFRA_DIR}
  96. ${FIND} ./src -name "infra_defs.[ch]" | xargs -i cp -f {} ${INFRA_DIR}
  97. ${FIND} ./src -name "infra_list.h" | xargs -i cp -f {} ${INFRA_DIR}
  98. ${FIND} ./src -name "infra_compat.[ch]" | xargs -i cp -f {} ${INFRA_DIR}
  99. # echo -e "${MACRO_LIST}"
  100. cond_and_check()
  101. {
  102. COND_AND_VAR=$(echo $1 | gawk -F '&' '{for(i=1;i<=NF;i++){print $i;}}')
  103. # echo "${COND_AND_VAR}"
  104. for item in ${COND_AND_VAR}
  105. do
  106. echo ${MACRO_LIST} | grep -wo ${item} > /dev/null
  107. if [ $? -ne 0 ];then
  108. return 1
  109. fi
  110. done
  111. return 0
  112. }
  113. cond_not_check()
  114. {
  115. COND_NOT_VAR=$(echo $1 | gawk -F '&' '{for(i=1;i<=NF;i++){print $i;}}')
  116. # echo "${COND_AND_VAR}"
  117. for item in ${COND_NOT_VAR}
  118. do
  119. echo ${MACRO_LIST} | grep -wo ${item} > /dev/null
  120. if [ $? -eq 0 ];then
  121. return 0
  122. fi
  123. done
  124. return 1
  125. }
  126. DOTS_LINE=".................................................................."
  127. extract_file_by()
  128. {
  129. local rule="$*"
  130. COND_AND=$(echo $rule | gawk -F'|' '{print $1}')
  131. COND_NOT=$(echo $rule | gawk -F'|' '{print $2}')
  132. SRC_DIR=$(echo $rule | gawk -F'|' '{print $3}')
  133. DEST_DIR=$(echo $rule | gawk -F'|' '{print $4}')
  134. # echo "${COND_AND}"
  135. cond_and_check "${COND_AND}"
  136. if [ $? -ne 0 ]; then
  137. return 1
  138. fi
  139. # echo "${COND_NOT}"
  140. cond_not_check "${COND_NOT}"
  141. if [ $? -eq 0 ]; then
  142. return 1
  143. fi
  144. # echo "${SRC_DIR}"
  145. # echo "${DEST_DIR}"
  146. if [ "${DEST_DIR}" != "" ];then
  147. mkdir -p ${DEST_DIR} && ${FIND} ${SRC_DIR} -maxdepth 1 -name *.[ch] | xargs -i cp -rf {} ${DEST_DIR}
  148. fi
  149. }
  150. echo ""
  151. echo "Analysing extract rules for sources and wrappers ..."
  152. echo ""
  153. SWITCHES=$(cat make.settings | grep -v '^#' | sed '/^$/d;s:FEATURE_::g;s:=.*::g')
  154. SWCH_PAT="$(echo ${SWITCHES}|sed 's: :\\\|:g')"
  155. SPEC_PAT="$(echo ${SWITCHES}|sed 's:\([_A-Z]*\) :^\1||\\\|:g')"
  156. SPEC_PAT="${SPEC_PAT}||"
  157. grep ${SWCH_PAT} ${XTRC_FILE_RULS} > ${TEMP_FILE_RULS}
  158. grep ${SWCH_PAT} ${XTRC_WRAPPER_RULS} > ${TEMP_WRAPPER_RULS}
  159. FUNC_NAME_LIST=""
  160. HEADER_FILE_LIST=""
  161. FUNC_NAME_LIST=$(grep "${SPEC_PAT}" ${TEMP_WRAPPER_RULS}|gawk -F '|' '{ print $3 }'|sort -u)
  162. HEADER_FILE_LIST=$(grep "${SPEC_PAT}" ${TEMP_WRAPPER_RULS}|gawk -F '|' '{ print $4 }'|sort -u)
  163. FUNC_PAT="$(echo ${FUNC_NAME_LIST}|sed 's: :\\\|:g')"
  164. HDER_PAT="$(echo ${HEADER_FILE_LIST}|sed 's: :\\\|:g')"
  165. # [ "${FUNC_PAT}" != "" ] && sed -i "/${FUNC_PAT}/d" ${TEMP_WRAPPER_RULS}
  166. # [ "${HDER_PAT}" != "" ] && sed -i "/${HDER_PAT}/d" ${TEMP_WRAPPER_RULS}
  167. if [ "${FUNC_PAT}" != "" ] && [ "${HDER_PAT}" != "" ]; then
  168. sed -i "/${FUNC_PAT}/{/${HDER_PAT}/d}" ${TEMP_WRAPPER_RULS}
  169. fi
  170. printf "Interpret [%03d] sources rules" $(cat ${TEMP_FILE_RULS}|wc -l|sed 's/[[:space:]]//g')
  171. printf " from [%03d] base\n" $(cat ${XTRC_FILE_RULS}|wc -l|sed 's/[[:space:]]//g')
  172. printf "Interpret [%03d] wrapper rules" $(cat ${TEMP_WRAPPER_RULS}|wc -l|sed 's/[[:space:]]//g')
  173. printf " from [%03d] base" $(cat ${XTRC_WRAPPER_RULS}|wc -l|sed 's/[[:space:]]//g')
  174. echo ""
  175. FUNC_NAME_LIST="$(echo ${FUNC_NAME_LIST}|tr ' ' '\n')\n"
  176. HEADER_FILE_LIST="$(echo ${HEADER_FILE_LIST}|tr ' ' '\n')\n"
  177. echo ""
  178. # Read xtrc_file_rules
  179. TOTAL_ITERATION=$(wc -l ${TEMP_FILE_RULS}|gawk '{ print $1 }')
  180. ITER=0
  181. while read rule
  182. do
  183. ITER=$(( ${ITER} + 1 ))
  184. printf "\r%.40s %.2f%%" "Extract Files ${DOTS_LINE}" $(echo 100*${ITER}/${TOTAL_ITERATION}|bc -l)
  185. TEST=$(echo $rule | gawk -F'|' '{print NF}')
  186. if [ ${TEST} -ne 4 ];then
  187. continue
  188. fi
  189. if [ "${OS}" = "Linux" ]; then
  190. extract_file_by ${rule} &
  191. else
  192. extract_file_by ${rule}
  193. fi
  194. done < ${TEMP_FILE_RULS}
  195. [ "${OS}" = "Linux" ] && wait
  196. rm -f ${TEMP_FILE_RULS}
  197. echo -e ""
  198. # Generate wrapper.c
  199. mkdir -p ${WRAPPERS_DIR}
  200. cp -f wrappers/wrappers_defs.h ${WRAPPERS_DIR}/
  201. # Read xtrc_wrapper_rules
  202. TOTAL_ITERATION=$(wc -l ${TEMP_WRAPPER_RULS}|gawk '{ print $1 }')
  203. ITER=0
  204. while read rule
  205. do
  206. ITER=$(( ${ITER} + 1 ))
  207. printf "\r%.40s %.2f%%" "Extract HAL/Wrapper Functions ${DOTS_LINE}" $(echo 100*${ITER}/${TOTAL_ITERATION}|bc -l)
  208. TEST=$(echo $rule | gawk -F'|' '{print NF}')
  209. if [ ${TEST} -ne 4 ];then
  210. continue
  211. fi
  212. COND_AND=$(echo $rule | gawk -F'|' '{print $1}')
  213. COND_NOT=$(echo $rule | gawk -F'|' '{print $2}')
  214. FUNC_NAME=$(echo $rule | gawk -F'|' '{print $3}')
  215. HEADER_FILE=$(echo $rule | gawk -F'|' '{print $4}')
  216. # echo "${COND_AND}"
  217. cond_and_check "${COND_AND}"
  218. if [ $? -ne 0 ];then
  219. continue
  220. fi
  221. # echo "${COND_NOT}"
  222. cond_not_check "${COND_NOT}"
  223. if [ $? -eq 0 ];then
  224. continue
  225. fi
  226. if [ "${FUNC_NAME}" != "" ];then
  227. FUNC_NAME_LIST="${FUNC_NAME_LIST}""${FUNC_NAME}\n"
  228. fi
  229. if [ "${HEADER_FILE}" != "" ];then
  230. HEADER_FILE_LIST="${HEADER_FILE_LIST}""${HEADER_FILE}\n"
  231. fi
  232. done < ${TEMP_WRAPPER_RULS}
  233. rm -f ${TEMP_WRAPPER_RULS}
  234. echo -e ""
  235. FUNC_NAME_LIST=$(echo -e "${FUNC_NAME_LIST}" | sed -n '/^$/!{p}' | sort -u)
  236. HEADER_FILE_LIST=$(echo -e "${HEADER_FILE_LIST}" | sed -n '/^$/!{p}' | sort -u)
  237. # For Debug
  238. if [ "${FUNC_NAME_LIST}" != "" ];then
  239. echo -e "\nHAL/Wrapper Function List:" && echo -e "${FUNC_NAME_LIST}" |gawk '{ printf("%03d %s\n", NR, $0); }'
  240. fi
  241. if [ "${HEADER_FILE_LIST}" != "" ];then
  242. echo -e "\nHAL/Wrapper Header File List:" && echo -e "${HEADER_FILE_LIST}" |gawk '{ printf("%03d %s\n", NR, $0); }'
  243. fi
  244. # Annotation For wrapper.c
  245. sed -n '/WRAPPER_NOTE:/{:a;N;/*\//!ba;p}' ${WRAPPER_DOC} | sed -n '1d;p' >> ${WRAPPERS_DIR}/wrapper.c
  246. # Output Header File Into wrapper.c
  247. echo -e "#include \"infra_types.h\"" >> ${WRAPPERS_DIR}/wrapper.c
  248. echo -e "#include \"infra_defs.h\"" >> ${WRAPPERS_DIR}/wrapper.c
  249. echo -e "#include \"infra_compat.h\"" >> ${WRAPPERS_DIR}/wrapper.c
  250. echo -e "#include \"wrappers_defs.h\"" >> ${WRAPPERS_DIR}/wrapper.c
  251. echo -e "${HEADER_FILE_LIST}" | sed -n '/.h/{s/^/#include "/p}' | sed -n 's/$/"/p' >> ${WRAPPERS_DIR}/wrapper.c
  252. echo -e "" >> ${WRAPPERS_DIR}/wrapper.c
  253. # Generate Default Implenmentation For HAL/Wrapper Function
  254. echo ""
  255. TOTAL_ITERATION=$(echo "${FUNC_NAME_LIST}"|wc -w|sed 's/[[:space:]]//g')
  256. ITER=0
  257. for func in $(echo "${FUNC_NAME_LIST}")
  258. do
  259. ITER=$(( ${ITER} + 1 ))
  260. printf "\r%.40s %.2f%%" "Generate wrapper.c ${DOTS_LINE}" $(echo 100*${ITER}/${TOTAL_ITERATION}|bc -l)
  261. # echo ${func}
  262. if [ "${func}" = "" ];then
  263. continue
  264. fi
  265. FUNC_DEC=$(${FIND} ./${OUTPUT_DIR}/eng -name *wrapper.h | xargs -i cat {})
  266. FUNC_DEC=$(echo "${FUNC_DEC}" | sed -n '/.*'${func}'(.*/{/.*);/ba;{:c;N;/.*);/!bc};:a;p;q}')
  267. DATA_TYPE=$(echo "${FUNC_DEC}" | head -1 | gawk -F' ' '{if ($1~/^DLL/ || $1~/extern/) {if ($3~/*/) {print $2"*";} else {print $2;}} else {if ($2~/*/) {print $1"*";} else {print $1;}}}'# | sed s/[[:space:]]//g)
  268. # echo -e "\n${DATA_TYPE}"
  269. sed -n '/'${func}':/{:a;N;/*\//!ba;p}' ${WRAPPER_DOC} | sed -n '1d;p' >> ${WRAPPERS_DIR}/wrapper.c
  270. if [ "${DATA_TYPE}" = "void" ];then
  271. echo "${FUNC_DEC}" | sed -n '/;/{s/;/\n{\n\treturn;\n}\n\n/g};p' >> ${WRAPPERS_DIR}/wrapper.c
  272. else
  273. echo "${FUNC_DEC}" | sed -n '/;/{s/;/\n{\n\treturn ('${DATA_TYPE}')1;\n}\n\n/g};p' >> ${WRAPPERS_DIR}/wrapper.c
  274. fi
  275. done
  276. if [ "${TOTAL_ITERATION}" = "0" ]; then
  277. echo "Only [dev_sign] enabled, so NO function requires being implemented in [${WRAPPERS_DIR}/wrapper.c]"
  278. else
  279. echo ""
  280. fi
  281. echo -e "#ifndef _SDK_INCLUDE_H_" > ${OUTPUT_DIR}/eng/sdk_include.h
  282. echo -e "#define _SDK_INCLUDE_H_\n" >> ${OUTPUT_DIR}/eng/sdk_include.h
  283. echo -e "#include \"infra_types.h\"" >> ${OUTPUT_DIR}/eng/sdk_include.h
  284. echo -e "#include \"infra_defs.h\"" >> ${OUTPUT_DIR}/eng/sdk_include.h
  285. echo -e "#include \"infra_compat.h\"" >> ${OUTPUT_DIR}/eng/sdk_include.h
  286. echo -e "#include \"wrappers_defs.h\"" >> ${OUTPUT_DIR}/eng/sdk_include.h
  287. find ${OUTPUT_DIR}/eng -name "*wrapper.h" | gawk -F'/' '{print $NF}' | sed -n 's/^/#include "/g;s/$/"/gp' >> ${OUTPUT_DIR}/eng/sdk_include.h
  288. find ${OUTPUT_DIR}/eng -name "*api.h" | gawk -F'/' '{print $NF}' | sed -n 's/^/#include "/g;s/$/"/gp' >> ${OUTPUT_DIR}/eng/sdk_include.h
  289. echo -e "\n#endif" >> ${OUTPUT_DIR}/eng/sdk_include.h
  290. # if echo "${SWITCHES}"|grep -qw "DEVICE_MODEL_ENABLED"; then
  291. # echo ""
  292. # bash tools/misc/compose.sh ${PWD}/output/examples/linkkit_example_auto.c
  293. # fi
  294. echo ""
  295. echo "Please pick up extracted source files in [${PWD}/${OUTPUT_DIR}]"
  296. echo ""
  297. cp tools/misc/makefile.output output/Makefile
  298. if [ "${1}" = "test" ];then
  299. ENV_TEST=$(cat .config 2>/dev/null| sed -n '/VENDOR/{s/[[:space:]]//gp}'| gawk -F ':' '{print $2}')
  300. if [ "${ENV_TEST}" = "ubuntu" ];then
  301. rm -f ${WRAPPERS_DIR}/wrapper.c
  302. cp -rf wrappers/os/ubuntu ${WRAPPERS_DIR}/
  303. cp -rf wrappers/tls ${WRAPPERS_DIR}/
  304. cp -rfl external_libs ${WRAPPERS_DIR}/
  305. rm -f ${WRAPPERS_DIR}/ubuntu/HAL_UART_linux.c
  306. fi
  307. fi
  308. # rm -rf ${LOCK_FILE}