host-functions-source.sh 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. # -----------------------------------------------------------------------------
  2. # This file is part of the xPack distribution.
  3. # (https://xpack.github.io)
  4. # Copyright (c) 2020 Liviu Ionescu.
  5. #
  6. # Permission to use, copy, modify, and/or distribute this software
  7. # for any purpose is hereby granted, under the terms of the MIT license.
  8. # -----------------------------------------------------------------------------
  9. # Helper script used in the second edition of the xPack build
  10. # scripts. As the name implies, it should contain only functions and
  11. # should be included with 'source' by the host build scripts.
  12. # -----------------------------------------------------------------------------
  13. function host_get_current_date()
  14. {
  15. # Use the UTC date as version in the name of the distribution file.
  16. DISTRIBUTION_FILE_DATE=${DISTRIBUTION_FILE_DATE:-$(date -u +%Y%m%d-%H%M)}
  17. # Leave a track of the start date, in case of resume needed.
  18. mkdir -pv "${HOST_WORK_FOLDER_PATH}"
  19. touch "${HOST_WORK_FOLDER_PATH}/${DISTRIBUTION_FILE_DATE}"
  20. echo
  21. echo "DISTRIBUTION_FILE_DATE=\"${DISTRIBUTION_FILE_DATE}\""
  22. }
  23. function host_start_timer()
  24. {
  25. HOST_BEGIN_SECOND=$(date +%s)
  26. echo
  27. echo "Script \"$0\" started at $(date)."
  28. }
  29. function host_stop_timer()
  30. {
  31. local host_end_second=$(date +%s)
  32. echo
  33. echo "Script \"$0\" completed at $(date)."
  34. local delta_seconds=$((host_end_second-HOST_BEGIN_SECOND))
  35. if [ ${delta_seconds} -lt 100 ]
  36. then
  37. echo "Duration: ${delta_seconds} seconds."
  38. else
  39. local delta_minutes=$(((delta_seconds+30)/60))
  40. echo "Duration: ${delta_minutes} minutes."
  41. fi
  42. }
  43. function host_notify_completed()
  44. {
  45. if [ "${HOST_UNAME}" == "Darwin" ]
  46. then
  47. say "Wake up, the build completed successfully"
  48. fi
  49. }
  50. # -----------------------------------------------------------------------------
  51. # Detect the machine the build runs on.
  52. function host_detect()
  53. {
  54. echo
  55. uname -a
  56. HOST_UNAME="$(uname)"
  57. HOST_MACHINE="$(uname -m)"
  58. HOST_DISTRO_NAME="?" # Linux distribution name (Ubuntu|CentOS|...)
  59. HOST_DISTRO_LC_NAME="?" # Same, in lower case.
  60. HOST_NODE_ARCH="?" # Node.js process.arch (x32|x64|arm|arm64)
  61. HOST_NODE_PLATFORM="?" # Node.js process.platform (darwin|linux|win32)
  62. if [ "${HOST_UNAME}" == "Darwin" ]
  63. then
  64. # uname -p -> i386
  65. # uname -m -> x86_64
  66. HOST_BITS="64"
  67. HOST_DISTRO_NAME=Darwin
  68. HOST_DISTRO_LC_NAME=darwin
  69. HOST_NODE_ARCH="x64" # For now.
  70. HOST_NODE_PLATFORM="darwin"
  71. elif [ "${HOST_UNAME}" == "Linux" ]
  72. then
  73. # ----- Determine distribution name and word size -----
  74. # uname -p -> x86_64|i686 (unknown in recent versions, use -m)
  75. # uname -m -> x86_64|i686|aarch64|armv7l
  76. if [ "${HOST_MACHINE}" == "x86_64" ]
  77. then
  78. HOST_BITS="64"
  79. HOST_NODE_ARCH="x64"
  80. elif [ "${HOST_MACHINE}" == "i386" -o "${HOST_MACHINE}" == "i686" ]
  81. then
  82. HOST_BITS="32"
  83. HOST_NODE_ARCH="x32"
  84. elif [ "${HOST_MACHINE}" == "aarch64" ]
  85. then
  86. HOST_BITS="64"
  87. HOST_NODE_ARCH="arm64"
  88. elif [ "${HOST_MACHINE}" == "armv7l" -o "${HOST_MACHINE}" == "armv8l" ]
  89. then
  90. HOST_BITS="32"
  91. HOST_NODE_ARCH="arm"
  92. else
  93. echo "Unknown uname -m ${HOST_MACHINE}"
  94. exit 1
  95. fi
  96. HOST_NODE_PLATFORM="linux"
  97. local lsb_path=$(which lsb_release)
  98. if [ -z "${lsb_path}" ]
  99. then
  100. echo "Please install the lsb core package and rerun."
  101. exit 1
  102. fi
  103. HOST_DISTRO_NAME=$(lsb_release -si)
  104. HOST_DISTRO_LC_NAME=$(echo ${HOST_DISTRO_NAME} | tr "[:upper:]" "[:lower:]")
  105. else
  106. echo "Unsupported uname ${HOST_UNAME}"
  107. exit 1
  108. fi
  109. echo
  110. echo "Running on ${HOST_DISTRO_NAME} ${HOST_NODE_ARCH} (${HOST_BITS}-bit)."
  111. USER_ID=$(id -u)
  112. USER_NAME="$(id -u -n)"
  113. GROUP_ID=$(id -g)
  114. GROUP_NAME="$(id -g -n)"
  115. TARGET_ARCH="${HOST_NODE_ARCH}"
  116. TARGET_PLATFORM="${HOST_NODE_PLATFORM}"
  117. TARGET_MACHINE="${HOST_MACHINE}"
  118. IS_NATIVE=""
  119. IS_DEVELOP=""
  120. # Redefine it to "y" to run as root inside the container.
  121. CONTAINER_RUN_AS_ROOT=${CONTAINER_RUN_AS_ROOT:-""}
  122. HAS_WINPTHREAD=${HAS_WINPTHREAD:-""}
  123. }
  124. # -----------------------------------------------------------------------------
  125. function host_prepare_cache()
  126. {
  127. # The folder that caches all downloads is in Work, for easy access.
  128. HOST_CACHE_FOLDER_PATH=${HOST_CACHE_FOLDER_PATH:-"${HOME}/Work/cache"}
  129. CONTAINER_CACHE_FOLDER_PATH="/Host${HOST_CACHE_FOLDER_PATH}"
  130. mkdir -pv "${HOST_CACHE_FOLDER_PATH}"
  131. }
  132. function host_options()
  133. {
  134. local help_message="$1"
  135. shift
  136. ACTION=""
  137. DO_BUILD_SOURCES=""
  138. DO_BUILD_WIN32=""
  139. DO_BUILD_WIN64=""
  140. DO_BUILD_LINUX32=""
  141. DO_BUILD_LINUX64=""
  142. DO_BUILD_LINUX_ARM32=""
  143. DO_BUILD_LINUX_ARM64=""
  144. DO_BUILD_OSX=""
  145. ENV_FILE=""
  146. argc=$#
  147. declare -a argv
  148. argv=( "$@" )
  149. if [ ! -z "${DEBUG}" ]
  150. then
  151. echo ${argv[@]-}
  152. fi
  153. i=0
  154. # Must be declared by the caller.
  155. # declare -a rest
  156. # Identify some of the options. The rest are collected and passed
  157. # to the container script.
  158. while [ $i -lt $argc ]
  159. do
  160. arg="${argv[$i]}"
  161. case "${arg}" in
  162. clean|cleanlibs|cleanall|preload-images)
  163. ACTION="${arg}"
  164. ;;
  165. --win32|--windows32)
  166. DO_BUILD_WIN32="y"
  167. ;;
  168. --win64|--windows64)
  169. DO_BUILD_WIN64="y"
  170. ;;
  171. --linux32)
  172. DO_BUILD_LINUX32="y"
  173. ;;
  174. --linux64)
  175. DO_BUILD_LINUX64="y"
  176. ;;
  177. --arm32)
  178. DO_BUILD_LINUX_ARM32="y"
  179. ;;
  180. --arm64)
  181. DO_BUILD_LINUX_ARM64="y"
  182. ;;
  183. --osx)
  184. DO_BUILD_OSX="y"
  185. ;;
  186. --sources)
  187. DO_BUILD_SOURCES="y"
  188. ;;
  189. --all)
  190. if [ "${HOST_NODE_ARCH}" == "arm64" ]
  191. then
  192. DO_BUILD_LINUX_ARM32="y"
  193. DO_BUILD_LINUX_ARM64="y"
  194. elif [ "${HOST_NODE_ARCH}" == "x64" ]
  195. then
  196. DO_BUILD_WIN32="y"
  197. DO_BUILD_WIN64="y"
  198. DO_BUILD_LINUX32="y"
  199. DO_BUILD_LINUX64="y"
  200. DO_BUILD_SOURCES="y"
  201. if [ "$(uname)" == "Darwin" ]
  202. then
  203. DO_BUILD_OSX="y"
  204. fi
  205. else
  206. echo "--all supported only on 64-bit hosts"
  207. fi
  208. ;;
  209. --env-file)
  210. ((++i))
  211. ENV_FILE="${argv[$i]}"
  212. if [ ! -f "${ENV_FILE}" ];
  213. then
  214. echo "The specified environment file \"${ENV_FILE}\" does not exist, exiting..."
  215. exit 1
  216. fi
  217. ;;
  218. # Deprecated.
  219. --date)
  220. ((++i))
  221. DISTRIBUTION_FILE_DATE="${argv[$i]}"
  222. ;;
  223. --help)
  224. echo "Usage:"
  225. # Some of the options are processed by the container script.
  226. echo "${help_message}"
  227. echo
  228. exit 1
  229. ;;
  230. *)
  231. # Collect all other in an array. Append to the end.
  232. # Will be later processed by the container script.
  233. set +u
  234. rest[${#rest[*]}]="$arg"
  235. set -u
  236. ;;
  237. esac
  238. ((++i))
  239. done
  240. DO_BUILD_ANY="${DO_BUILD_OSX}${DO_BUILD_LINUX64}${DO_BUILD_LINUX_ARM64}${DO_BUILD_WIN64}${DO_BUILD_LINUX32}${DO_BUILD_LINUX_ARM32}${DO_BUILD_WIN32}${DO_BUILD_SOURCES}"
  241. # The ${rest[@]} options will be passed to the inner script.
  242. if [ ! -z "${DEBUG}" ]
  243. then
  244. echo ${rest[@]-}
  245. fi
  246. }
  247. function host_options_windows()
  248. {
  249. local help_message="$1"
  250. shift
  251. ACTION=""
  252. DO_BUILD_WIN32=""
  253. DO_BUILD_WIN64=""
  254. # Kept, since they are used in various common functions.
  255. DO_BUILD_LINUX32=""
  256. DO_BUILD_LINUX64=""
  257. DO_BUILD_LINUX_ARM32=""
  258. DO_BUILD_LINUX_ARM64=""
  259. DO_BUILD_OSX=""
  260. ENV_FILE=""
  261. argc=$#
  262. declare -a argv
  263. argv=( "$@" )
  264. if [ ! -z "${DEBUG}" ]
  265. then
  266. echo ${argv[@]-}
  267. fi
  268. i=0
  269. # Must be declared by the caller.
  270. # declare -a rest
  271. # Identify some of the options. The rest are collected and passed
  272. # to the container script.
  273. while [ $i -lt $argc ]
  274. do
  275. arg="${argv[$i]}"
  276. case "${arg}" in
  277. clean|cleanlibs|cleanall|preload-images)
  278. ACTION="${arg}"
  279. ;;
  280. --win32|--windows32)
  281. DO_BUILD_WIN32="y"
  282. ;;
  283. --win64|--windows64)
  284. DO_BUILD_WIN64="y"
  285. ;;
  286. --all)
  287. DO_BUILD_WIN32="y"
  288. DO_BUILD_WIN64="y"
  289. ;;
  290. --env-file)
  291. ((++i))
  292. ENV_FILE="${argv[$i]}"
  293. if [ ! -f "${ENV_FILE}" ];
  294. then
  295. echo "The specified environment file \"${ENV_FILE}\" does not exist, exiting..."
  296. exit 1
  297. fi
  298. ;;
  299. # Deprecated.
  300. --date)
  301. ((++i))
  302. DISTRIBUTION_FILE_DATE="${argv[$i]}"
  303. ;;
  304. --help)
  305. echo "Usage:"
  306. # Some of the options are processed by the container script.
  307. echo "${help_message}"
  308. echo
  309. exit 1
  310. ;;
  311. *)
  312. # Collect all other in an array. Append to the end.
  313. # Will be later processed by the container script.
  314. set +u
  315. rest[${#rest[*]}]="$arg"
  316. set -u
  317. ;;
  318. esac
  319. ((++i))
  320. done
  321. DO_BUILD_ANY="${DO_BUILD_WIN64}${DO_BUILD_WIN32}"
  322. # The ${rest[@]} options will be passed to the inner script.
  323. if [ ! -z "${DEBUG}" ]
  324. then
  325. echo ${rest[@]-}
  326. fi
  327. }
  328. function host_native_options()
  329. {
  330. local help_message="$1"
  331. shift
  332. ACTION=""
  333. DO_BUILD_WIN=""
  334. IS_DEBUG=""
  335. IS_DEVELOP=""
  336. WITH_STRIP="y"
  337. IS_NATIVE="y"
  338. if [ "$(uname)" == "Linux" ]
  339. then
  340. JOBS="$(nproc)"
  341. elif [ "$(uname)" == "Darwin" ]
  342. then
  343. JOBS="$(sysctl hw.ncpu | sed 's/hw.ncpu: //')"
  344. else
  345. JOBS="1"
  346. fi
  347. while [ $# -gt 0 ]
  348. do
  349. case "$1" in
  350. clean|cleanlibs|cleanall)
  351. ACTION="$1"
  352. ;;
  353. --win|--windows)
  354. DO_BUILD_WIN="y"
  355. ;;
  356. --debug)
  357. IS_DEBUG="y"
  358. ;;
  359. --develop)
  360. IS_DEVELOP="y"
  361. ;;
  362. --jobs)
  363. shift
  364. JOBS=$1
  365. ;;
  366. --disable-strip)
  367. WITH_STRIP="n"
  368. shift
  369. ;;
  370. --help)
  371. echo "Build a local/native ${DISTRO_UC_NAME} ${APP_NAME}."
  372. echo "Usage:"
  373. # Some of the options are processed by the container script.
  374. echo "${help_message}"
  375. echo
  376. exit 0
  377. ;;
  378. *)
  379. echo "Unknown action/option $1"
  380. exit 1
  381. ;;
  382. esac
  383. shift
  384. done
  385. if [ "${DO_BUILD_WIN}" == "y" ]
  386. then
  387. if [ "${HOST_NODE_PLATFORM}" == "linux" ]
  388. then
  389. TARGET_PLATFORM="win32"
  390. else
  391. echo "Windows cross builds are available only on GNU/Linux."
  392. exit 1
  393. fi
  394. fi
  395. }
  396. function host_common()
  397. {
  398. if [ -f "${script_folder_path}/VERSION" ]
  399. then
  400. # When running from the distribution folder.
  401. RELEASE_VERSION=${RELEASE_VERSION:-"$(cat "${script_folder_path}"/VERSION)"}
  402. fi
  403. echo
  404. echo "Preparing release ${RELEASE_VERSION}..."
  405. # -----------------------------------------------------------------------------
  406. common_helper_functions_script_path="${script_folder_path}/helper/common-functions-source.sh"
  407. echo "Common helper functions source script: \"${common_helper_functions_script_path}\"."
  408. source "${common_helper_functions_script_path}"
  409. # May override some of the helper/common definitions.
  410. common_functions_script_path="${script_folder_path}/common-functions-source.sh"
  411. if [ -f "${common_functions_script_path}" ]
  412. then
  413. echo "Common functions source script: \"${common_functions_script_path}\"."
  414. source "${common_functions_script_path}"
  415. fi
  416. # ---------------------------------------------------------------------------
  417. # The Work folder is in HOME.
  418. HOST_WORK_FOLDER_PATH=${WORK_FOLDER_PATH:-"${HOME}/Work"}
  419. if [ "${IS_NATIVE}" == "y" -a "${IS_DEVELOP}" == "y" ]
  420. then
  421. HOST_WORK_FOLDER_PATH+="/${APP_LC_NAME}-dev"
  422. else
  423. HOST_WORK_FOLDER_PATH+="/${APP_LC_NAME}-${RELEASE_VERSION}"
  424. fi
  425. CONTAINER_WORK_FOLDER_PATH="/Host${HOST_WORK_FOLDER_PATH}"
  426. SOURCES_FOLDER_PATH="${SOURCES_FOLDER_PATH:-"${HOST_WORK_FOLDER_PATH}/sources"}"
  427. do_actions
  428. host_prepare_cache
  429. CONTAINER_BUILD_SCRIPT_REL_PATH="build.git/scripts/${CONTAINER_SCRIPT_NAME}"
  430. echo "Container build script: \"${HOST_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}\"."
  431. # ---------------------------------------------------------------------------
  432. mkdir -pv "${HOST_WORK_FOLDER_PATH}"
  433. mkdir -pv "${SOURCES_FOLDER_PATH}"
  434. # ---------------------------------------------------------------------------
  435. # Set the DISTRIBUTION_FILE_DATE.
  436. host_get_current_date
  437. # ---------------------------------------------------------------------------
  438. host_start_timer
  439. host_prepare_prerequisites
  440. # ---------------------------------------------------------------------------
  441. copy_build_git
  442. }
  443. function host_prepare_prerequisites()
  444. {
  445. if [ "${HOST_UNAME}" == "Darwin" ]
  446. then
  447. local xbb_folder_path
  448. local must_install=""
  449. if [ -d "${HOME}/opt/xbb" ]
  450. then
  451. xbb_folder_path="${HOME}/opt/xbb"
  452. elif [ -d "${HOME}/opt/homebrew/xbb" ]
  453. then
  454. xbb_folder_path="${HOME}/opt/homebrew/xbb"
  455. else
  456. must_install="y"
  457. fi
  458. if [ ! -z "${xbb_folder_path}" ]
  459. then
  460. echo
  461. echo "Checking XBB in '${xbb_folder_path}'..."
  462. if [ ! -f "${xbb_folder_path}/xbb-source.sh" ]
  463. then
  464. must_install="y"
  465. fi
  466. fi
  467. if [ -n "${must_install}" ]
  468. then
  469. echo
  470. echo "Please install the macOS XBB and rerun."
  471. echo "https://github.com/xpack/xpack-build-box/tree/master/macos"
  472. exit 1
  473. fi
  474. if true
  475. then
  476. local tl_folder="$HOME/opt/texlive"
  477. must_install=""
  478. # Check local TeX Live.
  479. if [ ! -d "${tl_folder}" ]
  480. then
  481. must_install="y"
  482. else
  483. PATH="${tl_folder}/bin/x86_64-darwin:${PATH}"
  484. export PATH
  485. echo
  486. echo "Checking TeX Live in '${tl_folder}'..."
  487. set +e
  488. tex --version | grep 'TeX 3'
  489. if [ $? != 0 ]
  490. then
  491. must_install="y"
  492. fi
  493. set -e
  494. fi
  495. if [ -n "${must_install}" ]
  496. then
  497. echo
  498. echo "Please install TeX Live and rerun."
  499. echo "Alternatively restart the build script using '--without-pdf'."
  500. echo "https://github.com/xpack/xpack-build-box/blob/master/macos/README.md#install-tex"
  501. exit 1
  502. fi
  503. fi # -z "${no_pdf}"
  504. fi # "${HOST_UNAME}" == "Darwin"
  505. host_prepare_cache
  506. # The host script will pass to the container script
  507. # various environment variables.
  508. HOST_DEFINES_SCRIPT_PATH="${HOST_WORK_FOLDER_PATH}/build.git/scripts/host-defs-source.sh"
  509. DEPLOY_FOLDER_NAME=${DEPLOY_FOLDER_NAME:-"deploy"}
  510. }
  511. # -----------------------------------------------------------------------------
  512. function host_prepare_docker()
  513. {
  514. echo
  515. echo "Checking Docker..."
  516. set +e
  517. docker --version
  518. if [ $? != 0 ]
  519. then
  520. echo "Please start docker daemon and rerun."
  521. echo "If not installed, see https://docs.docker.com/installation/."
  522. exit 1
  523. fi
  524. echo
  525. echo "Pruning Docker..."
  526. docker system prune -f
  527. set -e
  528. }
  529. # -----------------------------------------------------------------------------
  530. function host_build_target()
  531. {
  532. message="$1"
  533. shift
  534. echo
  535. echo "================================================================================"
  536. echo "=== ${message}"
  537. echo
  538. echo $@
  539. local container_script_path=""
  540. local target_platform="${HOST_NODE_PLATFORM}"
  541. local target_arch="${HOST_NODE_ARCH}"
  542. local target_machine="${HOST_MACHINE}"
  543. local target_bits="${HOST_BITS}"
  544. # If the docker image is not set, it is a native build.
  545. local docker_image=""
  546. local build_binaries_path=""
  547. local env_file=""
  548. while [ $# -gt 0 ]
  549. do
  550. case "$1" in
  551. --script)
  552. container_script_path="$2"
  553. shift 2
  554. ;;
  555. --target-platform)
  556. target_platform="$2"
  557. shift 2
  558. ;;
  559. --target-arch)
  560. target_arch="$2"
  561. shift 2
  562. ;;
  563. --target-machine)
  564. target_machine="$2"
  565. shift 2
  566. ;;
  567. --target-bits)
  568. target_bits="$2"
  569. shift 2
  570. ;;
  571. --docker-image)
  572. docker_image="$2"
  573. shift 2
  574. ;;
  575. --env-file)
  576. env_file="$2"
  577. shift 2
  578. ;;
  579. --)
  580. shift
  581. break
  582. ;;
  583. *)
  584. echo "Unknown option $1, exit."
  585. exit 1
  586. esac
  587. done
  588. if [ "${target_platform}" == "sources" ]
  589. then
  590. target_arch="none"
  591. target_bits=""
  592. fi
  593. # The remaining "$@" options will be passed to the inner script.
  594. if [ -n "${DEBUG}" ]
  595. then
  596. echo "$@"
  597. fi
  598. # ---------------------------------------------------------------------------
  599. mkdir -pv "$(dirname "${HOST_DEFINES_SCRIPT_PATH}")"
  600. echo "${RELEASE_VERSION}" >"$(dirname "${HOST_DEFINES_SCRIPT_PATH}")"/VERSION
  601. rm -rf "${HOST_DEFINES_SCRIPT_PATH}"
  602. touch "${HOST_DEFINES_SCRIPT_PATH}"
  603. echo "RELEASE_VERSION=\"${RELEASE_VERSION}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  604. echo "DISTRIBUTION_FILE_DATE=\"${DISTRIBUTION_FILE_DATE}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  605. echo "TARGET_PLATFORM=\"${target_platform}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  606. echo "TARGET_ARCH=\"${target_arch}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  607. echo "TARGET_MACHINE=\"${target_machine}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  608. echo "TARGET_BITS=\"${target_bits}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  609. echo "HOST_UNAME=\"${HOST_UNAME}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  610. echo "USER_ID=\"${USER_ID}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  611. echo "USER_NAME=\"${USER_NAME}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  612. echo "GROUP_ID=\"${GROUP_ID}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  613. echo "GROUP_NAME=\"${GROUP_NAME}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  614. echo "CONTAINER_RUN_AS_ROOT=\"${CONTAINER_RUN_AS_ROOT}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  615. echo "HOST_WORK_FOLDER_PATH=\"${HOST_WORK_FOLDER_PATH}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  616. echo "CONTAINER_WORK_FOLDER_PATH=\"${CONTAINER_WORK_FOLDER_PATH}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  617. echo "HOST_CACHE_FOLDER_PATH=\"${HOST_CACHE_FOLDER_PATH}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  618. echo "CONTAINER_CACHE_FOLDER_PATH=\"${CONTAINER_CACHE_FOLDER_PATH}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  619. echo "DEPLOY_FOLDER_NAME=\"${DEPLOY_FOLDER_NAME}\"" >>"${HOST_DEFINES_SCRIPT_PATH}"
  620. if [ -z "${docker_image}" ]
  621. then
  622. host_run_native_script \
  623. --script "${container_script_path}" \
  624. --env-file "${env_file}" \
  625. -- \
  626. "$@"
  627. else
  628. host_run_docker_script \
  629. --script "${container_script_path}" \
  630. --docker-image "${docker_image}" \
  631. --docker-container-name "${APP_LC_NAME}-${target_platform}-${target_arch}-build" \
  632. --env-file "${env_file}" \
  633. --host-uname "${HOST_UNAME}" \
  634. -- \
  635. "$@"
  636. fi
  637. if [ -n "${DEBUG}" ]
  638. then
  639. echo "host_build_target ${rest[@]-} completed."
  640. fi
  641. }
  642. # -----------------------------------------------------------------------------
  643. function host_run_native_script()
  644. {
  645. local local_script=""
  646. local env_file=""
  647. while [ $# -gt 0 ]
  648. do
  649. case "$1" in
  650. --script)
  651. local_script="$2"
  652. shift 2
  653. ;;
  654. --env-file)
  655. env_file="$2"
  656. shift 2
  657. ;;
  658. --)
  659. shift
  660. break
  661. ;;
  662. *)
  663. echo "Unknown option $1, exit."
  664. exit 1
  665. esac
  666. done
  667. # The remaining $@ options will be passed to the inner script.
  668. echo
  669. echo "Running script \"$(basename "${local_script}")\" natively..."
  670. # Run the inner script in a local sub-shell, possibly with the
  671. # custom environment.
  672. (
  673. if [ -n "${env_file}" -a -f "${env_file}" ]
  674. then
  675. source "${env_file}"
  676. fi
  677. /bin/bash ${DEBUG} "${local_script}" "$@"
  678. )
  679. }
  680. # -----------------------------------------------------------------------------
  681. function host_run_docker_script()
  682. {
  683. local docker_script=""
  684. local docker_image=""
  685. local docker_container_name=""
  686. local host_uname=""
  687. local env_file=""
  688. local opt_env_file=
  689. while [ $# -gt 0 ]
  690. do
  691. case "$1" in
  692. --script)
  693. docker_script="$2"
  694. shift 2
  695. ;;
  696. --docker-image)
  697. docker_image="$2"
  698. shift 2
  699. ;;
  700. --docker-container-name)
  701. docker_container_name="$2"
  702. shift 2
  703. ;;
  704. --host-uname)
  705. host_uname="$2"
  706. shift 2
  707. ;;
  708. --env-file)
  709. env_file="$2"
  710. shift 2
  711. ;;
  712. --)
  713. shift
  714. break
  715. ;;
  716. *)
  717. echo "Unknown option $1, exit."
  718. exit 1
  719. esac
  720. done
  721. set +e
  722. # Remove a possible previously crashed container.
  723. docker rm --force "${docker_container_name}" > /dev/null 2> /dev/null
  724. set -e
  725. echo
  726. echo "Running script \"$(basename "${docker_script}")\" inside docker image \"${docker_image}\"..."
  727. local env_file_option=""
  728. # Run the inner script in a fresh Docker container.
  729. if [ -n "${env_file}" -a -f "${env_file}" ]
  730. then
  731. env_file_option="--env-file=\"${env_file}\""
  732. fi
  733. if [ "${HOST_UNAME}" == "Darwin" -o "${CONTAINER_RUN_AS_ROOT}" == "y" ]
  734. then
  735. docker run \
  736. --name="${docker_container_name}" \
  737. --tty \
  738. --hostname "docker" \
  739. --workdir="/root" \
  740. --volume="${HOST_WORK_FOLDER_PATH}/:${CONTAINER_WORK_FOLDER_PATH}" \
  741. --volume="${HOST_CACHE_FOLDER_PATH}/:${CONTAINER_CACHE_FOLDER_PATH}" \
  742. ${env_file_option} \
  743. "${docker_image}" \
  744. /bin/bash ${DEBUG} "${docker_script}" "$@"
  745. else
  746. # This is a bit tricky, since it needs to do multiple actions in
  747. # one go: add a new user and run the script with that user credentials,
  748. # including passing the extra args (in the middle of the string).
  749. #
  750. # From the [bash manual](https://www.gnu.org/software/bash/manual/bash.html):
  751. # ($*) Expands to the positional parameters, starting from one.
  752. # When the expansion is not within double quotes, each positional
  753. # parameter expands to a separate word. In contexts where it is
  754. # performed, those words are subject to further word splitting and
  755. # pathname expansion. When the expansion occurs within double quotes,
  756. # it expands to a single word with the value of each parameter separated
  757. # by the first character of the IFS special variable. That is, "$*"
  758. # is equivalent to "$1c$2c…", where c is the first character of the
  759. # value of the IFS variable. If IFS is unset, the parameters are
  760. # separated by spaces. If IFS is null, the parameters are joined
  761. # without intervening separators.
  762. local ifs="${IFS}"
  763. IFS=" "
  764. # Without -m, wine fails to create .wine.
  765. local cmd_string="groupadd -g ${GROUP_ID} ${GROUP_NAME} && useradd -m -u ${USER_ID} -g ${GROUP_ID} ${USER_NAME} && su -c \"DEBUG=${DEBUG} bash ${docker_script} $*\" ${USER_NAME}"
  766. IFS="${ifs}"
  767. docker run \
  768. --name="${docker_container_name}" \
  769. --tty \
  770. --hostname "docker" \
  771. --workdir="/root" \
  772. --volume="${HOST_WORK_FOLDER_PATH}/:${CONTAINER_WORK_FOLDER_PATH}" \
  773. --volume="${HOST_CACHE_FOLDER_PATH}/:${CONTAINER_CACHE_FOLDER_PATH}" \
  774. ${env_file_option} \
  775. "${docker_image}" \
  776. /bin/bash ${DEBUG} -c "${cmd_string}"
  777. fi
  778. # Remove the container.
  779. echo "Docker container \"$(docker rm --force "${docker_container_name}")\" removed."
  780. }
  781. # -----------------------------------------------------------------------------
  782. function host_build_all() {
  783. if [ ! -z "${DO_BUILD_LINUX64}${DO_BUILD_WIN64}${DO_BUILD_LINUX_ARM64}${DO_BUILD_LINUX32}${DO_BUILD_WIN32}${DO_BUILD_LINUX_ARM32}" ]
  784. then
  785. host_prepare_docker
  786. fi
  787. if [ -z "${DO_BUILD_ANY}" ]
  788. then
  789. # ----- Build the native distribution. --------------------------------------
  790. host_build_target "Creating the native distribution..." \
  791. --script "${HOST_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}" \
  792. --env-file "${ENV_FILE}" \
  793. -- \
  794. ${rest[@]-}
  795. else
  796. # ----- Build the OS X distribution. ----------------------------------------
  797. if [ "${DO_BUILD_OSX}" == "y" ]
  798. then
  799. if [ "${HOST_UNAME}" == "Darwin" ]
  800. then
  801. host_build_target "Creating the OS X distribution..." \
  802. --script "${HOST_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}" \
  803. --env-file "${ENV_FILE}" \
  804. --target-platform "darwin" \
  805. -- \
  806. ${rest[@]-}
  807. else
  808. echo "Building the macOS image is not possible on this platform."
  809. exit 1
  810. fi
  811. fi
  812. # ----- Build the GNU/Linux 64-bit distribution. ----------------------------
  813. if [ "${DO_BUILD_LINUX64}" == "y" ]
  814. then
  815. host_build_target "Creating the GNU/Linux 64-bit distribution..." \
  816. --script "${CONTAINER_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}" \
  817. --env-file "${ENV_FILE}" \
  818. --target-platform "linux" \
  819. --target-arch "x64" \
  820. --target-machine "x86_64" \
  821. --target-bits 64 \
  822. --docker-image "${docker_linux64_image}" \
  823. -- \
  824. ${rest[@]-}
  825. fi
  826. # ----- Build the Windows 64-bit distribution. ------------------------------
  827. if [ "${DO_BUILD_WIN64}" == "y" ]
  828. then
  829. host_build_target "Creating the Windows 64-bit distribution..." \
  830. --script "${CONTAINER_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}" \
  831. --env-file "${ENV_FILE}" \
  832. --target-platform "win32" \
  833. --target-arch "x64" \
  834. --target-machine "x86_64" \
  835. --target-bits 64 \
  836. --docker-image "${docker_linux64_image}" \
  837. -- \
  838. ${rest[@]-}
  839. fi
  840. # ----- Build the GNU/Linux 32-bit distribution. ----------------------------
  841. if [ "${DO_BUILD_LINUX32}" == "y" ]
  842. then
  843. host_build_target "Creating the GNU/Linux 32-bit distribution..." \
  844. --script "${CONTAINER_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}" \
  845. --env-file "${ENV_FILE}" \
  846. --target-platform "linux" \
  847. --target-arch "x32" \
  848. --target-machine "i386" \
  849. --target-bits 32 \
  850. --docker-image "${docker_linux32_image}" \
  851. -- \
  852. ${rest[@]-}
  853. fi
  854. # ----- Build the Windows 32-bit distribution. ------------------------------
  855. # Since the actual container is a 32-bit, use the debian32 binaries.
  856. if [ "${DO_BUILD_WIN32}" == "y" ]
  857. then
  858. host_build_target "Creating the Windows 32-bit distribution..." \
  859. --script "${CONTAINER_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}" \
  860. --env-file "${ENV_FILE}" \
  861. --target-platform "win32" \
  862. --target-arch "x32" \
  863. --target-machine "i386" \
  864. --target-bits 32 \
  865. --docker-image "${docker_linux32_image}" \
  866. -- \
  867. ${rest[@]-}
  868. fi
  869. # ----- Build the GNU/Linux Arm 64-bit distribution. ---------------------------
  870. if [ "${DO_BUILD_LINUX_ARM64}" == "y" ]
  871. then
  872. host_build_target "Creating the GNU/Linux Arm 64-bit distribution..." \
  873. --script "${CONTAINER_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}" \
  874. --env-file "${ENV_FILE}" \
  875. --target-platform "linux" \
  876. --target-arch "arm64" \
  877. --target-machine "aarch64" \
  878. --target-bits 64 \
  879. --docker-image "${docker_linux_arm64_image}" \
  880. -- \
  881. ${rest[@]-}
  882. fi
  883. # ----- Build the GNU/Linux Arm 32-bit distribution. ---------------------------
  884. if [ "${DO_BUILD_LINUX_ARM32}" == "y" ]
  885. then
  886. host_build_target "Creating the GNU/Linux Arm 32-bit distribution..." \
  887. --script "${CONTAINER_WORK_FOLDER_PATH}/${CONTAINER_BUILD_SCRIPT_REL_PATH}" \
  888. --env-file "${ENV_FILE}" \
  889. --target-platform "linux" \
  890. --target-arch "arm" \
  891. --target-machine "armhf" \
  892. --target-bits 32 \
  893. --docker-image "${docker_linux_arm32_image}" \
  894. -- \
  895. ${rest[@]-}
  896. fi
  897. fi
  898. }
  899. # -----------------------------------------------------------------------------
  900. function host_show_sha() {
  901. if [ -d "${HOST_WORK_FOLDER_PATH}/${DEPLOY_FOLDER_NAME}" ]
  902. then
  903. echo
  904. echo "${HOST_WORK_FOLDER_PATH}/${DEPLOY_FOLDER_NAME}"
  905. ls -l "${HOST_WORK_FOLDER_PATH}/${DEPLOY_FOLDER_NAME}"
  906. echo
  907. echo "SHA signatures..."
  908. set +e
  909. cat "${HOST_WORK_FOLDER_PATH}/${DEPLOY_FOLDER_NAME}"/*.sha
  910. set -e
  911. fi
  912. }
  913. # -----------------------------------------------------------------------------