build_avr_gcc_toolchain.sh 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. #!/bin/sh
  2. #
  3. # AVR GCC toolchain install script.
  4. #
  5. # Author: Michael Buesch <m@bues.ch>
  6. #
  7. # This code is Public Domain.
  8. # Permission to use, copy, modify, and/or distribute this software for any
  9. # purpose with or without fee is hereby granted.
  10. #
  11. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  12. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  13. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  14. # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  15. # RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  16. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
  17. # USE OR PERFORMANCE OF THIS SOFTWARE.
  18. #
  19. BINUTILS_URL="https://ftp-stud.hs-esslingen.de/pub/Mirrors/ftp.gnu.org/binutils/binutils-2.43.1.tar.xz"
  20. BINUTILS_SHA256="13f74202a3c4c51118b797a39ea4200d3f6cfbe224da6d1d95bb938480132dfd"
  21. GCC_URL="https://ftp-stud.hs-esslingen.de/pub/Mirrors/ftp.gnu.org/gcc/gcc-14.2.0/gcc-14.2.0.tar.xz"
  22. GCC_SHA256="a7b39bc69cbf9e25826c5a60ab26477001f7c08d85cec04bc0e29cabed6f3cc9"
  23. AVRLIBC_URL="https://github.com/avrdudes/avr-libc/releases/download/avr-libc-2_2_1-release/avr-libc-2.2.1.tar.bz2"
  24. AVRLIBC_SHA256="006a6306cbbc938c3bdb583ac54f93fe7d7c8cf97f9cde91f91c6fb0273ab465"
  25. AVRDUDE_URL="https://github.com/avrdudes/avrdude/releases/download/v8.0/avrdude-8.0.tar.gz"
  26. AVRDUDE_SHA256="a689d70a826e2aa91538342c46c77be1987ba5feb9f7dab2606b8dae5d2a52d5"
  27. GDB_URL="https://ftp-stud.hs-esslingen.de/pub/Mirrors/ftp.gnu.org/gdb/gdb-15.2.tar.xz"
  28. GDB_SHA256="83350ccd35b5b5a0cba6b334c41294ea968158c573940904f00b92f76345314d"
  29. AVRA_URL="https://github.com/Ro5bert/avra/archive/refs/tags/1.4.2.tar.gz"
  30. AVRA_SHA256="cc56837be973d1a102dc6936a0b7235a1d716c0f7cd053bf77e0620577cff986"
  31. SIMAVR_COMMIT="ae75edec3f4068f3d1a6c30130abef7ef8e83155"
  32. SIMAVR_URL="https://github.com/buserror/simavr/archive/$SIMAVR_COMMIT.tar.gz"
  33. SIMAVR_SHA256="ae4e4d01cc87f9a483555dc023a7fb7f5bbf996cad95acbd60893798fcefc188"
  34. DWDEBUG_COMMIT="a51e9cc342d2437052103169d9a5c81c4cf480cf"
  35. DWDEBUG_URL="https://github.com/mbuesch/dwire-debug/archive/$DWDEBUG_COMMIT.tar.gz"
  36. DWDEBUG_SHA256="54d617de19272cae1b86330f56bb04b01b90df9810b26fca4aa6e4576d2c33e6"
  37. die()
  38. {
  39. echo "$*" >&2
  40. exit 1
  41. }
  42. show_help()
  43. {
  44. echo "Usage: avr_gcc_rust_toolchain.sh <OPTIONS> [PREFIX]"
  45. echo
  46. echo "Options:"
  47. echo " -h|--help Print help."
  48. echo " -k|--keep-tmp Keep temporary build files."
  49. echo
  50. echo
  51. echo "Install toolchain to $HOME/usr/avr"
  52. echo " ./build_avr_gcc_toolchain.sh"
  53. echo
  54. echo "Install toolchain to another destination"
  55. echo " ./build_avr_gcc_toolchain.sh /home/user/directory"
  56. }
  57. parse_args()
  58. {
  59. # Defaults:
  60. PREFIX="$HOME/usr/avr"
  61. KEEP_TMP=0
  62. # Parse command line options
  63. while [ $# -ge 1 ]; do
  64. [ "$(printf '%s' "$1" | cut -c1)" != "-" ] && break
  65. case "$1" in
  66. -h|--help)
  67. show_help
  68. exit 0
  69. ;;
  70. -k|--keep-tmp)
  71. KEEP_TMP=1
  72. ;;
  73. *)
  74. echo "Unknown option: $1"
  75. exit 1
  76. ;;
  77. esac
  78. shift
  79. done
  80. if [ $# -ge 1 -a -n "$1" ]; then
  81. # User defined PREFIX
  82. PREFIX="$1"
  83. fi
  84. }
  85. checkprog()
  86. {
  87. local prog="$1"
  88. which "$prog" >/dev/null ||\
  89. die "$prog is not installed. Please install it by use of the distribution package manager (apt, apt-get, rpm, etc...)"
  90. }
  91. check_build_environment()
  92. {
  93. checkprog bunzip2
  94. checkprog cmake
  95. checkprog gcc
  96. checkprog gunzip
  97. checkprog make
  98. checkprog nproc
  99. checkprog schedtool
  100. checkprog sha256sum
  101. checkprog tar
  102. checkprog wget
  103. checkprog xz
  104. }
  105. check_shasum()
  106. {
  107. local file="$1"
  108. local sum="$2"
  109. if ! [ "$(sha256sum -b "$file" | cut -f1 -d' ')" = "$sum" ]; then
  110. die "$file: Checksum check failed"
  111. fi
  112. }
  113. download()
  114. {
  115. local url="$1"
  116. local sum="$2"
  117. DOWNLOAD_FILE="$(basename "$url")"
  118. if ! [ -e "$DOWNLOAD_FILE" ]; then
  119. echo "Downloading $DOWNLOAD_FILE ..."
  120. wget --quiet "$url" || die "download failed"
  121. fi
  122. check_shasum "$DOWNLOAD_FILE" "$sum" || die "checksum failed"
  123. }
  124. download_and_extract()
  125. {
  126. local url="$1"
  127. local sum="$2"
  128. download "$url" "$sum" || die "download failed"
  129. case "$DOWNLOAD_FILE" in
  130. *.tar.xz)
  131. local extension=".tar.xz"
  132. ;;
  133. *.tar.bz2)
  134. local extension=".tar.bz2"
  135. ;;
  136. *.tar.gz)
  137. local extension=".tar.gz"
  138. ;;
  139. *)
  140. die "Unknown archive extension: $DOWNLOAD_FILE"
  141. ;;
  142. esac
  143. EXTRACT_DIR="$(basename "$DOWNLOAD_FILE" $extension)"
  144. echo "Extracting $DOWNLOAD_FILE ..."
  145. rm -rf "$EXTRACT_DIR"
  146. tar xf "$DOWNLOAD_FILE" || die "Failed to extract"
  147. if ! [ -d "$EXTRACT_DIR" ]; then
  148. # Workaround for github tag tarballs.
  149. # Remove leading "v".
  150. EXTRACT_DIR="$(printf '%s' "$EXTRACT_DIR" | sed -e 's/^v\(.*\)/\1/')"
  151. # Find dir-prefix.
  152. for d in *-"$EXTRACT_DIR"; do
  153. if [ -d "$d" ]; then
  154. EXTRACT_DIR="$d"
  155. fi
  156. break
  157. done
  158. fi
  159. [ -d "$EXTRACT_DIR" ] || die "Extracted directory $EXTRACT_DIR not present"
  160. }
  161. remove_build_tmp()
  162. {
  163. local builddir="$1"
  164. local logfile="$2"
  165. cd "$PREFIX/src" || die "cd failed"
  166. if [ $KEEP_TMP -eq 0 ]; then
  167. echo "Cleanup..."
  168. if [ -d "$builddir" ]; then
  169. rm -rf "$builddir" || die "Build cleanup failed"
  170. fi
  171. if [ -f "$logfile" ]; then
  172. rm "$logfile" || die "Log cleanup failed"
  173. fi
  174. fi
  175. }
  176. prepare()
  177. {
  178. # Resolve paths.
  179. PREFIX="$(realpath -m -s "$PREFIX")"
  180. echo "PREFIX=$PREFIX"
  181. [ -n "$PREFIX" ] || die "Failed to resolve install prefix"
  182. export PATH="$PREFIX/bin:$PATH"
  183. echo
  184. # Set priority
  185. schedtool -D -n19 $$ || die "Failed to reduce process priority"
  186. # Create the build directories.
  187. mkdir -p "$PREFIX" "$PREFIX/src" || die "Failed to create PREFIX"
  188. # Unset environment
  189. unset CFLAGS
  190. unset CXXFLAGS
  191. unset CPPFLAGS
  192. unset MAKEFLAGS
  193. unset DESTDIR
  194. }
  195. build_binutils()
  196. {
  197. printf '\nbinutils:\n'
  198. if [ -e "$PREFIX/bin/avr-ld" ]; then
  199. echo "binutils are already installed."
  200. return
  201. fi
  202. (
  203. mkdir -p "$PREFIX/src/binutils" || die "mkdir failed"
  204. cd "$PREFIX/src/binutils" || "cd failed"
  205. download_and_extract "$BINUTILS_URL" "$BINUTILS_SHA256" || die "download failed"
  206. cd "$EXTRACT_DIR" || die "cd failed"
  207. mkdir mybuild || die "mkdir failed"
  208. cd mybuild || die "cd failed"
  209. local log="$PREFIX/src/binutils/build.log"
  210. rm -f "$log"
  211. echo "Building..."
  212. ../configure \
  213. --prefix="$PREFIX" \
  214. --target=avr \
  215. --disable-nls \
  216. >>"$log" 2>&1 ||\
  217. die "configure failed"
  218. make -j "$(nproc)" >>"$log" 2>&1 || die "make failed"
  219. make install >>"$log" 2>&1 || die "make install failed"
  220. remove_build_tmp "$PREFIX/src/binutils/$EXTRACT_DIR" "$log"
  221. ) || die
  222. }
  223. build_gcc()
  224. {
  225. printf '\ngcc:\n'
  226. if [ -e "$PREFIX/bin/avr-gcc" ]; then
  227. echo "gcc is already installed."
  228. return
  229. fi
  230. (
  231. mkdir -p "$PREFIX/src/gcc" || die "mkdir failed"
  232. cd "$PREFIX/src/gcc" || "cd failed"
  233. download_and_extract "$GCC_URL" "$GCC_SHA256" || die "download failed"
  234. cd "$EXTRACT_DIR" || die "cd failed"
  235. mkdir mybuild || die "mkdir failed"
  236. cd mybuild || die "cd failed"
  237. local log="$PREFIX/src/gcc/build.log"
  238. rm -f "$log"
  239. echo "Building..."
  240. ../configure \
  241. --prefix="$PREFIX" \
  242. --target=avr \
  243. --enable-languages=c,c++ \
  244. --disable-nls \
  245. --disable-libssp \
  246. --with-dwarf2 \
  247. >>"$log" 2>&1 ||\
  248. die "configure failed"
  249. make -j "$(nproc)" >>"$log" 2>&1 || die "make failed"
  250. make install >>"$log" 2>&1 || die "make install failed"
  251. remove_build_tmp "$PREFIX/src/gcc/$EXTRACT_DIR" "$log"
  252. ) || die
  253. }
  254. build_avrlibc()
  255. {
  256. printf '\navr-libc:\n'
  257. if [ -e "$PREFIX/avr/include/stdlib.h" ]; then
  258. echo "avr-libc is already installed."
  259. return
  260. fi
  261. (
  262. mkdir -p "$PREFIX/src/avrlibc" || die "mkdir failed"
  263. cd "$PREFIX/src/avrlibc" || "cd failed"
  264. download_and_extract "$AVRLIBC_URL" "$AVRLIBC_SHA256" || die "download failed"
  265. cd "$EXTRACT_DIR" || die "cd failed"
  266. local log="$PREFIX/src/avrlibc/build.log"
  267. rm -f "$log"
  268. echo "Building..."
  269. ./configure \
  270. --prefix="$PREFIX" \
  271. --build="$(./config.guess)" \
  272. --host=avr \
  273. >>"$log" 2>&1 ||\
  274. die "configure failed"
  275. make -j "$(nproc)" >>"$log" 2>&1 || die "make failed"
  276. make install >>"$log" 2>&1 || die "make install failed"
  277. remove_build_tmp "$PREFIX/src/avrlibc/$EXTRACT_DIR" "$log"
  278. ) || die
  279. }
  280. build_avrdude()
  281. {
  282. printf '\navrdude:\n'
  283. if [ -e "$PREFIX/bin/avrdude" ]; then
  284. echo "avrdude is already installed."
  285. return
  286. fi
  287. (
  288. mkdir -p "$PREFIX/src/avrdude" || die "mkdir failed"
  289. cd "$PREFIX/src/avrdude" || "cd failed"
  290. download_and_extract "$AVRDUDE_URL" "$AVRDUDE_SHA256" || die "download failed"
  291. cd "$EXTRACT_DIR" || die "cd failed"
  292. local log="$PREFIX/src/avrdude/build.log"
  293. rm -f "$log"
  294. echo "Building..."
  295. ./build.sh \
  296. -f "-DCMAKE_INSTALL_PREFIX=$PREFIX" \
  297. -j "$(nproc)" \
  298. >>"$log" 2>&1 ||\
  299. die "configure failed"
  300. cmake --build build_linux --target install \
  301. >>"$log" 2>&1 ||\
  302. die "make install failed"
  303. remove_build_tmp "$PREFIX/src/avrdude/$EXTRACT_DIR" "$log"
  304. ) || die
  305. }
  306. build_gdb()
  307. {
  308. printf '\ngdb:\n'
  309. if [ -e "$PREFIX/bin/avr-gdb" ]; then
  310. echo "avr-gdb is already installed."
  311. return
  312. fi
  313. (
  314. mkdir -p "$PREFIX/src/gdb" || die "mkdir failed"
  315. cd "$PREFIX/src/gdb" || "cd failed"
  316. download_and_extract "$GDB_URL" "$GDB_SHA256" || die "download failed"
  317. cd "$EXTRACT_DIR" || die "cd failed"
  318. mkdir mybuild || die "mkdir failed"
  319. cd mybuild || die "cd failed"
  320. local log="$PREFIX/src/gdb/build.log"
  321. rm -f "$log"
  322. echo "Building..."
  323. ../configure \
  324. --prefix="$PREFIX" \
  325. --target=avr \
  326. >>"$log" 2>&1 ||\
  327. die "configure failed"
  328. make -j "$(nproc)" >>"$log" 2>&1 || die "make failed"
  329. make install >>"$log" 2>&1 || die "make install failed"
  330. remove_build_tmp "$PREFIX/src/gdb/$EXTRACT_DIR" "$log"
  331. ) || die
  332. }
  333. build_avra()
  334. {
  335. printf '\navra:\n'
  336. if [ -e "$PREFIX/bin/avra" ]; then
  337. echo "avra is already installed."
  338. return
  339. fi
  340. (
  341. mkdir -p "$PREFIX/src/avra" || die "mkdir failed"
  342. cd "$PREFIX/src/avra" || "cd failed"
  343. download_and_extract "$AVRA_URL" "$AVRA_SHA256" || die "download failed"
  344. cd "$EXTRACT_DIR" || die "cd failed"
  345. local log="$PREFIX/src/avra/build.log"
  346. rm -f "$log"
  347. echo "Building..."
  348. make -j "$(nproc)" PREFIX="$PREFIX" >>"$log" 2>&1 || die "make failed"
  349. make PREFIX="$PREFIX" install >>"$log" 2>&1 || die "make install failed"
  350. remove_build_tmp "$PREFIX/src/avra/$EXTRACT_DIR" "$log"
  351. ) || die
  352. }
  353. build_simavr()
  354. {
  355. printf '\nsimavr:\n'
  356. if [ -e "$PREFIX/bin/simavr" ]; then
  357. echo "simavr is already installed."
  358. return
  359. fi
  360. (
  361. mkdir -p "$PREFIX/src/simavr" || die "mkdir failed"
  362. cd "$PREFIX/src/simavr" || "cd failed"
  363. download_and_extract "$SIMAVR_URL" "$SIMAVR_SHA256" || die "download failed"
  364. cd "$EXTRACT_DIR" || die "cd failed"
  365. local log="$PREFIX/src/simavr/build.log"
  366. rm -f "$log"
  367. echo "Building..."
  368. make -j "$(nproc)" RELEASE=1 PREFIX="$PREFIX" DESTDIR="$PREFIX" \
  369. >>"$log" 2>&1 ||\
  370. die "make failed"
  371. make RELEASE=1 PREFIX="$PREFIX" DESTDIR="$PREFIX" install \
  372. >>"$log" 2>&1 ||\
  373. die "make install failed"
  374. remove_build_tmp "$PREFIX/src/simavr/$EXTRACT_DIR" "$log"
  375. ) || die
  376. }
  377. build_dwdebug()
  378. {
  379. printf '\ndwdebug:\n'
  380. if [ -e "$PREFIX/bin/dwdebug" ]; then
  381. echo "dwdebug is already installed."
  382. return
  383. fi
  384. (
  385. mkdir -p "$PREFIX/src/dwdebug" || die "mkdir failed"
  386. cd "$PREFIX/src/dwdebug" || "cd failed"
  387. download_and_extract "$DWDEBUG_URL" "$DWDEBUG_SHA256" || die "download failed"
  388. cd "$EXTRACT_DIR" || die "cd failed"
  389. local log="$PREFIX/src/dwdebug/build.log"
  390. rm -f "$log"
  391. echo "Building..."
  392. make -j1 dwdebug \
  393. >>"$log" 2>&1 ||\
  394. die "make failed"
  395. install -m755 ./dwdebug "$PREFIX/bin/"
  396. >>"$log" 2>&1 ||\
  397. die "install failed"
  398. remove_build_tmp "$PREFIX/src/dwdebug/$EXTRACT_DIR" "$log"
  399. ) || die
  400. }
  401. basedir="$(realpath "$0" | xargs dirname)"
  402. parse_args "$@"
  403. check_build_environment
  404. prepare
  405. build_binutils
  406. build_gcc
  407. build_avrlibc
  408. build_avrdude
  409. build_gdb
  410. build_avra
  411. build_simavr
  412. build_dwdebug
  413. echo
  414. echo
  415. echo
  416. echo "Successfully built and installed all tools to: $PREFIX"
  417. echo