build-ubuntu 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. #!/usr/bin/env zsh
  2. builtin emulate -L zsh
  3. setopt EXTENDED_GLOB
  4. setopt PUSHD_SILENT
  5. setopt ERR_EXIT
  6. setopt ERR_RETURN
  7. setopt NO_UNSET
  8. setopt PIPE_FAIL
  9. setopt NO_AUTO_PUSHD
  10. setopt NO_PUSHD_IGNORE_DUPS
  11. setopt FUNCTION_ARGZERO
  12. ## Enable for script debugging
  13. # setopt WARN_CREATE_GLOBAL
  14. # setopt WARN_NESTED_VAR
  15. # setopt XTRACE
  16. autoload -Uz is-at-least && if ! is-at-least 5.2; then
  17. print -u2 -PR "${CI:+::error::}%F{1}${funcstack[1]##*/}:%f Running on Zsh version %B${ZSH_VERSION}%b, but Zsh %B5.2%b is the minimum supported version. Upgrade Zsh to fix this issue."
  18. exit 1
  19. fi
  20. TRAPZERR() {
  21. if (( ${_loglevel:-3} > 2 )) {
  22. print -u2 -PR "${CI:+::error::}%F{1} ✖︎ script execution error%f"
  23. print -PR -e "
  24. Callstack:
  25. ${(j:\n :)funcfiletrace}
  26. "
  27. }
  28. exit 2
  29. }
  30. build() {
  31. if (( ! ${+SCRIPT_HOME} )) typeset -g SCRIPT_HOME=${ZSH_ARGZERO:A:h}
  32. local host_os='ubuntu'
  33. local project_root=${SCRIPT_HOME:A:h:h}
  34. local buildspec_file=${project_root}/buildspec.json
  35. fpath=("${SCRIPT_HOME}/utils.zsh" ${fpath})
  36. autoload -Uz log_group log_info log_error log_output set_loglevel check_ubuntu setup_ccache
  37. if [[ ! -r ${buildspec_file} ]] {
  38. log_error \
  39. 'No buildspec.json found. Please create a build specification for your project.'
  40. return 2
  41. }
  42. local -i debug=0
  43. typeset -g -a skips=()
  44. local -i verbosity=1
  45. local -r _version='2.0.0'
  46. local -r -a _valid_targets=(
  47. ubuntu-x86_64
  48. )
  49. local target
  50. local config='RelWithDebInfo'
  51. local -r -a _valid_configs=(Debug RelWithDebInfo Release MinSizeRel)
  52. local -i codesign=0
  53. local -r -a _valid_generators=(Ninja 'Unix Makefiles')
  54. local generator='Ninja'
  55. local -r _usage_host="
  56. %F{yellow} Additional options for Linux builds%f
  57. -----------------------------------------------------------------------------
  58. %B--generator%b Specify build system to generate
  59. Available generators:
  60. - Ninja
  61. - Unix Makefiles"
  62. local -i print_config=0
  63. local -r _usage="
  64. Usage: %B${functrace[1]%:*}%b <option> [<options>]
  65. %BOptions%b:
  66. %F{yellow} Build configuration options%f
  67. -----------------------------------------------------------------------------
  68. %B-t | --target%b Specify target
  69. %B-c | --config%b Build configuration
  70. %B--skip-[all|build|deps]%b Skip all|building|checking for dependencies
  71. %F{yellow} Output options%f
  72. -----------------------------------------------------------------------------
  73. %B-q | --quiet%b Quiet (error output only)
  74. %B-v | --verbose%b Verbose (more detailed output)
  75. %B--debug%b Debug (very detailed and added output)
  76. %F{yellow} General options%f
  77. -----------------------------------------------------------------------------
  78. %B-h | --help%b Print this usage help
  79. %B-V | --version%b Print script version information
  80. ${_usage_host:-}"
  81. local -a args
  82. while (( # )) {
  83. case ${1} {
  84. -t|--target|-c|--config|--generator)
  85. if (( # == 1 )) || [[ ${2:0:1} == '-' ]] {
  86. log_error "Missing value for option %B${1}%b"
  87. log_output ${_usage}
  88. exit 2
  89. }
  90. ;;
  91. }
  92. case ${1} {
  93. --)
  94. shift
  95. args+=($@)
  96. break
  97. ;;
  98. -t|--target)
  99. if (( ! ${_valid_targets[(Ie)${2}]} )) {
  100. log_error "Invalid value %B${2}%b for option %B${1}%b"
  101. log_output ${_usage}
  102. exit 2
  103. }
  104. target=${2}
  105. shift 2
  106. ;;
  107. -c|--config)
  108. if (( ! ${_valid_configs[(Ie)${2}]} )) {
  109. log_error "Invalid value %B${2}%b for option %B${1}%b"
  110. log_output ${_usage}
  111. exit 2
  112. }
  113. config=${2}
  114. shift 2
  115. ;;
  116. -s|--codesign) codesign=1; shift ;;
  117. -q|--quiet) (( verbosity -= 1 )) || true; shift ;;
  118. -v|--verbose) (( verbosity += 1 )); shift ;;
  119. -h|--help) log_output ${_usage}; exit 0 ;;
  120. -V|--version) print -Pr "${_version}"; exit 0 ;;
  121. --debug) verbosity=3; shift ;;
  122. --generator)
  123. if (( ! ${_valid_generators[(Ie)${2}]} )) {
  124. log_error "Invalid value %B${2}%b for option %B${1}%b"
  125. log_output ${_usage}
  126. exit 2
  127. }
  128. generator=${2}
  129. shift 2
  130. ;;
  131. --print-config) print_config=1; skips+=(deps); shift ;;
  132. --skip-*)
  133. local -r _skip="${${(s:-:)1}[-1]}"
  134. local -r -a _check=(all build deps)
  135. (( ${_check[(Ie)${_skip}]} )) || log_warning "Invalid skip mode %B${_skip}%b supplied"
  136. typeset -g -a skips=(${skips} ${_skip})
  137. shift
  138. ;;
  139. *) log_error "Unknown option: %B${1}%b"; log_output ${_usage}; exit 2 ;;
  140. }
  141. }
  142. : "${target:="${host_os}-${CPUTYPE}"}"
  143. set -- ${(@)args}
  144. set_loglevel ${verbosity}
  145. if (( ! (${skips[(Ie)all]} + ${skips[(Ie)deps]}) )) {
  146. check_${host_os}
  147. }
  148. if [[ ${host_os} == ubuntu ]] {
  149. autoload -Uz setup_ubuntu && setup_ubuntu
  150. }
  151. local product_name
  152. local product_version
  153. read -r product_name product_version <<< \
  154. "$(jq -r '. | {name, version} | join(" ")' ${buildspec_file})"
  155. pushd ${project_root}
  156. if (( ! (${skips[(Ie)all]} + ${skips[(Ie)build]}) )) {
  157. log_group "Configuring ${product_name}..."
  158. local -a cmake_args=()
  159. local -a cmake_build_args=(--build)
  160. local -a cmake_install_args=(--install)
  161. case ${_loglevel} {
  162. 0) cmake_args+=(-Wno_deprecated -Wno-dev --log-level=ERROR) ;;
  163. 1) ;;
  164. 2) cmake_build_args+=(--verbose) ;;
  165. *) cmake_args+=(--debug-output) ;;
  166. }
  167. local -r _preset="${target%%-*}${CI:+-ci}"
  168. case ${target} {
  169. ubuntu-*)
  170. cmake_args+=(
  171. --preset ${_preset}-${target##*-}
  172. -G "${generator}"
  173. -DQT_VERSION=${QT_VERSION:-6}
  174. -DCMAKE_BUILD_TYPE=${config}
  175. -DCMAKE_INSTALL_PREFIX=/usr
  176. )
  177. local cmake_version
  178. read -r _ _ cmake_version <<< "$(cmake --version)"
  179. cmake_build_args+=(--preset ${_preset}-${target##*-} --config ${config})
  180. if [[ ${generator} == 'Unix Makefiles' ]] {
  181. cmake_build_args+=(--parallel $(( $(nproc) + 1 )))
  182. } else {
  183. cmake_build_args+=(--parallel)
  184. }
  185. cmake_install_args+=(build_${target##*-} --prefix ${project_root}/release/${config})
  186. ;;
  187. }
  188. log_debug "Attempting to configure with CMake arguments: ${cmake_args}"
  189. cmake ${cmake_args}
  190. log_group "Building ${product_name}..."
  191. cmake ${cmake_build_args}
  192. }
  193. log_group "Installing ${product_name}..."
  194. if (( _loglevel > 1 )) cmake_install_args+=(--verbose)
  195. cmake ${cmake_install_args}
  196. popd
  197. log_group
  198. }
  199. build ${@}