buildx.sh 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  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. --flavor)
  95. EMQX_FLAVOR="$2"
  96. shift 2
  97. ;;
  98. *)
  99. echo "WARN: Unknown arg (ignored): $1"
  100. shift
  101. continue
  102. ;;
  103. esac
  104. done
  105. ## we have a different naming for them
  106. if [[ $(uname -m) == "x86_64" ]]; then
  107. NATIVE_ARCH='amd64'
  108. elif [[ $(uname -m) == "aarch64" ]]; then
  109. NATIVE_ARCH='arm64'
  110. elif [[ $(uname -m) == "arm64" ]]; then
  111. NATIVE_ARCH='arm64'
  112. elif [[ $(uname -m) == "armv7l" ]]; then
  113. # CHECKME: really ?
  114. NATIVE_ARCH='arm64'
  115. fi
  116. ARCH="${ARCH:-${NATIVE_ARCH:-}}"
  117. [ -z "${PROFILE:-}" ] && die "missing --profile"
  118. [ -z "${PKGTYPE:-}" ] && die "missing --pkgtype"
  119. [ -z "${EMQX_BUILDER:-}" ] && die "missing --builder"
  120. [ -z "${ARCH:-}" ] && die "missing --arch"
  121. set -x
  122. if [ -z "${IS_ELIXIR:-}" ]; then
  123. IS_ELIXIR=no
  124. fi
  125. if [ -z "${EMQX_FLAVOR:-}" ]; then
  126. EMQX_FLAVOR=official
  127. fi
  128. case "${PKGTYPE:-}" in
  129. tgz|pkg|rel|relup)
  130. true
  131. ;;
  132. *)
  133. echo "Bad --pkgtype option, should be tgz, pkg, rel or relup"
  134. exit 1
  135. ;;
  136. esac
  137. export CODE_PATH="${SRC_DIR:-$PWD}"
  138. cd "${CODE_PATH}"
  139. if [ "$IS_ELIXIR" = "yes" ]; then
  140. MAKE_TARGET="${PROFILE}-elixir-${PKGTYPE}"
  141. else
  142. MAKE_TARGET="${PROFILE}-${PKGTYPE}"
  143. fi
  144. HOST_SYSTEM="$(./scripts/get-distro.sh)"
  145. BUILDER_SYSTEM="${BUILDER_SYSTEM:-$(echo "$EMQX_BUILDER" | awk -F'-' '{print $NF}')}"
  146. if [[ "${PKGTYPE}" != 'rel' && "${PKGTYPE}" != 'relup' ]]; then
  147. CMD_RUN="make ${MAKE_TARGET} && ./scripts/pkg-tests.sh ${MAKE_TARGET}"
  148. else
  149. CMD_RUN="make ${MAKE_TARGET}"
  150. fi
  151. IS_NATIVE_SYSTEM='no'
  152. if [[ "$BUILDER_SYSTEM" != "force_docker" ]]; then
  153. if [[ "$BUILDER_SYSTEM" == "force_host" ]] || [[ "$BUILDER_SYSTEM" == "$HOST_SYSTEM" ]]; then
  154. IS_NATIVE_SYSTEM='yes'
  155. fi
  156. fi
  157. IS_NATIVE_ARCH='no'
  158. if [[ "$NATIVE_ARCH" == "$ARCH" ]]; then
  159. IS_NATIVE_ARCH='yes'
  160. fi
  161. if [[ "${IS_NATIVE_SYSTEM}" == 'yes' && "${IS_NATIVE_ARCH}" == 'yes' ]]; then
  162. export ACLOCAL_PATH="/usr/share/aclocal:/usr/local/share/aclocal"
  163. eval "$CMD_RUN"
  164. elif docker info; then
  165. if [[ "${IS_NATIVE_ARCH}" == 'no' ]]; then
  166. docker run --rm --privileged tonistiigi/binfmt:latest --install "${ARCH}"
  167. fi
  168. docker run -i --rm \
  169. -v "$(pwd)":/emqx \
  170. --workdir /emqx \
  171. --platform="linux/$ARCH" \
  172. --env ACLOCAL_PATH="/usr/share/aclocal:/usr/local/share/aclocal" \
  173. --env EMQX_FLAVOR="$EMQX_FLAVOR" \
  174. "$EMQX_BUILDER" \
  175. bash -euc "git config --global --add safe.directory /emqx && $CMD_RUN"
  176. else
  177. echo "Error: Docker not available on unsupported platform"
  178. exit 1;
  179. fi