build.sh 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #!/bin/sh
  2. # Rebuild FPGA bit files
  3. # Copyright (c) 2010-2021 Michael Buesch <m@bues.ch>
  4. # Licensed under the GNU/GPL v2+
  5. basedir="$(dirname "$0")"
  6. [ "$(echo -n "$basedir" | cut -c1)" = "/" ] || basedir="$PWD/$basedir"
  7. srcdir="$basedir/src"
  8. bindir="$basedir/bin"
  9. die()
  10. {
  11. echo "$*" >&2
  12. exit 1
  13. }
  14. terminate()
  15. {
  16. die "Interrupted."
  17. }
  18. trap terminate TERM INT
  19. usage()
  20. {
  21. echo "Usage: build.sh [OPTIONS] [TARGETS]"
  22. echo
  23. echo "Options:"
  24. echo " -h|--help Show this help text"
  25. echo " -v|--verbose Verbose build"
  26. echo
  27. echo "Targets:"
  28. echo "Specify the names of the targets to build, or leave blank to rebuild all."
  29. }
  30. # Parse commandline
  31. verbose=0
  32. targets="/"
  33. while [ $# -gt 0 ]; do
  34. [ "$1" = "-h" -o "$1" = "--help" ] && {
  35. usage
  36. exit 0
  37. }
  38. [ "$1" = "-v" -o "$1" = "--verbose" ] && {
  39. verbose=1
  40. shift
  41. continue
  42. }
  43. target="$(basename "$1" .bit)"
  44. # Add to list
  45. targets="${targets}${target}/"
  46. shift
  47. done
  48. [ "$targets" = "/" ] && targets=
  49. bitparser()
  50. {
  51. PYTHONPATH="$basedir/../..:$PYTHONPATH" python3 "$basedir/../bitfile.py" "$@" ||\
  52. die "Failed to execute bitparser"
  53. }
  54. should_build() # $1=target
  55. {
  56. target="$1"
  57. [ "$target" = "template" ] && return 1
  58. [ -z "$targets" ] && return 0
  59. echo "$targets" | grep -qe '/'"$target"'/'
  60. }
  61. # Check if the payload of two bitfiles matches
  62. bitfile_is_equal() # $1=file1, $2=file2
  63. {
  64. [ -r $1 -a -r $2 ] || return 1
  65. bitparser "$1" NOACTION # Test if bitparser works
  66. sum1="$(bitparser "$1" GETPAYLOAD | sha1sum -b - | awk '{print $1;}')"
  67. sum2="$(bitparser "$2" GETPAYLOAD | sha1sum -b - | awk '{print $1;}')"
  68. [ "$sum1" = "$sum2" ]
  69. }
  70. # $1=src-directory, $1=verbose
  71. warning_filter()
  72. {
  73. local chip_filter="$1/warning.filter"
  74. local global_filter="$basedir/warning.filter"
  75. local verbose="$2"
  76. [ -n "$verbose" -a "$verbose" != "0" ] && {
  77. # Show all messages
  78. cat
  79. return 0
  80. }
  81. # Read filter regexes
  82. local discard_regexes=
  83. [ -r "$global_filter" ] &&\
  84. discard_regexes="$discard_regexes $(cat "$global_filter")"
  85. [ -r "$chip_filter" ] &&\
  86. discard_regexes="$discard_regexes $(cat "$chip_filter")"
  87. # Filter for warnings and remove blacklisted warnings.
  88. grep -Ee '^WARNING' | while read line; do
  89. local discard=
  90. for discard_regex in $discard_regexes; do
  91. echo "$line" | grep -Eqe "$discard_regex" && {
  92. discard=1 # Discard it!
  93. break
  94. }
  95. done
  96. [ -z "$discard" ] && echo "$line"
  97. done
  98. }
  99. # $1=source_directory
  100. run_build()
  101. {
  102. local source_dir="$1"
  103. for src in "$source_dir"/*; do
  104. [ -d "$src" ] || continue
  105. [ -f "$src/Makefile" ] || {
  106. # Recurse
  107. run_build "$src"
  108. continue
  109. }
  110. srcname="$(basename $src)"
  111. logfile="$basedir/$srcname.build.log"
  112. should_build "$srcname" || continue
  113. echo "Building $srcname..."
  114. rm -f "$logfile"
  115. make -C "$src/" clean >/dev/null ||\
  116. die "FAILED to clean $srcname."
  117. errfile="$(mktemp)"
  118. {
  119. make -C "$src/" all 2>&1
  120. echo "$?" >> "$errfile"
  121. } | tee "$logfile" | warning_filter "$src" "$verbose"
  122. errcode="$(cat "$errfile")"
  123. rm -f "$errfile"
  124. [ "$errcode" = "0" ] || {
  125. [ $verbose -eq 0 ] && cat "$logfile"
  126. die "FAILED to build $srcname."
  127. }
  128. new="$src/$srcname.bit"
  129. old="$bindir/$srcname.bit"
  130. if bitfile_is_equal "$old" "$new"; then
  131. echo "Bitfile for target $srcname did not change"
  132. else
  133. cp -f "$new" "$old"
  134. fi
  135. make -C "$src/" clean > /dev/null ||\
  136. die "FAILED to clean $srcname."
  137. rm -f "$logfile"
  138. done
  139. }
  140. # Pull in the ISE settings and paths.
  141. if [ -d "$XILINX_10_1_DIR" ] && \
  142. [ -r "$XILINX_10_1_DIR/ISE/settings32.sh" ]; then
  143. . "$XILINX_10_1_DIR/ISE/settings32.sh"
  144. elif [ -r "/opt/Xilinx/10.1/ISE/settings32.sh" ]; then
  145. . "/opt/Xilinx/10.1/ISE/settings32.sh"
  146. else
  147. die "Did not find Xilinx ISE webpack 10.1"
  148. fi
  149. run_build "$srcdir"
  150. echo "Successfully built all images."
  151. exit 0