media-suite_helper.sh 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638
  1. #!/bin/bash
  2. # shellcheck disable=SC2154,SC2120,SC2119,SC2034,SC1090,SC1117,SC2030,SC2031
  3. if [[ -z ${MSYS+x} ]]; then
  4. export MSYS=winsymlinks:nativestrict
  5. touch linktest
  6. ln -s linktest symlinktest > /dev/null 2>&1
  7. ln linktest hardlinktest > /dev/null 2>&1
  8. test -h symlinktest || unset MSYS
  9. [[ $(stat --printf '%h\n' hardlinktest) -eq 2 ]] || unset MSYS
  10. rm -f symlinktest hardlinktest linktest
  11. fi
  12. case $cpuCount in
  13. '' | *[!0-9]*) cpuCount=$(($(nproc) / 2)) ;;
  14. esac
  15. : "${bits:=64bit}"
  16. curl_opts=(/usr/bin/curl --connect-timeout 15 --retry 3
  17. --retry-delay 5 --silent --location --insecure --fail)
  18. if test -n "$(tput colors)" && test "$(tput colors)" -ge 8; then
  19. bold=$(tput bold)
  20. blue=$(tput setaf 12)
  21. orange=$(tput setaf 11)
  22. purple=$(tput setaf 13)
  23. green=$(tput setaf 2)
  24. red=$(tput setaf 1)
  25. reset=$(tput sgr0)
  26. fi
  27. ncols=72
  28. do_simple_print() {
  29. local plain=false formatString dateValue newline='\n' OPTION OPTIND
  30. while getopts ':np' OPTION; do
  31. case "$OPTION" in
  32. n) newline='' ;;
  33. p) plain=true ;;
  34. *) break ;;
  35. esac
  36. done
  37. shift "$((OPTIND - 1))"
  38. if [[ $timeStamp == y ]]; then
  39. formatString="${purple}"'%(%H:%M:%S)T'"${reset}"' '
  40. dateValue='-1'
  41. elif $plain; then
  42. formatString='\t'
  43. fi
  44. if ! $plain; then
  45. formatString+="${bold}├${reset} "
  46. fi
  47. printf "$formatString"'%b'"${reset}${newline}" $dateValue "$*"
  48. }
  49. do_print_status() {
  50. local _prefix _prefixpad=0
  51. if [[ $1 == prefix ]]; then
  52. _prefix="$2" && shift 2
  53. _prefixpad=2
  54. fi
  55. local name="$1 " color="$2" status="$3" pad
  56. eval printf -v pad ".%.s" "{1..$ncols}"
  57. if [[ $timeStamp == y ]]; then
  58. printf "${purple}"'%(%H:%M:%S)T'"${reset}"' %s%s %s [%s]\n' -1 "$_prefix" "${bold}$name${reset}" \
  59. "${pad:0:$((ncols - _prefixpad - ${#name} - ${#status} - 12))}" "${color}${status}${reset}"
  60. else
  61. printf '%s%s %s [%s]\n' "$_prefix" "${bold}$name${reset}" \
  62. "${pad:0:$((ncols - _prefixpad - ${#name} - ${#status} - 2))}" "${color}${status}${reset}"
  63. fi
  64. }
  65. do_print_progress() {
  66. case $logging$timeStamp in
  67. yy) printf "${purple}"'%(%H:%M:%S)T'"${reset}"' %s\n' -1 "$([[ $1 =~ ^[a-zA-Z] ]] && echo "${bold}├${reset} ")$*..." ;;
  68. yn)
  69. [[ $1 =~ ^[a-zA-Z] ]] &&
  70. printf '%s' "${bold}├${reset} "
  71. echo -e "$*..."
  72. ;;
  73. *)
  74. set_title "$* in $(get_first_subdir)"
  75. if [[ $timeStamp == y ]]; then
  76. printf "${purple}"'%(%H:%M:%S)T'"${reset}"' %s\n' -1 "${bold}$* in $(get_first_subdir)${reset}"
  77. else
  78. echo -e "${bold}$* in $(get_first_subdir)${reset}"
  79. fi
  80. ;;
  81. esac
  82. }
  83. set_title() {
  84. printf '\033]0;media-autobuild_suite %s\a' "($bits)${1:+: $1}"
  85. }
  86. do_exit_prompt() {
  87. if [[ -n $build32$build64 ]]; then # meaning "executing this in the suite's context"
  88. create_diagnostic
  89. zip_logs
  90. fi
  91. do_prompt "$*"
  92. [[ -n $build32$build64 ]] && exit 1
  93. }
  94. cd_safe() {
  95. cd "$1" || do_exit_prompt "Failed changing to directory $1."
  96. }
  97. test_newer() {
  98. [[ $1 == installed ]] && local installed=y && shift
  99. local file
  100. local files=("$@")
  101. local cmp="${files[-1]}"
  102. [[ $installed ]] && cmp="$(file_installed "$cmp")"
  103. [[ ${#files[@]} -gt 1 ]] && unset 'files[-1]'
  104. [[ -f $cmp ]] || return 0
  105. for file in "${files[@]}"; do
  106. [[ $installed ]] && file="$(file_installed "$file")"
  107. [[ -f $file ]] &&
  108. [[ $file -nt $cmp ]] && return
  109. done
  110. return 1
  111. }
  112. # vcs_get_current_type /build/myrepo
  113. vcs_get_current_type() {
  114. git -C "${1:-$PWD}" rev-parse --is-inside-work-tree > /dev/null 2>&1 &&
  115. echo "git" &&
  116. return 0
  117. echo "unknown"
  118. return 1
  119. }
  120. # check_valid_vcs /build/ffmpeg-git
  121. check_valid_vcs() {
  122. [[ -d ${1:-$PWD}/.git ]] &&
  123. git -C "${1:-$PWD}/.git" rev-parse HEAD > /dev/null 2>&1
  124. }
  125. # vcs_get_current_head /build/ffmpeg-git
  126. vcs_get_current_head() {
  127. git -C "${1:-$PWD}" rev-parse HEAD
  128. }
  129. # vcs_test_remote "https://github.com/m-ab-s/media-autobuild_suite.git"
  130. vcs_test_remote() {
  131. GIT_TERMINAL_PROMPT=0 git ls-remote -q --refs "$1" > /dev/null 2>&1
  132. }
  133. vcs_clean() {
  134. GIT_TERMINAL_PROMPT=0 \
  135. git -C "${1:-$PWD}" clean -dffxq \
  136. -e{recently_{updated,checked},build_successful*,*.{patch,diff},custom_updated,**/ab-suite.*.log} "$@"
  137. }
  138. # vcs_get_latest_tag "libopenmpt-*"
  139. vcs_get_latest_tag() {
  140. if ! case $1 in
  141. LATEST) git describe --abbrev=0 --tags "$(git rev-list --tags --max-count=1)" 2> /dev/null ;;
  142. GREATEST) git describe --abbrev=0 --tags 2> /dev/null ;;
  143. *\**) git describe --abbrev=0 --tags "$(git tag -l "$1" --sort=-version:refname | head -1)" 2> /dev/null ;;
  144. *) false ;;
  145. esac then
  146. echo "$1"
  147. fi
  148. }
  149. # vcs_set_url https://github.com/FFmpeg/FFmpeg.git
  150. vcs_set_url() {
  151. if vcs_test_remote "$1"; then
  152. git remote set-url origin "$1"
  153. fi
  154. git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
  155. }
  156. # vcs_clone https://gitlab.com/libtiff/libtiff.git tiff v4.1.0
  157. vcs_clone() (
  158. set -x
  159. vcsURL=$1 vcsFolder=${2:-$(basename "$vcsURL" .git)}
  160. [[ -z $vcsURL ]] && return 1
  161. check_valid_vcs "$vcsFolder-git" && return 0
  162. rm -rf "$vcsFolder-git"
  163. case $- in
  164. *i*) unset GIT_TERMINAL_PROMPT ;;
  165. *) export GIT_TERMINAL_PROMPT=0 ;;
  166. esac
  167. git clone --filter=tree:0 "$vcsURL" "$vcsFolder-git"
  168. git -C "$vcsFolder-git" reset --hard "${3:-origin/HEAD}"
  169. check_valid_vcs "$vcsFolder-git"
  170. )
  171. vcs_get_merge_base() {
  172. git merge-base HEAD "$(vcs_get_latest_tag "$1")"
  173. }
  174. vcs_reset() (
  175. set -x
  176. git checkout --no-track -fB ab-suite "$(vcs_get_latest_tag "$1")"
  177. git log --oneline --no-merges --no-color -n 1 | tee /dev/null
  178. )
  179. vcs_fetch() (
  180. set -x
  181. [[ -f $(git rev-parse --git-dir)/shallow ]] && unshallow="--unshallow" || unshallow=''
  182. git fetch --all -Ppft $unshallow
  183. git remote set-head -a origin
  184. )
  185. # do_mabs_clone "$vcsURL" "$vcsFolder" "$ref"
  186. # For internal use for fallback links
  187. do_mabs_clone() {
  188. vcs_test_remote "$1" &&
  189. log -q git.clone vcs_clone "$1" "$2" "$3"
  190. check_valid_vcs "$2-git"
  191. }
  192. vcs_ref_to_hash() (
  193. vcsURL=$1 ref=$2 vcsFolder=${3:-$(basename "$vcsURL" .git)}
  194. if _ref=$(git ls-remote --refs --exit-code -q -- "$vcsURL" "$ref"); then
  195. cut -f1 <<< "$_ref"
  196. return 0
  197. fi
  198. if git -C "$vcsFolder-git" rev-parse --verify -q --end-of-options "$ref" 2> /dev/null ||
  199. git -C "$vcsFolder" rev-parse --verify -q --end-of-options "$ref" 2> /dev/null ||
  200. git rev-parse --verify -q --end-of-options "$ref" 2> /dev/null; then
  201. return 0
  202. fi
  203. return 1
  204. )
  205. # get source from VCS
  206. # example:
  207. # do_vcs "url#branch|revision|tag|commit=NAME[ folder]" "folder"
  208. do_vcs() {
  209. local vcsURL=${1#*::} vcsFolder=$2 vcsCheck=("${_check[@]}")
  210. local vcsBranch=${vcsURL#*#} ref=origin/HEAD commit='' refmsg=''
  211. local deps=("${_deps[@]}") && unset _deps
  212. [[ $vcsBranch == "$vcsURL" ]] && unset vcsBranch
  213. local vcsPotentialFolder=${vcsURL#* }
  214. if [[ -z $vcsFolder ]] && [[ $vcsPotentialFolder != "$vcsURL" ]]; then
  215. vcsFolder=$vcsPotentialFolder # if there was a space, use the folder name
  216. fi
  217. vcsURL=${vcsURL%#*}
  218. : "${vcsFolder:=$(basename "$vcsURL" .git)}" # else just grab from the url like git normally does
  219. if [[ -n $vcsBranch ]]; then
  220. commit=${vcsBranch##*commit=}
  221. [[ $vcsBranch == "$commit" ]] && unset commit
  222. ref=${vcsBranch##*=}
  223. unset vcsBranch
  224. fi
  225. cd_safe "$LOCALBUILDDIR"
  226. rm -f "$vcsFolder-git/custom_updated"
  227. check_custom_patches "$vcsFolder-git"
  228. extra_script pre vcs
  229. # try to see if we can "resolve" the currently provided ref to a commit,
  230. # excluding special tags that we will resolve later. Ignore it if it's
  231. # a specific head. glslang's HEAD != their main branch somehow.
  232. case $ref in
  233. LATEST | GREATEST | *\**) ;;
  234. origin/HEAD | origin/* | HEAD) ;;
  235. *) ref=$(vcs_ref_to_hash "$vcsURL" "$ref" "$vcsFolder") ;;
  236. esac
  237. if [[ -n $commit ]]; then
  238. ref=$commit
  239. refmsg="with ref $ref"
  240. fi
  241. if ! check_valid_vcs "$vcsFolder-git"; then
  242. rm -rf "$vcsFolder-git"
  243. do_print_progress " Running git clone for $vcsFolder $refmsg"
  244. if ! do_mabs_clone "$vcsURL" "$vcsFolder" "$ref"; then
  245. echo "$vcsFolder git seems to be down"
  246. echo "Try again later or <Enter> to continue"
  247. do_prompt "if you're sure nothing depends on it."
  248. unset_extra_script
  249. return 1
  250. fi
  251. touch "$vcsFolder-git"/recently_{updated,checked}
  252. fi
  253. cd_safe "$vcsFolder-git"
  254. if [[ $ffmpegUpdate == onlyFFmpeg && $vcsFolder != ffmpeg && $vcsFolder != mpv ]] &&
  255. files_exist "${vcsCheck[@]:-$vcsFolder.pc}"; then
  256. do_print_status "${vcsFolder} git" "$green" "Already built"
  257. unset_extra_script
  258. return 1
  259. fi
  260. vcs_set_url "$vcsURL"
  261. log -q git.fetch vcs_fetch
  262. oldHead=$(vcs_get_merge_base "$ref")
  263. do_print_progress " Running git update for $vcsFolder $refmsg"
  264. log -q git.reset vcs_reset "$ref"
  265. newHead=$(vcs_get_current_head "$PWD")
  266. vcs_clean
  267. if [[ $oldHead != "$newHead" || -f custom_updated ]]; then
  268. touch recently_updated
  269. rm -f ./build_successful{32,64}bit{,_*}
  270. if [[ $build32$build64$bits == yesyes64bit ]]; then
  271. new_updates=yes
  272. new_updates_packages="$new_updates_packages [$vcsFolder]"
  273. fi
  274. {
  275. echo "$vcsFolder"
  276. git log --no-merges --pretty="%ci: %an - %h%n %s" "$oldHead..$newHead"
  277. echo
  278. } >> "$LOCALBUILDDIR/newchangelog"
  279. do_print_status "┌ $vcsFolder git" "$orange" "Updates found"
  280. elif [[ -f recently_updated && ! -f build_successful$bits${flavor:+_$flavor} ]]; then
  281. do_print_status "┌ $vcsFolder git" "$orange" "Recently updated"
  282. elif [[ -n ${vcsCheck[*]} ]] && ! files_exist "${vcsCheck[@]}"; then
  283. do_print_status "┌ $vcsFolder git" "$orange" "Files missing"
  284. elif [[ -n ${deps[*]} ]] && test_newer installed "${deps[@]}" "${vcsCheck[0]}"; then
  285. do_print_status "┌ $vcsFolder git" "$orange" "Newer dependencies"
  286. else
  287. do_print_status "$vcsFolder git" "$green" "Up-to-date"
  288. [[ ! -f recompile ]] && {
  289. unset_extra_script
  290. return 1
  291. }
  292. do_print_status "┌ $vcsFolder git" "$orange" "Forcing recompile"
  293. do_print_status prefix "$bold├$reset " "Found recompile flag" "$orange" "Recompiling"
  294. fi
  295. extra_script post vcs
  296. return 0
  297. }
  298. # get source from VCS to a local subfolder
  299. # example:
  300. # do_vcs_local "url#branch|revision|tag|commit=NAME" "subfolder"
  301. do_vcs_local() {
  302. local vcsURL=${1#*::} vcsFolder=$2 vcsCheck=("${_check[@]}")
  303. local vcsBranch=${vcsURL#*#} ref=origin/HEAD
  304. local deps=("${_deps[@]}") && unset _deps
  305. [[ $vcsBranch == "$vcsURL" ]] && unset vcsBranch
  306. vcsURL=${vcsURL%#*}
  307. : "${vcsFolder:=$(basename "$vcsURL" .git)}"
  308. if [[ -n $vcsBranch ]]; then
  309. ref=${vcsBranch##*=}
  310. [[ ${vcsBranch%%=*}/$ref == branch/${ref%/*} ]] && ref=origin/$ref
  311. fi
  312. rm -f "$vcsFolder/custom_updated"
  313. # try to see if we can "resolve" the currently provided ref, minus the origin/ part,
  314. # if so, set ref to the ref on the origin, this might make it harder for people who
  315. # want use multiple remotes other than origin. Converts ref=develop to ref=origin/develop
  316. # ignore those that use the special tags/branches
  317. case $ref in
  318. LATEST | GREATEST | *\**) ;;
  319. *) git ls-remote --exit-code "$vcsURL" "${ref#origin/}" > /dev/null 2>&1 && ref=origin/${ref#origin/} ;;
  320. esac
  321. if ! check_valid_vcs "$vcsFolder"; then
  322. rm -rf "$vcsFolder"
  323. rm -rf "$vcsFolder-git"
  324. do_print_progress " Running git clone for $vcsFolder"
  325. if ! do_mabs_clone "$vcsURL" "$vcsFolder" "$ref"; then
  326. echo "$vcsFolder git seems to be down"
  327. echo "Try again later or <Enter> to continue"
  328. do_prompt "if you're sure nothing depends on it."
  329. # unset_extra_script
  330. return 1
  331. fi
  332. mv "$vcsFolder-git" "$vcsFolder"
  333. touch "$vcsFolder"/recently_{updated,checked}
  334. fi
  335. cd_safe "$vcsFolder"
  336. vcs_set_url "$vcsURL"
  337. log -q git.fetch vcs_fetch
  338. oldHead=$(vcs_get_merge_base "$ref")
  339. do_print_progress " Running git update for $vcsFolder"
  340. log -q git.reset vcs_reset "$ref"
  341. newHead=$(vcs_get_current_head "$PWD")
  342. vcs_clean
  343. cd ..
  344. return 0
  345. }
  346. guess_dirname() {
  347. expr "$1" : '\(.\+\)\.\(tar\(\.\(gz\|bz2\|xz\|lz\)\)\?\|7z\|zip\)$'
  348. }
  349. check_hash() {
  350. local file="$1" check="$2" md5sum sha256sum
  351. if [[ -z $file || ! -f $file ]]; then
  352. return 1
  353. elif [[ -z $check ]]; then
  354. # if no hash to check, just check if the file exists
  355. return 0
  356. fi
  357. sha256sum=$(sha256sum "$file" | cut -d' ' -f1)
  358. if [[ $check == print ]]; then
  359. echo "$sha256sum"
  360. else
  361. md5sum=$(md5sum "$file" | cut -d' ' -f1)
  362. if [[ $sha256sum == "$check" || $md5sum == "$check" ]]; then
  363. return 0
  364. fi
  365. do_simple_print "${orange}Hash mismatch, file may be broken: ${check} != ${sha256sum} || ${md5sum}"
  366. return 1
  367. fi
  368. }
  369. # get wget download
  370. do_wget() {
  371. local nocd=false norm=false quiet=false notmodified=false noextract=false hash
  372. while true; do
  373. case $1 in
  374. -c) nocd=true && shift ;;
  375. -r) norm=true && shift ;;
  376. -q) quiet=true && shift ;;
  377. -h) hash="$2" && shift 2 ;;
  378. -z) notmodified=true && shift ;;
  379. -n) noextract=true && shift ;;
  380. --)
  381. shift
  382. break
  383. ;;
  384. *) break ;;
  385. esac
  386. done
  387. local url="$1" archive="$2" dirName="$3" response_code=000 curlcmds=("${curl_opts[@]}") tries=1 temp_file
  388. if [[ -z $archive ]]; then
  389. # remove arguments and filepath
  390. archive=${url%%\?*}
  391. archive=${archive##*/}
  392. fi
  393. if [[ -f $url ]]; then
  394. return 1
  395. fi
  396. archive=${archive:-"$(/usr/bin/curl -sI "$url" | grep -Eo 'filename=.*$' | sed 's/filename=//')"}
  397. [[ -z $dirName ]] && dirName=$(guess_dirname "$archive")
  398. $nocd || cd_safe "$LOCALBUILDDIR"
  399. $notmodified && [[ -f $archive ]] && curlcmds+=(-z "$archive" -R)
  400. [[ $hash ]] && tries=3
  401. if [[ -f $archive ]] && [[ $hash ]] && check_hash "$archive" "$hash"; then
  402. $quiet || do_print_status prefix "${bold}├${reset} " "${dirName:-$archive}" "$green" "File up-to-date"
  403. tries=0
  404. fi
  405. while [[ $tries -gt 0 ]]; do
  406. temp_file=$(mktemp)
  407. response_code=$("${curlcmds[@]}" -w "%{http_code}" -o "$temp_file" "$url")
  408. if [[ -f $archive ]] && diff -q "$archive" "$temp_file" > /dev/null 2>&1; then
  409. $quiet || do_print_status prefix "${bold}├${reset} " "${dirName:-$archive}" "$green" "File up-to-date"
  410. rm -f "$temp_file"
  411. break
  412. fi
  413. ((tries -= 1))
  414. case $response_code in
  415. 2**)
  416. $quiet || do_print_status "┌ ${dirName:-$archive}" "$orange" "Downloaded"
  417. check_hash "$temp_file" "$hash" && cp -f "$temp_file" "$archive"
  418. rm -f "$temp_file"
  419. break
  420. ;;
  421. 304)
  422. $quiet || do_print_status "┌ ${dirName:-$archive}" "$orange" "File up-to-date"
  423. rm -f "$temp_file"
  424. break
  425. ;;
  426. esac
  427. if check_hash "$archive" "$hash"; then
  428. printf '%b\n' "${orange}${archive}${reset}" \
  429. '\tFile not found online. Using local copy.'
  430. else
  431. do_print_status "└ ${dirName:-$archive}" "$red" "Failed"
  432. printf '%s\n' "Error $response_code while downloading $url" \
  433. "<Ctrl+c> to cancel build or <Enter> to continue"
  434. do_prompt "if you're sure nothing depends on it."
  435. rm -f "$temp_file"
  436. return 1
  437. fi
  438. done
  439. $norm || add_to_remove "$(pwd)/$archive"
  440. $noextract || do_extract "$archive" "$dirName"
  441. ! $norm && [[ -n $dirName ]] && ! $nocd && add_to_remove
  442. [[ -z $response_code || $response_code != "304" ]] && return 0
  443. }
  444. real_extract() {
  445. local archive="$1" dirName="$2" archive_type strip_comp=''
  446. [[ -z $archive ]] && return 1
  447. archive_type=$(expr "$archive" : '.\+\(tar\(\.\(gz\|bz2\|xz\|lz\)\)\?\|7z\|zip\)$')
  448. [[ ! $dirName ]] && dirName=$(guess_dirname "$archive" || echo "${archive}")
  449. case $archive_type in
  450. zip | 7z)
  451. 7z x -aoa -o"$dirName" "$archive"
  452. ;;
  453. tar*)
  454. [[ -n $dirName && ! -d $dirName ]] && mkdir -p "$dirName"
  455. case $archive_type in
  456. tar\.lz)
  457. do_pacman_install -m lzip
  458. lzip -d "$archive"
  459. ;;
  460. tar\.*) 7z x -aoa "$archive" ;;
  461. esac
  462. [[ $(tar -tf "${archive%.tar*}.tar" | cut -d'/' -f1 | sort -u | wc -l) == 1 ]] && strip_comp="--strip-components=1"
  463. if ! tar $strip_comp -C "$dirName" -xf "${1%.tar*}.tar"; then
  464. 7z x -aoa "${archive%.tar*}.tar" -o"$dirName"
  465. fi
  466. rm -f "${archive%.tar*}.tar"
  467. ;;
  468. esac
  469. local temp_dir
  470. temp_dir=$(find "$dirName/" -maxdepth 1 ! -wholename "$dirName/")
  471. if [[ -n $temp_dir && $(wc -l <<< "$temp_dir") == 1 ]]; then
  472. find "$temp_dir" -maxdepth 1 ! -wholename "$temp_dir" -exec mv -t "$dirName/" {} +
  473. rmdir "$temp_dir" 2> /dev/null
  474. fi
  475. }
  476. do_extract() {
  477. local nocd="${nocd:-false}"
  478. local archive="$1" dirName="$2"
  479. # accepted: zip, 7z, tar, tar.gz, tar.bz2 and tar.xz
  480. [[ -z $dirName ]] && dirName=$(guess_dirname "$archive")
  481. if [[ $dirName != "." && -d $dirName ]]; then
  482. if [[ $build32 == "yes" && ! -f \
  483. "$dirName/build_successful32bit${flavor:+_$flavor}" ]]; then
  484. rm -rf "$dirName"
  485. elif [[ $build64 == "yes" && ! -f \
  486. "$dirName/build_successful64bit${flavor:+_$flavor}" ]]; then
  487. rm -rf "$dirName"
  488. fi
  489. elif [[ -d $dirName ]]; then
  490. $nocd || cd_safe "$dirName"
  491. return 0
  492. elif ! expr "$archive" : '.\+\(tar\(\.\(gz\|bz2\|xz\|lz\)\)\?\|7z\|zip\)$' > /dev/null; then
  493. return 0
  494. fi
  495. log "extract" real_extract "$archive" "$dirName"
  496. $nocd || cd_safe "$dirName"
  497. }
  498. do_wget_sf() {
  499. # do_wget_sf "faac/faac-src/faac-1.28/faac-$_ver.tar.bz2" "faac-$_ver"
  500. local hash
  501. [[ $1 == "-h" ]] && hash="$2" && shift 2
  502. local url="https://download.sourceforge.net/$1"
  503. shift 1
  504. if [[ -n $hash ]]; then
  505. do_wget -h "$hash" "$url" "$@"
  506. else
  507. do_wget "$url" "$@"
  508. fi
  509. local ret=$?
  510. check_custom_patches
  511. return $ret
  512. }
  513. do_strip() {
  514. local cmd exts nostrip file
  515. local cmd=(strip)
  516. local nostrip="x265|x265-numa|ffmpeg|ffprobe|ffplay"
  517. local exts="exe|dll|com|a"
  518. [[ -f $LOCALDESTDIR/bin-video/mpv.exe.debug ]] && nostrip+="|mpv"
  519. for file; do
  520. if [[ $file =~ \.($exts)$ && ! $file =~ ($nostrip)\.exe$ ]]; then
  521. do_print_progress Stripping
  522. break
  523. fi
  524. done
  525. for file; do
  526. local orig_file="$file"
  527. if ! file="$(file_installed "$orig_file")"; then
  528. continue
  529. fi
  530. if [[ $file =~ \.(exe|com)$ ]] &&
  531. [[ ! $file =~ ($nostrip)\.exe$ ]]; then
  532. cmd+=(--strip-all)
  533. elif [[ $file =~ \.dll$ ]] ||
  534. [[ $file =~ (x265|x265-numa)\.exe$ ]]; then
  535. cmd+=(--strip-unneeded)
  536. elif ! disabled debug && [[ $file =~ \.a$ ]]; then
  537. cmd+=(--strip-debug)
  538. else
  539. file=""
  540. fi
  541. [[ $file ]] &&
  542. { eval "${cmd[@]}" "$file" 2> /dev/null ||
  543. eval "${cmd[@]}" "$file" -o "$file.stripped" 2> /dev/null; }
  544. [[ -f ${file}.stripped ]] && mv -f "${file}"{.stripped,}
  545. done
  546. }
  547. do_pack() {
  548. local file
  549. local cmd=(/opt/bin/upx -9 -qq)
  550. local nopack=""
  551. local exts="exe|dll"
  552. [[ $bits == 64bit ]] && enabled_any libtls openssl && nopack="ffmpeg|mplayer|mpv"
  553. for file; do
  554. if [[ $file =~ \.($exts)$ && ! $file =~ ($nopack)\.exe$ ]]; then
  555. do_print_progress Packing with UPX
  556. break
  557. fi
  558. done
  559. for file; do
  560. local orig_file="$file"
  561. if ! file="$(file_installed "$orig_file")"; then
  562. continue
  563. fi
  564. if [[ $file =~ \.($exts)$ ]] &&
  565. ! [[ -n $nopack && $file =~ ($nopack)\.exe$ ]]; then
  566. [[ $stripping == y ]] && cmd+=("--strip-relocs=0")
  567. else
  568. file=""
  569. fi
  570. [[ $file ]] && eval "${cmd[@]}" "$file"
  571. done
  572. }
  573. do_zipman() {
  574. local file files
  575. local man_dirs=(/local{32,64}/share/man)
  576. files=$(find "${man_dirs[@]}" -type f \! -name "*.gz" \! -name "*.db" \! -name "*.bz2" 2> /dev/null)
  577. for file in $files; do
  578. gzip -9 -n -f "$file"
  579. rm -f "$file"
  580. done
  581. }
  582. # check if compiled file exist
  583. do_checkIfExist() {
  584. local packetName
  585. packetName="$(get_first_subdir)"
  586. local packageDir="${LOCALBUILDDIR}/${packetName}"
  587. local buildSuccessFile="${packageDir}/build_successful${bits}"
  588. local dry="${dry:-n}"
  589. local check=()
  590. if [[ -n $1 ]]; then
  591. check+=("$@")
  592. else
  593. check+=("${_check[@]}")
  594. unset _check
  595. fi
  596. unset_extra_script
  597. [[ -z ${check[*]} ]] && echo "No files to check" && return 1
  598. if [[ $dry == y ]]; then
  599. files_exist -v -s "${check[@]}"
  600. return $?
  601. fi
  602. if files_exist -v "${check[@]}"; then
  603. [[ $stripping == y ]] && do_strip "${check[@]}"
  604. [[ $packing == y ]] && do_pack "${check[@]}"
  605. do_print_status "└ $packetName" "$blue" "Updated"
  606. [[ $build32 == yes || $build64 == yes ]] && [[ -d $packageDir ]] &&
  607. touch "$buildSuccessFile"
  608. else
  609. [[ $build32 == yes || $build64 == yes ]] && [[ -d $packageDir ]] &&
  610. rm -f "$buildSuccessFile"
  611. do_print_status "└ $packetName" "$red" "Failed"
  612. if ${_notrequired:-false}; then
  613. printf '%s\n' \
  614. "$orange"'Package failed to build, but is not required; proceeding with compilation.'"$reset"
  615. else
  616. printf '%s\n' \
  617. '' "Try deleting '$packageDir' and start the script again." \
  618. 'If you are sure there are no dependencies, <Enter> to continue building.'
  619. do_prompt "Close this window if you wish to stop building."
  620. fi
  621. fi
  622. }
  623. file_installed() {
  624. local file silent
  625. [[ $1 == "-s" ]] && silent=true && shift
  626. case $1 in
  627. /* | ./*)
  628. file="$1"
  629. ;;
  630. *.pc)
  631. file="lib/pkgconfig/$1"
  632. ;;
  633. *.a | *.la | *.lib)
  634. file="lib/$1"
  635. ;;
  636. *.h | *.hpp | *.c)
  637. file="include/$1"
  638. ;;
  639. *)
  640. file="$1"
  641. ;;
  642. esac
  643. [[ ${file::1} != "/" ]] && file="$LOCALDESTDIR/$file"
  644. ${silent:-false} || echo "$file"
  645. test -e "$file"
  646. }
  647. files_exist() {
  648. local verbose list soft ignorebinaries term='\n' file
  649. while true; do
  650. case $1 in
  651. -v) verbose=y && shift ;;
  652. -l) list=y && shift ;;
  653. -s) soft=y && shift ;;
  654. -b) ignorebinaries=y && shift ;;
  655. -l0) list=y && term='\0' && shift ;;
  656. --)
  657. shift
  658. break
  659. ;;
  660. *) break ;;
  661. esac
  662. done
  663. [[ $list ]] && verbose= && soft=y
  664. for opt; do
  665. if file=$(file_installed "$opt"); then
  666. [[ $verbose && $soft ]] && do_print_status "├ $file" "${green}" "Found"
  667. if [[ $list ]]; then
  668. if [[ $ignorebinaries && $file =~ .(exe|com)$ ]]; then
  669. continue
  670. fi
  671. printf "%s%b" "$file" "$term"
  672. fi
  673. else
  674. [[ $verbose ]] && do_print_status prefix "${bold}├${reset} " "$file" "${red}" "Not found"
  675. [[ ! $soft ]] && return 1
  676. fi
  677. done
  678. return 0
  679. }
  680. pc_exists() {
  681. for opt; do
  682. local _pkg=${opt%% *}
  683. local _check=${opt#$_pkg}
  684. [[ $_pkg == "$_check" ]] && _check=""
  685. [[ $_pkg == *.pc ]] || _pkg="${LOCALDESTDIR}/lib/pkgconfig/${_pkg}.pc"
  686. $PKG_CONFIG --exists --silence-errors "${_pkg}${_check}" || return
  687. done
  688. }
  689. do_install() {
  690. [[ $1 == dry ]] && local dryrun=y && shift
  691. local files=("$@")
  692. local dest="${files[-1]}"
  693. [[ ${dest::1} != "/" ]] && dest="$(file_installed "$dest")"
  694. [[ ${#files[@]} -gt 1 ]] && unset 'files[-1]'
  695. [[ ${dest: -1:1} == "/" ]] && mkdir -p "$dest"
  696. if [[ -n $dryrun ]]; then
  697. echo install -D -p "${files[@]}" "$dest"
  698. else
  699. extra_script pre install
  700. [[ -f "$(get_first_subdir -f)/do_not_install" ]] &&
  701. return
  702. install -D -p "${files[@]}" "$dest"
  703. extra_script post install
  704. fi
  705. }
  706. do_uninstall() {
  707. local dry quiet all files
  708. [[ $1 == dry ]] && dry=y && shift
  709. [[ $1 == q ]] && quiet=y && shift
  710. [[ $1 == all ]] && all=y && shift
  711. if [[ $all ]]; then
  712. mapfile -t files < <(files_exist -l "$@")
  713. else
  714. mapfile -t files < <(files_exist -l -b "$@")
  715. fi
  716. if [[ -n ${files[*]} ]]; then
  717. [[ ! $quiet ]] && do_print_progress Running uninstall
  718. if [[ $dry ]]; then
  719. echo "rm -rf ${files[*]}"
  720. else
  721. rm -rf "${files[@]}"
  722. fi
  723. fi
  724. }
  725. do_pkgConfig() {
  726. local pkg="${1%% *}"
  727. local pc_check="${1#$pkg}"
  728. local pkg_and_version="$pkg"
  729. [[ $pkg == "$pc_check" ]] && pc_check=""
  730. local version=$2
  731. local deps=("${_deps[@]}") && unset _deps
  732. [[ ! $version && $pc_check ]] && version="${pc_check#*= }"
  733. [[ "$version" ]] && pkg_and_version="${pkg} ${version}"
  734. if ! pc_exists "${pkg}"; then
  735. do_print_status "${pkg_and_version}" "$red" "Not installed"
  736. elif ! pc_exists "${pkg}${pc_check}"; then
  737. do_print_status "${pkg_and_version}" "$orange" "Outdated"
  738. elif [[ -n ${deps[*]} ]] && test_newer installed "${deps[@]}" "${pkg}.pc"; then
  739. do_print_status "${pkg_and_version}" "$orange" "Newer dependencies"
  740. elif [[ -n ${_check[*]} ]] && ! files_exist "${_check[@]}"; then
  741. do_print_status "${pkg_and_version}" "$orange" "Files missing"
  742. else
  743. do_print_status "${pkg_and_version}" "$green" "Up-to-date"
  744. return 1
  745. fi
  746. }
  747. do_readoptionsfile() {
  748. local filename="$1"
  749. if [[ -f $filename ]]; then
  750. sed -r '# remove commented text
  751. s/#.*//
  752. # delete empty lines
  753. /^\s*$/d
  754. # remove leading whitespace
  755. s/^\s+//
  756. # remove trailing whitespace
  757. s/\s+$//
  758. ' "$filename" | tr -d '\r' # cut cr out from any crlf files
  759. echo "Imported options from ${filename##*/}" >&2
  760. fi
  761. }
  762. do_readbatoptions() {
  763. local varname="$1"
  764. # shellcheck disable=SC1117
  765. printf '%s\n' "${bat[@]}" |
  766. sed -En "/set ${varname}=/,/[^^]$/p" |
  767. sed -E "/^:/d;s/(set ${varname}=| \\^|\")//g;s/ /\\n/g" |
  768. sed -E '/^#/d;/^[^-]/{s/^/--enable-/g}'
  769. }
  770. do_getFFmpegConfig() {
  771. local license="${1:-nonfree}"
  772. FFMPEG_DEFAULT_OPTS=()
  773. if [[ -f "/trunk/media-autobuild_suite.bat" && $ffmpegChoice =~ (n|z|f) ]]; then
  774. IFS=$'\r\n' read -d '' -r -a bat < /trunk/media-autobuild_suite.bat
  775. mapfile -t FFMPEG_DEFAULT_OPTS < <(do_readbatoptions "ffmpeg_options_(builtin|basic)")
  776. local option
  777. [[ $ffmpegChoice != n ]] && while read -r option; do
  778. FFMPEG_DEFAULT_OPTS+=("$option")
  779. done < <(do_readbatoptions "ffmpeg_options_zeranoe")
  780. [[ $ffmpegChoice == f ]] && while read -r option; do
  781. FFMPEG_DEFAULT_OPTS+=("$option")
  782. done < <(do_readbatoptions "ffmpeg_options_full(|_shared)")
  783. echo "Imported default FFmpeg options from .bat"
  784. else
  785. local custom_opts_file="$LOCALBUILDDIR/ffmpeg_options.txt"
  786. if [[ -f "$LOCALBUILDDIR/ffmpeg_options_$bits.txt" ]]; then
  787. custom_opts_file="$LOCALBUILDDIR/ffmpeg_options_$bits.txt"
  788. fi
  789. IFS=$'\n' read -d '' -r -a FFMPEG_DEFAULT_OPTS < <(do_readoptionsfile "$custom_opts_file")
  790. unset FFMPEG_DEFAULT_OPTS_SHARED
  791. if [[ -f "$LOCALBUILDDIR/ffmpeg_options_shared.txt" ]]; then
  792. IFS=$'\n' read -d '' -r -a FFMPEG_DEFAULT_OPTS_SHARED < <(
  793. do_readoptionsfile "$LOCALBUILDDIR/ffmpeg_options_shared.txt"
  794. )
  795. fi
  796. fi
  797. FFMPEG_OPTS=()
  798. for opt in "${FFMPEG_BASE_OPTS[@]}" "${FFMPEG_DEFAULT_OPTS[@]}"; do
  799. [[ -n $opt ]] && FFMPEG_OPTS+=("$opt")
  800. done
  801. echo "License: $license"
  802. # we set these accordingly for static or shared
  803. do_removeOption "--(en|dis)able-(shared|static)"
  804. # OK to use GnuTLS for rtmpdump if not nonfree since GnuTLS was built for rtmpdump anyway
  805. # If nonfree will use SChannel if neither openssl/libtls or gnutls are in the options
  806. if ! enabled_any libtls openssl gnutls &&
  807. { enabled librtmp || [[ $rtmpdump == y ]]; }; then
  808. if [[ $license == nonfree ]] ||
  809. [[ $license == lgpl* && $rtmpdump == n ]]; then
  810. do_addOption --enable-openssl
  811. else
  812. do_addOption --enable-gnutls
  813. fi
  814. do_removeOption "--enable-(gmp|gcrypt|mbedtls)"
  815. fi
  816. local _all_tls="--enable-(mbedtls|gnutls|openssl|libtls|schannel)"
  817. if enabled_any libtls openssl && [[ $license != gpl* ]]; then
  818. # prefer openssl/libtls if both are in options and not gpl
  819. # prefer openssl over libtls if both enabled
  820. local _prefer=libtls
  821. if enabled openssl; then
  822. _prefer=openssl
  823. fi
  824. do_removeOption "${_all_tls}"
  825. do_addOption "--enable-${_prefer}"
  826. elif enabled mbedtls; then
  827. # prefer mbedtls if any other tls libs are enabled and gpl
  828. do_removeOption "${_all_tls}"
  829. do_addOption --enable-mbedtls
  830. elif enabled gnutls; then
  831. do_removeOption "${_all_tls}"
  832. do_addOption --enable-gnutls
  833. elif ! disabled schannel; then
  834. # fallback to schannel if no other tls libs are enabled
  835. do_addOption --enable-schannel
  836. fi
  837. enabled_any lib{vo-aacenc,aacplus,utvideo,dcadec,faac,ebur128,ndi_newtek,ndi-newtek,ssh,wavpack} netcdf &&
  838. do_removeOption "--enable-(lib(vo-aacenc|aacplus|utvideo|dcadec|faac|ebur128|ndi_newtek|ndi-newtek|ssh|wavpack)|netcdf)" &&
  839. sed -ri 's;--enable-(lib(vo-aacenc|aacplus|utvideo|dcadec|faac|ebur128|ndi_newtek|ndi-newtek|ssh|wavpack)|netcdf);;g' \
  840. "$LOCALBUILDDIR/ffmpeg_options.txt"
  841. }
  842. do_changeFFmpegConfig() {
  843. local license="${1:-nonfree}"
  844. do_print_progress Changing options to comply to "$license"
  845. # if w32threads is disabled, pthreads is used and needs this cflag
  846. # decklink includes zvbi, which requires pthreads
  847. if disabled w32threads || enabled pthreads || enabled_all decklink libzvbi || enabled libvmaf; then
  848. do_removeOption --enable-w32threads
  849. do_addOption --disable-w32threads
  850. fi
  851. # add options for static kvazaar
  852. enabled libkvazaar && do_addOption --extra-cflags=-DKVZ_STATIC_LIB
  853. # get libs restricted by license
  854. local config_script=configure
  855. [[ $(get_first_subdir) != "ffmpeg-git" ]] && config_script="$LOCALBUILDDIR/ffmpeg-git/configure"
  856. [[ -f $config_script ]] || do_exit_prompt "There's no configure script to retrieve libs from"
  857. eval "$(sed -n '/EXTERNAL_LIBRARY_GPL_LIST=/,/^"/p' "$config_script" | tr -s '\n' ' ')"
  858. eval "$(sed -n '/HWACCEL_LIBRARY_NONFREE_LIST=/,/^"/p' "$config_script" | tr -s '\n' ' ')"
  859. eval "$(sed -n '/EXTERNAL_LIBRARY_NONFREE_LIST=/,/^"/p' "$config_script" | tr -s '\n' ' ')"
  860. eval "$(sed -n '/EXTERNAL_LIBRARY_VERSION3_LIST=/,/^"/p' "$config_script" | tr -s '\n' ' ')"
  861. # handle gpl libs
  862. local gpl
  863. read -ra gpl <<< "${EXTERNAL_LIBRARY_GPL_LIST//_/-} gpl"
  864. if [[ $license == gpl* || $license == nonfree ]] &&
  865. { enabled_any "${gpl[@]}" || ! disabled postproc; }; then
  866. do_addOption --enable-gpl
  867. else
  868. do_removeOptions "${gpl[*]/#/--enable-} --enable-postproc --enable-gpl"
  869. fi
  870. # handle (l)gplv3 libs
  871. local version3
  872. read -ra version3 <<< "${EXTERNAL_LIBRARY_VERSION3_LIST//_/-}"
  873. if [[ $license =~ (l|)gplv3 || $license == nonfree ]] && enabled_any "${version3[@]}"; then
  874. do_addOption --enable-version3
  875. else
  876. do_removeOptions "${version3[*]/#/--enable-} --enable-version3"
  877. fi
  878. local nonfreehwaccel
  879. read -ra nonfreehwaccel <<< "(${HWACCEL_LIBRARY_NONFREE_LIST//_/-}"
  880. if [[ $license == "nonfree" ]] && enabled_any "${nonfreehwaccel[@]}"; then
  881. do_addOption --enable-nonfree
  882. else
  883. do_removeOptions "${nonfreehwaccel[*]/#/--enable-} --enable-nonfree"
  884. fi
  885. # cuda-only workarounds
  886. if verify_cuda_deps; then
  887. if enabled libnpp; then
  888. echo -e "${orange}FFmpeg and related apps will depend on CUDA SDK to run!${reset}"
  889. local fixed_CUDA_PATH
  890. fixed_CUDA_PATH="$(cygpath -sm "$CUDA_PATH")"
  891. if [[ $fixed_CUDA_PATH != "${fixed_CUDA_PATH// /}" ]]; then
  892. # Assumes CUDA_PATH backwards is version/CUDA/NVIDIA GPU Computing Toolkit/rest of the path
  893. # Strips the onion to the rest of the path
  894. {
  895. cat << EOF
  896. @echo off
  897. fltmc > NUL 2>&1 || echo Elevation required, right click the script and click 'Run as administrator'. & echo/ & pause & exit /b 1
  898. cd /d "$(dirname "$(dirname "$(dirname "$(cygpath -sw "$CUDA_PATH")")")")"
  899. EOF
  900. # Generate up to 4 shortnames
  901. for _n in 1 2 3 4; do
  902. printf 'fsutil file setshortname "NVIDIA GPU Computing Toolkit" NVIDIA~%d || ' "$_n"
  903. done
  904. echo 'echo Failed to set a shortname for your CUDA_PATH'
  905. } > "$LOCALBUILDDIR/cuda.bat"
  906. do_simple_print "${orange}Spaces detected in the CUDA path"'!'"$reset"
  907. do_simple_print "Path returned by windows: ${bold}$fixed_CUDA_PATH${reset}"
  908. do_simple_print "A script to create the missing short paths for your CUDA_PATH"
  909. do_simple_print "was created at $(cygpath -m "$LOCALBUILDDIR/cuda.bat")"
  910. do_simple_print "Please run that script as an administrator and rerun the suite"
  911. do_simple_print "${red}This will break FFmpeg compilation, so aborting early"'!'"${reset}"
  912. logging=n compilation_fail "do_changeFFmpegConfig"
  913. fi
  914. do_addOption "--extra-cflags=-I$fixed_CUDA_PATH/include"
  915. do_addOption "--extra-ldflags=-L$fixed_CUDA_PATH/lib/x64"
  916. fi
  917. if enabled cuda-nvcc; then
  918. local fixed_CUDA_PATH_UNIX
  919. fixed_CUDA_PATH_UNIX="$(cygpath -u "$CUDA_PATH")"
  920. nvcc.exe --help &> /dev/null || export PATH="$PATH:$fixed_CUDA_PATH_UNIX/bin"
  921. echo -e "${orange}FFmpeg and related apps will depend on Nvidia drivers!${reset}"
  922. fi
  923. else
  924. do_removeOption "--enable-(libnpp|cuda-nvcc)"
  925. fi
  926. # handle gpl-incompatible libs
  927. local nonfreegpl
  928. read -ra nonfreegpl <<< "${EXTERNAL_LIBRARY_NONFREE_LIST//_/-}"
  929. if enabled_any "${nonfreegpl[@]}"; then
  930. if [[ $license == "nonfree" ]] && enabled gpl; then
  931. do_addOption --enable-nonfree
  932. elif [[ $license == gpl* ]]; then
  933. do_removeOptions "${nonfreegpl[*]/#/--enable-}"
  934. fi
  935. # no lgpl here because they are accepted with it
  936. fi
  937. if ! disabled debug "debug=gdb"; then
  938. # fix issue with ffprobe not working with debug and strip
  939. do_addOption --disable-stripping
  940. fi
  941. # both openssl and mbedtls don't need gcrypt/gmp for rtmpe
  942. enabled_any openssl mbedtls && do_removeOption "--enable-(gcrypt|gmp)"
  943. # remove libs that don't work with shared
  944. if [[ $ffmpeg =~ "shared" || $ffmpeg =~ "both" ]]; then
  945. FFMPEG_OPTS_SHARED=()
  946. for opt in "${FFMPEG_OPTS[@]}" "${FFMPEG_DEFAULT_OPTS_SHARED[@]}"; do
  947. FFMPEG_OPTS_SHARED+=("$opt")
  948. done
  949. fi
  950. if [[ $ffmpeg == "bothstatic" ]]; then
  951. do_removeOption "--enable-(opencl|opengl|cuda-nvcc|libnpp|libopenh264)"
  952. fi
  953. }
  954. opt_exists() {
  955. local array="${1}[@]" && shift 1
  956. local opt value
  957. for opt; do
  958. for value in "${!array}"; do
  959. [[ $value =~ $opt ]] && return
  960. done
  961. done
  962. return 1
  963. }
  964. enabled() {
  965. test "${FFMPEG_OPTS[*]}" != "${FFMPEG_OPTS[*]#--enable-$1}"
  966. }
  967. disabled() {
  968. test "${FFMPEG_OPTS[*]}" != "${FFMPEG_OPTS[*]#--disable-$1}"
  969. }
  970. enabled_any() {
  971. local opt
  972. for opt; do
  973. enabled "$opt" && return 0
  974. done
  975. return 1
  976. }
  977. disabled_any() {
  978. local opt
  979. for opt; do
  980. disabled "$opt" && return 0
  981. done
  982. return 1
  983. }
  984. enabled_all() {
  985. local opt
  986. for opt; do
  987. enabled "$opt" || return 1
  988. done
  989. return 0
  990. }
  991. disabled_all() {
  992. local opt
  993. for opt; do
  994. disabled "$opt" || return 1
  995. done
  996. return 0
  997. }
  998. do_getMpvConfig() {
  999. local MPV_TEMP_OPTS=()
  1000. MPV_OPTS=()
  1001. if [[ -f "/trunk/media-autobuild_suite.bat" && $ffmpegChoice =~ (n|z|f) ]]; then
  1002. IFS=$'\r\n' read -d '' -r -a bat < /trunk/media-autobuild_suite.bat
  1003. mapfile -t MPV_TEMP_OPTS < <(do_readbatoptions "mpv_options_(builtin|basic)")
  1004. local option
  1005. [[ $ffmpegChoice == f ]] && while read -r option; do
  1006. [[ -n $option ]] && MPV_TEMP_OPTS+=("$option")
  1007. done < <(do_readbatoptions "mpv_options_full")
  1008. echo "Imported default mpv options from .bat"
  1009. else
  1010. IFS=$'\n' read -d '' -r -a MPV_TEMP_OPTS < <(do_readoptionsfile "$LOCALBUILDDIR/mpv_options.txt")
  1011. fi
  1012. do_removeOption MPV_TEMP_OPTS \
  1013. "--(en|dis)able-(vapoursynth-lazy|libguess|static-build|enable-gpl3|egl-angle-lib|encoding|crossc|dvdread|libass)"
  1014. for opt in "${MPV_TEMP_OPTS[@]}"; do
  1015. [[ -n $opt ]] && MPV_OPTS+=("$opt")
  1016. done
  1017. }
  1018. mpv_enabled() {
  1019. local option
  1020. [[ $mpv == n ]] && return 1
  1021. for option in "${MPV_OPTS[@]}"; do
  1022. [[ $option =~ "--enable-$1"$ ]] && return
  1023. done
  1024. return 1
  1025. }
  1026. mpv_disabled() {
  1027. local option
  1028. [[ $mpv == n ]] && return 0
  1029. for option in "${MPV_OPTS[@]}"; do
  1030. [[ $option =~ "--disable-$1"$ ]] && return
  1031. done
  1032. return 1
  1033. }
  1034. mpv_enabled_any() {
  1035. local opt
  1036. for opt; do
  1037. mpv_enabled "$opt" && return 0
  1038. done
  1039. return 1
  1040. }
  1041. mpv_disabled_any() {
  1042. local opt
  1043. for opt; do
  1044. mpv_disabled "$opt" && return 0
  1045. done
  1046. return 1
  1047. }
  1048. mpv_enabled_all() {
  1049. local opt
  1050. for opt; do
  1051. mpv_enabled "$opt" || return 1
  1052. done
  1053. }
  1054. mpv_disabled_all() {
  1055. local opt
  1056. for opt; do
  1057. mpv_disabled "$opt" || return 1
  1058. done
  1059. }
  1060. mpv_enable() {
  1061. local opt newopts=()
  1062. for opt in "${MPV_OPTS[@]}"; do
  1063. if [[ $opt =~ "--disable-$1"$ ]]; then
  1064. newopts+=("--enable-$1")
  1065. else
  1066. newopts+=("$opt")
  1067. fi
  1068. done
  1069. MPV_OPTS=("${newopts[@]}")
  1070. }
  1071. mpv_disable() {
  1072. local opt newopts=()
  1073. for opt in "${MPV_OPTS[@]}"; do
  1074. if [[ $opt =~ "--enable-$1"$ ]]; then
  1075. newopts+=("--disable-$1")
  1076. else
  1077. newopts+=("$opt")
  1078. fi
  1079. done
  1080. MPV_OPTS=("${newopts[@]}")
  1081. }
  1082. do_addOption() {
  1083. local varname="$1" array opt
  1084. if [[ ${varname#--} == "$varname" ]]; then
  1085. array="$varname" && shift 1
  1086. else
  1087. array="FFMPEG_OPTS"
  1088. fi
  1089. for opt; do
  1090. ! opt_exists "$array" "$opt" && declare -ag "$array+=(\"$opt\")"
  1091. done
  1092. }
  1093. do_removeOption() {
  1094. local varname="$1"
  1095. local arrayname
  1096. if [[ ${varname#--} == "$varname" ]]; then
  1097. arrayname="$varname" && shift 1
  1098. else
  1099. arrayname="FFMPEG_OPTS"
  1100. fi
  1101. local option="$1"
  1102. local basearray temp=()
  1103. basearray="${arrayname}[@]"
  1104. local orig=("${!basearray}")
  1105. for ((i = 0; i < ${#orig[@]}; i++)); do
  1106. if [[ ! ${orig[$i]} =~ ^${option}$ ]]; then
  1107. temp+=("${orig[$i]}")
  1108. fi
  1109. done
  1110. # shellcheck disable=SC1117,SC1083
  1111. eval "$arrayname"=\(\"\${temp[@]}\"\)
  1112. }
  1113. do_removeOptions() {
  1114. local option
  1115. local shared=$2
  1116. for option in $1; do
  1117. do_removeOption "$option" "$shared"
  1118. done
  1119. }
  1120. do_patch() {
  1121. local binarypatch="--binary"
  1122. case $1 in -p) binarypatch="" && shift ;; esac
  1123. local patch="${1%% *}" # Location or link to patch.
  1124. local patchName="${1##* }" # Basename of file. (test-diff-files.diff)
  1125. local am=false # Use git am to apply patch. Use with .patch files
  1126. local strip=${3:-1} # Leading directories to strip. "patch -p${strip}"
  1127. [[ $patchName == "$patch" ]] && patchName="${patch##*/}"
  1128. [[ $2 == am ]] && am=true
  1129. # hack for URLs without filename
  1130. patchName=${patchName:-"$(/usr/bin/curl -LsI "$patch" | grep -Eo 'filename=.*$' | sed 's/filename=//')"}
  1131. [[ -z $patchName ]] &&
  1132. printf '%b\n' "${red}Failed to apply patch '$patch'" \
  1133. "Patch without filename, ignoring. Specify an explicit filename.${reset}" &&
  1134. return 1
  1135. # Just don't. Make a fork or use the suite's directory as the root for
  1136. # your diffs or manually edit the scripts if you are trying to modify
  1137. # the helper and compile scripts. If you really need to, use patch instead.
  1138. # Else create a patch file for the individual folders you want to apply
  1139. # the patch to.
  1140. [[ $PWD == "$LOCALBUILDDIR" ]] &&
  1141. do_exit_prompt "Running patches in the build folder is not supported.
  1142. Please make a patch for individual folders or modify the script directly"
  1143. # Filter out patches that would require curl; else
  1144. # check if the patch is a local patch and copy it to the current dir
  1145. if ! do_wget -c -r -q "$patch" "$patchName" && [[ -f $patch ]]; then
  1146. patch="$(
  1147. cd_safe "$(dirname "$patch")"
  1148. printf '%s' "$(pwd -P)" '/' "$(basename -- "$patch")"
  1149. )" # Resolve fullpath
  1150. [[ ${patch%/*} != "$PWD" ]] && cp -f "$patch" "$patchName" > /dev/null 2>&1
  1151. fi
  1152. if [[ -f $patchName ]]; then
  1153. if $am; then
  1154. git apply -3 --check --ignore-space-change --ignore-whitespace "$patchName" > /dev/null 2>&1 &&
  1155. git am -q -3 --ignore-whitespace --no-gpg-sign "$patchName" > /dev/null 2>&1 &&
  1156. return 0
  1157. git am -q --abort > /dev/null 2>&1
  1158. else
  1159. patch --dry-run $binarypatch -s -N -p"$strip" -i "$patchName" > /dev/null 2>&1 &&
  1160. patch $binarypatch -s -N -p"$strip" -i "$patchName" &&
  1161. return 0
  1162. fi
  1163. printf '%b\n' "${orange}${patchName}${reset}" \
  1164. '\tPatch could not be applied with `'"$($am && echo "git am" || echo "patch")"'`. Continuing without patching.'
  1165. else
  1166. printf '%b\n' "${orange}${patchName}${reset}" \
  1167. '\tPatch not found anywhere. Continuing without patching.'
  1168. fi
  1169. return 1
  1170. }
  1171. do_custom_patches() {
  1172. local patch
  1173. for patch in "$@"; do
  1174. [[ ${patch##*.} == "patch" ]] && do_patch "$patch" am
  1175. [[ ${patch##*.} == "diff" ]] && do_patch "$patch"
  1176. done
  1177. }
  1178. do_cmake() {
  1179. local bindir=""
  1180. local root=".."
  1181. local cmake_build_dir=""
  1182. while [[ -n $* ]]; do
  1183. case "$1" in
  1184. global | audio | video)
  1185. bindir="-DCMAKE_INSTALL_BINDIR=$LOCALDESTDIR/bin-$1"
  1186. shift
  1187. ;;
  1188. builddir=*)
  1189. cmake_build_dir="${1#*=}"
  1190. shift
  1191. ;;
  1192. skip_build_dir)
  1193. local skip_build_dir=y
  1194. shift
  1195. ;;
  1196. *)
  1197. if [[ -d "./$1" ]]; then
  1198. [[ -n $skip_build_dir ]] && root="./$1" || root="../$1"
  1199. shift
  1200. elif [[ -d "../$1" ]]; then
  1201. root="../$1"
  1202. shift
  1203. fi
  1204. break
  1205. ;;
  1206. esac
  1207. done
  1208. [[ -z $skip_build_dir ]] && create_build_dir "$cmake_build_dir"
  1209. # use this array to pass additional parameters to cmake
  1210. local cmake_extras=()
  1211. extra_script pre cmake
  1212. [[ -f "$(get_first_subdir -f)/do_not_reconfigure" ]] &&
  1213. return
  1214. # shellcheck disable=SC2086
  1215. log "cmake" cmake "$root" -G Ninja -DBUILD_SHARED_LIBS=off \
  1216. -DPython3_EXECUTABLE="${MINGW_PREFIX}/bin/python.exe" \
  1217. -DCMAKE_EXPORT_COMPILE_COMMANDS=on \
  1218. -DCMAKE_TOOLCHAIN_FILE="$LOCALDESTDIR/etc/toolchain.cmake" \
  1219. -DCMAKE_INSTALL_PREFIX="$LOCALDESTDIR" -DUNIX=on \
  1220. -DCMAKE_BUILD_TYPE=Release $bindir "$@" "${cmake_extras[@]}"
  1221. extra_script post cmake
  1222. unset cmake_extras
  1223. }
  1224. do_ninja() {
  1225. extra_script pre ninja
  1226. [[ -f "$(get_first_subdir -f)/do_not_build" ]] &&
  1227. return
  1228. log "build" ninja "$@"
  1229. extra_script post ninja
  1230. }
  1231. do_ninjainstall() {
  1232. extra_script pre install
  1233. [[ -f "$(get_first_subdir -f)/do_not_install" ]] &&
  1234. return
  1235. cpuCount=1 log "install" ninja install "$@"
  1236. extra_script post install
  1237. }
  1238. do_cmakeinstall() {
  1239. do_cmake "$@"
  1240. do_ninja
  1241. do_ninjainstall
  1242. }
  1243. do_meson() {
  1244. local bindir=""
  1245. local root=".."
  1246. case "$1" in
  1247. global | audio | video)
  1248. bindir="--bindir=bin-$1"
  1249. ;;
  1250. *)
  1251. [[ -d "./$1" ]] && root="../$1" || bindir="$1"
  1252. ;;
  1253. esac
  1254. shift 1
  1255. create_build_dir
  1256. # use this array to pass additional parameters to meson
  1257. local meson_extras=()
  1258. extra_script pre meson
  1259. [[ -f "$(get_first_subdir -f)/do_not_reconfigure" ]] &&
  1260. return
  1261. # shellcheck disable=SC2086
  1262. PKG_CONFIG="pkgconf --keep-system-libs --keep-system-cflags" CC=${CC/ccache /}.bat CXX=${CXX/ccache /}.bat \
  1263. log "meson" meson setup "$root" --default-library=static --buildtype=release \
  1264. --prefix="$LOCALDESTDIR" --backend=ninja $bindir "$@" "${meson_extras[@]}"
  1265. extra_script post meson
  1266. unset meson_extras
  1267. }
  1268. do_mesoninstall() {
  1269. do_meson "$@"
  1270. do_ninja
  1271. do_ninjainstall
  1272. }
  1273. do_rust() {
  1274. log "rust.update" cargo update
  1275. # use this array to pass additional parameters to cargo
  1276. local rust_extras=()
  1277. [[ $CC =~ clang ]] && local target_suffix="llvm"
  1278. extra_script pre rust
  1279. [[ -f "$(get_first_subdir -f)/do_not_reconfigure" ]] &&
  1280. return
  1281. PKG_CONFIG_ALL_STATIC=true \
  1282. log "rust.build" cargo build \
  1283. --target="$CARCH"-pc-windows-gnu$target_suffix \
  1284. --jobs="$cpuCount" "${@:---release}" "${rust_extras[@]}"
  1285. extra_script post rust
  1286. unset rust_extras
  1287. }
  1288. do_rustinstall() {
  1289. log "rust.update" cargo update
  1290. # use this array to pass additional parameters to cargo
  1291. local rust_extras=()
  1292. [[ $CC =~ clang ]] && local target_suffix="llvm"
  1293. extra_script pre rust
  1294. [[ -f "$(get_first_subdir -f)/do_not_reconfigure" ]] &&
  1295. return
  1296. PKG_CONFIG_ALL_STATIC=true \
  1297. PKG_CONFIG="$LOCALDESTDIR/bin/ab-pkg-config" \
  1298. log "rust.install" cargo install \
  1299. --target="$CARCH"-pc-windows-gnu$target_suffix \
  1300. --jobs="$cpuCount" "${@:---path=.}" "${rust_extras[@]}"
  1301. extra_script post rust
  1302. unset rust_extras
  1303. }
  1304. do_rustcinstall() {
  1305. log "rust.update" cargo update
  1306. # use this array to pass additional parameters to cargo
  1307. local rust_extras=()
  1308. [[ $CC =~ clang ]] && local target_suffix="llvm"
  1309. extra_script pre rust
  1310. [[ -f "$(get_first_subdir -f)/do_not_reconfigure" ]] &&
  1311. return
  1312. PKG_CONFIG_ALL_STATIC=true \
  1313. PKG_CONFIG="$LOCALDESTDIR/bin/ab-pkg-config" \
  1314. log "rust.cinstall" cargo cinstall \
  1315. --target="$CARCH"-pc-windows-gnu$target_suffix \
  1316. --jobs="$cpuCount" --prefix="$LOCALDESTDIR" "$@" "${rust_extras[@]}"
  1317. extra_script post rust
  1318. unset rust_extras
  1319. }
  1320. compilation_fail() {
  1321. [[ -z $build32$build64 ]] && return 1
  1322. local reason="$1"
  1323. local operation="${reason,,}"
  1324. if [[ $logging == y ]]; then
  1325. echo "Likely error (tail of the failed operation logfile):"
  1326. tail "ab-suite.${operation}.log"
  1327. echo "${red}$reason failed. Check $(pwd -W)/ab-suite.$operation.log${reset}"
  1328. fi
  1329. if ${_notrequired:-false}; then
  1330. echo "This isn't required for anything so we can move on."
  1331. return 1
  1332. else
  1333. echo "${red}This is required for other packages, so this script will exit.${reset}"
  1334. create_diagnostic
  1335. zip_logs
  1336. echo "Make sure the suite is up-to-date before reporting an issue. It might've been fixed already."
  1337. $([[ $noMintty == y ]] && echo echo || echo do_prompt) "Try running the build again at a later time."
  1338. exit 1
  1339. fi
  1340. }
  1341. strip_ansi() {
  1342. local txtfile newfile
  1343. for txtfile; do
  1344. [[ $txtfile != "${txtfile//stripped/}" ]] && continue
  1345. local name="${txtfile%.*}" ext="${txtfile##*.}"
  1346. [[ $txtfile != "$name" ]] &&
  1347. newfile="$name.stripped.$ext" || newfile="$txtfile-stripped"
  1348. sed -r "s/\x1b[[(][0-9;?]*[a-zA-Z]|\x1b\][0-9];//g" "$txtfile" > "$newfile"
  1349. done
  1350. }
  1351. zip_logs() {
  1352. local failed url
  1353. failed=$(get_first_subdir)
  1354. strip_ansi "$LOCALBUILDDIR"/*.log
  1355. rm -f "$LOCALBUILDDIR/logs.zip"
  1356. (
  1357. cd "$LOCALBUILDDIR" > /dev/null || do_exit_prompt "Did you delete /build?"
  1358. {
  1359. echo /trunk/media-autobuild_suite.bat
  1360. [[ $failed != . ]] && find "$failed" -name "*.log"
  1361. find . -maxdepth 1 -name "*.stripped.log" -o -name "*_options.txt" -o -name "media-suite_*.sh" \
  1362. -o -name "last_run" -o -name "media-autobuild_suite.ini" -o -name "diagnostics.txt" -o -name "patchedFolders"
  1363. } | sort -uo failedFiles
  1364. 7za -mx=9 a logs.zip -- @failedFiles > /dev/null && rm failedFiles
  1365. )
  1366. # [[ ! -f $LOCALBUILDDIR/no_logs && -n $build32$build64 && $autouploadlogs = y ]] &&
  1367. # url="$(cd "$LOCALBUILDDIR" && /usr/bin/curl -sF'file=@logs.zip' https://0x0.st)"
  1368. echo
  1369. if [[ $url ]]; then
  1370. echo "${green}All relevant logs have been anonymously uploaded to $url"
  1371. echo "${green}Copy and paste ${red}[logs.zip]($url)${green} in the GitHub issue.${reset}"
  1372. elif [[ -f "$LOCALBUILDDIR/logs.zip" ]]; then
  1373. echo "${green}Attach $(cygpath -w "$LOCALBUILDDIR/logs.zip") to the GitHub issue.${reset}"
  1374. else
  1375. echo "${red}Failed to generate logs.zip!${reset}"
  1376. fi
  1377. }
  1378. log() {
  1379. local errorOut=true quiet=false ret OPTION OPTIND
  1380. while getopts ':qe' OPTION; do
  1381. case "$OPTION" in
  1382. e) errorOut=false ;;
  1383. q) quiet=true ;;
  1384. *) break ;;
  1385. esac
  1386. done
  1387. shift "$((OPTIND - 1))"
  1388. [[ $1 == quiet ]] && quiet=true && shift # Temp compat with old style just in case
  1389. local name="${1// /.}" _cmd="$2" extra
  1390. shift 2
  1391. $quiet || do_print_progress Running "$name"
  1392. [[ $_cmd =~ ^(make|ninja)$ ]] && extra="-j$cpuCount"
  1393. if [[ $logging == "y" ]]; then
  1394. printf 'CPPFLAGS: %s\nCFLAGS: %s\nCXXFLAGS: %s\nLDFLAGS: %s\n%s %s\n' "$CPPFLAGS" "$CFLAGS" "$CXXFLAGS" "$LDFLAGS" "$_cmd${extra:+ $extra}" "$*" > "ab-suite.$name.log"
  1395. $_cmd $extra "$@" >> "ab-suite.$name.log" 2>&1 ||
  1396. { [[ $extra ]] && $_cmd -j1 "$@" >> "ab-suite.$name.log" 2>&1; }
  1397. else
  1398. $_cmd $extra "$@" || { [[ $extra ]] && $_cmd -j1 "$@"; }
  1399. fi
  1400. case ${ret:=$?} in
  1401. 0) return 0 ;;
  1402. *) $errorOut && compilation_fail "$name" || return $ret ;;
  1403. esac
  1404. }
  1405. create_build_dir() {
  1406. local print_build_dir=false nocd=${nocd:-false} norm=false build_root build_dir getoptopt OPTARG OPTIND
  1407. while getopts ":pcrC:" getoptopt; do
  1408. case $getoptopt in
  1409. p) print_build_dir=true ;;
  1410. c) nocd=true ;;
  1411. r) norm=true ;;
  1412. C) build_root="$OPTARG" ;;
  1413. \?)
  1414. echo "Invalid Option: -$OPTARG" 1>&2
  1415. return 1
  1416. ;;
  1417. :)
  1418. echo "Invalid option: $OPTARG requires an argument" 1>&2
  1419. return 1
  1420. ;;
  1421. esac
  1422. done
  1423. shift $((OPTIND - 1))
  1424. build_dir="${build_root:+$build_root/}build${1:+-$1}-$bits"
  1425. [[ -z $build_root && -d ../$build_dir ]] && cd_safe ..
  1426. if [[ -d $build_dir && ! -f $(get_first_subdir -f)/do_not_clean ]]; then
  1427. $norm || rm -rf "$build_dir" ||
  1428. (cd_safe "$build_dir" && rm -rf ./*)
  1429. fi
  1430. [[ ! -d $build_dir ]] && mkdir -p "$build_dir"
  1431. $nocd || cd_safe "$build_dir"
  1432. $print_build_dir && printf '%s\n' "$build_dir"
  1433. }
  1434. get_external_opts() {
  1435. local array="$1"
  1436. local pkgname
  1437. pkgname="$(get_first_subdir)"
  1438. local optsfile="$LOCALBUILDDIR/${pkgname%-*}_options.txt"
  1439. if [[ -n $array ]]; then
  1440. # shellcheck disable=SC2034
  1441. IFS=$'\n' read -d '' -r -a tmp < <(do_readoptionsfile "$optsfile")
  1442. declare -ag "$array+=(\"\${tmp[@]}\")"
  1443. else
  1444. do_readoptionsfile "$optsfile"
  1445. fi
  1446. }
  1447. do_separate_conf() {
  1448. local bindir=""
  1449. local last config_path
  1450. case "$1" in
  1451. global | audio | video)
  1452. bindir="--bindir=$LOCALDESTDIR/bin-$1"
  1453. ;;
  1454. *) bindir="$1" ;;
  1455. esac
  1456. shift 1
  1457. for last; do true; done
  1458. if test -x "${last}/configure"; then
  1459. config_path="$last"
  1460. else
  1461. config_path=".."
  1462. create_build_dir
  1463. fi
  1464. do_configure --disable-shared --enable-static "$bindir" "$@"
  1465. }
  1466. do_separate_confmakeinstall() {
  1467. do_separate_conf "$@"
  1468. do_make
  1469. do_makeinstall
  1470. cd_safe ..
  1471. }
  1472. do_configure() {
  1473. # use this array to pass additional parameters to configure
  1474. local conf_extras=()
  1475. extra_script pre configure
  1476. [[ -f "$(get_first_subdir -f)/do_not_reconfigure" ]] &&
  1477. return
  1478. log "configure" ${config_path:-.}/configure --prefix="$LOCALDESTDIR" "$@" \
  1479. "${conf_extras[@]}"
  1480. extra_script post configure
  1481. unset conf_extras
  1482. }
  1483. do_qmake() {
  1484. extra_script pre qmake
  1485. log "qmake" qmake "$@"
  1486. extra_script post qmake
  1487. }
  1488. do_make() {
  1489. extra_script pre make
  1490. [[ -f "$(get_first_subdir -f)/do_not_build" ]] &&
  1491. return
  1492. log "make" make "$@"
  1493. extra_script post make
  1494. }
  1495. do_makeinstall() {
  1496. extra_script pre install
  1497. [[ -f "$(get_first_subdir -f)/do_not_install" ]] &&
  1498. return
  1499. log "install" make install "$@"
  1500. extra_script post install
  1501. }
  1502. do_hide_pacman_sharedlibs() {
  1503. local packages="$1"
  1504. local revert="$2"
  1505. local files
  1506. files="$(pacman -Qql "$packages" 2> /dev/null | grep .dll.a)"
  1507. for file in $files; do
  1508. if [[ -f "${file%*.dll.a}.a" ]]; then
  1509. if [[ -z $revert ]]; then
  1510. mv -f "${file}" "${file}.dyn"
  1511. elif [[ -n $revert && -f "${file}.dyn" && ! -f ${file} ]]; then
  1512. mv -f "${file}.dyn" "${file}"
  1513. elif [[ -n $revert && -f "${file}.dyn" ]]; then
  1514. rm -f "${file}.dyn"
  1515. fi
  1516. fi
  1517. done
  1518. }
  1519. do_hide_all_sharedlibs() {
  1520. local dryrun="${dry:-n}"
  1521. local files
  1522. files="$(find /{mingw{32,64},clang64}/lib /{mingw{32/i686,64/x86_64},clang64/x86_64}-w64-mingw32/lib -name "*.dll.a" 2> /dev/null)"
  1523. local tomove=()
  1524. for file in $files; do
  1525. [[ -f ${file%*.dll.a}.a ]] && tomove+=("$file")
  1526. done
  1527. if [[ -n ${tomove[*]} ]]; then
  1528. if [[ $dryrun == "n" ]]; then
  1529. printf '%s\0' "${tomove[@]}" | xargs -0ri mv -f '{}' '{}.dyn'
  1530. else
  1531. printf '%s\n' "${tomove[@]}"
  1532. fi
  1533. fi
  1534. }
  1535. do_unhide_all_sharedlibs() {
  1536. local dryrun="${dry:-n}"
  1537. local files
  1538. files="$(find /{mingw{32,64},clang64}/lib /{mingw{32/i686,64/x86_64},clang64/x86_64}-w64-mingw32/lib -name "*.dll.a.dyn" 2> /dev/null)"
  1539. local tomove=()
  1540. local todelete=()
  1541. for file in $files; do
  1542. if [[ -f ${file%*.dyn} ]]; then
  1543. todelete+=("$file")
  1544. else
  1545. tomove+=("${file%*.dyn}")
  1546. fi
  1547. done
  1548. if [[ $dryrun == "n" ]]; then
  1549. printf '%s\n' "${todelete[@]}" | xargs -ri rm -f '{}'
  1550. printf '%s\n' "${tomove[@]}" | xargs -ri mv -f '{}.dyn' '{}'
  1551. else
  1552. printf 'rm %s\n' "${todelete[@]}"
  1553. printf '%s\n' "${tomove[@]}"
  1554. fi
  1555. }
  1556. do_pacman_resolve_pkgs() (
  1557. : "${prefix=$MINGW_PACKAGE_PREFIX-}"
  1558. pacsift --exact --sync --any "${@/#/--provides=$prefix}" "${@/#/--name=$prefix}" 2>&1 | sed "s|^.*/$prefix||"
  1559. )
  1560. is_pkg_installed() (
  1561. : "${prefix=$MINGW_PACKAGE_PREFIX-}"
  1562. # checks if a package is installed/provided by a package that is installed
  1563. # example is omp, which is purely a provided packge, so that fails with pacman -Qe
  1564. pacsift --exact --local --any --exists --provides="$prefix$1" --name="$prefix$1" > /dev/null 2>&1
  1565. )
  1566. do_pacman_install() (
  1567. ret=true
  1568. prefix=$MINGW_PACKAGE_PREFIX-
  1569. file=/etc/pac-mingw-extra.pk
  1570. pkgs=()
  1571. while true; do
  1572. case "$1" in
  1573. -m)
  1574. prefix=
  1575. file=/etc/pac-msys-extra.pk
  1576. shift
  1577. ;;
  1578. *) break ;;
  1579. esac
  1580. done
  1581. for pkg; do
  1582. for line in $(do_pacman_resolve_pkgs "$pkg"); do
  1583. if ! is_pkg_installed "$line"; then
  1584. pkgs+=("$line")
  1585. fi
  1586. done
  1587. done
  1588. for pkg in "${pkgs[@]}"; do
  1589. do_simple_print -n "Installing $pkg... "
  1590. if pacman -S \
  1591. --noconfirm --ask=20 --needed \
  1592. --overwrite "/usr/*" \
  1593. --overwrite "/ucrt64/*" \
  1594. --overwrite "/mingw64/*" \
  1595. --overwrite "/mingw32/*" \
  1596. --overwrite "/clang64/*" \
  1597. "$prefix$pkg" > /dev/null 2>&1; then
  1598. pacman -D --asexplicit "$prefix$pkg" > /dev/null 2>&1
  1599. echo "$pkg" >> $file
  1600. echo "done"
  1601. else
  1602. ret=false
  1603. echo "failed"
  1604. fi
  1605. done
  1606. sort -uo $file{,} > /dev/null 2>&1
  1607. do_hide_all_sharedlibs
  1608. $ret
  1609. )
  1610. do_pacman_remove() (
  1611. ret=true
  1612. prefix=$MINGW_PACKAGE_PREFIX-
  1613. file=/etc/pac-mingw-extra.pk
  1614. pkgs=()
  1615. while true; do
  1616. case "$1" in
  1617. -m)
  1618. prefix=
  1619. file=/etc/pac-msys-extra.pk
  1620. shift
  1621. ;;
  1622. *) break ;;
  1623. esac
  1624. done
  1625. for pkg; do
  1626. for line in $(do_pacman_resolve_pkgs "$pkg"); do
  1627. if is_pkg_installed "$line"; then
  1628. pkgs+=("$line")
  1629. fi
  1630. done
  1631. done
  1632. for pkg in "${pkgs[@]}"; do
  1633. sed -i "/^${pkg}$/d" "$file" > /dev/null 2>&1
  1634. do_simple_print -n "Uninstalling $pkg... "
  1635. do_hide_pacman_sharedlibs "$prefix$pkg" revert
  1636. if pacman -Rs --noconfirm --ask=20 "$prefix$pkg" > /dev/null 2>&1; then
  1637. echo "done"
  1638. else
  1639. ret=false
  1640. pacman -D --asdeps "$prefix$pkg" > /dev/null 2>&1
  1641. echo "failed"
  1642. fi
  1643. done
  1644. sort -uo "$file"{,} > /dev/null 2>&1
  1645. do_hide_all_sharedlibs
  1646. $ret
  1647. )
  1648. do_prompt() {
  1649. # from http://superuser.com/a/608509
  1650. while read -r -s -e -t 0.1; do :; done
  1651. read -r -p "$1" ret
  1652. }
  1653. do_autoreconf() {
  1654. extra_script pre autoreconf
  1655. log "autoreconf" autoreconf -fiv "$@"
  1656. extra_script post autoreconf
  1657. }
  1658. do_autoupdate() {
  1659. extra_script pre autoupdate
  1660. log "autoupdate" autoupdate "$@"
  1661. extra_script post autoupdate
  1662. }
  1663. do_autogen() {
  1664. extra_script pre autogen
  1665. log "autogen" ./autogen.sh "$@"
  1666. extra_script post autogen
  1667. }
  1668. get_first_subdir() {
  1669. local subdir="${PWD#*$LOCALBUILDDIR/}" fullpath=false OPTION OPTIND
  1670. while getopts ':f' OPTION; do
  1671. case "$OPTION" in
  1672. f) fullpath=true ;;
  1673. *) break ;;
  1674. esac
  1675. done
  1676. shift "$((OPTIND - 1))"
  1677. if [[ $subdir != "$PWD" ]]; then
  1678. $fullpath && printf '%s' "$LOCALBUILDDIR/"
  1679. echo "${subdir%%/*}"
  1680. else
  1681. $fullpath && echo "$PWD" || echo "."
  1682. fi
  1683. }
  1684. clean_html_index() {
  1685. local url="$1"
  1686. local filter="${2:-(?<=href=\")[^\"]+\.(tar\.(gz|bz2|xz)|7z)}"
  1687. "${curl_opts[@]}" -l "$url" | grep -ioP "$filter" | sort -uV
  1688. }
  1689. get_last_version() {
  1690. local filelist="$1"
  1691. local filter="$2"
  1692. local version="$3"
  1693. local ret
  1694. ret="$(grep -E "$filter" <<< "$filelist" | sort -V | tail -1)"
  1695. [[ -n $version ]] && ret="$(grep -oP "$version" <<< "$ret")"
  1696. echo "$ret"
  1697. }
  1698. create_debug_link() {
  1699. for file; do
  1700. if [[ -f $file && ! -f "$file".debug ]]; then
  1701. echo "Stripping and creating debug link for ${file##*/}..."
  1702. objcopy --only-keep-debug "$file" "$file".debug
  1703. if [[ ${file: -3} == "dll" ]]; then
  1704. strip --strip-debug "$file"
  1705. else
  1706. strip --strip-all "$file"
  1707. fi
  1708. objcopy --add-gnu-debuglink="$file".debug "$file"
  1709. fi
  1710. done
  1711. }
  1712. # do_dlltool lib.a a.def
  1713. do_dlltool() (
  1714. if dlltool --help | grep -q llvm; then
  1715. # llvm's dlltool does not support delay import libraries.
  1716. # Until I can find a better way than just injecting `-Wl,--delayload=a.dll` into the LDFLAGS,
  1717. # ignore them for now.
  1718. exec llvm-dlltool -k -l "$1" -d "$2"
  1719. fi
  1720. exec dlltool -k -y "$1" -d "$2" -A
  1721. )
  1722. get_vs_prefix() {
  1723. unset vsprefix
  1724. local winvsprefix
  1725. local regkey="/HKLM/software/vapoursynth/path"
  1726. local embedded
  1727. embedded="$(find "$LOCALDESTDIR"/bin-video -iname vspipe.exe)"
  1728. if [[ -n $embedded ]]; then
  1729. # look for .dlls in bin-video
  1730. vsprefix="${embedded%/*}"
  1731. elif [[ $bits == 64bit ]] && winvsprefix="$(regtool -q get "$regkey")"; then
  1732. # check in native HKLM for installed VS (R31+)
  1733. [[ -n $winvsprefix && -f "$winvsprefix/core64/vspipe.exe" ]] &&
  1734. vsprefix="$(cygpath -u "$winvsprefix")/core64"
  1735. elif winvsprefix="$(regtool -qW get "$regkey")"; then
  1736. # check in 32-bit registry for installed VS
  1737. [[ -n $winvsprefix && -f "$winvsprefix/core${bits%bit}/vspipe.exe" ]] &&
  1738. vsprefix="$(cygpath -u "$winvsprefix/core${bits%bit}")"
  1739. elif [[ -n $(command -v vspipe.exe 2> /dev/null) ]]; then
  1740. # last resort, check if vspipe is in path
  1741. vsprefix="$(dirname "$(command -v vspipe.exe)")"
  1742. fi
  1743. if [[ -n $vsprefix && -f "$vsprefix/vapoursynth.dll" && -f "$vsprefix/vsscript.dll" ]]; then
  1744. local bitness
  1745. bitness="$(file "$vsprefix/vapoursynth.dll")"
  1746. { [[ $bits == 64bit && $bitness == *x86-64* ]] ||
  1747. [[ $bits == 32bit && $bitness == *80386* ]]; } &&
  1748. return 0
  1749. else
  1750. return 1
  1751. fi
  1752. }
  1753. get_cl_path() {
  1754. { type cl.exe && cl --help; } > /dev/null 2>&1 && return 0
  1755. local _suite_vswhere=/opt/bin/vswhere.exe _sys_vswhere
  1756. if _sys_vswhere=$(cygpath -u "$(cygpath -F 0x002a)/Microsoft Visual Studio/Installer/vswhere.exe") &&
  1757. "$_sys_vswhere" -help > /dev/null 2>&1; then
  1758. vswhere=$_sys_vswhere
  1759. elif [[ -e $_suite_vswhere ]] &&
  1760. $_suite_vswhere -help > /dev/null 2>&1; then
  1761. vswhere=$_suite_vswhere
  1762. elif (
  1763. cd "$LOCALBUILDDIR" 2> /dev/null || return 1
  1764. do_wget -c -r -q "https://github.com/Microsoft/vswhere/releases/latest/download/vswhere.exe"
  1765. ./vswhere.exe -help > /dev/null 2>&1 || return 1
  1766. do_install vswhere.exe /opt/bin/
  1767. ); then
  1768. vswhere=$_suite_vswhere
  1769. else
  1770. return 1
  1771. fi
  1772. local _hostbits=HostX64 _arch=x64
  1773. [[ $(uname -m) != x86_64 ]] && _hostbits=HostX86
  1774. [[ $bits == 32bit ]] && _arch=x86
  1775. local basepath
  1776. if basepath=$(cygpath -u "$("$vswhere" -latest -all -find "VC/Tools/MSVC/*/bin/${_hostbits:-HostX64}/${_arch:-x64}" | sort -uV | tail -1)") &&
  1777. "$basepath/cl.exe" /? > /dev/null 2>&1; then
  1778. export PATH="$basepath:$PATH"
  1779. return 0
  1780. else
  1781. return 1
  1782. fi
  1783. }
  1784. get_java_home() {
  1785. local javahome version
  1786. local javabasereg="/HKLM/software/javasoft"
  1787. local regkey="$javabasereg/java development kit"
  1788. export JAVA_HOME=
  1789. export JDK_HOME=""
  1790. if ! regtool -q check "$regkey"; then
  1791. echo "no version of JDK found"
  1792. return
  1793. fi
  1794. version="$(regtool -q get "$regkey/CurrentVersion")"
  1795. [[ $(vercmp "$version" 1.8) != 0 ]] &&
  1796. echo "JDK 1.8 required, 9 doesn't work" && return
  1797. javahome="$(regtool -q get "$regkey/$version/JavaHome")"
  1798. javahome="$(cygpath -u "$javahome")"
  1799. [[ -f "$javahome/bin/java.exe" ]] &&
  1800. export JAVA_HOME="$javahome"
  1801. }
  1802. # can only retrieve the dll version if it's actually in the ProductVersion field
  1803. get_dll_version() (
  1804. dll=$1
  1805. [[ -f $dll ]] || return 1
  1806. version="$(7z l "$dll" | grep 'ProductVersion:' | sed 's/.*ProductVersion: //')"
  1807. [[ -n $version ]] || return 1
  1808. echo "$version"
  1809. )
  1810. get_api_version() {
  1811. local header="$1"
  1812. [[ -n $(file_installed "$header") ]] && header="$(file_installed "$header")"
  1813. local line="$2"
  1814. local column="$3"
  1815. [[ ! -f $header ]] && printf '' && return
  1816. grep "${line:-VERSION}" "$header" | awk '{ print $c }' c="${column:-3}" | sed 's|"||g'
  1817. }
  1818. hide_files() {
  1819. local reverse=false echo_cmd
  1820. [[ $1 == "-R" ]] && reverse=true && shift
  1821. [[ $dryrun == y ]] && echo_cmd="echo"
  1822. for opt; do
  1823. if ! $reverse; then
  1824. [[ -f $opt ]] && $echo_cmd mv -f "$opt" "$opt.bak"
  1825. else
  1826. [[ -f "$opt.bak" ]] && $echo_cmd mv -f "$opt.bak" "$opt"
  1827. fi
  1828. done
  1829. }
  1830. hide_conflicting_libs() {
  1831. # meant for rude build systems
  1832. local reverse=false
  1833. [[ $1 == "-R" ]] && reverse=true && shift
  1834. local priority_prefix
  1835. local -a installed
  1836. mapfile -t installed < <(find "$LOCALDESTDIR/lib" -maxdepth 1 -name "*.a")
  1837. if ! $reverse; then
  1838. hide_files "${installed[@]//$LOCALDESTDIR/$MINGW_PREFIX}"
  1839. else
  1840. hide_files -R "${installed[@]//$LOCALDESTDIR/$MINGW_PREFIX}"
  1841. fi
  1842. if [[ -n $1 ]]; then
  1843. priority_prefix="$1"
  1844. mapfile -t installed < <(find "$priority_prefix/lib" -maxdepth 1 -name "*.a")
  1845. if ! $reverse; then
  1846. hide_files "${installed[@]//$1/$LOCALDESTDIR}"
  1847. else
  1848. hide_files -R "${installed[@]//$1/$LOCALDESTDIR}"
  1849. fi
  1850. fi
  1851. }
  1852. hide_libressl() {
  1853. local _hide_files=(include/openssl
  1854. lib/lib{crypto,ssl,tls}.{,l}a
  1855. lib/pkgconfig/openssl.pc
  1856. lib/pkgconfig/lib{crypto,ssl,tls}.pc)
  1857. local reverse=n
  1858. local _f
  1859. [[ $1 == "-R" ]] && reverse=y && shift
  1860. for _f in ${_hide_files[*]}; do
  1861. _f="$LOCALDESTDIR/$_f"
  1862. if [[ $reverse == n ]]; then
  1863. [[ -e $_f ]] && mv -f "$_f" "$_f.bak"
  1864. else
  1865. [[ -e "$_f.bak" ]] && mv -f "$_f.bak" "$_f"
  1866. fi
  1867. done
  1868. }
  1869. add_to_remove() {
  1870. echo "${1:-$(get_first_subdir -f)}" >> "$LOCALBUILDDIR/_to_remove"
  1871. }
  1872. clean_suite() {
  1873. do_simple_print -p "${orange}Deleting status files...${reset}"
  1874. cd_safe "$LOCALBUILDDIR" > /dev/null
  1875. find . -maxdepth 2 -name recently_updated -delete
  1876. find . -maxdepth 2 -regex ".*build_successful\(32\|64\)bit\(_\\w+\)?\$" -delete
  1877. echo -e "\\n\\t${green}Zipping man files...${reset}"
  1878. do_zipman
  1879. if [[ $deleteSource == y ]]; then
  1880. echo -e "\\t${orange}Deleting temporary build dirs...${reset}"
  1881. find . -maxdepth 5 -name "ab-suite.*.log" -delete
  1882. find . -maxdepth 5 -type d -name "build-*bit" -exec rm -rf {} +
  1883. find . -maxdepth 2 -type d -name "build" -exec test -f "{}/CMakeCache.txt" ';' -exec rm -rf {} ';'
  1884. if [[ -f _to_remove ]]; then
  1885. echo -e "\\n\\t${orange}Deleting source folders...${reset}"
  1886. grep -E "^($LOCALBUILDDIR|/trunk$LOCALBUILDDIR)" < _to_remove |
  1887. grep -Ev "^$LOCALBUILDDIR/(patches|extras|$)" | sort -u | xargs -r rm -rf
  1888. fi
  1889. if [[ $(du -s /var/cache/pacman/pkg/ | cut -f1) -gt 1000000 ]]; then
  1890. echo -e "\\t${orange}Deleting unneeded Pacman packages...${reset}"
  1891. pacman -Sc --noconfirm
  1892. fi
  1893. fi
  1894. rm -f {firstrun,firstUpdate,secondUpdate,pacman,mingw32,mingw64}.log diagnostics.txt \
  1895. logs.zip _to_remove ./*.stripped.log
  1896. [[ -f last_run ]] && mv last_run last_successful_run && touch last_successful_run
  1897. [[ -f CHANGELOG.txt ]] && cat CHANGELOG.txt >> newchangelog
  1898. unix2dos -n newchangelog CHANGELOG.txt 2> /dev/null && rm -f newchangelog
  1899. }
  1900. create_diagnostic() (
  1901. cmds=("uname -a" "pacman -Qe" "pacman -Qd")
  1902. envs=(MINGW_{PACKAGE_PREFIX,CHOST,PREFIX} MSYSTEM CPATH
  1903. LIBRARY_PATH {LD,C,CPP,CXX}FLAGS PATH)
  1904. do_print_progress " Creating diagnostics file"
  1905. git -C /trunk rev-parse --is-inside-work-tree > /dev/null 2>&1 &&
  1906. cmds+=("git -C /trunk log -1 --pretty=%h")
  1907. {
  1908. echo "Env variables:"
  1909. for _env in "${envs[@]}"; do
  1910. declare -p "$_env" 2> /dev/null
  1911. done
  1912. for cmd in "${cmds[@]}"; do
  1913. echo
  1914. (set -x; $cmd)
  1915. done
  1916. } > "$LOCALBUILDDIR/diagnostics.txt" 2>&1
  1917. )
  1918. create_winpty_exe() {
  1919. local exename="$1"
  1920. local installdir="$2"
  1921. shift 2
  1922. [[ -f "${installdir}/${exename}".exe ]] && mv "${installdir}/${exename}"{.,_}exe
  1923. # shellcheck disable=SC2016
  1924. printf '%s\n' "#!/usr/bin/env bash" "$@" \
  1925. 'if [[ -t 1 ]]; then' \
  1926. '/usr/bin/winpty "$( dirname ${BASH_SOURCE[0]} )/'"${exename}"'.exe" "$@"' \
  1927. 'else "$( dirname ${BASH_SOURCE[0]} )/'"${exename}"'.exe" "$@"; fi' \
  1928. > "${installdir}/${exename}"
  1929. [[ -f "${installdir}/${exename}"_exe ]] && mv "${installdir}/${exename}"{_,.}exe
  1930. }
  1931. create_ab_pkgconfig() {
  1932. # from https://stackoverflow.com/a/8088167
  1933. local script_file
  1934. IFS=$'\n' read -r -d '' script_file << 'EOF' || true
  1935. #!/bin/sh
  1936. while true; do
  1937. case $1 in
  1938. --libs|--libs-*) libs_args+=" $1"; shift ;;
  1939. --static) static="--static"; shift ;;
  1940. --* ) base_args+=" $1"; shift ;;
  1941. * ) break ;;
  1942. esac
  1943. done
  1944. [[ -n $PKGCONF_STATIC ]] && static="--static"
  1945. run_pkgcfg() {
  1946. "$MINGW_PREFIX/bin/pkgconf" --keep-system-libs --keep-system-cflags "$@" || exit 1
  1947. }
  1948. deduplicateLibs() {
  1949. otherflags="$(run_pkgcfg $static $base_args "$@")"
  1950. unordered="$(run_pkgcfg $static $libs_args "$@")"
  1951. libdirs="$(printf '%s\n' $unordered | grep '^-L' | tr '\n' ' ')"
  1952. unordered="${unordered//$libdirs}"
  1953. ord_libdirs=""
  1954. for libdir in $libdirs; do
  1955. libdir="$(cygpath -m ${libdir#-L})"
  1956. ord_libdirs+=" -L$libdir"
  1957. done
  1958. ord_libdirs="$(printf '%s\n' $ord_libdirs | awk '!x[$0]++' | tr '\n' ' ')"
  1959. ord_libs="$(printf '%s\n' $unordered | tac | awk '!x[$0]++' | tac | tr '\n' ' ')"
  1960. printf '%s ' $otherflags $ord_libdirs $ord_libs
  1961. echo
  1962. }
  1963. if [[ -n $libs_args ]]; then
  1964. deduplicateLibs "$@"
  1965. else
  1966. run_pkgcfg $static $base_args $libs_args "$@"
  1967. fi
  1968. EOF
  1969. mkdir -p "$LOCALDESTDIR"/bin > /dev/null 2>&1
  1970. [[ -f "$LOCALDESTDIR"/bin/ab-pkg-config ]] &&
  1971. diff -q <(printf '%s' "$script_file") "$LOCALDESTDIR"/bin/ab-pkg-config > /dev/null ||
  1972. printf '%s' "$script_file" > "$LOCALDESTDIR"/bin/ab-pkg-config
  1973. [[ -f "$LOCALDESTDIR"/bin/ab-pkg-config.bat ]] ||
  1974. printf '%s\r\n' "@echo off" "" "bash $LOCALDESTDIR/bin/ab-pkg-config %*" > "$LOCALDESTDIR"/bin/ab-pkg-config.bat
  1975. [[ -f "$LOCALDESTDIR"/bin/ab-pkg-config-static.bat ]] ||
  1976. printf '%s\r\n' "@echo off" "" "bash $LOCALDESTDIR/bin/ab-pkg-config --static %*" > "$LOCALDESTDIR"/bin/ab-pkg-config-static.bat
  1977. }
  1978. create_ab_ccache() {
  1979. local bin temp_file ccache_path=false ccache_win_path=
  1980. temp_file=$(mktemp)
  1981. if [[ $ccache == y ]] && type ccache > /dev/null 2>&1; then
  1982. ccache_path="$(command -v ccache)"
  1983. ccache_win_path=$(cygpath -m "$ccache_path")
  1984. fi
  1985. mkdir -p "$LOCALDESTDIR"/bin > /dev/null 2>&1
  1986. for bin in {$MINGW_CHOST-,}{gcc,g++} clang{,++} cc cpp c++; do
  1987. type "$bin" > /dev/null 2>&1 || continue
  1988. cat << EOF > "$temp_file"
  1989. @echo off >nul 2>&1
  1990. rem() { "\$@"; }
  1991. rem test -f nul && rm nul
  1992. rem $ccache_path --help > /dev/null 2>&1 && $ccache_path $(command -v $bin) "\$@" || $(command -v $bin) "\$@"
  1993. rem exit \$?
  1994. $ccache_win_path $(cygpath -m "$(command -v $bin)") %*
  1995. EOF
  1996. diff -q "$temp_file" "$LOCALDESTDIR/bin/$bin.bat" > /dev/null 2>&1 || cp -f "$temp_file" "$LOCALDESTDIR/bin/$bin.bat"
  1997. chmod +x "$LOCALDESTDIR/bin/$bin.bat"
  1998. done
  1999. rm "$temp_file"
  2000. }
  2001. create_cmake_toolchain() {
  2002. local _win_paths mingw_path
  2003. _win_paths=$(cygpath -pm "$LOCALDESTDIR:$MINGW_PREFIX:$MINGW_PREFIX/$MINGW_CHOST")
  2004. mingw_path=$(cygpath -m "$MINGW_PREFIX/include")
  2005. local toolchain_file=(
  2006. "SET(CMAKE_RC_COMPILER_INIT windres)"
  2007. ""
  2008. "LIST(APPEND CMAKE_PROGRAM_PATH \"$(cygpath -m "$LOCALDESTDIR/bin")\")"
  2009. "SET(CMAKE_PREFIX_PATH \"$_win_paths\")"
  2010. "SET(CMAKE_FIND_ROOT_PATH \"$_win_paths\")"
  2011. "SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)"
  2012. "SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)"
  2013. "SET(CMAKE_BUILD_TYPE Release)"
  2014. )
  2015. mkdir -p "$LOCALDESTDIR"/etc > /dev/null 2>&1
  2016. [[ -f "$LOCALDESTDIR"/etc/toolchain.cmake ]] &&
  2017. diff -q <(printf '%s\n' "${toolchain_file[@]}") "$LOCALDESTDIR"/etc/toolchain.cmake > /dev/null ||
  2018. printf '%s\n' "${toolchain_file[@]}" > "$LOCALDESTDIR"/etc/toolchain.cmake
  2019. }
  2020. do_fix_pkgconfig_abspaths() {
  2021. # in case the root was moved, this fixes windows abspaths
  2022. mkdir -p "$LOCALDESTDIR/lib/pkgconfig"
  2023. # pkgconfig keys to find the wrong abspaths from
  2024. local _keys="(prefix|exec_prefix|libdir|includedir)"
  2025. # current abspath root
  2026. local _root
  2027. _root=$(cygpath -m "$LOCALDESTDIR")
  2028. # find .pc files with Windows abspaths
  2029. grep -ElZR "${_keys}=[^/$].*" "$LOCALDESTDIR"/lib/pkgconfig | \
  2030. # find those with a different abspath than the current
  2031. xargs -0r grep -LZ "$_root" | \
  2032. # replace with current abspath
  2033. xargs -0r sed -ri "s;${_keys}=.*$LOCALDESTDIR;\1=$_root;g"
  2034. }
  2035. do_clean_old_builds() {
  2036. local _old_libs=(j{config,error,morecfg,peglib}.h
  2037. lib{jpeg,nettle,gnurx,regex}.{,l}a
  2038. lib{opencore-amr{nb,wb},twolame,theora{,enc,dec},caca,magic,uchardet}.{,l}a
  2039. libSDL{,main}.{,l}a libopen{jpwl,mj2,jp2}.{a,pc}
  2040. include/{nettle,opencore-amr{nb,wb},theora,cdio,SDL,openjpeg-2.{1,2},luajit-2.0,uchardet,wels}
  2041. regex.h magic.h
  2042. {nettle,vo-aacenc,sdl,uchardet}.pc
  2043. {opencore-amr{nb,wb},twolame,theora{,enc,dec},caca,dcadec,libEGL,openh264}.pc
  2044. libcdio_{cdda,paranoia}.{{,l}a,pc}
  2045. twolame.h bin-audio/{twolame,cd-paranoia}.exe
  2046. bin-global/{{file,uchardet}.exe,sdl-config,luajit-2.0.4.exe}
  2047. libebur128.a ebur128.h
  2048. libopenh264.a
  2049. liburiparser.{{,l}a,pc}
  2050. libchromaprint.{a,pc} chromaprint.h
  2051. bin-global/libgcrypt-config libgcrypt.a gcrypt.h
  2052. lib/libgcrypt.def bin-global/{dumpsexp,hmac256,mpicalc}.exe
  2053. crossc.{h,pc} libcrossc.a
  2054. include/onig{uruma,gnu,posix}.h libonig.a oniguruma.pc
  2055. )
  2056. do_uninstall q all "${_old_libs[@]}"
  2057. }
  2058. grep_or_sed() {
  2059. local grep_re="$1"
  2060. local grep_file="$2"
  2061. [[ ! -f $grep_file ]] && return
  2062. local sed_re="$3"
  2063. shift 3
  2064. local sed_files=("$grep_file")
  2065. [[ -n $1 ]] && sed_files=("$@")
  2066. grep -q -- "$grep_re" "$grep_file" ||
  2067. sed -ri -- "$sed_re" "${sed_files[@]}"
  2068. }
  2069. grep_and_sed() {
  2070. local grep_re="$1"
  2071. local grep_file="$2"
  2072. [[ ! -f $grep_file ]] && return
  2073. local sed_re="$3"
  2074. shift 3
  2075. local sed_files=("$grep_file")
  2076. [[ -n $1 ]] && sed_files=("$@")
  2077. grep -q -- "$grep_re" "$grep_file" &&
  2078. sed -ri -- "$sed_re" "${sed_files[@]}"
  2079. }
  2080. fix_cmake_crap_exports() {
  2081. local _dir="$1"
  2082. # noop if passed directory is not valid
  2083. test -d "$_dir" || return 1
  2084. local _mixeddestdir _oldDestDir _cmakefile
  2085. declare -a _cmakefiles
  2086. _mixeddestdir="$(cygpath -m "$LOCALDESTDIR")"
  2087. mapfile -t _cmakefiles < <(grep -Plr '\w:/[\w/]*local(?:32|64)' "$_dir"/*.cmake)
  2088. # noop if array is empty
  2089. test ${#_cmakefiles[@]} -lt 1 && return
  2090. for _cmakefile in "${_cmakefiles[@]}"; do
  2091. # find at least one
  2092. _oldDestDir="$(grep -oP -m1 '\w:/[\w/]*local(?:32|64)' "$_cmakefile")"
  2093. # noop if there's no expected install prefix found
  2094. [[ -z $_oldDestDir ]] && continue
  2095. # noop if old and current install prefix are equal
  2096. [[ $_mixeddestdir == "$_oldDestDir" ]] && continue
  2097. # use perl for the matching and replacing, a bit simpler than with sed
  2098. perl -i -p -e 's;([A-Z]:/.*?)local(?:32|64);'"$_mixeddestdir"'\2;' "$_cmakefile"
  2099. done
  2100. }
  2101. verify_cuda_deps() {
  2102. enabled cuda-sdk && do_removeOption --enable-cuda-sdk && do_addOption --enable-cuda-nvcc
  2103. if enabled_any libnpp cuda-nvcc && [[ $license != "nonfree" ]]; then
  2104. do_removeOption "--enable-(cuda-nvcc|libnpp)"
  2105. fi
  2106. if enabled libnpp && [[ $bits == 32bit ]]; then
  2107. echo -e "${orange}libnpp is only supported in 64-bit.${reset}"
  2108. do_removeOption --enable-libnpp
  2109. fi
  2110. if enabled_any libnpp cuda-nvcc && [[ -z $CUDA_PATH || ! -d $CUDA_PATH ]]; then
  2111. echo -e "${orange}CUDA_PATH environment variable not set or directory does not exist.${reset}"
  2112. do_removeOption "--enable-(cuda-nvcc|libnpp)"
  2113. fi
  2114. if enabled libnpp && [[ ! -f "$CUDA_PATH/lib/x64/nppc.lib" ]]; then
  2115. do_removeOption --enable-libnpp
  2116. fi
  2117. if enabled cuda-llvm && do_pacman_install clang; then
  2118. do_removeOption --enable-cuda-nvcc
  2119. else
  2120. do_removeOption --enable-cuda-llvm
  2121. if ! disabled autodetect; then
  2122. do_addOption --disable-cuda-llvm
  2123. fi
  2124. fi
  2125. if enabled cuda-nvcc; then
  2126. if ! get_cl_path; then
  2127. echo -e "${orange}MSVC cl.exe not found in PATH or through vswhere; needed by nvcc.${reset}"
  2128. do_removeOption --enable-cuda-nvcc
  2129. elif enabled cuda-nvcc && ! nvcc.exe --help &> /dev/null &&
  2130. ! "$(cygpath -sm "$CUDA_PATH")/bin/nvcc.exe" --help &> /dev/null; then
  2131. echo -e "${orange}nvcc.exe not found in PATH or installed in CUDA_PATH.${reset}"
  2132. do_removeOption --enable-cuda-nvcc
  2133. fi
  2134. fi
  2135. enabled_any libnpp cuda-nvcc || ! disabled cuda-llvm
  2136. }
  2137. check_custom_patches() {
  2138. local _basedir=$1 vcsFolder=${1%-*}
  2139. if [[ -z $1 ]]; then
  2140. _basedir=$(get_first_subdir)
  2141. vcsFolder=${_basedir%-*}
  2142. fi
  2143. [[ -f $LOCALBUILDDIR/${vcsFolder}_extra.sh ]] || return
  2144. export REPO_DIR=$LOCALBUILDDIR/$_basedir
  2145. export REPO_NAME=$vcsFolder
  2146. do_print_progress " Found ${vcsFolder}_extra.sh. Sourcing script"
  2147. source "$LOCALBUILDDIR/${vcsFolder}_extra.sh"
  2148. echo "$vcsFolder" >> "$LOCALBUILDDIR/patchedFolders"
  2149. sort -uo "$LOCALBUILDDIR/patchedFolders"{,}
  2150. }
  2151. extra_script() {
  2152. local stage="$1"
  2153. local commandname="$2"
  2154. local vcsFolder="${REPO_DIR%-*}"
  2155. vcsFolder="${vcsFolder#*build/}"
  2156. if [[ $commandname =~ ^(make|ninja)$ ]] &&
  2157. type "_${stage}_build" > /dev/null 2>&1; then
  2158. pushd "${REPO_DIR}" > /dev/null 2>&1 || true
  2159. do_print_progress "Running ${stage} build from ${vcsFolder}_extra.sh"
  2160. log -q "${stage}_build" "_${stage}_build"
  2161. popd > /dev/null 2>&1 || true
  2162. elif type "_${stage}_${commandname}" > /dev/null 2>&1; then
  2163. pushd "${REPO_DIR}" > /dev/null 2>&1 || true
  2164. do_print_progress "Running ${stage} ${commandname} from ${vcsFolder}_extra.sh"
  2165. log -q "${stage}_${commandname}" "_${stage}_${commandname}"
  2166. popd > /dev/null 2>&1 || true
  2167. fi
  2168. }
  2169. unset_extra_script() {
  2170. # The current repository folder (/build/ffmpeg-git)
  2171. unset REPO_DIR
  2172. # The repository name (ffmpeg)
  2173. unset REPO_NAME
  2174. # Should theoretically be the same as REPO_NAME with
  2175. unset vcsFolder
  2176. # Each of the _{pre,post}_<Command> means that there is a "_pre_<Command>"
  2177. # and "_post_<Command>"
  2178. # Runs before cloning or fetching a git repo and after
  2179. unset _{pre,post}_vcs
  2180. # Runs before and after building rust packages (do_rust)
  2181. unset _{pre,post}_rust
  2182. ## Pregenerational hooks
  2183. # Runs before and after running autoreconf -fiv (do_autoreconf)
  2184. unset _{pre,post}_autoreconf
  2185. # Runs before and after running ./autogen.sh (do_autogen)
  2186. unset _{pre,post}_autogen
  2187. # Generational hooks
  2188. # Runs before and after running ./configure (do_separate_conf, do_configure)
  2189. unset _{pre,post}_configure
  2190. # Runs before and after running cmake (do_cmake)
  2191. unset _{pre,post}_cmake
  2192. ## Build hooks
  2193. # Runs before and after runing make (do_make)
  2194. unset _{pre,post}_make
  2195. # Runs before and after running meson (do_meson)
  2196. unset _{pre,post}_meson
  2197. # Runs before and after running ninja (do_ninja)
  2198. unset _{pre,post}_ninja
  2199. unset _{pre,post}_qmake
  2200. # Runs before and after running make, meson, ninja, and waf (Generic hook for the previous build hooks)
  2201. # If this is present, it will override the other hooks
  2202. # Use for mpv and python waf based stuff.
  2203. unset _{pre,post}_build
  2204. ## Post build hooks
  2205. # Runs before and after either ninja install
  2206. # or make install or using install
  2207. # (do_makeinstall, do_ninjainstall, do_install)
  2208. unset _{pre,post}_install
  2209. }
  2210. create_extra_skeleton() {
  2211. local overwrite
  2212. while true; do
  2213. case $1 in
  2214. -f) overwrite=y && shift ;;
  2215. --)
  2216. shift
  2217. break
  2218. ;;
  2219. *) break ;;
  2220. esac
  2221. done
  2222. local extraName="$1"
  2223. [[ -z $extraName ]] &&
  2224. printf '%s\n' \
  2225. 'Usage: create_extra_skeleton [-f] <vcs folder name without the vcs type suffix>' \
  2226. 'For example, to create a ffmpeg_extra.sh skeleton file in '"$LOCALBUILDDIR"':' \
  2227. '> create_extra_skeleton ffmpeg' && return 1
  2228. [[ -f "$LOCALBUILDDIR/$extraName"_extra.sh && -z $overwrite ]] &&
  2229. echo "$LOCALBUILDDIR/$extraName_extra.sh already exists. Use -f if you are sure you want to overwrite it." && return 1
  2230. IFS=$'\n' read -r -d '' script_file << 'EOF' || true
  2231. #!/bin/bash
  2232. # Force to the suite to think the package has updates to recompile.
  2233. # Alternatively, you can use "touch recompile" for a similar effect.
  2234. #touch custom_updated
  2235. # Commands to run before and after cloning a repo
  2236. _pre_vcs() {
  2237. # ref changes the branch/commit/tag that you want to clone
  2238. ref=research
  2239. }
  2240. # Commands to run before and after running cmake (do_cmake)
  2241. _pre_cmake(){
  2242. # Installs libwebp
  2243. #do_pacman_install libwebp
  2244. # Downloads the patch and then applies the patch
  2245. #do_patch "https://gist.githubusercontent.com/1480c1/9fa9292afedadcea2b3a3e067e96dca2/raw/50a3ed39543d3cf21160f9ad38df45d9843d8dc5/0001-Example-patch-for-learning-purpose.patch"
  2246. # Change directory to the build folder
  2247. #cd_safe "build-${bits}"
  2248. # Add additional options to suite's cmake execution
  2249. #cmake_extras=(-DENABLE_SWEET_BUT_BROKEN_FEATURE=on)
  2250. # To bypass the suite's cmake execution completely, create a do_not_reconfigure file in the repository root:
  2251. #touch "$(get_first_subdir -f)/do_not_reconfigure"
  2252. true
  2253. }
  2254. _post_cmake(){
  2255. # Run cmake directly with custom options. $LOCALDESTDIR refers to local64 or local32
  2256. #cmake .. -G"Ninja" -DCMAKE_INSTALL_PREFIX="$LOCALDESTDIR" \
  2257. # -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang \
  2258. # -DBUILD_SHARED_LIBS=off -DENABLE_TOOLS=off
  2259. true
  2260. }
  2261. # Runs before and after building rust packages (do_rust)
  2262. _pre_rust() {
  2263. # Add additional options to suite's rust (cargo) execution
  2264. #rust_extras=(--no-default-features --features=binaries)
  2265. # To bypass the suite's cargo execution completely, create a do_not_reconfigure file in the repository root:
  2266. #touch "$(get_first_subdir -f)/do_not_reconfigure"
  2267. true
  2268. }
  2269. _post_rust() {
  2270. true
  2271. }
  2272. # Runs before and after running meson (do_meson)
  2273. _pre_meson() {
  2274. # Add additional options to suite's rust (cargo) execution
  2275. #meson_extras=(-Denable_tools=true)
  2276. # To bypass the suite's meson execution completely, create a do_not_reconfigure file in the repository root:
  2277. #touch "$(get_first_subdir -f)/do_not_reconfigure"
  2278. true
  2279. }
  2280. _post_meson() {
  2281. true
  2282. }
  2283. # Runs before and after running autoreconf -fiv (do_autoreconf)
  2284. _pre_autoreconf() {
  2285. true
  2286. }
  2287. _post_autoreconf() {
  2288. true
  2289. }
  2290. # Runs before and after running ./autogen.sh (do_autogen)
  2291. _pre_autogen() {
  2292. true
  2293. }
  2294. _post_autogen() {
  2295. true
  2296. }
  2297. # Commands to run before and after running configure on a Autoconf/Automake/configure-using package
  2298. _pre_configure(){
  2299. true
  2300. #
  2301. # Apply a patch from ffmpeg's patchwork site.
  2302. #do_patch "https://patchwork.ffmpeg.org/patch/12563/mbox/" am
  2303. #
  2304. # Apply a local patch inside the directory where is "ffmpeg_extra.sh"
  2305. #patch -p1 -i "$LOCALBUILDDIR/ffmpeg-0001-my_patch.patch"
  2306. #
  2307. # Add extra configure options to ffmpeg (ffmpeg specific)
  2308. # If you want to add something to ffmpeg not within the suite already
  2309. # you will need to install it yourself, either through pacman
  2310. # or compiling from source.
  2311. #FFMPEG_OPTS+=(--enable-libsvthevc)
  2312. #
  2313. }
  2314. _post_configure(){
  2315. true
  2316. }
  2317. # Runs before and after runing make (do_make)
  2318. _pre_make(){
  2319. # To bypass the suite's make execution completely, create a do_not_build file in the repository root:
  2320. #touch "$(get_first_subdir -f)/do_not_build"
  2321. true
  2322. }
  2323. _post_make(){
  2324. true
  2325. # Don't run configure again.
  2326. #touch "$(get_first_subdir -f)/do_not_reconfigure"
  2327. # Don't clean the build folder on each successive run.
  2328. # This is for if you want to keep the current build folder as is and just recompile only.
  2329. #touch "$(get_first_subdir -f)/do_not_clean"
  2330. }
  2331. # Runs before and after running ninja (do_ninja)
  2332. _pre_ninja() {
  2333. # To bypass the suite's ninja execution completely, create a do_not_build file in the repository root:
  2334. #touch "$(get_first_subdir -f)/do_not_build"
  2335. true
  2336. }
  2337. _post_ninja() {
  2338. true
  2339. }
  2340. # Runs before and after running make, meson, ninja, and waf (Generic hook for the previous build hooks)
  2341. # If this is present, it will override the other hooks
  2342. # Use for mpv and python waf based stuff.
  2343. _pre_build() {
  2344. # To bypass the suite's build execution completely, create a do_not_build file in the repository root:
  2345. #touch "$(get_first_subdir -f)/do_not_build"
  2346. true
  2347. }
  2348. _post_build() {
  2349. true
  2350. }
  2351. # Runs before and after either ninja install
  2352. # or make install or using install
  2353. # (do_makeinstall, do_ninjainstall, do_install)
  2354. _pre_install() {
  2355. # To bypass the suite's install completely, create a do_not_install file in the repository root:
  2356. #touch "$(get_first_subdir -f)/do_not_install"
  2357. true
  2358. }
  2359. _post_install() {
  2360. true
  2361. }
  2362. EOF
  2363. printf '%s' "$script_file" > "${LOCALBUILDDIR}/${extraName}_extra.sh"
  2364. echo "Created skeleton file ${LOCALBUILDDIR}/${extraName}_extra.sh"
  2365. }
  2366. # if you absolutely need to remove some of these,
  2367. # add a "-e '!<hardcoded rule>'" option
  2368. # ex: "-e '!/recently_updated'"
  2369. safe_git_clean() {
  2370. git clean -xfd \
  2371. -e "/build_successful*" \
  2372. -e "/recently_updated" \
  2373. -e '/custom_updated' \
  2374. -e '**/ab-suite.*.log' \
  2375. "${@}"
  2376. }