gen_pack.sh 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. #!/bin/bash
  2. # Version: 1.5
  3. # Date: 2022-04-06
  4. # This bash script generates a CMSIS Software Pack:
  5. #
  6. # Pre-requisites:
  7. # - bash shell (for Windows: install git for Windows)
  8. # - git in path (for Windows: install git for Windows)
  9. # - 7z in path (zip archiving utility)
  10. # e.g. Ubuntu: sudo apt-get install p7zip-full p7zip-rar)
  11. # - xmllint in path (XML schema validation; available only for Linux)
  12. #
  13. # Preparation steps:
  14. # - Generate documentation, see CMSIS/DoxyGen/gen_doc.sh
  15. # - Populate utilities, see
  16. # - CMSIS/Utilities/fetch_devtools.sh
  17. # - Populate pre-built libraries, see
  18. # - CMSIS/RTOS/RTX/LIB/fetch_libs.sh
  19. # - CMSIS/RTOS2/RTX/Library/fetch_libs.sh
  20. #
  21. ############### EDIT BELOW ###############
  22. # Extend Path environment variable locally
  23. #
  24. set -o pipefail
  25. function usage {
  26. echo "$(basename $0) [-h|--help] [<pdsc>]"
  27. echo ""
  28. echo "Arguments:"
  29. echo " -h|--help Print this usage message and exit."
  30. echo " --ignore_errors Ignore errors detected during pack generation."
  31. echo " --version <VER> Force pack version to <VER>."
  32. echo " pdsc The pack description to generate the pack for."
  33. echo ""
  34. echo "Environment:"
  35. echo " 7z"
  36. if [ $(uname -s) = "Linux" ]; then
  37. echo " xmllint"
  38. fi
  39. echo ""
  40. }
  41. function pack_version()
  42. {
  43. local version=$(grep -Pzo "(?s)<releases>\s+<release version=\"([^\"]+)\"" "$1" | tr -d '\0' | tail -n 1 | sed -r -e 's/.*version="([^"]+)"/\1/g')
  44. echo "PDSC version: '$version'" >&2
  45. echo $version
  46. }
  47. function git_describe()
  48. {
  49. if git rev-parse --git-dir 2>&1 >/dev/null; then
  50. local gitversion=$(git describe --tags --match $1* --abbrev=9 2>/dev/null || echo "$1-dirty-0-g$(git describe --tags --match $1* --always --abbrev=9 2>/dev/null)")
  51. local version=$(echo $gitversion | sed -r -e 's/-([0-9]+)-(g[0-9a-f]{9})/\1+\2/')
  52. if [[ $version != $1 ]] && [[ $version == $gitversion ]]; then
  53. version+=0
  54. fi
  55. echo "Git version: '$version'" >&2
  56. echo $version
  57. else
  58. echo "No Git repository: '$1-nogit'" >&2
  59. echo "$1-nogit"
  60. fi
  61. }
  62. function patch_pdsc()
  63. {
  64. if [[ "$2" != "$3" ]]; then
  65. echo "Updating latest release tag with version '$3'"
  66. sed -r -i -e "s/<release version=\"$2\"/<release version=\"$3\"/" $1
  67. fi
  68. }
  69. IGNORE_ERRORS=0
  70. VERSION=
  71. POSITIONAL=()
  72. while [[ $# -gt 0 ]]
  73. do
  74. key="$1"
  75. case $key in
  76. '-h'|'--help')
  77. usage
  78. exit 1
  79. ;;
  80. '--ignore-errors')
  81. IGNORE_ERRORS=1
  82. shift # past argument
  83. ;;
  84. '--version')
  85. shift # past argument
  86. VERSION=$1
  87. shift # past argument
  88. ;;
  89. *) # unknown option
  90. POSITIONAL+=("$1") # save it in an array for later
  91. shift # past argument
  92. ;;
  93. esac
  94. done
  95. set -- "${POSITIONAL[@]}" # restore positional parameters
  96. OS=$(uname -s)
  97. case $OS in
  98. 'Linux')
  99. CMSIS_TOOLSDIR="./CMSIS/Utilities/Linux64"
  100. ;;
  101. 'WindowsNT'|MINGW*|CYGWIN*)
  102. CMSIS_TOOLSDIR="./CMSIS/Utilities/Win32"
  103. ;;
  104. 'Darwin')
  105. CMSIS_TOOLSDIR="./CMSIS/Utilities/Darwin64"
  106. ;;
  107. *)
  108. echo "Error: unrecognized OS $OS"
  109. exit 1
  110. ;;
  111. esac
  112. PATH_TO_ADD="$CMSIS_TOOLSDIR"
  113. [[ ":$PATH:" != *":${PATH_TO_ADD}:"* ]] && PATH="${PATH}:${PATH_TO_ADD}"
  114. echo $PATH_TO_ADD appended to PATH
  115. echo " "
  116. # Pack warehouse directory - destination
  117. PACK_WAREHOUSE=./output
  118. # Temporary pack build directory
  119. PACK_BUILD=./build
  120. # Specify directory names to be added to pack base directory
  121. PACK_DIRS="
  122. Device
  123. CMSIS/Core/Include
  124. CMSIS/Core/Template
  125. CMSIS/Core_A
  126. CMSIS/DAP
  127. CMSIS/Driver
  128. CMSIS/RTOS
  129. CMSIS/RTOS2
  130. CMSIS/Utilities/Win32
  131. CMSIS/Utilities/Linux64
  132. CMSIS/Utilities/Darwin64
  133. CMSIS/Documentation
  134. "
  135. # Specify file names to be added to pack base directory
  136. PACK_BASE_FILES="
  137. LICENSE.txt
  138. CMSIS/Utilities/ARM_Example.*
  139. CMSIS/Utilities/*.xsd
  140. "
  141. # Specify file names to be deleted from pack build directory
  142. PACK_DELETE_FILES="
  143. CMSIS/RTOS/CMSIS_RTOS_Tutorial.pdf
  144. CMSIS/RTOS/RTX/LIB/fetch_libs.sh
  145. CMSIS/RTOS/RTX/LIB/*.zip
  146. CMSIS/RTOS2/RTX/Library/fetch_libs.sh
  147. CMSIS/RTOS2/RTX/Library/*.zip
  148. CMSIS/RTOS2/RTX/Library/build.py
  149. "
  150. # Specify patches to be applied
  151. PACK_PATCH_FILES=""
  152. ############ DO NOT EDIT BELOW ###########
  153. echo Starting CMSIS-Pack Generation: `date`
  154. # Zip utility check
  155. ZIP=7z
  156. type -a "${ZIP}"
  157. errorlevel=$?
  158. if [ $errorlevel -gt 0 ]
  159. then
  160. echo "Error: No 7zip Utility found"
  161. echo "Action: Add 7zip to your path"
  162. echo " "
  163. exit 1
  164. fi
  165. # Pack checking utility check
  166. PACKCHK=packchk
  167. type -a ${PACKCHK}
  168. errorlevel=$?
  169. if [ $errorlevel != 0 ]; then
  170. echo "Error: No packchk Utility found"
  171. echo "Action: Add packchk to your path"
  172. echo "Hint: Included in CMSIS Pack:"
  173. echo "$CMSIS_PACK_ROOT/ARM/CMSIS/<version>/CMSIS/Utilities/<os>/"
  174. echo " "
  175. if [[ $IGNORE_ERRORS == 0 ]]; then
  176. exit 1
  177. fi
  178. fi
  179. echo " "
  180. # Locate Package Description file
  181. # check whether there is more than one pdsc file
  182. NUM_PDSCS=$(ls -1 *.pdsc | wc -l)
  183. PACK_DESCRIPTION_FILE=$(ls *.pdsc)
  184. if [[ -n $1 && -f $1 ]]; then
  185. PACK_DESCRIPTION_FILE=$1
  186. elif [ ${NUM_PDSCS} -lt 1 ]; then
  187. echo "Error: No *.pdsc file found in current directory"
  188. echo " "
  189. exit 1
  190. elif [ ${NUM_PDSCS} -gt 1 ]; then
  191. echo "Error: Only one PDSC file allowed in directory structure:"
  192. echo "Found:"
  193. echo "$PACK_DESCRIPTION_FILE"
  194. echo "Action: Provide PDSC file explicitly!"
  195. echo " "
  196. usage
  197. exit 1
  198. fi
  199. SAVEIFS=$IFS
  200. IFS=.
  201. set ${PACK_DESCRIPTION_FILE}
  202. # Pack Vendor
  203. PACK_VENDOR=$1
  204. # Pack Name
  205. PACK_NAME=$2
  206. echo "Generating Pack: for $PACK_VENDOR.$PACK_NAME"
  207. echo " "
  208. IFS=$SAVEIFS
  209. #if $PACK_BUILD directory does not exist, create it.
  210. if [ ! -d "$PACK_BUILD" ]; then
  211. mkdir -p "$PACK_BUILD"
  212. fi
  213. # Copy files into build base directory: $PACK_BUILD
  214. # pdsc file is mandatory in base directory:
  215. cp -f "./${PACK_VENDOR}.${PACK_NAME}.pdsc" "${PACK_BUILD}"
  216. # Add directories
  217. echo Adding directories to pack:
  218. echo "${PACK_DIRS}"
  219. echo " "
  220. for d in ${PACK_DIRS}; do
  221. cp -r --parents "$d" "${PACK_BUILD}"
  222. done
  223. # Add files
  224. echo Adding files to pack:
  225. echo "${PACK_BASE_FILES}"
  226. echo " "
  227. if [ ! -x ${PACK_BASE_FILES+x} ]; then
  228. for f in ${PACK_BASE_FILES}; do
  229. cp -f --parents "$f" $PACK_BUILD/
  230. done
  231. fi
  232. # Delete files
  233. echo Deleting files from pack:
  234. echo "${PACK_DELETE_FILES}"
  235. echo " "
  236. if [ ! -x ${PACK_DELETE_FILES+x} ]; then
  237. for f in ${PACK_DELETE_FILES}; do
  238. find $PACK_BUILD/$(dirname "$f") -name $(basename "$f") -delete
  239. done
  240. fi
  241. # Apply patches
  242. echo Applying patches to pack:
  243. echo "${PACK_PATCH_FILES}"
  244. echo " "
  245. if [ ! -x ${PACK_PATCH_FILES+x} ]; then
  246. CWD=$(pwd)
  247. pushd $PACK_BUILD > /dev/null
  248. for f in ${PACK_PATCH_FILES}; do
  249. patch -p0 -t -i "${CWD}/${f}"
  250. done
  251. popd > /dev/null
  252. fi
  253. # Create checksum file
  254. echo Creating checksum file:
  255. pushd $PACK_BUILD > /dev/null
  256. find . -type f -exec sha1sum {} + > ../${PACK_VENDOR}.${PACK_NAME}.sha1
  257. mv ../${PACK_VENDOR}.${PACK_NAME}.sha1 .
  258. popd > /dev/null
  259. # Run Schema Check (for Linux only):
  260. # sudo apt-get install libxml2-utils
  261. if [ $(uname -s) = "Linux" ]; then
  262. echo "Running schema check for ${PACK_VENDOR}.${PACK_NAME}.pdsc"
  263. curl https://raw.githubusercontent.com/Open-CMSIS-Pack/Open-CMSIS-Pack-Spec/main/schema/PACK.xsd -o CMSIS/Utilities/PACK.xsd
  264. xmllint --noout --schema "$(realpath -m ./CMSIS/Utilities/PACK.xsd)" "${PACK_BUILD}/${PACK_VENDOR}.${PACK_NAME}.pdsc"
  265. errorlevel=$?
  266. if [ $errorlevel -ne 0 ]; then
  267. echo "build aborted: Schema check of $PACK_VENDOR.$PACK_NAME.pdsc against PACK.xsd failed"
  268. echo " "
  269. if [[ $IGNORE_ERRORS == 0 ]]; then
  270. exit 1
  271. fi
  272. fi
  273. else
  274. echo "Use MDK PackInstaller to run schema validation for $PACK_VENDOR.$PACK_NAME.pdsc"
  275. fi
  276. # Patch pack version
  277. echo "Checking PDCS version against Git..."
  278. pdsc_version=$(pack_version "${PACK_BUILD}/${PACK_VENDOR}.${PACK_NAME}.pdsc")
  279. if [ -z $VERSION ]; then
  280. VERSION=$(git_describe ${pdsc_version})
  281. fi
  282. patch_pdsc "${PACK_BUILD}/${PACK_VENDOR}.${PACK_NAME}.pdsc" ${pdsc_version} ${VERSION}
  283. # Run Pack Check and generate PackName file with version
  284. "${PACKCHK}" "${PACK_BUILD}/${PACK_VENDOR}.${PACK_NAME}.pdsc" \
  285. -n ${PACK_BUILD}/PackName.txt \
  286. -x M353 -x M364 -x M335 -x M336
  287. errorlevel=$?
  288. if [ $errorlevel -ne 0 ]; then
  289. echo "build aborted: pack check failed"
  290. echo "Check preparation steps if missing files are reported!"
  291. echo " "
  292. if [[ $IGNORE_ERRORS == 0 ]]; then
  293. exit 1
  294. fi
  295. fi
  296. PACKNAME=$(cat ${PACK_BUILD}/PackName.txt)
  297. rm -rf ${PACK_BUILD}/PackName.txt
  298. # Archiving
  299. # $ZIP a $PACKNAME
  300. echo "creating pack file $PACKNAME"
  301. #if $PACK_WAREHOUSE directory does not exist create it
  302. if [ ! -d "$PACK_WAREHOUSE" ]; then
  303. mkdir -p "$PACK_WAREHOUSE"
  304. fi
  305. pushd "$PACK_WAREHOUSE" > /dev/null
  306. PACK_WAREHOUSE=$(pwd)
  307. popd > /dev/null
  308. pushd "$PACK_BUILD" > /dev/null
  309. PACK_BUILD=$(pwd)
  310. "$ZIP" a "$PACK_WAREHOUSE/$PACKNAME" -tzip
  311. popd > /dev/null
  312. errorlevel=$?
  313. if [ $errorlevel -ne 0 ]; then
  314. echo "build aborted: archiving failed"
  315. exit 1
  316. fi
  317. echo "build of pack succeeded"
  318. # Clean up
  319. echo "cleaning up ..."
  320. rm -rf "$PACK_BUILD"
  321. echo " "
  322. echo Completed CMSIS-Pack Generation: $(date)