build-linux.sh 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. #!/bin/bash
  2. #
  3. # Copyright (c) Contributors to the Open 3D Engine Project.
  4. # For complete copyright and license terms please see the LICENSE at the root of this distribution.
  5. #
  6. # SPDX-License-Identifier: Apache-2.0 OR MIT
  7. #
  8. # This script will utilize Docker to build on either AMD64 or AARCH64 architectures.
  9. DOCKER_BUILD_SCRIPT=docker_build_linux.sh
  10. TARGET_BUILD_FOLDER=build
  11. #
  12. # Collect the required arguments for this ubuntu docker-base build script
  13. #
  14. # Get the base docker image name
  15. DOCKER_IMAGE_NAME_BASE=$1
  16. if [ "${DOCKER_IMAGE_NAME_BASE}" == "" ]
  17. then
  18. echo "Missing argument 1: Docker image name for this process"
  19. exit 1
  20. fi
  21. # Get the ubuntu base version (20.04|22.04)
  22. UBUNTU_BASE=$2
  23. if [ "${UBUNTU_BASE}" == "" ]
  24. then
  25. echo "Missing argument 2: Ubuntu docker tag"
  26. exit 1
  27. fi
  28. # Determine the host architecture
  29. CURRENT_HOST_ARCH=$(uname -m)
  30. # Use the host architecture if not supplied
  31. TARGET_ARCH=${3:-$(uname -m)}
  32. # Recompute the DOWNLOADED_PACKAGE_FOLDERS to apply to $WORKSPACE/temp inside the Docker script
  33. DEP_PACKAGES_FOLDERNAMES_ONLY=${DOWNLOADED_PACKAGE_FOLDERS//$TEMP_FOLDER\//}
  34. DEP_PACKAGES_DOCKER_FOLDERNAMES=${DOWNLOADED_PACKAGE_FOLDERS//$TEMP_FOLDER/"/data/workspace/temp"}
  35. echo "Executing docker-based build from the following arguments"
  36. echo " DOCKER_IMAGE_NAME_BASE = ${DOCKER_IMAGE_NAME_BASE}"
  37. echo " UBUNTU_BASE = ${UBUNTU_BASE}"
  38. echo " DOCKER_BUILD_SCRIPT = ${DOCKER_BUILD_SCRIPT}"
  39. echo " TARGET_BUILD_FOLDER = ${TARGET_BUILD_FOLDER}"
  40. echo " TARGET_ARCH = ${TARGET_ARCH}"
  41. echo " TEMP_FOLDER = ${TEMP_FOLDER}"
  42. echo " DOWNLOADED_PACKAGE_FOLDERS = ${DEP_PACKAGES_FOLDERNAMES_ONLY}"
  43. #
  44. # Make sure docker is installed
  45. #
  46. DOCKER_VERSION=$(docker --version)
  47. if [ $? -ne 0 ]
  48. then
  49. echo "Required package docker is not installed"
  50. echo "Follow instructions on https://docs.docker.com/engine/install/ubuntu/ to install docker properly"
  51. exit 1
  52. fi
  53. echo "Detected Docker Version $DOCKER_VERSION"
  54. #
  55. # Check the target architecture and determine if the necessary cross compilation requirements are met
  56. #
  57. # If the host and target architecture does not match, make sure the necessary cross compilation packages are installed
  58. if [ "${CURRENT_HOST_ARCH}" != ${TARGET_ARCH} ]
  59. then
  60. echo "Checking cross compiling requirements."
  61. for package_check in docker-ce qemu binfmt-support qemu-user-static
  62. do
  63. echo "Checking package $package_check"
  64. dpkg -s $package_check > /dev/null 2>&1
  65. if [ $? -ne 0 ]
  66. then
  67. echo ""
  68. echo "Missing package $package_check. Make sure to install it with your local package manager."
  69. echo ""
  70. exit 1
  71. fi
  72. done
  73. # Only cross compilation of an ARM64 image on an x86_64 host is supported
  74. if [ "${TARGET_ARCH}" = "aarch64" ]
  75. then
  76. # Make sure qemu-aarch64 is installed properly
  77. QEMU_AARCH_COUNT=$(update-binfmts --display | grep qemu-aarch64 | wc -l)
  78. if [ $QEMU_AARCH_COUNT -eq 0 ]
  79. then
  80. echo ""
  81. echo "QEMU aarch64 binary format not registered."
  82. echo "Run the following command to register"
  83. echo ""
  84. echo "sudo docker run --rm --privileged multiarch/qemu-user-static --reset -p yes"
  85. echo ""
  86. exit 1
  87. fi
  88. echo ""
  89. echo "Cross compiling aarch64 on an amd64 machine validated."
  90. echo ""
  91. fi
  92. else
  93. echo "Building ${TARGET_ARCH} natively."
  94. fi
  95. # Setup the docker arguments
  96. if [ "${TARGET_ARCH}" = "x86_64" ]
  97. then
  98. echo "Processing Docker for amd64"
  99. DOCKER_INPUT_ARCHITECTURE=amd64
  100. TARGET_DOCKER_PLATFORM_ARG=linux/amd64
  101. elif [ "${TARGET_ARCH}" = "aarch64" ]
  102. then
  103. echo "Processing Docker for aarch64"
  104. DOCKER_INPUT_ARCHITECTURE=arm64v8
  105. TARGET_DOCKER_PLATFORM_ARG=linux/arm64/v8
  106. else
  107. echo "Unsupported architecture ${TARGET_ARCH}"
  108. exit 1
  109. fi
  110. #
  111. # Prepare the docker base context based on ${TEMP_FOLDER}
  112. mkdir -p ${TEMP_FOLDER}
  113. cp -f ${DOCKER_BUILD_SCRIPT} ${TEMP_FOLDER}/
  114. echo "Building on ubuntu public.ecr.aws/ubuntu/ubuntu:${UBUNTU_BASE}"
  115. # Build the Docker Image
  116. DOCKER_IMAGE_NAME=${DOCKER_IMAGE_NAME_BASE}_${DOCKER_INPUT_ARCHITECTURE}_3p
  117. echo DOCKER_IMAGE_NAME=${DOCKER_IMAGE_NAME}
  118. echo "Building the docker build script for ${DOCKER_IMAGE_NAME_BASE} on ${DOCKER_INPUT_ARCHITECTURE} for Ubuntu $1"
  119. echo ""
  120. CMD_DOCKER_BUILD="\
  121. docker build --build-arg INPUT_DOCKER_BUILD_SCRIPT=${DOCKER_BUILD_SCRIPT}\
  122. --build-arg INPUT_ARCHITECTURE=${DOCKER_INPUT_ARCHITECTURE}\
  123. --build-arg INPUT_IMAGE=ubuntu:${UBUNTU_BASE}\
  124. --build-arg INPUT_DEPENDENT_PACKAGE_FOLDERS=${DEP_PACKAGES_DOCKER_FOLDERNAMES}\
  125. -f Dockerfile -t ${DOCKER_IMAGE_NAME}:latest temp "
  126. echo $CMD_DOCKER_BUILD
  127. eval $CMD_DOCKER_BUILD
  128. if [ $? -ne 0 ]
  129. then
  130. echo "Error occurred creating Docker image ${DOCKER_IMAGE_NAME}:latest."
  131. exit 1
  132. fi
  133. # Prepare the target build folder to copy from the docker container on successful run of the docker script
  134. INSTALL_PACKAGE_PATH=${TEMP_FOLDER}/${TARGET_BUILD_FOLDER}/
  135. # Run the build script in the docker image
  136. echo "Running build script in the docker image ${DOCKER_IMAGE_NAME}"
  137. echo ""
  138. CMD_DOCKER_RUN="\
  139. docker run --platform ${TARGET_DOCKER_PLATFORM_ARG}\
  140. --tty\
  141. -v ${TEMP_FOLDER}:/data/workspace/temp:ro\
  142. ${DOCKER_IMAGE_NAME}:latest /data/workspace/${DOCKER_BUILD_SCRIPT}"
  143. echo $CMD_DOCKER_RUN
  144. eval $CMD_DOCKER_RUN
  145. if [ $? -ne 0 ]
  146. then
  147. echo Failed to build from docker image ${DOCKER_IMAGE_NAME}:latest
  148. echo "To log into and troubleshoot the docker container, run the following command:"
  149. echo ""
  150. echo "docker run --platform ${TARGET_DOCKER_PLATFORM_ARG} -it --tty -v ${TEMP_FOLDER}:/data/workspace/temp:ro ${DOCKER_IMAGE_NAME}:latest"
  151. echo ""
  152. exit 1
  153. fi
  154. echo "Build Complete"
  155. # Copy the build artifacts from the docker image
  156. # Capture the Docker Image ID
  157. IMAGE_ID=$(docker images -q ${DOCKER_IMAGE_NAME}:latest)
  158. if [ -z $IMAGE_ID ]
  159. then
  160. echo "Error: Cannot find Image ID for ${DOCKER_IMAGE_NAME}"
  161. exit 1
  162. fi
  163. # Capture the container ID
  164. echo "Capturing the Container ID"
  165. CONTAINER_ID=$(docker container ls -l -q --filter "ancestor=${DOCKER_IMAGE_NAME}:latest")
  166. if [ -z $CONTAINER_ID ]
  167. then
  168. echo "Error: Cannot find Container ID for Image ${DOCKER_IMAGE_NAME}"
  169. exit 1
  170. fi
  171. DOCKER_BUILD_ROOT=/data/workspace/${TARGET_BUILD_FOLDER}
  172. rm -rf ${INSTALL_PACKAGE_PATH}
  173. mkdir -p ${INSTALL_PACKAGE_PATH}
  174. echo "Copying from $CONTAINER_ID:${DOCKER_BUILD_ROOT} to ${TEMP_FOLDER}/"
  175. docker cp $CONTAINER_ID:${DOCKER_BUILD_ROOT} ${TEMP_FOLDER}/
  176. if [ $? -ne 0 ]
  177. then
  178. echo "Error copying build from docker image ${DOCKER_IMAGE_NAME}:latest."
  179. exit 1
  180. fi
  181. echo "Built ${DOCKER_IMAGE_NAME_BASE} into ${INSTALL_PACKAGE_PATH} successfully"
  182. exit 0