build_fpga_toolchain.sh 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. #!/bin/sh
  2. #
  3. # FPGA toolchain install script.
  4. # v1.1
  5. # This script installs a full Open Source FPGA toolchain to a user directory.
  6. #
  7. # Author: Michael Buesch <m@bues.ch>
  8. #
  9. # This code is Public Domain.
  10. # Permission to use, copy, modify, and/or distribute this software for any
  11. # purpose with or without fee is hereby granted.
  12. #
  13. # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  14. # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  15. # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
  16. # SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  17. # RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  18. # NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
  19. # USE OR PERFORMANCE OF THIS SOFTWARE.
  20. #
  21. die()
  22. {
  23. echo "$*" >&2
  24. exit 1
  25. }
  26. show_help()
  27. {
  28. echo "Usage: build_fpga_toolchain.sh <OPTIONS> [INSTALLDIR]"
  29. echo
  30. echo "Options:"
  31. echo " -j|--jobs NR Set the number of build jobs to run in parallel."
  32. echo " Default: Number of CPUs"
  33. echo " -h|--help Print help."
  34. echo
  35. echo
  36. echo "Install toolchain to $HOME/fpga-toolchain"
  37. echo " ./build_fpga_toolchain.sh"
  38. echo
  39. echo "Install toolchain to another destination"
  40. echo " ./build_fpga_toolchain.sh /home/user/directory"
  41. echo
  42. echo "The script will create a temporary directory during build to build all tools:"
  43. echo " ./fpga-toolchain-build-tmp"
  44. echo
  45. echo "The following tools are needed to build the toolchain:"
  46. echo "- gcc"
  47. echo "- clang"
  48. echo "- python3"
  49. echo "- cmake"
  50. echo "- git"
  51. echo "- schedtool"
  52. echo "Please ensure that all of these tools are installed in the system."
  53. }
  54. parse_args()
  55. {
  56. # Defaults:
  57. PARALLEL="$(getconf _NPROCESSORS_ONLN)"
  58. BUILDDIR="./fpga-toolchain-build-tmp"
  59. INSTALLDIR="$HOME/fpga-toolchain"
  60. # Source repositories:
  61. REPO_ICESTORM="https://github.com/cliffordwolf/icestorm.git"
  62. REPO_NEXTPNR="https://github.com/YosysHQ/nextpnr.git"
  63. REPO_YOSYS="https://github.com/YosysHQ/yosys.git"
  64. REPO_TINYPROG="https://github.com/tinyfpga/TinyFPGA-Bootloader.git"
  65. # Parse command line options
  66. while [ $# -ge 1 ]; do
  67. [ "$(printf '%s' "$1" | cut -c1)" != "-" ] && break
  68. case "$1" in
  69. -h|--help)
  70. show_help
  71. exit 0
  72. ;;
  73. -j|--jobs)
  74. shift
  75. PARALLEL="$1"
  76. [ -z "$PARALLEL" -o -n "$(printf '%s' "$PARALLEL" | tr -d '[0-9]')" ] &&\
  77. die "--jobs: '$PARALLEL' is not a positive integer number."
  78. ;;
  79. *)
  80. echo "Unknown option: $1"
  81. exit 1
  82. ;;
  83. esac
  84. shift
  85. done
  86. if [ $# -ge 1 -a -n "$1" ]; then
  87. # User defined INSTALLDIR
  88. INSTALLDIR="$1"
  89. fi
  90. }
  91. checkprog()
  92. {
  93. local prog="$1"
  94. which "$prog" >/dev/null ||\
  95. die "$prog is not installed. Please install it by use of the distribution package manager (apt, apt-get, rpm, etc...)"
  96. }
  97. check_build_environment()
  98. {
  99. [ "$(id -u)" = "0" ] && die "Do not run this as root!"
  100. checkprog gcc
  101. checkprog clang
  102. checkprog python3
  103. checkprog cmake
  104. checkprog git
  105. checkprog schedtool
  106. }
  107. cleanup()
  108. {
  109. rm -rf "$BUILDDIR" || die "Failed to cleanup BUILDDIR"
  110. }
  111. prepare()
  112. {
  113. # Resolve paths.
  114. BUILDDIR="$(realpath -m -s "$BUILDDIR")"
  115. INSTALLDIR="$(realpath -m -s "$INSTALLDIR")"
  116. echo "BUILDDIR=$BUILDDIR"
  117. echo "INSTALLDIR=$INSTALLDIR"
  118. echo "PARALLEL=$PARALLEL"
  119. [ -n "$BUILDDIR" -a -n "$INSTALLDIR" ] || die "Failed to resolve directories"
  120. echo
  121. # Set priority
  122. schedtool -D -n19 $$ || die "Failed to reduce process priority"
  123. # Create the build directories.
  124. cleanup
  125. mkdir -p "$BUILDDIR" || die "Failed to create BUILDDIR"
  126. mkdir -p "$INSTALLDIR" || die "Failed to create INSTALLDIR"
  127. # Reset the new PATH.
  128. NEWPATH="\$PATH"
  129. }
  130. build_icestorm()
  131. {
  132. echo "Building icestorm..."
  133. cd "$BUILDDIR" || die "Failed to cd to builddir."
  134. git clone "$REPO_ICESTORM" "$BUILDDIR/icestorm" || die "Failed to clone icestorm"
  135. cd "$BUILDDIR/icestorm" || die "Failed to cd to icestorm."
  136. export PREFIX="$INSTALLDIR/icestorm"
  137. make -j "$PARALLEL" PREFIX="$PREFIX" || die "Failed to build icestorm"
  138. rm -rf "$PREFIX" || die "Failed to clean install icestorm"
  139. make install PREFIX="$PREFIX" || die "Failed to install icestorm"
  140. NEWPATH="$PREFIX/bin:$NEWPATH"
  141. }
  142. build_nextpnr()
  143. {
  144. echo "Building nextpnr..."
  145. cd "$BUILDDIR" || die "Failed to cd to builddir."
  146. git clone "$REPO_NEXTPNR" "$BUILDDIR/nextpnr" || die "Failed to clone nextpnr"
  147. mkdir "$BUILDDIR/nextpnr/builddir" || die "Failed to create nextpnr builddir"
  148. cd "$BUILDDIR/nextpnr/builddir" || die "Failed to cd to nextpnr."
  149. export PREFIX="$INSTALLDIR/nextpnr"
  150. cmake -DARCH=ice40 -DICEBOX_ROOT="$INSTALLDIR/icestorm/share/icebox" -DCMAKE_INSTALL_PREFIX="$PREFIX" .. || die "Failed to build nextpnr"
  151. make -j "$PARALLEL" || die "Failed to build nextpnr"
  152. rm -rf "$PREFIX" || die "Failed to clean install nextpnr"
  153. make install || die "Failed to install nextpnr"
  154. NEWPATH="$PREFIX/bin:$NEWPATH"
  155. }
  156. build_yosys()
  157. {
  158. echo "Building yosys..."
  159. cd "$BUILDDIR" || die "Failed to cd to builddir."
  160. git clone "$REPO_YOSYS" "$BUILDDIR/yosys" || die "Failed to clone yosys"
  161. cd "$BUILDDIR/yosys" || die "Failed to cd to yosys."
  162. export PREFIX="$INSTALLDIR/yosys"
  163. make config-clang PREFIX="$PREFIX" || die "Failed to configure yosys"
  164. make -j "$PARALLEL" PREFIX="$PREFIX" || die "Failed to build yosys"
  165. rm -rf "$PREFIX" || die "Failed to clean install yosys"
  166. make install PREFIX="$PREFIX" || die "Failed to install yosys"
  167. NEWPATH="$PREFIX/bin:$NEWPATH"
  168. }
  169. build_tinyprog()
  170. {
  171. echo "Building tinyprog..."
  172. cd "$BUILDDIR" || die "Failed to cd to builddir."
  173. git clone "$REPO_TINYPROG" "$BUILDDIR/TinyFPGA-Bootloader" || die "Failed to clone tinyprog"
  174. cd "$BUILDDIR/TinyFPGA-Bootloader/programmer" || die "Failed to cd to tinyprog."
  175. export PREFIX="$INSTALLDIR/tinyprog"
  176. rm -rf "$PREFIX" || die "Failed to clean install tinyprog"
  177. mkdir -p "$PREFIX/lib" || die "Failed to create tinyprog lib"
  178. mkdir -p "$PREFIX/bin" || die "Failed to create tinyprog bin"
  179. cp -r "$BUILDDIR/TinyFPGA-Bootloader/programmer/tinyprog" "$PREFIX/lib/" || die "Failed to install tinyprog"
  180. cat > "$PREFIX/bin/tinyprog" <<EOF
  181. #!/bin/sh
  182. export PYTHONPATH="$PREFIX/lib/:\$PYTHONPATH"
  183. exec python3 "$PREFIX/lib/tinyprog" "\$@"
  184. EOF
  185. [ -f "$PREFIX/bin/tinyprog" ] || die "Failed to install tinyprog wrapper"
  186. chmod 755 "$PREFIX/bin/tinyprog" || die "Failed to chmod tinyprog"
  187. NEWPATH="$PREFIX/bin:$NEWPATH"
  188. }
  189. parse_args "$@"
  190. check_build_environment
  191. prepare
  192. build_icestorm
  193. build_nextpnr
  194. build_yosys
  195. build_tinyprog
  196. cleanup
  197. echo
  198. echo
  199. echo
  200. echo "Successfully built and installed all FPGA tools to: $INSTALLDIR"
  201. echo "Please add the following line to your $HOME/.bashrc file:"
  202. echo
  203. echo "export PATH=\"$NEWPATH\""
  204. echo