diff options
-rwxr-xr-x | build.sh | 59 | ||||
-rw-r--r-- | build.subr | 62 | ||||
-rw-r--r-- | build.usage | 36 |
3 files changed, 70 insertions, 87 deletions
@@ -1,23 +1,36 @@ #!/bin/sh # + { . ./build.subr; -parse_args_into_vars "${0}" build-scripts,build-steps,help,tarball "${@}"; -[ -n "${ARG_HELP}" ] && { exec cat build.usage; } || . ./build.vars; +while getopts hr:t CURRENT_ARG; do +case ${CURRENT_ARG} in +r) ARG_BUILD_SCRIPTS="${OPTARG%%:*}"; + [ -z "${ARG_BUILD_STEPS:="${ARG_BUILD_SCRIPTS##*:}"}" ] &&\ + ARG_BUILD_STEPS=ALL; ;; +t) ARG_TARBALL=1; ;; +h|\?) exec cat build.usage; ;; +esac; done; shift $((${OPTIND} - 1)); +while [ ${#} -gt 0 ]; do + if [ "x${1#*=*}" != "x${1}" ]; then + set_var_unsafe "$(get_prefix_lrg "${1}" =)" \ + "$(get_postfix "${1}" =)"; shift; + fi; +done; . ./build.vars; clear_env_with_except HOME PATH SHELL TERM USER; check_path_vars PREFIX PREFIX_NATIVE WORKDIR; check_prereqs git make mktemp openssl sed sort tar tr wget; log_msg info "Build started by ${BUILD_USER:=${USER}}@${BUILD_HNAME:=$(hostname)} at ${BUILD_DATE:=$(date %Y-%m-%d-%H-%M-%S)}."; -touch ${PREFIX}/BUILD_IN_PROGRESS; log_env_vars ${LOG_ENV_VARS}; (mkdir -p ${PREFIX} ${PREFIX_NATIVE} ${PREFIX_TARGET} ${WORKDIR}; +touch BUILD_IN_PROGRESS ${BUILD_PROGRESS_FNAME:=${PREFIX}/BUILD_STARTED_AT_${BUILD_DATE}}; BUILD_NFINI=${BUILD_NSKIP:=${BUILD_NFAIL:=${BUILD_NBUILT:=0}}}; BUILD_SECS=$(command date +%s); for BUILD_LVL in 0 1 2 3; do for BUILD_SCRIPT_FNAME in ${BUILD_LVL}[0-9][0-9].*.build; do - if [ -n "${ARG_BUILD_SCRIPTS}" ]\ - && [ "${ARG_BUILD_SCRIPTS}" != "ALL" ]\ - && ! match_list "${ARG_BUILD_SCRIPTS}" \ + if [ -n "${ARG_BUILD_SCRIPTS}" ] \ + && [ "${ARG_BUILD_SCRIPTS}" != "ALL" ] \ + && ! match_list "${ARG_BUILD_SCRIPTS}" \ , "${BUILD_SCRIPT_FNAME}"; then log_msg info "Skipped build script \`${BUILD_SCRIPT_FNAME}' (--build-scripts policy.)"; continue; @@ -31,7 +44,7 @@ for BUILD_LVL in 0 1 2 3; do log_msg info "Skipped build script \`${BUILD_SCRIPT_FNAME}' (already built.)"; : $((BUILD_NSKIP+=1)); BUILD_SCRIPT_RC=0; continue; fi; - log_msg info "Invoking build script${ARG_BUILD_SCRIPTS:+ (forcibly)} \`${BUILD_SCRIPT_FNAME}'${ARG_BUILD_STEPS:+ at build step(s) ${ARG_BUILD_STEPS}}."; + log_msg info "Invoking build script${ARG_BUILD_SCRIPTS:+ (forcibly)} \`${BUILD_SCRIPT_FNAME}'${ARG_BUILD_STEPS:+ at build step ${ARG_BUILD_STEPS}}."; (set -o errexit -- $(split . ${BUILD_SCRIPT_FNAME%%.build*}); \ SCRIPT_FNAME=${BUILD_SCRIPT_FNAME}; \ SCRIPT_NAME=${SCRIPT_FNAME%%.build*}; \ @@ -40,7 +53,7 @@ for BUILD_LVL in 0 1 2 3; do _PWD=$(pwd); cd ${WORKDIR}; \ for SCRIPT_SOURCE in build.subr ${SCRIPT_NAME}.vars \ ${BUILD_SCRIPT_FNAME}; do \ - [ -r ${_PWD}/${SCRIPT_SOURCE} ] && \ + [ -f ${_PWD}/${SCRIPT_SOURCE} ] && \ . ${_PWD}/${SCRIPT_SOURCE}; \ done); case ${BUILD_SCRIPT_RC:=${?}} in @@ -61,7 +74,12 @@ log_msg info "${BUILD_NFINI} finished, ${BUILD_NSKIP} skipped, and ${BUILD_NFAIL : $((BUILD_MINUTES=(${BUILD_SECS}%3600)/60)); : $((BUILD_SECS=(${BUILD_SECS}%3600)%60)); log_msg info "Build time: ${BUILD_HOURS} hour(s), ${BUILD_MINUTES} minute(s), and ${BUILD_SECS} second(s)."; -if [ $(( ${BUILD_NFINI} + ${BUILD_NSKIP} )) -ge 0 ]\ +[ -f ${BUILD_PROGRESS_FNAME} ] && rm -f ${BUILD_PROGRESS_FNAME}; +touch ${BUILD_FINISH_FNAME:=${PREFIX}/BUILD_FINISHED_AT_$(date %Y-%m-%d-%H-%M-%S)} \ + ${TARBALL_PROGRESS_FNAME:=${PREFIX}/TARBALL_STARTED_AT_$(date %Y-%m-%d-%H-%M-%S)}; +ln -sf ${BUILD_FINISH_FNAME} ${PREFIX}/BUILD_FINISHED_AT; +# rotate BUILD_FINISH_FNAME files +if [ $(( ${BUILD_NFINI} + ${BUILD_NSKIP} )) -ge 0 ] \ && [ ${BUILD_NFAIL} -eq 0 ]\ && [ ${ARG_TARBALL:-0} -eq 1 ]; then log_msg info "Building distribution tarball."; @@ -71,23 +89,24 @@ if [ $(( ${BUILD_NFINI} + ${BUILD_NSKIP} )) -ge 0 ]\ rm_if_exists -m ${PREFIX_BASENAME}/lib.bak; rm_if_exists ${DISTRIB_FNAME}; tar -C ${PREFIX_BASENAME}/lib -cpf - . | tar -C ${PREFIX_BASENAME}/lib.bak -xpf -; (cd native/lib && - find . -maxdepth 1 -type l \ + find . -maxdepth 1 -type l \ -exec sh -c 'dest=$(readlink -- "$0") && rm -- "$0" && ln -- "$dest" "$0"' {} \;); wait; - find . -maxdepth 2 -type d \ - -not -path . \ - -not -path ./src/midipix_build \ - -not -path ./src/midipix_build/\* \ - -not -path ./${WORKDIR_BASENAME} \ - -not -path ./${WORKDIR_BASENAME}/\* \ - -not -path ./${PREFIX_BASENAME} \ - -not -path ./${PREFIX_BASENAME}/lib.bak |\ + find . -maxdepth 2 -type d \ + -not -path . \ + -not -path ./src/midipix_build \ + -not -path ./src/midipix_build/\* \ + -not -path ./${WORKDIR_BASENAME} \ + -not -path ./${WORKDIR_BASENAME}/\* \ + -not -path ./${PREFIX_BASENAME} \ + -not -path ./${PREFIX_BASENAME}/lib.bak |\ tar -T - -cpf - | bzip2 -9c - > ${DISTRIB_FNAME} rm -rf ${PREFIX_BASENAME}/lib; mv ${PREFIX_BASENAME}/lib.bak ${PREFIX_BASENAME}/lib); wait; + # rotate tarballs fi; -[ -f ${PREFIX}/BUILD_IN_PROGRESS ] &&\ - rm -f ${PREFIX}/BUILD_IN_PROGRESS; +[ -f ${TARBALL_PROGRESS_FNAME} ] && rm -f ${TARBALL_PROGRESS_FNAME}; +[ -f BUILD_IN_PROGRESS ] && rm -f BUILD_IN_PROGRESS; exit ${BUILD_SCRIPT_RC})} 2>&1 | tee build.log; # vim:filetype=sh @@ -6,15 +6,16 @@ date() { command date +"${1:-${TIMESTAMP_FMT}}"; }; fetch_git() { [ -d ${1} ] && (cd ${1} && git pull origin main) || git clone ${3} ${2} ${1}; }; get_basename() { set -- $(get_name_without_slash ${1}); echo "${1##*/}"; }; -get_var() { eval echo \${${1}}; }; # XXX -set_var() { eval ${1}=\"${2}\"; }; # XXX +get_var_dyn() { ${1}; }; +get_var_unsafe() { eval echo \${${1}}; }; +set_var_dyn() { eval ${1}\(\) \{ echo \"${2}\"\; \}; }; +set_var_unsafe() { eval ${1}=\"${2}\"; }; get_name_without_slash() { while [ "x${1%/}" != "x${1}" ]; do set -- ${1%/}; done; echo ${1}; }; get_postfix_lrg() { echo "${1##*${2}}"; }; get_prefix_lrg() { echo "${1%%${2}*}"; }; get_postfix() { echo "${1#*${2}}"; }; get_prefix() { echo "${1%${2}*}"; }; match_any() { [ "x${1#*${2}*}" != "x${1}" ]; }; -match_start() { [ "x${1#${2}}" != "x${1}" ]; }; push_IFS() { _pI_IFS="${IFS}"; IFS="${1}"; }; pop_IFS() { IFS="${_pI_IFS}"; unset _pI_IFS; }; set_build_dir() { PKG_BUILD_DIR=${1}-${2}-${TARGET}; }; @@ -26,33 +27,19 @@ unsplit() { push_IFS "${1}"; shift; set -- "${@}"; echo "${*}"; pop_IFS; }; export_vars_subst() { _evs_pfx=${1}; _evs_pfx_new=${2}; shift 2; while [ ${#} -gt 0 ]; do - if [ -n "${_evs_vval:=$(get_var ${_evs_pfx}${1})}" ]; then + if [ -n "${_evs_vval:=$(get_var_unsafe ${_evs_pfx}${1})}" ]; then export "${_evs_pfx_new}${1}=${_evs_vval}"; fi; unset _evs_vval; shift; done; unset _evs_pfx _evs_pfx_new; }; rm_if_exists() { - set_flag_vars_from_args "$@"; shift ${_sfvfa_nshift:-0}; - [ -d ${1} ] && rm -rf ${1}; [ -f ${1} ] && rm -f ${1}; - [ ${_arg_m:-0} -eq 1 ] && mkdir ${1}; - [ ${_arg_c:-0} -eq 1 ] && cd ${1}; - unset_flag_vars_from_args; -}; - -set_flag_vars_from_args() { - unset _sfvfa_flag_vars _sfvfa_nshift; - while [ ${#} -gt 1 ]; do - if [ "x${1%[a-z]}" = "x-" ]; then - set_var _arg_${1#-} 1; - _sfvfa_flag_vars="${_sfvfa_flag_vars:+${_sfvfa_flag_vars} }_arg_${1#-}"; - : $((_sfvfa_nshift+=1)); - fi; shift; - done; -}; -unset_flag_vars_from_args() { - set -- ${_sfvfa_flag_vars}; while [ ${#} -gt 0 ]; do - unset ${1}; shift; done; unset _sfvfa_flag_vars _sfvfa_nshift; + [ -z "${1#-m}" ] && { _rie_arg_m=1; shift; }; + [ -z "${1#-c}" ] && { _rie_arg_c=1; shift; }; + [ -d ${1} -o -f ${1} ] && rm -rf ${1}; + [ ${_rie_arg_m:-0} -eq 1 ] && { mkdir ${1}; unset _rie_arg_m; }; + [ ${_rie_arg_c:-0} -eq 1 ] && { cd ${1}; unset _rie_arg_c; }; + return 0; }; set_env_vars() { @@ -78,7 +65,7 @@ apply_patches() { # Check whether all supplied arguments contain non-empty valid values. check_path_vars() { while [ ${#} -gt 0 ]; do - if [ -z "${_cpv_val:=$(get_var "${1}")}" ]; then + if [ -z "${_cpv_val:=$(get_var_unsafe "${1}")}" ]; then log_msg failexit "Error: variable \`${1}' is empty or unset."; elif match_any "${_cpv_val}" " "; then log_msg failexit "Error: variable \`${1}' contains one or more whitespace characters."; @@ -104,6 +91,7 @@ clear_env_with_except() { _cewe_vfilter="${*}"; _cewe_unset_cmds="$(mktemp -q)"; export | while read _cewe_vspec; do set -- ${_cewe_vspec}; shift; + [ "x${1#*[^\"\'=a-zA-Z0-9_]}" != "x${1}" ] && continue; if ! match_list "${_cewe_vfilter}" " " \ $(get_prefix_lrg ${1} =); then echo unset $(get_prefix_lrg ${1} =) >> ${_cewe_unset_cmds}; @@ -180,7 +168,7 @@ log_env_vars() { while [ ${#} -gt 0 ]; do log_msg info "$(printf \ "%${_lev_arg_len_max}.${_lev_arg_len_max}s=%s" \ - "${1%%=*}" "$(get_var ${1#*=})")"; + "${1%%=*}" "$(get_var_unsafe ${1#*=})")"; shift; done; unset _lev_arg_len_max; }; @@ -208,28 +196,6 @@ match_list() { done; unset _ml_cmp; return 1; }; -parse_args_into_vars() { - _paiv_arg0="${1}"; _paiv_args_valid="${2}"; shift 2; - while [ $# -gt 0 ]; do - case "${1}" in - --*) _paiv_aname="${1#--}"; - if ! match_list "${_paiv_args_valid}" , "${_paiv_aname%%=*}"; then - log_msg failexit "Unknown parameter --${_paiv_aname%%=*} specified."; - elif match_start "${_paiv_aname}" "*="; then - _paiv_aval="$(get_postfix "${_paiv_aname}" =)"; - _paiv_aname="$(get_prefix_lrg "${_paiv_aname}" =)"; - else - _paiv_aval=1; - fi; - set_var $(echo arg_${_paiv_aname} | tr a-z- A-Z_) "${_paiv_aval}"; - shift; ;; - *=*) set_var "$(get_prefix_lrg "${1}" =)"\ - "$(get_postfix "${1}" =)"; shift; ;; - *) log_msg failexit "Invalid or unknown command line argument \`${1}'."; ;; - esac; - done; unset _paiv_arg0 _paiv_args_valid _paiv_aname _paiv_aval; -}; - parse_with_pkg_name() { PKG_LVL=${1}; PKG_NAME=${2}; shift 2; while [ ${#} -ge 0 ]; do diff --git a/build.usage b/build.usage index 19ac8bc4..00ef1583 100644 --- a/build.usage +++ b/build.usage @@ -1,22 +1,20 @@ -usage: ./build.sh - [--build-scripts=ALL|fname[,fname...]] [--build-steps=ALL|step[,step...]] - [--help] [--tarball] [VAR=VAL...] - --build-scripts=... Only invoke all or the specified build script(s). - --build-steps=... Forcibly invoke build scripts at all or only the - specified build steps. Currently defined build steps - are: fetch extract patch configure clean build install - configure1 configure2 build1 build2 install1 install2 - install3 finish. - --help Show this screen. - --tarball Produce a distribution tarball containing $PREFIX - sans $WORKDIR at the end of a build with zero failures. +usage: ./build.sh [-r ALL|name[:step]] [-h] [-t] + -r ALL|name[:step] Restart all or the specified build script(s) completely + or at the optionally specified build step. Currently defined + build steps are: fetch extract patch configure clean build + install configure1 configure2 build1 build2 install1 install2 + install3. + -h Show this screen. + -t Produce a distribution tarball containing $PREFIX + sans $WORKDIR and $PREFIX/src/midipix_build at the end of a + build with zero failures. - Packages that are built by pkg.build will apply local patches in $WORKDIR - named ${PKG_SUBDIR}.local.patch. + Packages that are built by pkg.build will apply local patches in $WORKDIR + named ${PKG_SUBDIR}.local.patch. - Examples: - ./build.sh GITROOT_HEAD=... --build-scripts=204.psxscl.build --build-steps=ALL PKG_PSXSCL_CFLAGS=-DPSX_INTERNAL_STRACE - Build psxscl from the internal repository with strace enabled. + Examples: + ./build.sh -r psxscl -- GITROOT_HEAD=... PKG_PSXSCL_CFLAGS=-DPSX_INTERNAL_STRACE + Build psxscl from the internal repository with strace enabled. - ./build.sh GITROOT_HEAD=... --build-scripts=ALL --build-steps=ALL - Forcibly rebuild everything. + ./build.sh -r ALL -- GITROOT_HEAD=... + Forcibly rebuild everything. |