build.sh 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #!/bin/bash
  2. #
  3. # Copyright (c) 2013-2021 Igor Pecovnik, igor.pecovnik@gma**.com
  4. #
  5. # This file is licensed under the terms of the GNU General Public
  6. # License version 2. This program is licensed "as is" without any
  7. # warranty of any kind, whether express or implied.
  8. # DO NOT EDIT THIS FILE
  9. # use configuration files like config-default.conf to set the build configuration
  10. # Please check Orange Pi documentation for more info
  11. # http://www.orangepi.cn/downloadresourcescn
  12. # http://www.orangepi.org/downloadresources
  13. SRC="$(dirname "$(realpath "${BASH_SOURCE[0]}")")"
  14. # check for whitespace in ${SRC} and exit for safety reasons
  15. grep -q "[[:space:]]" <<<"${SRC}" && { echo "\"${SRC}\" contains whitespace. Not supported. Aborting." >&2 ; exit 1 ; }
  16. cd "${SRC}" || exit
  17. if [[ "${ORANGEPI_ENABLE_CALL_TRACING}" == "yes" ]]; then
  18. set -T # inherit return/debug traps
  19. mkdir -p "${SRC}"/output/debug
  20. echo -n "" > "${SRC}"/output/debug/calls.txt
  21. trap 'echo "${BASH_LINENO[@]}|${BASH_SOURCE[@]}|${FUNCNAME[@]}" >> ${SRC}/output/debug/calls.txt ;' RETURN
  22. fi
  23. if [[ -f "${SRC}"/scripts/general.sh ]]; then
  24. # shellcheck source=scripts/general.sh
  25. source "${SRC}"/scripts/general.sh
  26. else
  27. echo "Error: missing build directory structure"
  28. echo "Please clone the full repository by https://github.com/orangepi-xunlong/orangepi-build"
  29. exit 255
  30. fi
  31. # Add the variables needed at the beginning of the path
  32. check_args ()
  33. {
  34. for p in "$@"; do
  35. case "${p%=*}" in
  36. LIB_TAG)
  37. # Take a variable if the branch exists locally
  38. if [ "${p#*=}" == "$(git branch | \
  39. gawk -v b="${p#*=}" '{if ( $NF == b ) {print $NF}}')" ]; then
  40. echo -e "[\e[0;35m warn \x1B[0m] Setting $p"
  41. eval "$p"
  42. else
  43. echo -e "[\e[0;35m warn \x1B[0m] Skip $p setting as LIB_TAG=\"\""
  44. eval LIB_TAG=""
  45. fi
  46. ;;
  47. esac
  48. done
  49. }
  50. check_args "$@"
  51. update_src() {
  52. cd "${SRC}" || exit
  53. if [[ ! -f "${SRC}"/.ignore_changes ]]; then
  54. echo -e "[\e[0;32m o.k. \x1B[0m] This script will try to update"
  55. CHANGED_FILES=$(git diff --name-only)
  56. if [[ -n "${CHANGED_FILES}" ]]; then
  57. echo -e "[\e[0;35m warn \x1B[0m] Can't update since you made changes to: \e[0;32m\n${CHANGED_FILES}\x1B[0m"
  58. while true; do
  59. echo -e "Press \e[0;33m<Ctrl-C>\x1B[0m or \e[0;33mexit\x1B[0m to abort compilation"\
  60. ", \e[0;33m<Enter>\x1B[0m to ignore and continue, \e[0;33mdiff\x1B[0m to display changes"
  61. read -r
  62. if [[ "${REPLY}" == "diff" ]]; then
  63. git diff
  64. elif [[ "${REPLY}" == "exit" ]]; then
  65. exit 1
  66. elif [[ "${REPLY}" == "" ]]; then
  67. break
  68. else
  69. echo "Unknown command!"
  70. fi
  71. done
  72. elif [[ $(git branch | grep "*" | awk '{print $2}') != "${LIB_TAG}" && -n "${LIB_TAG}" ]]; then
  73. git checkout "${LIB_TAG:-master}"
  74. git pull
  75. fi
  76. fi
  77. }
  78. TMPFILE=$(mktemp)
  79. chmod 644 "${TMPFILE}"
  80. {
  81. echo SRC="$SRC"
  82. echo LIB_TAG="$LIB_TAG"
  83. declare -f update_src
  84. #echo "update_src"
  85. } > "$TMPFILE"
  86. #do not update/checkout git with root privileges to messup files onwership.
  87. #due to in docker/VM, we can't su to a normal user, so do not update/checkout git.
  88. if [[ $(systemd-detect-virt) == 'none' ]]; then
  89. if [[ "${EUID}" == "0" ]]; then
  90. su "$(stat --format=%U "${SRC}"/.git)" -c "bash ${TMPFILE}"
  91. else
  92. bash "${TMPFILE}"
  93. fi
  94. fi
  95. rm "${TMPFILE}"
  96. if [[ "${EUID}" == "0" ]] || [[ "${1}" == "vagrant" ]]; then
  97. :
  98. elif [[ "${1}" == docker || "${1}" == dockerpurge || "${1}" == docker-shell ]] && grep -q "$(whoami)" <(getent group docker); then
  99. :
  100. else
  101. display_alert "This script requires root privileges, trying to use sudo" "" "wrn"
  102. sudo "${SRC}/build.sh" "$@"
  103. exit $?
  104. fi
  105. if [ "$OFFLINE_WORK" == "yes" ]; then
  106. echo -e "\n"
  107. display_alert "* " "You are working offline."
  108. display_alert "* " "Sources, time and host will not be checked"
  109. echo -e "\n"
  110. sleep 3s
  111. else
  112. # check and install the basic utilities here
  113. prepare_host_basic
  114. fi
  115. # Check for Vagrant
  116. if [[ "${1}" == vagrant && -z "$(command -v vagrant)" ]]; then
  117. display_alert "Vagrant not installed." "Installing"
  118. sudo apt-get update
  119. sudo apt-get install -y vagrant virtualbox
  120. fi
  121. # Purge Orange Pi Docker images
  122. if [[ "${1}" == dockerpurge && -f /etc/debian_version ]]; then
  123. display_alert "Purging Orange Pi Docker containers" "" "wrn"
  124. docker container ls -a | grep orangepi | awk '{print $1}' | xargs docker container rm &> /dev/null
  125. docker image ls | grep orangepi | awk '{print $3}' | xargs docker image rm &> /dev/null
  126. shift
  127. set -- "docker" "$@"
  128. fi
  129. # Docker shell
  130. if [[ "${1}" == docker-shell ]]; then
  131. shift
  132. #shellcheck disable=SC2034
  133. SHELL_ONLY=yes
  134. set -- "docker" "$@"
  135. fi
  136. # Install Docker if not there but wanted. We cover only Debian based distro install. On other distros, manual Docker install is needed
  137. if [[ "${1}" == docker && -f /etc/debian_version && -z "$(command -v docker)" ]]; then
  138. DOCKER_BINARY="docker-ce"
  139. # add exception for Ubuntu Focal until Docker provides dedicated binary
  140. codename=$(cat /etc/os-release | grep VERSION_CODENAME | cut -d"=" -f2)
  141. codeid=$(cat /etc/os-release | grep ^NAME | cut -d"=" -f2 | awk '{print tolower($0)}' | tr -d '"' | awk '{print $1}')
  142. [[ "${codename}" == "debbie" ]] && codename="buster" && codeid="debian"
  143. [[ "${codename}" == "ulyana" || "${codename}" == "jammy" ]] && codename="focal" && codeid="ubuntu"
  144. # different binaries for some. TBD. Need to check for all others
  145. [[ "${codename}" =~ focal|hirsute ]] && DOCKER_BINARY="docker containerd docker.io"
  146. display_alert "Docker not installed." "Installing" "Info"
  147. sudo bash -c "echo \"deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/${codeid} ${codename} stable\" > /etc/apt/sources.list.d/docker.list"
  148. sudo bash -c "curl -fsSL \"https://download.docker.com/linux/${codeid}/gpg\" | apt-key add -qq - > /dev/null 2>&1 "
  149. export DEBIAN_FRONTEND=noninteractive
  150. sudo apt-get update
  151. sudo apt-get install -y -qq --no-install-recommends ${DOCKER_BINARY}
  152. display_alert "Add yourself to docker group to avoid root privileges" "" "wrn"
  153. "${SRC}/build.sh" "$@"
  154. exit $?
  155. fi
  156. EXTER="${SRC}/external"
  157. # Create userpatches directory if not exists
  158. mkdir -p "${SRC}"/userpatches
  159. # Create example configs if none found in userpatches
  160. if ! ls "${SRC}"/userpatches/{config-example.conf,config-docker.conf,config-vagrant.conf} 1> /dev/null 2>&1; then
  161. # Migrate old configs
  162. if ls "${SRC}"/*.conf 1> /dev/null 2>&1; then
  163. display_alert "Migrate config files to userpatches directory" "all *.conf" "info"
  164. cp "${SRC}"/*.conf "${SRC}"/userpatches || exit 1
  165. rm "${SRC}"/*.conf
  166. [[ ! -L "${SRC}"/userpatches/config-example.conf ]] && ln -fs config-example.conf "${SRC}"/userpatches/config-default.conf || exit 1
  167. fi
  168. display_alert "Create example config file using template" "config-default.conf" "info"
  169. # Create example config
  170. if [[ ! -f "${SRC}"/userpatches/config-example.conf ]]; then
  171. cp "${EXTER}"/config/templates/config-example.conf "${SRC}"/userpatches/config-example.conf || exit 1
  172. ln -fs config-example.conf "${SRC}"/userpatches/config-default.conf || exit 1
  173. fi
  174. # Create Docker config
  175. if [[ ! -f "${SRC}"/userpatches/config-docker.conf ]]; then
  176. cp "${EXTER}"/config/templates/config-docker.conf "${SRC}"/userpatches/config-docker.conf || exit 1
  177. fi
  178. # Create Docker file
  179. if [[ ! -f "${SRC}"/userpatches/Dockerfile ]]; then
  180. cp "${EXTER}"/config/templates/Dockerfile "${SRC}"/userpatches/Dockerfile || exit 1
  181. fi
  182. # Create Vagrant config
  183. if [[ ! -f "${SRC}"/userpatches/config-vagrant.conf ]]; then
  184. cp "${EXTER}"/config/templates/config-vagrant.conf "${SRC}"/userpatches/config-vagrant.conf || exit 1
  185. fi
  186. # Create Vagrant file
  187. if [[ ! -f "${SRC}"/userpatches/Vagrantfile ]]; then
  188. cp "${EXTER}"/config/templates/Vagrantfile "${SRC}"/userpatches/Vagrantfile || exit 1
  189. fi
  190. fi
  191. if [[ -z "${CONFIG}" && -n "$1" && -f "${SRC}/userpatches/config-$1.conf" ]]; then
  192. CONFIG="userpatches/config-$1.conf"
  193. shift
  194. fi
  195. # usind default if custom not found
  196. if [[ -z "${CONFIG}" && -f "${SRC}/userpatches/config-default.conf" ]]; then
  197. CONFIG="userpatches/config-default.conf"
  198. fi
  199. # source build configuration file
  200. CONFIG_FILE="$(realpath "${CONFIG}")"
  201. if [[ ! -f "${CONFIG_FILE}" ]]; then
  202. display_alert "Config file does not exist" "${CONFIG}" "error"
  203. exit 254
  204. fi
  205. CONFIG_PATH=$(dirname "${CONFIG_FILE}")
  206. # Source the extensions manager library at this point, before sourcing the config.
  207. # This allows early calls to enable_extension(), but initialization proper is done later.
  208. # shellcheck source=scripts/extensions.sh
  209. source "${SRC}"/scripts/extensions.sh
  210. display_alert "Using config file" "${CONFIG_FILE}" "info"
  211. pushd "${CONFIG_PATH}" > /dev/null || exit
  212. # shellcheck source=/dev/null
  213. source "${CONFIG_FILE}"
  214. popd > /dev/null || exit
  215. [[ -z "${USERPATCHES_PATH}" ]] && USERPATCHES_PATH="${CONFIG_PATH}"
  216. # Script parameters handling
  217. while [[ "${1}" == *=* ]]; do
  218. parameter=${1%%=*}
  219. value=${1##*=}
  220. shift
  221. display_alert "Command line: setting $parameter to" "${value:-(empty)}" "info"
  222. eval "$parameter=\"$value\""
  223. done
  224. if [[ "${BUILD_ALL}" == "yes" || "${BUILD_ALL}" == "demo" ]]; then
  225. # shellcheck source=scripts/build-all-ng.sh
  226. source "${SRC}"/scripts/build-all-ng.sh
  227. else
  228. # shellcheck source=scripts/main.sh
  229. source "${SRC}"/scripts/main.sh
  230. fi