media-suite_helper.sh 85 KB

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