media-suite_helper.sh 86 KB

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