buildx.sh 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. #!/usr/bin/env bash
  2. ## This script helps to run docker buildx to build cross-arch/platform packages (linux only)
  3. ## It mounts (not copy) host directory to a cross-arch/platform builder container
  4. ## Make sure the source dir (specified by --src_dir option) is clean before running this script
  5. ## NOTE: it requires $USER in docker group
  6. ## i.e. will not work if docker command has to be executed with sudo
  7. ## example:
  8. ## ./scripts/buildx.sh --profile emqx --pkgtype tgz
  9. set -euo pipefail
  10. help() {
  11. echo
  12. echo "-h|--help:"
  13. echo " To display this usage information"
  14. echo ""
  15. echo "--profile <PROFILE>:"
  16. echo " EMQX profile to build (emqx|emqx-enterprise)"
  17. echo ""
  18. echo "--pkgtype tgz|pkg|rel|relup:"
  19. echo " Specify which package to build, tgz for .tar.gz,"
  20. echo " pkg for .rpm or .deb, rel for release only"
  21. echo ""
  22. echo "--elixir:"
  23. echo " Specify if the release should be built with Elixir, "
  24. echo " defaults to 'no'."
  25. echo ""
  26. echo "--arch amd64|arm64:"
  27. echo " Target arch to build the EMQX package for"
  28. echo ""
  29. echo "--src_dir <SRC_DIR>:"
  30. echo " EMQX source code in this dir, default to PWD"
  31. echo ""
  32. echo "--builder <BUILDER>:"
  33. echo " Docker image to use for building"
  34. echo " E.g. ghcr.io/emqx/emqx-builder/5.3-13:1.15.7-26.2.5.2-1-debian12"
  35. echo " For hot upgrading tar.gz, specify a builder image with the same OS distribution as the running one."
  36. echo " Specifically, for EMQX's docker containers hot upgrading, please use the debian12-based builder. "
  37. }
  38. die() {
  39. msg="$1"
  40. echo "$msg" >&2
  41. help
  42. exit 1
  43. }
  44. # ensure dir
  45. cd -P -- "$(dirname -- "${BASH_SOURCE[0]}")/.."
  46. # shellcheck disable=SC1091
  47. source ./env.sh
  48. while [ "$#" -gt 0 ]; do
  49. case $1 in
  50. -h|--help)
  51. help
  52. exit 0
  53. ;;
  54. --src_dir)
  55. SRC_DIR="$2"
  56. shift 2
  57. ;;
  58. --profile)
  59. PROFILE="$2"
  60. shift 2
  61. ;;
  62. --pkgtype)
  63. PKGTYPE="$2"
  64. shift 2
  65. ;;
  66. --builder)
  67. EMQX_BUILDER="$2"
  68. shift 2
  69. ;;
  70. --arch)
  71. ARCH="$2"
  72. shift 2
  73. ;;
  74. --elixir)
  75. shift 1
  76. case ${1:-novalue} in
  77. -*)
  78. # another option
  79. IS_ELIXIR='yes'
  80. ;;
  81. yes|no)
  82. IS_ELIXIR="${1}"
  83. shift 1
  84. ;;
  85. novalue)
  86. IS_ELIXIR='yes'
  87. ;;
  88. *)
  89. echo "ERROR: unknown option: --elixir $2"
  90. exit 1
  91. ;;
  92. esac
  93. ;;
  94. *)
  95. echo "WARN: Unknown arg (ignored): $1"
  96. shift
  97. continue
  98. ;;
  99. esac
  100. done
  101. ## we have a different naming for them
  102. if [[ $(uname -m) == "x86_64" ]]; then
  103. NATIVE_ARCH='amd64'
  104. elif [[ $(uname -m) == "aarch64" ]]; then
  105. NATIVE_ARCH='arm64'
  106. elif [[ $(uname -m) == "arm64" ]]; then
  107. NATIVE_ARCH='arm64'
  108. elif [[ $(uname -m) == "armv7l" ]]; then
  109. # CHECKME: really ?
  110. NATIVE_ARCH='arm64'
  111. fi
  112. ARCH="${ARCH:-${NATIVE_ARCH:-}}"
  113. [ -z "${PROFILE:-}" ] && die "missing --profile"
  114. [ -z "${PKGTYPE:-}" ] && die "missing --pkgtype"
  115. [ -z "${EMQX_BUILDER:-}" ] && die "missing --builder"
  116. [ -z "${ARCH:-}" ] && die "missing --arch"
  117. set -x
  118. if [ -z "${IS_ELIXIR:-}" ]; then
  119. IS_ELIXIR=no
  120. fi
  121. case "${PKGTYPE:-}" in
  122. tgz|pkg|rel|relup)
  123. true
  124. ;;
  125. *)
  126. echo "Bad --pkgtype option, should be tgz, pkg, rel or relup"
  127. exit 1
  128. ;;
  129. esac
  130. export CODE_PATH="${SRC_DIR:-$PWD}"
  131. cd "${CODE_PATH}"
  132. if [ "$IS_ELIXIR" = "yes" ]; then
  133. MAKE_TARGET="${PROFILE}-elixir-${PKGTYPE}"
  134. else
  135. MAKE_TARGET="${PROFILE}-${PKGTYPE}"
  136. fi
  137. HOST_SYSTEM="$(./scripts/get-distro.sh)"
  138. BUILDER_SYSTEM="${BUILDER_SYSTEM:-$(echo "$EMQX_BUILDER" | awk -F'-' '{print $NF}')}"
  139. if [[ "${PKGTYPE}" != 'rel' && "${PKGTYPE}" != 'relup' ]]; then
  140. CMD_RUN="make ${MAKE_TARGET} && ./scripts/pkg-tests.sh ${MAKE_TARGET}"
  141. else
  142. CMD_RUN="make ${MAKE_TARGET}"
  143. fi
  144. IS_NATIVE_SYSTEM='no'
  145. if [[ "$BUILDER_SYSTEM" != "force_docker" ]]; then
  146. if [[ "$BUILDER_SYSTEM" == "force_host" ]] || [[ "$BUILDER_SYSTEM" == "$HOST_SYSTEM" ]]; then
  147. IS_NATIVE_SYSTEM='yes'
  148. fi
  149. fi
  150. IS_NATIVE_ARCH='no'
  151. if [[ "$NATIVE_ARCH" == "$ARCH" ]]; then
  152. IS_NATIVE_ARCH='yes'
  153. fi
  154. if [[ "${IS_NATIVE_SYSTEM}" == 'yes' && "${IS_NATIVE_ARCH}" == 'yes' ]]; then
  155. export ACLOCAL_PATH="/usr/share/aclocal:/usr/local/share/aclocal"
  156. eval "$CMD_RUN"
  157. elif docker info; then
  158. if [[ "${IS_NATIVE_ARCH}" == 'no' ]]; then
  159. docker run --rm --privileged tonistiigi/binfmt:latest --install "${ARCH}"
  160. fi
  161. docker run -i --rm \
  162. -v "$(pwd)":/emqx \
  163. --workdir /emqx \
  164. --platform="linux/$ARCH" \
  165. --env ACLOCAL_PATH="/usr/share/aclocal:/usr/local/share/aclocal" \
  166. "$EMQX_BUILDER" \
  167. bash -euc "git config --global --add safe.directory /emqx && $CMD_RUN"
  168. else
  169. echo "Error: Docker not available on unsupported platform"
  170. exit 1;
  171. fi