gen_pack.sh 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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/DSP/ComputeLibrary
  129. CMSIS/DSP/Include
  130. CMSIS/DSP/Source
  131. CMSIS/DSP/Examples
  132. CMSIS/DSP/Include
  133. CMSIS/DSP/PrivateInclude
  134. CMSIS/NN
  135. CMSIS/RTOS
  136. CMSIS/RTOS2
  137. CMSIS/Utilities/Win32
  138. CMSIS/Utilities/Linux64
  139. CMSIS/Utilities/Darwin64
  140. CMSIS/Documentation
  141. "
  142. # Specify file names to be added to pack base directory
  143. PACK_BASE_FILES="
  144. LICENSE.txt
  145. CMSIS/Utilities/ARM_Example.*
  146. CMSIS/Utilities/*.xsd
  147. "
  148. # Specify file names to be deleted from pack build directory
  149. PACK_DELETE_FILES="
  150. CMSIS/RTOS/CMSIS_RTOS_Tutorial.pdf
  151. CMSIS/RTOS/RTX/LIB/fetch_libs.sh
  152. CMSIS/RTOS/RTX/LIB/*.zip
  153. CMSIS/RTOS2/RTX/Library/fetch_libs.sh
  154. CMSIS/RTOS2/RTX/Library/*.zip
  155. CMSIS/RTOS2/RTX/Library/build.py
  156. "
  157. # Specify patches to be applied
  158. PACK_PATCH_FILES=""
  159. ############ DO NOT EDIT BELOW ###########
  160. echo Starting CMSIS-Pack Generation: `date`
  161. # Zip utility check
  162. ZIP=7z
  163. type -a "${ZIP}"
  164. errorlevel=$?
  165. if [ $errorlevel -gt 0 ]
  166. then
  167. echo "Error: No 7zip Utility found"
  168. echo "Action: Add 7zip to your path"
  169. echo " "
  170. exit 1
  171. fi
  172. # Pack checking utility check
  173. PACKCHK=packchk
  174. type -a ${PACKCHK}
  175. errorlevel=$?
  176. if [ $errorlevel != 0 ]; then
  177. echo "Error: No packchk Utility found"
  178. echo "Action: Add packchk to your path"
  179. echo "Hint: Included in CMSIS Pack:"
  180. echo "$CMSIS_PACK_ROOT/ARM/CMSIS/<version>/CMSIS/Utilities/<os>/"
  181. echo " "
  182. if [[ $IGNORE_ERRORS == 0 ]]; then
  183. exit 1
  184. fi
  185. fi
  186. echo " "
  187. # Locate Package Description file
  188. # check whether there is more than one pdsc file
  189. NUM_PDSCS=$(ls -1 *.pdsc | wc -l)
  190. PACK_DESCRIPTION_FILE=$(ls *.pdsc)
  191. if [[ -n $1 && -f $1 ]]; then
  192. PACK_DESCRIPTION_FILE=$1
  193. elif [ ${NUM_PDSCS} -lt 1 ]; then
  194. echo "Error: No *.pdsc file found in current directory"
  195. echo " "
  196. exit 1
  197. elif [ ${NUM_PDSCS} -gt 1 ]; then
  198. echo "Error: Only one PDSC file allowed in directory structure:"
  199. echo "Found:"
  200. echo "$PACK_DESCRIPTION_FILE"
  201. echo "Action: Provide PDSC file explicitly!"
  202. echo " "
  203. usage
  204. exit 1
  205. fi
  206. SAVEIFS=$IFS
  207. IFS=.
  208. set ${PACK_DESCRIPTION_FILE}
  209. # Pack Vendor
  210. PACK_VENDOR=$1
  211. # Pack Name
  212. PACK_NAME=$2
  213. echo "Generating Pack: for $PACK_VENDOR.$PACK_NAME"
  214. echo " "
  215. IFS=$SAVEIFS
  216. #if $PACK_BUILD directory does not exist, create it.
  217. if [ ! -d "$PACK_BUILD" ]; then
  218. mkdir -p "$PACK_BUILD"
  219. fi
  220. # Copy files into build base directory: $PACK_BUILD
  221. # pdsc file is mandatory in base directory:
  222. cp -f "./${PACK_VENDOR}.${PACK_NAME}.pdsc" "${PACK_BUILD}"
  223. # Add directories
  224. echo Adding directories to pack:
  225. echo "${PACK_DIRS}"
  226. echo " "
  227. for d in ${PACK_DIRS}; do
  228. cp -r --parents "$d" "${PACK_BUILD}"
  229. done
  230. # Add files
  231. echo Adding files to pack:
  232. echo "${PACK_BASE_FILES}"
  233. echo " "
  234. if [ ! -x ${PACK_BASE_FILES+x} ]; then
  235. for f in ${PACK_BASE_FILES}; do
  236. cp -f --parents "$f" $PACK_BUILD/
  237. done
  238. fi
  239. # Delete files
  240. echo Deleting files from pack:
  241. echo "${PACK_DELETE_FILES}"
  242. echo " "
  243. if [ ! -x ${PACK_DELETE_FILES+x} ]; then
  244. for f in ${PACK_DELETE_FILES}; do
  245. find $PACK_BUILD/$(dirname "$f") -name $(basename "$f") -delete
  246. done
  247. fi
  248. # Apply patches
  249. echo Applying patches to pack:
  250. echo "${PACK_PATCH_FILES}"
  251. echo " "
  252. if [ ! -x ${PACK_PATCH_FILES+x} ]; then
  253. CWD=$(pwd)
  254. pushd $PACK_BUILD > /dev/null
  255. for f in ${PACK_PATCH_FILES}; do
  256. patch -p0 -t -i "${CWD}/${f}"
  257. done
  258. popd > /dev/null
  259. fi
  260. # Create checksum file
  261. echo Creating checksum file:
  262. pushd $PACK_BUILD > /dev/null
  263. find . -type f -exec sha1sum {} + > ../${PACK_VENDOR}.${PACK_NAME}.sha1
  264. mv ../${PACK_VENDOR}.${PACK_NAME}.sha1 .
  265. popd > /dev/null
  266. # Run Schema Check (for Linux only):
  267. # sudo apt-get install libxml2-utils
  268. if [ $(uname -s) = "Linux" ]; then
  269. echo "Running schema check for ${PACK_VENDOR}.${PACK_NAME}.pdsc"
  270. curl https://raw.githubusercontent.com/Open-CMSIS-Pack/Open-CMSIS-Pack-Spec/main/schema/PACK.xsd -o CMSIS/Utilities/PACK.xsd
  271. xmllint --noout --schema "$(realpath -m ./CMSIS/Utilities/PACK.xsd)" "${PACK_BUILD}/${PACK_VENDOR}.${PACK_NAME}.pdsc"
  272. errorlevel=$?
  273. if [ $errorlevel -ne 0 ]; then
  274. echo "build aborted: Schema check of $PACK_VENDOR.$PACK_NAME.pdsc against PACK.xsd failed"
  275. echo " "
  276. if [[ $IGNORE_ERRORS == 0 ]]; then
  277. exit 1
  278. fi
  279. fi
  280. else
  281. echo "Use MDK PackInstaller to run schema validation for $PACK_VENDOR.$PACK_NAME.pdsc"
  282. fi
  283. # Patch pack version
  284. echo "Checking PDCS version against Git..."
  285. pdsc_version=$(pack_version "${PACK_BUILD}/${PACK_VENDOR}.${PACK_NAME}.pdsc")
  286. if [ -z $VERSION ]; then
  287. VERSION=$(git_describe ${pdsc_version})
  288. fi
  289. patch_pdsc "${PACK_BUILD}/${PACK_VENDOR}.${PACK_NAME}.pdsc" ${pdsc_version} ${VERSION}
  290. # Run Pack Check and generate PackName file with version
  291. "${PACKCHK}" "${PACK_BUILD}/${PACK_VENDOR}.${PACK_NAME}.pdsc" \
  292. -n ${PACK_BUILD}/PackName.txt \
  293. -x M353 -x M364 -x M335 -x M336
  294. errorlevel=$?
  295. if [ $errorlevel -ne 0 ]; then
  296. echo "build aborted: pack check failed"
  297. echo "Check preparation steps if missing files are reported!"
  298. echo " "
  299. if [[ $IGNORE_ERRORS == 0 ]]; then
  300. exit 1
  301. fi
  302. fi
  303. PACKNAME=$(cat ${PACK_BUILD}/PackName.txt)
  304. rm -rf ${PACK_BUILD}/PackName.txt
  305. # Archiving
  306. # $ZIP a $PACKNAME
  307. echo "creating pack file $PACKNAME"
  308. #if $PACK_WAREHOUSE directory does not exist create it
  309. if [ ! -d "$PACK_WAREHOUSE" ]; then
  310. mkdir -p "$PACK_WAREHOUSE"
  311. fi
  312. pushd "$PACK_WAREHOUSE" > /dev/null
  313. PACK_WAREHOUSE=$(pwd)
  314. popd > /dev/null
  315. pushd "$PACK_BUILD" > /dev/null
  316. PACK_BUILD=$(pwd)
  317. "$ZIP" a "$PACK_WAREHOUSE/$PACKNAME" -tzip
  318. popd > /dev/null
  319. errorlevel=$?
  320. if [ $errorlevel -ne 0 ]; then
  321. echo "build aborted: archiving failed"
  322. exit 1
  323. fi
  324. echo "build of pack succeeded"
  325. # Clean up
  326. echo "cleaning up ..."
  327. rm -rf "$PACK_BUILD"
  328. echo " "
  329. echo Completed CMSIS-Pack Generation: $(date)