mirror of
https://github.com/levogevo/ffmpeg-builder.git
synced 2026-01-16 11:26:17 +00:00
Compare commits
36 Commits
dd07038ab7
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 38c160e2bd | |||
| 47e287ef7f | |||
| 691d0f857a | |||
| 3c3fc6164c | |||
| 1adcaa15a4 | |||
| 108561a002 | |||
| ff1b0c2304 | |||
| ff656d477f | |||
| 7ce42985e2 | |||
| 8feeccc46a | |||
| 87f65e48f4 | |||
| 200d4c4a6c | |||
| 71c7266661 | |||
| 69ada12884 | |||
| 30ddc39ed5 | |||
| 25093463af | |||
| 2356e05ad5 | |||
| 7419027a80 | |||
| 71a35d1320 | |||
| cf27104939 | |||
| fac5951fc9 | |||
| ff7921c45d | |||
| 65fb35877e | |||
| ad5b8e4482 | |||
| e6ab74c351 | |||
| 1b8c411458 | |||
| 5c9e97e0a2 | |||
| 687a8473b5 | |||
| c07b52f5c2 | |||
| e1d5595b06 | |||
| c7c855a35a | |||
| 1b03235761 | |||
| 0b35c8b94a | |||
| c038798d2c | |||
| 23d05a8c3a | |||
| c399c008ba |
20
Jenkinsfile
vendored
20
Jenkinsfile
vendored
@@ -13,7 +13,9 @@ def withDockerCreds(body) {
|
|||||||
|
|
||||||
pipeline {
|
pipeline {
|
||||||
agent none
|
agent none
|
||||||
environment { DEBUG = "1" }
|
environment {
|
||||||
|
DEBUG = "1"
|
||||||
|
}
|
||||||
options { buildDiscarder logRotator(numToKeepStr: '4') }
|
options { buildDiscarder logRotator(numToKeepStr: '4') }
|
||||||
stages {
|
stages {
|
||||||
stage('build docker image') {
|
stage('build docker image') {
|
||||||
@@ -36,14 +38,16 @@ pipeline {
|
|||||||
stage('build ffmpeg on darwin') {
|
stage('build ffmpeg on darwin') {
|
||||||
matrix {
|
matrix {
|
||||||
axes {
|
axes {
|
||||||
axis { name 'OPT_LTO'; values 'OPT=0 LTO=OFF', 'OPT=3 LTO=ON' }
|
axis {
|
||||||
axis { name 'STATIC'; values 'ON', 'OFF' }
|
name 'COMP_OPTS';
|
||||||
|
values 'OPT=0 LTO=OFF STATIC=OFF', 'OPT=2 LTO=OFF STATIC=ON', 'OPT=3 LTO=ON STATIC=ON PGO=ON'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('build on darwin ') {
|
stage('build on darwin ') {
|
||||||
agent { label "darwin" }
|
agent { label "darwin" }
|
||||||
steps {
|
steps {
|
||||||
sh "${OPT_LTO} ./scripts/build.sh"
|
sh "${COMP_OPTS} ./scripts/build.sh"
|
||||||
archiveArtifacts allowEmptyArchive: true, artifacts: 'gitignore/package/*.tar.xz', defaultExcludes: false
|
archiveArtifacts allowEmptyArchive: true, artifacts: 'gitignore/package/*.tar.xz', defaultExcludes: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,15 +59,17 @@ pipeline {
|
|||||||
axes {
|
axes {
|
||||||
axis { name 'ARCH'; values 'armv8-a', 'x86-64-v3' }
|
axis { name 'ARCH'; values 'armv8-a', 'x86-64-v3' }
|
||||||
axis { name 'DISTRO'; values 'ubuntu', 'fedora', 'debian', 'archlinux' }
|
axis { name 'DISTRO'; values 'ubuntu', 'fedora', 'debian', 'archlinux' }
|
||||||
axis { name 'OPT_LTO'; values 'OPT=0 LTO=OFF', 'OPT=3 LTO=ON' }
|
axis {
|
||||||
axis { name 'STATIC'; values 'ON', 'OFF' }
|
name 'COMP_OPTS';
|
||||||
|
values 'OPT=0 LTO=OFF STATIC=OFF', 'OPT=2 LTO=OFF STATIC=ON', 'OPT=3 LTO=ON STATIC=ON PGO=ON'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stages {
|
stages {
|
||||||
stage('build ffmpeg on linux using docker') {
|
stage('build ffmpeg on linux using docker') {
|
||||||
agent { label "linux && ${ARCH}" }
|
agent { label "linux && ${ARCH}" }
|
||||||
steps {
|
steps {
|
||||||
withDockerCreds {
|
withDockerCreds {
|
||||||
sh "${OPT_LTO} ./scripts/build_with_docker.sh ${DISTRO}"
|
sh "${COMP_OPTS} ./scripts/build_with_docker.sh ${DISTRO}"
|
||||||
archiveArtifacts allowEmptyArchive: true, artifacts: 'gitignore/package/*.tar.xz', defaultExcludes: false
|
archiveArtifacts allowEmptyArchive: true, artifacts: 'gitignore/package/*.tar.xz', defaultExcludes: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
79
README.md
79
README.md
@@ -32,16 +32,20 @@ The default enabled libraries included in the `ffmpeg` build are:
|
|||||||
- libx264
|
- libx264
|
||||||
- libx265
|
- libx265
|
||||||
- libwebp
|
- libwebp
|
||||||
|
- libvpx
|
||||||
|
- libass
|
||||||
|
- libvorbis
|
||||||
- libmp3lame
|
- libmp3lame
|
||||||
|
|
||||||
The user-overridable compile options are:
|
The user-overridable compile options are:
|
||||||
- `CLEAN`: clean build directories before building (default: ON)
|
- `ENABLE`: configure what ffmpeg enables (default: libsvtav1_psy libopus libdav1d libaom librav1e libvmaf libx264 libx265 libwebp libvpx libass libvorbis libmp3lame)
|
||||||
- `LTO`: enable link time optimization (default: ON)
|
|
||||||
- `OPT`: optimization level (0-3) (default: 3)
|
|
||||||
- `STATIC`: static or shared build (default: ON)
|
|
||||||
- `ARCH`: architecture type (x86-64-v{1,2,3,4}, armv8-a, etc) (default: native)
|
|
||||||
- `PREFIX`: prefix to install to, default is local install in ./gitignore/sysroot (default: local)
|
- `PREFIX`: prefix to install to, default is local install in ./gitignore/sysroot (default: local)
|
||||||
- `ENABLE`: configure what ffmpeg enables (default: libsvtav1_psy libopus libdav1d libaom librav1e libvmaf libx264 libx265 libwebp libmp3lame)
|
- `STATIC`: static or shared build (default: ON)
|
||||||
|
- `LTO`: enable link time optimization (default: ON)
|
||||||
|
- `CLEAN`: clean build directories before building (default: ON)
|
||||||
|
- `PGO`: enable profile guided optimization (default: OFF)
|
||||||
|
- `ARCH`: architecture type (x86-64-v{1,2,3,4}, armv8-a, etc) (default: native)
|
||||||
|
- `OPT`: optimization level (0-3) (default: 3)
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
- only build libsvtav1_psy and libopus: `ENABLE='libsvtav1_psy libopus' ./scripts/build.sh`
|
- only build libsvtav1_psy and libopus: `ENABLE='libsvtav1_psy libopus' ./scripts/build.sh`
|
||||||
@@ -77,7 +81,7 @@ encode -i input [options] output
|
|||||||
[-v] print relevant version info
|
[-v] print relevant version info
|
||||||
[-s] use same container as input, default is convert to mkv
|
[-s] use same container as input, default is convert to mkv
|
||||||
|
|
||||||
[output] if unset, defaults to ${HOME}/av1-input-file-name.mkv
|
[output] if unset, defaults to ${PWD}/av1-input-file-name.mkv
|
||||||
|
|
||||||
[-u] update script (git pull ffmpeg-builder)
|
[-u] update script (git pull ffmpeg-builder)
|
||||||
[-I] system install at /usr/local/bin/encode
|
[-I] system install at /usr/local/bin/encode
|
||||||
@@ -106,6 +110,7 @@ Example usage:
|
|||||||
## Estimate film-grain
|
## Estimate film-grain
|
||||||
```bash
|
```bash
|
||||||
efg -i input [options]
|
efg -i input [options]
|
||||||
|
[-P NUM] set preset (default: 10)
|
||||||
[-l NUM] low value (default: 0)
|
[-l NUM] low value (default: 0)
|
||||||
[-s NUM] step value (default: 1)
|
[-s NUM] step value (default: 1)
|
||||||
[-h NUM] high value (default: 30)
|
[-h NUM] high value (default: 30)
|
||||||
@@ -120,33 +125,41 @@ efg -i input [options]
|
|||||||
Example usage:
|
Example usage:
|
||||||
- `efg -i input.mkv -p`
|
- `efg -i input.mkv -p`
|
||||||
```
|
```
|
||||||
1 +------------------------------------------------------------------------------------------------------+
|
10000 +------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
| *****G***** + + + |
|
| **G* + + + + + |
|
||||||
| *****G** '/tmp/plot.dat' ***G*** |
|
| ** /Volumes/External/ffmpeg-builder/gitignore/tmp/efg-matrix-reloaded.mkv/plot.dat ***G*** |
|
||||||
0.95 |-+ ***** +-|
|
| *G** |
|
||||||
| **G* |
|
| **G |
|
||||||
| *** |
|
9000 |-+ ** +-|
|
||||||
| **** |
|
| *G** |
|
||||||
0.9 |-+ *G* +-|
|
| **G |
|
||||||
| **** |
|
|
||||||
| **** |
|
|
||||||
0.85 |-+ *G* +-|
|
|
||||||
| *** |
|
|
||||||
| **** |
|
|
||||||
0.8 |-+ *G* +-|
|
|
||||||
| *** |
|
|
||||||
| **** |
|
|
||||||
| *G* |
|
|
||||||
0.75 |-+ *** +-|
|
|
||||||
| **** |
|
|
||||||
| *G* |
|
|
||||||
0.7 |-+ *** +-|
|
|
||||||
| ** |
|
| ** |
|
||||||
| *** |
|
|
||||||
| *G* |
|
| *G* |
|
||||||
0.65 |-+ *** +-|
|
8000 |-+ ** +-|
|
||||||
| **** |
|
| *G** |
|
||||||
| + + + *|
|
| **G |
|
||||||
0.6 +------------------------------------------------------------------------------------------------------+
|
| ** |
|
||||||
|
| *G** |
|
||||||
|
7000 |-+ **G* +-|
|
||||||
|
| ** |
|
||||||
|
| *G* |
|
||||||
|
| **G** |
|
||||||
|
6000 |-+ **G* +-|
|
||||||
|
| ** |
|
||||||
|
| *G* |
|
||||||
|
| **G** |
|
||||||
|
| **G* |
|
||||||
|
5000 |-+ **G** +-|
|
||||||
|
| **G****G* |
|
||||||
|
| **G** |
|
||||||
|
| **G****G* |
|
||||||
|
| **G****G* |
|
||||||
|
4000 |-+ **G****G****G* +-|
|
||||||
|
| **G****|
|
||||||
|
| |
|
||||||
|
| |
|
||||||
|
| + + + + + |
|
||||||
|
3000 +------------------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
0 5 10 15 20 25 30
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
419
lib/0-utils.sh
Normal file
419
lib/0-utils.sh
Normal file
@@ -0,0 +1,419 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
|
||||||
|
# ANSI colors
|
||||||
|
RED='\e[0;31m'
|
||||||
|
CYAN='\e[0;36m'
|
||||||
|
GREEN='\e[0;32m'
|
||||||
|
YELLOW='\e[0;33m'
|
||||||
|
NC='\e[0m'
|
||||||
|
|
||||||
|
# echo wrappers
|
||||||
|
echo_wrapper() {
|
||||||
|
local args
|
||||||
|
if [[ $1 == '-n' ]]; then
|
||||||
|
args=("$1")
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
# COLOR is override for using ${color}
|
||||||
|
# shellcheck disable=SC2153
|
||||||
|
if [[ ${COLOR} == 'OFF' ]]; then
|
||||||
|
color=''
|
||||||
|
endColor=''
|
||||||
|
else
|
||||||
|
endColor="${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo -e "${args[@]}" "${color}${word:-''}${endColor}" "$@"
|
||||||
|
}
|
||||||
|
echo_fail() { color="${RED}" word="FAIL" echo_wrapper "$@"; }
|
||||||
|
echo_info() { color="${CYAN}" word="INFO" echo_wrapper "$@"; }
|
||||||
|
echo_pass() { color="${GREEN}" word="PASS" echo_wrapper "$@"; }
|
||||||
|
echo_warn() { color="${YELLOW}" word="WARN" echo_wrapper "$@"; }
|
||||||
|
echo_exit() {
|
||||||
|
echo_fail "$@"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
void() { echo "$@" >/dev/null; }
|
||||||
|
|
||||||
|
echo_if_fail() {
|
||||||
|
local cmd=("$@")
|
||||||
|
local logName="${LOGNAME:-${RANDOM}}-"
|
||||||
|
local out="${TMP_DIR}/${logName}stdout"
|
||||||
|
local err="${TMP_DIR}/${logName}stderr"
|
||||||
|
|
||||||
|
# set trace to the cmdEvalTrace and open file descriptor
|
||||||
|
local cmdEvalTrace="${TMP_DIR}/${logName}cmdEvalTrace"
|
||||||
|
exec 5>"${cmdEvalTrace}"
|
||||||
|
export BASH_XTRACEFD=5
|
||||||
|
|
||||||
|
set -x
|
||||||
|
"${cmd[@]}" >"${out}" 2>"${err}"
|
||||||
|
local retval=$?
|
||||||
|
|
||||||
|
# unset and close file descriptor
|
||||||
|
set +x
|
||||||
|
exec 5>&-
|
||||||
|
|
||||||
|
# parse out relevant part of the trace
|
||||||
|
local cmdEvalLines=()
|
||||||
|
while IFS= read -r line; do
|
||||||
|
line="${line/${PS4}/}"
|
||||||
|
test "${line}" == 'set +x' && continue
|
||||||
|
test "${line}" == '' && continue
|
||||||
|
cmdEvalLines+=("${line}")
|
||||||
|
done <"${cmdEvalTrace}"
|
||||||
|
|
||||||
|
if ! test ${retval} -eq 0; then
|
||||||
|
echo
|
||||||
|
echo_fail "command failed with ${retval}:"
|
||||||
|
printf "%s\n" "${cmdEvalLines[@]}"
|
||||||
|
echo_warn "command stdout:"
|
||||||
|
tail -n 32 "${out}"
|
||||||
|
echo_warn "command stderr:"
|
||||||
|
tail -n 32 "${err}"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
if [[ -z ${LOGNAME} ]]; then
|
||||||
|
rm "${out}" "${err}" "${cmdEvalTrace}"
|
||||||
|
fi
|
||||||
|
return ${retval}
|
||||||
|
}
|
||||||
|
|
||||||
|
is_root_owned() {
|
||||||
|
local path=$1
|
||||||
|
local uid
|
||||||
|
|
||||||
|
if stat --version >/dev/null 2>&1; then
|
||||||
|
# GNU coreutils (Linux)
|
||||||
|
uid=$(stat -c '%u' "$path")
|
||||||
|
else
|
||||||
|
# BSD/macOS
|
||||||
|
uid=$(stat -f '%u' "$path")
|
||||||
|
fi
|
||||||
|
|
||||||
|
test "$uid" -eq 0
|
||||||
|
}
|
||||||
|
|
||||||
|
dump_arr() {
|
||||||
|
local arrayNames=("$@")
|
||||||
|
for arrayName in "${arrayNames[@]}"; do
|
||||||
|
declare -n array="${arrayName}"
|
||||||
|
arrayExpanded=("${array[@]}")
|
||||||
|
|
||||||
|
# skip showing single element arrays by default
|
||||||
|
if [[ ! ${#arrayExpanded[@]} -gt 1 ]]; then
|
||||||
|
if [[ ${SHOW_SINGLE} == true ]]; then
|
||||||
|
echo_info "${arrayName}='${arrayExpanded[*]}'"
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
# don't care that the variable has "ARR"
|
||||||
|
echo_info "${arrayName//"_ARR"/}"
|
||||||
|
printf "\t%s\n" "${arrayExpanded[@]}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
has_cmd() {
|
||||||
|
local cmds=("$@")
|
||||||
|
local rv=0
|
||||||
|
for cmd in "${cmds[@]}"; do
|
||||||
|
command -v "${cmd}" >/dev/null 2>&1 || rv=1
|
||||||
|
done
|
||||||
|
|
||||||
|
return ${rv}
|
||||||
|
}
|
||||||
|
|
||||||
|
missing_cmd() {
|
||||||
|
local cmds=("$@")
|
||||||
|
local rv=1
|
||||||
|
for cmd in "${cmds[@]}"; do
|
||||||
|
if ! has_cmd "${cmd}"; then
|
||||||
|
echo_warn "missing ${cmd}"
|
||||||
|
rv=0
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
return ${rv}
|
||||||
|
}
|
||||||
|
|
||||||
|
bash_dirname() {
|
||||||
|
local tmp=${1:-.}
|
||||||
|
|
||||||
|
[[ $tmp != *[!/]* ]] && {
|
||||||
|
printf '/\n'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp=${tmp%%"${tmp##*[!/]}"}
|
||||||
|
|
||||||
|
[[ $tmp != */* ]] && {
|
||||||
|
printf '.\n'
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp=${tmp%/*}
|
||||||
|
tmp=${tmp%%"${tmp##*[!/]}"}
|
||||||
|
|
||||||
|
printf '%s\n' "${tmp:-/}"
|
||||||
|
}
|
||||||
|
|
||||||
|
bash_basename() {
|
||||||
|
local tmp
|
||||||
|
path="$1"
|
||||||
|
suffix="${2:-''}"
|
||||||
|
|
||||||
|
tmp=${path%"${path##*[!/]}"}
|
||||||
|
tmp=${tmp##*/}
|
||||||
|
tmp=${tmp%"${suffix/"$tmp"/}"}
|
||||||
|
|
||||||
|
printf '%s\n' "${tmp:-/}"
|
||||||
|
}
|
||||||
|
|
||||||
|
bash_realpath() {
|
||||||
|
local file=$1
|
||||||
|
local dir
|
||||||
|
|
||||||
|
# If the file is already absolute
|
||||||
|
[[ $file == /* ]] && {
|
||||||
|
printf '%s\n' "$file"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# Otherwise: split into directory + basename
|
||||||
|
dir="$(bash_dirname "${file}")"
|
||||||
|
file="$(bash_basename "${file}")"
|
||||||
|
|
||||||
|
# If no directory component, use current directory
|
||||||
|
if [[ $dir == "$file" ]]; then
|
||||||
|
dir="$PWD"
|
||||||
|
else
|
||||||
|
# Save current dir, move into target dir, capture $PWD, then return
|
||||||
|
local oldpwd="$PWD"
|
||||||
|
cd "$dir" || return 1
|
||||||
|
dir="$PWD"
|
||||||
|
cd "$oldpwd" || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
printf '%s/%s\n' "$dir" "$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
line_contains() {
|
||||||
|
local line="$1"
|
||||||
|
local substr="$2"
|
||||||
|
if [[ $line == *"${substr}"* ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
line_starts_with() {
|
||||||
|
local line="$1"
|
||||||
|
local substr="$2"
|
||||||
|
if [[ $line == "${substr}"* ]]; then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
is_linux() {
|
||||||
|
line_contains "${OSTYPE}" 'linux'
|
||||||
|
}
|
||||||
|
|
||||||
|
is_darwin() {
|
||||||
|
line_contains "$(print_os)" darwin
|
||||||
|
}
|
||||||
|
|
||||||
|
is_windows() {
|
||||||
|
line_contains "$(print_os)" windows
|
||||||
|
}
|
||||||
|
|
||||||
|
is_android() {
|
||||||
|
line_contains "$(print_os)" android
|
||||||
|
}
|
||||||
|
|
||||||
|
print_os() {
|
||||||
|
# cached response
|
||||||
|
if [[ -n ${FB_OS} ]]; then
|
||||||
|
echo "${FB_OS}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset FB_OS
|
||||||
|
if [[ -f /etc/os-release ]]; then
|
||||||
|
source /etc/os-release
|
||||||
|
FB_OS="${ID}"
|
||||||
|
if [[ ${VERSION_ID} != '' ]]; then
|
||||||
|
FB_OS+="-${VERSION_ID}"
|
||||||
|
fi
|
||||||
|
if line_starts_with "${FB_OS}" 'arch'; then
|
||||||
|
FB_OS='archlinux'
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
FB_OS="$(uname -o)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# lowercase
|
||||||
|
FB_OS="${FB_OS,,}"
|
||||||
|
|
||||||
|
# special treatment for windows
|
||||||
|
if line_contains "${FB_OS}" 'windows' || line_contains "${FB_OS}" 'msys'; then
|
||||||
|
FB_OS='windows'
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "${FB_OS}"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_positive_integer() {
|
||||||
|
local input="$1"
|
||||||
|
if [[ ${input} != ?(-)+([[:digit:]]) || ${input} -lt 0 ]]; then
|
||||||
|
echo_fail "${input} is not a positive integer"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
print_line_indent() {
|
||||||
|
local line="$1"
|
||||||
|
if [[ ${line} =~ ^( +) ]]; then
|
||||||
|
echo -n "${BASH_REMATCH[1]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
replace_line() {
|
||||||
|
local file="$1"
|
||||||
|
local search="$2"
|
||||||
|
local newLine="$3"
|
||||||
|
local newFile="${TMP_DIR}/$(bash_basename "${file}")"
|
||||||
|
|
||||||
|
test -f "${newFile}" && rm "${newFile}"
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if line_contains "${line}" "${search}"; then
|
||||||
|
print_line_indent "${line}" >>"${newFile}"
|
||||||
|
echo -en "${newLine}" >>"${newFile}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
echo "${line}" >>"${newFile}"
|
||||||
|
done <"${file}"
|
||||||
|
|
||||||
|
cp "${newFile}" "${file}"
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_line() {
|
||||||
|
local file="$1"
|
||||||
|
local search="$2"
|
||||||
|
replace_line "${file}" "${search}" ''
|
||||||
|
}
|
||||||
|
|
||||||
|
bash_sort() {
|
||||||
|
local arr=("$@")
|
||||||
|
local n=${#arr[@]}
|
||||||
|
local i j val1 val2
|
||||||
|
|
||||||
|
# Bubble sort, numeric comparison
|
||||||
|
for ((i = 0; i < n; i++)); do
|
||||||
|
for ((j = 0; j < n - i - 1; j++)); do
|
||||||
|
read -r val1 _ <<<"${arr[j]}"
|
||||||
|
read -r val2 _ <<<"${arr[j + 1]}"
|
||||||
|
if (("${val1}" > "${val2}")); then
|
||||||
|
local tmp=${arr[j]}
|
||||||
|
arr[j]=${arr[j + 1]}
|
||||||
|
arr[j + 1]=$tmp
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
printf '%s\n' "${arr[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
_start_spinner() {
|
||||||
|
local spinChars=(
|
||||||
|
"-"
|
||||||
|
'\'
|
||||||
|
"|"
|
||||||
|
"/"
|
||||||
|
)
|
||||||
|
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
for ((ind = 0; ind < "${#spinChars[@]}"; ind++)); do
|
||||||
|
echo -ne "${spinChars[${ind}]}" '\b\b'
|
||||||
|
sleep .25
|
||||||
|
done
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
spinner() {
|
||||||
|
local action="$1"
|
||||||
|
local spinPidFile="${TMP_DIR}/.spinner-pid"
|
||||||
|
case "${action}" in
|
||||||
|
start)
|
||||||
|
test -f "${spinPidFile}" && rm "${spinPidFile}"
|
||||||
|
|
||||||
|
_start_spinner &
|
||||||
|
echo $! >"${spinPidFile}"
|
||||||
|
;;
|
||||||
|
stop)
|
||||||
|
test -f "${spinPidFile}" && kill "$(<"${spinPidFile}")"
|
||||||
|
echo -ne ' \n'
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
get_pkgconfig_version() {
|
||||||
|
local pkg="$1"
|
||||||
|
pkg-config --modversion "${pkg}"
|
||||||
|
}
|
||||||
|
|
||||||
|
using_cmake_4() {
|
||||||
|
local cmakeVersion
|
||||||
|
IFS=$' \t' read -r _ _ cmakeVersion <<<"$(command cmake --version)"
|
||||||
|
line_starts_with "${cmakeVersion}" 4
|
||||||
|
}
|
||||||
|
|
||||||
|
recreate_dir() {
|
||||||
|
local dirs=("$@")
|
||||||
|
for dir in "${dirs[@]}"; do
|
||||||
|
test -d "${dir}" && rm -rf "${dir}"
|
||||||
|
mkdir -p "${dir}" || return 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_dir() {
|
||||||
|
local dirs=("$@")
|
||||||
|
for dir in "${dirs[@]}"; do
|
||||||
|
test -d "${dir}" || mkdir -p "${dir}" || return 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
get_remote_head() {
|
||||||
|
local url="$1"
|
||||||
|
local remoteHEAD=''
|
||||||
|
IFS=$' \t' read -r remoteHEAD _ <<< \
|
||||||
|
"$(git ls-remote "${url}" HEAD)"
|
||||||
|
echo "${remoteHEAD}"
|
||||||
|
}
|
||||||
|
|
||||||
|
fb_max() {
|
||||||
|
local a="$1"
|
||||||
|
local b="$2"
|
||||||
|
test "${a}" -gt "${b}" &&
|
||||||
|
echo "${a}" ||
|
||||||
|
echo "${b}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_padded() {
|
||||||
|
local str="$1"
|
||||||
|
local padding="$2"
|
||||||
|
echo -n "${str}"
|
||||||
|
for ((i = 0; i < padding - ${#str}; i++)); do
|
||||||
|
echo -n ' '
|
||||||
|
done
|
||||||
|
}
|
||||||
599
lib/build.sh
599
lib/build.sh
@@ -1,25 +1,34 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
set_compile_opts() {
|
set_compile_opts() {
|
||||||
test "$FB_COMPILE_OPTS_SET" == 1 && return 0
|
test "${FB_COMPILE_OPTS_SET}" == 1 && return 0
|
||||||
|
|
||||||
EXPORTED_ENV_NAMES=(
|
EXPORTED_ENV_NAMES=(
|
||||||
|
CC
|
||||||
|
CFLAGS
|
||||||
|
CXX
|
||||||
|
CXXFLAGS
|
||||||
|
CPPFLAGS
|
||||||
LDFLAGS
|
LDFLAGS
|
||||||
C_FLAGS
|
|
||||||
CXX_FLAGS
|
|
||||||
CPP_FLAGS
|
|
||||||
RUSTFLAGS
|
RUSTFLAGS
|
||||||
PKG_CONFIG_PATH
|
PKG_CONFIG_PATH
|
||||||
)
|
)
|
||||||
BUILD_ENV_NAMES=(
|
BUILD_ENV_NAMES=(
|
||||||
"${EXPORTED_ENV_NAMES[@]}"
|
"${EXPORTED_ENV_NAMES[@]}"
|
||||||
|
CFLAGS_ARR
|
||||||
|
CPPFLAGS_ARR
|
||||||
|
LDFLAGS_ARR
|
||||||
|
USE_LD
|
||||||
|
RUSTFLAGS_ARR
|
||||||
CONFIGURE_FLAGS
|
CONFIGURE_FLAGS
|
||||||
MESON_FLAGS
|
MESON_FLAGS
|
||||||
CMAKE_FLAGS
|
CMAKE_FLAGS
|
||||||
FFMPEG_EXTRA_FLAGS
|
FFMPEG_EXTRA_FLAGS
|
||||||
CARGO_CINSTALL_FLAGS
|
CARGO_CINSTALL_FLAGS
|
||||||
LTO_FLAG
|
LTO_FLAG
|
||||||
|
PGO_FLAG
|
||||||
LIB_SUFF
|
LIB_SUFF
|
||||||
|
BUILD_TYPE
|
||||||
)
|
)
|
||||||
unset "${BUILD_ENV_NAMES[@]}"
|
unset "${BUILD_ENV_NAMES[@]}"
|
||||||
export "${EXPORTED_ENV_NAMES[@]}"
|
export "${EXPORTED_ENV_NAMES[@]}"
|
||||||
@@ -50,11 +59,90 @@ set_compile_opts() {
|
|||||||
|
|
||||||
# set library/pkgconfig directory
|
# set library/pkgconfig directory
|
||||||
LIBDIR="${PREFIX}/lib"
|
LIBDIR="${PREFIX}/lib"
|
||||||
LDFLAGS=("-L${LIBDIR}")
|
LDFLAGS_ARR=("-L${LIBDIR}")
|
||||||
|
|
||||||
# HACK rope in libm
|
# android has different library location/names
|
||||||
|
# cannot build static due to missing liblog
|
||||||
if is_android; then
|
if is_android; then
|
||||||
test -f "${LIBDIR}/libm.so" || ln -s /system/lib64/libm.so "${LIBDIR}/libm.so"
|
if [[ ${STATIC} == 'ON' ]]; then
|
||||||
|
echo_warn "$(print_os) does not support STATIC=${STATIC}"
|
||||||
|
STATIC=OFF
|
||||||
|
echo_warn "setting STATIC=${STATIC}"
|
||||||
|
fi
|
||||||
|
LDFLAGS_ARR+=(
|
||||||
|
"-L/system/lib64"
|
||||||
|
"-lm"
|
||||||
|
"-landroid-shmem"
|
||||||
|
"-landroid-posix-semaphore"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# use clang
|
||||||
|
CC=clang
|
||||||
|
CXX=clang++
|
||||||
|
CMAKE_FLAGS+=(
|
||||||
|
"-DCMAKE_C_COMPILER=${CC}"
|
||||||
|
"-DCMAKE_CXX_COMPILER=${CXX}"
|
||||||
|
)
|
||||||
|
FFMPEG_EXTRA_FLAGS+=(
|
||||||
|
"--cc=${CC}"
|
||||||
|
"--cxx=${CXX}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# hack PATH to inject use of lld as linker
|
||||||
|
# PATH cc/c++ may be hardcoded as gcc
|
||||||
|
# which breaks when trying to use clang/lld
|
||||||
|
# not supported on darwin
|
||||||
|
if ! is_darwin; then
|
||||||
|
USE_LD=lld
|
||||||
|
LDFLAGS_ARR+=("-fuse-ld=${USE_LD}")
|
||||||
|
# android does not like LINKER_TYPE despite only using lld
|
||||||
|
if ! is_android; then
|
||||||
|
CMAKE_FLAGS+=("-DCMAKE_LINKER_TYPE=${USE_LD^^}")
|
||||||
|
fi
|
||||||
|
CMAKE_FLAGS+=("-DCMAKE_LINKER=${USE_LD}")
|
||||||
|
local compilerDir="${LOCAL_PREFIX}/compiler-tools"
|
||||||
|
recreate_dir "${compilerDir}" || return 1
|
||||||
|
# real:gnu:clang:generic
|
||||||
|
local compilerMap="\
|
||||||
|
${CC}:gcc:clang:cc
|
||||||
|
${CXX}:g++:clang++:c++
|
||||||
|
ld.lld:ld:lld:ld"
|
||||||
|
local realT gnuT clangT genericT
|
||||||
|
while read -r line; do
|
||||||
|
IFS=: read -r realT gnuT clangT genericT <<<"${line}"
|
||||||
|
# full path to the real tool
|
||||||
|
realT="$(command -v "${realT}")"
|
||||||
|
|
||||||
|
# add fuse-ld for the compiler
|
||||||
|
local addFlag='-v'
|
||||||
|
if line_contains "${realT}" clang; then addFlag+=" -fuse-ld=${USE_LD}"; fi
|
||||||
|
|
||||||
|
# create generic tool version
|
||||||
|
echo "#!/usr/bin/env bash
|
||||||
|
echo \$@ > ${compilerDir}/${genericT}.last-command
|
||||||
|
exec \"${realT}\" ${addFlag} \"\$@\"" >"${compilerDir}/${genericT}"
|
||||||
|
chmod +x "${compilerDir}/${genericT}"
|
||||||
|
echo_if_fail "${compilerDir}/${genericT}" --version || return 1
|
||||||
|
|
||||||
|
# copy generic to gnu/clang variants
|
||||||
|
# cp "${compilerDir}/${genericT}" "${compilerDir}/${gnuT}" 2>/dev/null
|
||||||
|
# cp "${compilerDir}/${genericT}" "${compilerDir}/${clangT}" 2>/dev/null
|
||||||
|
done <<<"${compilerMap}"
|
||||||
|
|
||||||
|
# also add fake which command in case one does not exist
|
||||||
|
# shellcheck disable=SC2016
|
||||||
|
echo '#!/usr/bin/env bash
|
||||||
|
which=""
|
||||||
|
test -f /bin/which && which=/bin/which
|
||||||
|
test -f /usr/bin/which && which=/usr/bin/which
|
||||||
|
if [[ ${which} == "" ]]; then
|
||||||
|
command -v "$@"
|
||||||
|
else
|
||||||
|
${which} "$@"
|
||||||
|
fi' >"${compilerDir}/which"
|
||||||
|
chmod +x "${compilerDir}/which"
|
||||||
|
export PATH="${compilerDir}:${PATH}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# set prefix flags and basic flags
|
# set prefix flags and basic flags
|
||||||
@@ -76,38 +164,56 @@ set_compile_opts() {
|
|||||||
"-DCMAKE_BUILD_TYPE=Release"
|
"-DCMAKE_BUILD_TYPE=Release"
|
||||||
"-DCMAKE_C_COMPILER_LAUNCHER=ccache"
|
"-DCMAKE_C_COMPILER_LAUNCHER=ccache"
|
||||||
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
|
"-DCMAKE_CXX_COMPILER_LAUNCHER=ccache"
|
||||||
|
"-DCMAKE_VERBOSE_MAKEFILE=ON"
|
||||||
|
"-G" "Ninja"
|
||||||
)
|
)
|
||||||
CARGO_CINSTALL_FLAGS=(
|
CARGO_CINSTALL_FLAGS=(
|
||||||
"--release"
|
"--release"
|
||||||
|
"--verbose"
|
||||||
"--prefix" "${PREFIX}"
|
"--prefix" "${PREFIX}"
|
||||||
"--libdir" "${LIBDIR}"
|
"--libdir" "${LIBDIR}"
|
||||||
)
|
)
|
||||||
PKG_CONFIG_PATH="${LIBDIR}/pkgconfig"
|
PKG_CONFIG_PATH="${LIBDIR}/pkgconfig"
|
||||||
|
|
||||||
|
# cmake version 4 breaks some builds
|
||||||
|
if using_cmake_4; then
|
||||||
|
CMAKE_FLAGS+=("-DCMAKE_POLICY_VERSION_MINIMUM=3.5")
|
||||||
|
fi
|
||||||
|
|
||||||
# add prefix include
|
# add prefix include
|
||||||
C_FLAGS+=("-I${PREFIX}/include")
|
# TODO use cygpath for windows
|
||||||
|
CPPFLAGS_ARR+=("-I${PREFIX}/include")
|
||||||
|
|
||||||
|
# if PGO is enabled, first build run will be to generate
|
||||||
|
# second run will be to use generated profdata
|
||||||
|
if [[ ${PGO} == 'ON' ]]; then
|
||||||
|
if [[ ${PGO_RUN} == 'generate' ]]; then
|
||||||
|
PGO_FLAG="-fprofile-generate"
|
||||||
|
CFLAGS_ARR+=("${PGO_FLAG}")
|
||||||
|
LDFLAGS_ARR+=("${PGO_FLAG}")
|
||||||
|
else
|
||||||
|
PGO_FLAG="-fprofile-use=${PGO_PROFDATA}"
|
||||||
|
CFLAGS_ARR+=("${PGO_FLAG}")
|
||||||
|
LDFLAGS_ARR+=("${PGO_FLAG}")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
# enabling link-time optimization
|
# enabling link-time optimization
|
||||||
if [[ ${LTO} == 'ON' ]]; then
|
if [[ ${LTO} == 'ON' ]]; then
|
||||||
LTO_FLAG='-flto'
|
LTO_FLAG='-flto=full'
|
||||||
C_FLAGS+=("${LTO_FLAG}")
|
CFLAGS_ARR+=("${LTO_FLAG}")
|
||||||
if ! is_darwin; then
|
LDFLAGS_ARR+=("${LTO_FLAG}")
|
||||||
CONFIGURE_FLAGS+=('--enable-lto')
|
CONFIGURE_FLAGS+=('--enable-lto')
|
||||||
fi
|
|
||||||
MESON_FLAGS+=("-Db_lto=true")
|
MESON_FLAGS+=("-Db_lto=true")
|
||||||
RUSTFLAGS+=("-C lto=yes" "-C inline-threshold=1000" "-C codegen-units=1")
|
|
||||||
else
|
else
|
||||||
LTO_FLAG=' '
|
LTO_FLAG='unreachable-flag'
|
||||||
MESON_FLAGS+=("-Db_lto=false")
|
MESON_FLAGS+=("-Db_lto=false")
|
||||||
RUSTFLAGS+=("-C lto=no")
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# setting optimization level
|
# setting optimization level
|
||||||
if [[ ${OPT} == '' ]]; then
|
if [[ ${OPT} == '' ]]; then
|
||||||
OPT='0'
|
OPT='0'
|
||||||
fi
|
fi
|
||||||
C_FLAGS+=("-O${OPT}")
|
CFLAGS_ARR+=("-O${OPT}")
|
||||||
RUSTFLAGS+=("-C opt-level=${OPT}")
|
|
||||||
MESON_FLAGS+=("--optimization=${OPT}")
|
MESON_FLAGS+=("--optimization=${OPT}")
|
||||||
|
|
||||||
STATIC_LIB_SUFF='a'
|
STATIC_LIB_SUFF='a'
|
||||||
@@ -120,6 +226,7 @@ set_compile_opts() {
|
|||||||
|
|
||||||
# static/shared linking
|
# static/shared linking
|
||||||
if [[ ${STATIC} == 'ON' ]]; then
|
if [[ ${STATIC} == 'ON' ]]; then
|
||||||
|
BUILD_TYPE=static
|
||||||
CONFIGURE_FLAGS+=(
|
CONFIGURE_FLAGS+=(
|
||||||
'--enable-static'
|
'--enable-static'
|
||||||
'--disable-shared'
|
'--disable-shared'
|
||||||
@@ -130,29 +237,39 @@ set_compile_opts() {
|
|||||||
"-DENABLE_SHARED=OFF"
|
"-DENABLE_SHARED=OFF"
|
||||||
"-DBUILD_SHARED_LIBS=OFF"
|
"-DBUILD_SHARED_LIBS=OFF"
|
||||||
)
|
)
|
||||||
RUSTFLAGS+=("-C target-feature=+crt-static")
|
# darwin does not support -static
|
||||||
FFMPEG_EXTRA_FLAGS+=("--pkg-config-flags=--static")
|
if is_darwin; then
|
||||||
# darwin does not support static linkage
|
FFMPEG_EXTRA_FLAGS+=("--extra-ldflags=${LDFLAGS_ARR[*]}")
|
||||||
if ! is_darwin; then
|
CMAKE_FLAGS+=("-DCMAKE_EXE_LINKER_FLAGS=${LDFLAGS_ARR[*]}")
|
||||||
LDFLAGS+=('-static')
|
else
|
||||||
CMAKE_FLAGS+=("-DCMAKE_EXE_LINKER_FLAGS=-static")
|
FFMPEG_EXTRA_FLAGS+=("--extra-ldflags=${LDFLAGS_ARR[*]} -static")
|
||||||
|
CMAKE_FLAGS+=("-DCMAKE_EXE_LINKER_FLAGS=${LDFLAGS_ARR[*]} -static")
|
||||||
fi
|
fi
|
||||||
FFMPEG_EXTRA_FLAGS+=(--extra-ldflags="${LDFLAGS[*]}")
|
FFMPEG_EXTRA_FLAGS+=("--pkg-config-flags=--static")
|
||||||
# remove shared libraries for static builds
|
# remove shared libraries for static builds
|
||||||
USE_LIB_SUFF="${STATIC_LIB_SUFF}"
|
USE_LIB_SUFF="${STATIC_LIB_SUFF}"
|
||||||
DEL_LIB_SUFF="${SHARED_LIB_SUFF}"
|
DEL_LIB_SUFF="${SHARED_LIB_SUFF}"
|
||||||
else
|
else
|
||||||
FFMPEG_EXTRA_FLAGS+=(--extra-ldflags="${LDFLAGS[*]}")
|
BUILD_TYPE=shared
|
||||||
LDFLAGS+=("-Wl,-rpath,${LIBDIR}" "-Wl,-rpath-link,${LIBDIR}")
|
|
||||||
CONFIGURE_FLAGS+=(
|
|
||||||
'--enable-shared'
|
|
||||||
'--disable-static'
|
|
||||||
)
|
|
||||||
CMAKE_FLAGS+=(
|
CMAKE_FLAGS+=(
|
||||||
"-DENABLE_STATIC=${STATIC}"
|
"-DENABLE_STATIC=${STATIC}"
|
||||||
"-DENABLE_SHARED=ON"
|
"-DENABLE_SHARED=ON"
|
||||||
"-DBUILD_SHARED_LIBS=ON"
|
"-DBUILD_SHARED_LIBS=ON"
|
||||||
"-DCMAKE_INSTALL_RPATH=${LIBDIR}"
|
"-DCMAKE_INSTALL_RPATH=${LIBDIR}"
|
||||||
|
"-DCMAKE_BUILD_WITH_INSTALL_RPATH=ON"
|
||||||
|
"-DCMAKE_EXE_LINKER_FLAGS=${LDFLAGS_ARR[*]}"
|
||||||
|
)
|
||||||
|
if is_darwin; then
|
||||||
|
CMAKE_FLAGS+=(
|
||||||
|
"-DCMAKE_MACOSX_RPATH=ON"
|
||||||
|
"-DCMAKE_INSTALL_NAME_DIR=@rpath"
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
FFMPEG_EXTRA_FLAGS+=("--extra-ldflags=${LDFLAGS_ARR[*]}")
|
||||||
|
LDFLAGS_ARR+=("-Wl,-rpath,${LIBDIR}")
|
||||||
|
CONFIGURE_FLAGS+=(
|
||||||
|
'--enable-shared'
|
||||||
|
'--disable-static'
|
||||||
)
|
)
|
||||||
FFMPEG_EXTRA_FLAGS+=('--enable-rpath')
|
FFMPEG_EXTRA_FLAGS+=('--enable-rpath')
|
||||||
# remove static libraries for shared builds
|
# remove static libraries for shared builds
|
||||||
@@ -172,54 +289,55 @@ set_compile_opts() {
|
|||||||
|
|
||||||
# can fail static builds with -fpic
|
# can fail static builds with -fpic
|
||||||
# warning: too many GOT entries for -fpic, please recompile with -fPIC
|
# warning: too many GOT entries for -fpic, please recompile with -fPIC
|
||||||
C_FLAGS+=("${arch_flags[@]}" "-fPIC")
|
CFLAGS_ARR+=("${arch_flags[@]}" "-fPIC")
|
||||||
CXX_FLAGS=("${C_FLAGS[@]}")
|
RUSTFLAGS_ARR+=("-C target-cpu=${ARCH}")
|
||||||
CPP_FLAGS=("${C_FLAGS[@]}")
|
|
||||||
RUSTFLAGS+=("-C target-cpu=${ARCH}")
|
# set exported env names to stringified arrays
|
||||||
CMAKE_FLAGS+=("-DCMAKE_C_FLAGS=${C_FLAGS[*]}")
|
CPPFLAGS="${CPPFLAGS_ARR[*]}"
|
||||||
CMAKE_FLAGS+=("-DCMAKE_CXX_FLAGS=${CXX_FLAGS[*]}")
|
CFLAGS="${CFLAGS_ARR[*]} ${CPPFLAGS}"
|
||||||
MESON_FLAGS+=("-Dc_args=${C_FLAGS[*]}" "-Dcpp_args=${CPP_FLAGS[*]}")
|
CXXFLAGS="${CFLAGS}"
|
||||||
dump_arr CONFIGURE_FLAGS
|
LDFLAGS="${LDFLAGS_ARR[*]}"
|
||||||
dump_arr C_FLAGS
|
RUSTFLAGS="${RUSTFLAGS_ARR[*]}"
|
||||||
dump_arr RUSTFLAGS
|
|
||||||
dump_arr CARGO_CINSTALL_FLAGS
|
CMAKE_FLAGS+=(
|
||||||
dump_arr CMAKE_FLAGS
|
"-DCMAKE_CFLAGS=${CFLAGS}"
|
||||||
dump_arr MESON_FLAGS
|
"-DCMAKE_CXX_FLAGS=${CFLAGS}"
|
||||||
echo_info "PKG_CONFIG_PATH=${PKG_CONFIG_PATH}"
|
)
|
||||||
|
MESON_FLAGS+=(
|
||||||
|
"-Dc_args=${CFLAGS}"
|
||||||
|
"-Dcpp_args=${CFLAGS}"
|
||||||
|
"-Dc_link_args=${LDFLAGS}"
|
||||||
|
"-Dcpp_link_args=${LDFLAGS}"
|
||||||
|
)
|
||||||
|
|
||||||
# extra ffmpeg flags
|
# extra ffmpeg flags
|
||||||
FFMPEG_EXTRA_FLAGS+=(
|
FFMPEG_EXTRA_FLAGS+=(
|
||||||
--extra-cflags="${C_FLAGS[*]}"
|
"--extra-cflags=${CFLAGS}"
|
||||||
--extra-cxxflags="${CXX_FLAGS[*]}"
|
"--extra-cxxflags=${CFLAGS}"
|
||||||
--pkg-config='pkg-config'
|
'--pkg-config=pkg-config'
|
||||||
)
|
)
|
||||||
dump_arr FFMPEG_EXTRA_FLAGS
|
|
||||||
|
|
||||||
# shellcheck disable=SC2178
|
dump_arr "${BUILD_ENV_NAMES[@]}"
|
||||||
RUSTFLAGS="${RUSTFLAGS[*]}"
|
|
||||||
|
|
||||||
FB_COMPILE_OPTS_SET=1
|
FB_COMPILE_OPTS_SET=1
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
get_remote_head() {
|
|
||||||
local url="$1"
|
|
||||||
local remoteHEAD=''
|
|
||||||
IFS=$' \t' read -r remoteHEAD _ <<< \
|
|
||||||
"$(git ls-remote "${url}" HEAD)"
|
|
||||||
echo "${remoteHEAD}"
|
|
||||||
}
|
|
||||||
|
|
||||||
get_build_conf() {
|
get_build_conf() {
|
||||||
local getBuild="${1}"
|
local getBuild="${1}"
|
||||||
|
|
||||||
|
local longestBuild=0
|
||||||
|
local longestVer=0
|
||||||
|
local longestExt=0
|
||||||
|
local padding=4
|
||||||
|
|
||||||
# name version file-extension url dep1,dep2
|
# name version file-extension url dep1,dep2
|
||||||
# shellcheck disable=SC2016
|
# shellcheck disable=SC2016
|
||||||
local BUILDS_CONF='
|
local BUILDS_CONF='
|
||||||
ffmpeg 8.0 tar.gz https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n${ver}.${ext}
|
ffmpeg 8.0.1 tar.gz https://github.com/FFmpeg/FFmpeg/archive/refs/tags/n${ver}.${ext}
|
||||||
|
|
||||||
libsvtav1_psy 3.0.2-B tar.gz https://github.com/BlueSwordM/svt-av1-psyex/archive/refs/tags/v${ver}.${ext} dovi_tool,hdr10plus_tool,cpuinfo
|
libsvtav1_psy 3.0.2-B tar.gz https://github.com/BlueSwordM/svt-av1-psyex/archive/refs/tags/v${ver}.${ext} dovi_tool,hdr10plus_tool,cpuinfo
|
||||||
hdr10plus_tool 1.7.1 tar.gz https://github.com/quietvoid/hdr10plus_tool/archive/refs/tags/${ver}.${ext}
|
hdr10plus_tool 1.7.2 tar.gz https://github.com/quietvoid/hdr10plus_tool/archive/refs/tags/${ver}.${ext}
|
||||||
dovi_tool 2.3.1 tar.gz https://github.com/quietvoid/dovi_tool/archive/refs/tags/${ver}.${ext}
|
dovi_tool 2.3.1 tar.gz https://github.com/quietvoid/dovi_tool/archive/refs/tags/${ver}.${ext}
|
||||||
cpuinfo latest git https://github.com/pytorch/cpuinfo/
|
cpuinfo latest git https://github.com/pytorch/cpuinfo/
|
||||||
|
|
||||||
@@ -227,14 +345,18 @@ libsvtav1 3.1.2 tar.gz https://gitlab.com/AOMediaCodec/SVT-AV1/-/archive/v${v
|
|||||||
librav1e 0.8.1 tar.gz https://github.com/xiph/rav1e/archive/refs/tags/v${ver}.${ext}
|
librav1e 0.8.1 tar.gz https://github.com/xiph/rav1e/archive/refs/tags/v${ver}.${ext}
|
||||||
libaom 3.13.1 tar.gz https://storage.googleapis.com/aom-releases/libaom-${ver}.${ext}
|
libaom 3.13.1 tar.gz https://storage.googleapis.com/aom-releases/libaom-${ver}.${ext}
|
||||||
libvmaf 3.0.0 tar.gz https://github.com/Netflix/vmaf/archive/refs/tags/v${ver}.${ext}
|
libvmaf 3.0.0 tar.gz https://github.com/Netflix/vmaf/archive/refs/tags/v${ver}.${ext}
|
||||||
libopus 1.5.2 tar.gz https://github.com/xiph/opus/releases/download/v${ver}/opus-${ver}.${ext}
|
libopus 1.6 tar.gz https://github.com/xiph/opus/archive/refs/tags/v${ver}.${ext}
|
||||||
libdav1d 1.5.1 tar.xz http://downloads.videolan.org/videolan/dav1d/${ver}/dav1d-${ver}.${ext}
|
libdav1d 1.5.3 tar.xz https://downloads.videolan.org/videolan/dav1d/${ver}/dav1d-${ver}.${ext}
|
||||||
libx264 latest git https://code.videolan.org/videolan/x264.git
|
libx264 latest git https://code.videolan.org/videolan/x264.git
|
||||||
libmp3lame 3.100 tar.gz https://pilotfiber.dl.sourceforge.net/project/lame/lame/${ver}/lame-${ver}.${ext}
|
libmp3lame 3.100 tar.gz https://pilotfiber.dl.sourceforge.net/project/lame/lame/${ver}/lame-${ver}.${ext}
|
||||||
|
libvpx 1.15.2 tar.gz https://github.com/webmproject/libvpx/archive/refs/tags/v${ver}.${ext}
|
||||||
|
|
||||||
|
libvorbis 1.3.7 tar.xz https://github.com/xiph/vorbis/releases/download/v${ver}/libvorbis-${ver}.${ext} libogg
|
||||||
|
libogg 1.3.6 tar.xz https://github.com/xiph/ogg/releases/download/v${ver}/libogg-${ver}.${ext}
|
||||||
|
|
||||||
libwebp 1.6.0 tar.gz https://github.com/webmproject/libwebp/archive/refs/tags/v${ver}.${ext} libpng,libjpeg
|
libwebp 1.6.0 tar.gz https://github.com/webmproject/libwebp/archive/refs/tags/v${ver}.${ext} libpng,libjpeg
|
||||||
libjpeg 3.0.3 tar.gz https://github.com/winlibs/libjpeg/archive/refs/tags/libjpeg-turbo-${ver}.${ext}
|
libjpeg 3.0.3 tar.gz https://github.com/winlibs/libjpeg/archive/refs/tags/libjpeg-turbo-${ver}.${ext}
|
||||||
libpng 1.6.50 tar.gz https://github.com/pnggroup/libpng/archive/refs/tags/v${ver}.${ext} zlib
|
libpng 1.6.53 tar.gz https://github.com/pnggroup/libpng/archive/refs/tags/v${ver}.${ext} zlib
|
||||||
zlib 1.3.1 tar.gz https://github.com/madler/zlib/archive/refs/tags/v${ver}.${ext}
|
zlib 1.3.1 tar.gz https://github.com/madler/zlib/archive/refs/tags/v${ver}.${ext}
|
||||||
|
|
||||||
libplacebo 7.351.0 tar.gz https://github.com/haasn/libplacebo/archive/refs/tags/v${ver}.${ext} glslang,vulkan_loader,glad
|
libplacebo 7.351.0 tar.gz https://github.com/haasn/libplacebo/archive/refs/tags/v${ver}.${ext} glslang,vulkan_loader,glad
|
||||||
@@ -243,17 +365,27 @@ spirv_tools 2025.4 tar.gz https://github.com/KhronosGroup/SPIRV-Tools/archive
|
|||||||
spirv_headers 1.4.328.1 tar.gz https://github.com/KhronosGroup/SPIRV-Headers/archive/refs/tags/vulkan-sdk-${ver}.${ext}
|
spirv_headers 1.4.328.1 tar.gz https://github.com/KhronosGroup/SPIRV-Headers/archive/refs/tags/vulkan-sdk-${ver}.${ext}
|
||||||
glad 2.0.8 tar.gz https://github.com/Dav1dde/glad/archive/refs/tags/v${ver}.${ext}
|
glad 2.0.8 tar.gz https://github.com/Dav1dde/glad/archive/refs/tags/v${ver}.${ext}
|
||||||
|
|
||||||
libx265 4.1 tar.gz https://bitbucket.org/multicoreware/x265_git/downloads/x265_${ver}.${ext} libnuma,cmake3
|
libx265 4.1 tar.gz https://bitbucket.org/multicoreware/x265_git/downloads/x265_${ver}.${ext} libnuma
|
||||||
libnuma 2.0.19 tar.gz https://github.com/numactl/numactl/archive/refs/tags/v${ver}.${ext}
|
libnuma 2.0.19 tar.gz https://github.com/numactl/numactl/archive/refs/tags/v${ver}.${ext}
|
||||||
cmake3 3.31.8 tar.gz https://github.com/Kitware/CMake/archive/refs/tags/v${ver}.${ext}
|
|
||||||
'
|
|
||||||
|
|
||||||
|
libass 0.17.4 tar.xz https://github.com/libass/libass/releases/download/${ver}/libass-${ver}.${ext} freetype,fribidi,libunibreak
|
||||||
|
freetype 2.14.1 tar.xz https://downloads.sourceforge.net/freetype/freetype-${ver}.${ext} libpng,harfbuzz
|
||||||
|
harfbuzz 12.3.0 tar.xz https://github.com/harfbuzz/harfbuzz/releases/download/${ver}/harfbuzz-${ver}.${ext}
|
||||||
|
fribidi 1.0.16 tar.xz https://github.com/fribidi/fribidi/releases/download/v${ver}/fribidi-${ver}.${ext}
|
||||||
|
libunibreak 6.1 tar.gz https://github.com/adah1972/libunibreak/releases/download/libunibreak_${ver//./_}/libunibreak-${ver}.${ext}
|
||||||
|
'
|
||||||
local supported_builds=()
|
local supported_builds=()
|
||||||
unset ver ext url deps extractedDir
|
unset ver ext url deps extractedDir
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
test "${line}" == '' && continue
|
test "${line}" == '' && continue
|
||||||
IFS=$' \t' read -r build ver ext url deps <<<"${line}"
|
IFS=$' \t' read -r build ver ext url deps <<<"${line}"
|
||||||
supported_builds+=("${build}")
|
supported_builds+=("${build}")
|
||||||
|
|
||||||
|
# padding support
|
||||||
|
longestBuild="$(fb_max "${#build}" "${longestBuild}")"
|
||||||
|
longestVer="$(fb_max "${#ver}" "${longestVer}")"
|
||||||
|
longestExt="$(fb_max "${#ext}" "${longestExt}")"
|
||||||
|
|
||||||
if [[ ${getBuild} != "${build}" ]]; then
|
if [[ ${getBuild} != "${build}" ]]; then
|
||||||
build=''
|
build=''
|
||||||
continue
|
continue
|
||||||
@@ -261,11 +393,27 @@ cmake3 3.31.8 tar.gz https://github.com/Kitware/CMake/archive/refs/tags/v${v
|
|||||||
break
|
break
|
||||||
done <<<"${BUILDS_CONF}"
|
done <<<"${BUILDS_CONF}"
|
||||||
|
|
||||||
|
# special arg to print supported builds only
|
||||||
if [[ ${getBuild} == 'supported' ]]; then
|
if [[ ${getBuild} == 'supported' ]]; then
|
||||||
echo "${supported_builds[@]}"
|
echo "${supported_builds[@]}"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# special arg to print BUILDS_CONF but formatted with spaces
|
||||||
|
if [[ ${getBuild} == 'format-builds-conf' ]]; then
|
||||||
|
echo "local BUILDS_CONF='"
|
||||||
|
while read -r line; do
|
||||||
|
IFS=$' \t' read -r build ver ext url deps <<<"${line}"
|
||||||
|
print_padded "${build}" $((padding + longestBuild))
|
||||||
|
print_padded "${ver}" $((padding + longestVer))
|
||||||
|
print_padded "${ext}" $((padding + longestExt))
|
||||||
|
print_padded "${url}" "${padding}"
|
||||||
|
echo " ${deps}"
|
||||||
|
done <<<"${BUILDS_CONF}"
|
||||||
|
echo "'"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ ${build} == '' ]]; then
|
if [[ ${build} == '' ]]; then
|
||||||
echo_fail "build ${getBuild} is not supported"
|
echo_fail "build ${getBuild} is not supported"
|
||||||
return 1
|
return 1
|
||||||
@@ -309,7 +457,7 @@ download_release() {
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
test -d "${alreadyBuilt}" || continue
|
test -d "${alreadyBuilt}" || continue
|
||||||
echo_warn "removing wrong version: ${extractedDir}"
|
echo_warn "removing wrong version: ${alreadyBuilt}"
|
||||||
rm -rf "${alreadyBuilt}"
|
rm -rf "${alreadyBuilt}"
|
||||||
done
|
done
|
||||||
|
|
||||||
@@ -352,6 +500,7 @@ download_release() {
|
|||||||
localHEAD="$(git rev-parse HEAD)"
|
localHEAD="$(git rev-parse HEAD)"
|
||||||
remoteHEAD="$(get_remote_head "$(git config --get remote.origin.url)")"
|
remoteHEAD="$(get_remote_head "$(git config --get remote.origin.url)")"
|
||||||
if [[ ${localHEAD} != "${remoteHEAD}" ]]; then
|
if [[ ${localHEAD} != "${remoteHEAD}" ]]; then
|
||||||
|
git stash
|
||||||
git pull --ff-only
|
git pull --ff-only
|
||||||
git submodule update --init --recursive
|
git submodule update --init --recursive
|
||||||
fi
|
fi
|
||||||
@@ -390,12 +539,20 @@ do_build() {
|
|||||||
local ffmpegOldMetadataFile="${TMP_DIR}/ffmpeg-old-metadata"
|
local ffmpegOldMetadataFile="${TMP_DIR}/ffmpeg-old-metadata"
|
||||||
|
|
||||||
# add build function, version, url, and top-level env to metadata
|
# add build function, version, url, and top-level env to metadata
|
||||||
type "build_${build}" >"${newMetadataFile}"
|
{
|
||||||
echo "ver: ${ver}" >>"${newMetadataFile}"
|
local buildFunction="$(type "build_${build}")"
|
||||||
echo "url: ${url}" >>"${newMetadataFile}"
|
# include meta builds
|
||||||
for envName in "${BUILD_ENV_NAMES[@]}"; do
|
for token in ${buildFunction}; do
|
||||||
COLOR=OFF dump_arr "${envName}" >>"${newMetadataFile}"
|
if [[ ${token} == "meta_"*"_build" ]]; then
|
||||||
|
type "${token}"
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
echo "${buildFunction}"
|
||||||
|
echo "ver: ${ver}"
|
||||||
|
echo "url: ${url}"
|
||||||
|
echo "LOCAL_PREFIX: ${LOCAL_PREFIX}"
|
||||||
|
COLOR=OFF SHOW_SINGLE=true dump_arr "${BUILD_ENV_NAMES[@]}"
|
||||||
|
} >"${newMetadataFile}"
|
||||||
|
|
||||||
# only ffmpeg cares about ENABLE and has special function
|
# only ffmpeg cares about ENABLE and has special function
|
||||||
if [[ ${build} == 'ffmpeg' ]]; then
|
if [[ ${build} == 'ffmpeg' ]]; then
|
||||||
@@ -421,17 +578,10 @@ do_build() {
|
|||||||
echo_info -n "building ${build} "
|
echo_info -n "building ${build} "
|
||||||
# build in background
|
# build in background
|
||||||
local timeBefore=${EPOCHSECONDS}
|
local timeBefore=${EPOCHSECONDS}
|
||||||
LOGNAME="${build}" echo_if_fail "build_${build}" &
|
spinner start
|
||||||
local buildPid=$!
|
LOGNAME="${build}" echo_if_fail "build_${build}"
|
||||||
# start spinner
|
|
||||||
spinner &
|
|
||||||
local spinPid=$!
|
|
||||||
# get build return code
|
|
||||||
wait ${buildPid}
|
|
||||||
local retval=$?
|
local retval=$?
|
||||||
# stop spinner
|
spinner stop
|
||||||
kill ${spinPid}
|
|
||||||
spinner reset
|
|
||||||
|
|
||||||
popd >/dev/null || return 1
|
popd >/dev/null || return 1
|
||||||
test ${retval} -eq 0 || return ${retval}
|
test ${retval} -eq 0 || return ${retval}
|
||||||
@@ -456,6 +606,14 @@ FB_FUNC_NAMES+=('build')
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
FB_FUNC_DESCS['build']='build ffmpeg with the desired configuration'
|
FB_FUNC_DESCS['build']='build ffmpeg with the desired configuration'
|
||||||
build() {
|
build() {
|
||||||
|
# if PGO is enabled, build will call build
|
||||||
|
# only want to recursively build on the first run
|
||||||
|
if [[ ${PGO} == 'ON' && ${PGO_RUN} != 'generate' ]]; then
|
||||||
|
PGO_RUN='generate' build || return 1
|
||||||
|
# will need to reset compile opts
|
||||||
|
unset FB_COMPILE_OPTS_SET
|
||||||
|
fi
|
||||||
|
|
||||||
set_compile_opts || return 1
|
set_compile_opts || return 1
|
||||||
|
|
||||||
for build in ${ENABLE}; do
|
for build in ${ENABLE}; do
|
||||||
@@ -464,9 +622,16 @@ build() {
|
|||||||
unset REQUIRES_REBUILD
|
unset REQUIRES_REBUILD
|
||||||
done
|
done
|
||||||
do_build ffmpeg || return 1
|
do_build ffmpeg || return 1
|
||||||
|
|
||||||
|
# skip packaging on PGO generate run
|
||||||
|
if [[ ${PGO} == 'ON' && ${PGO_RUN} == 'generate' ]]; then
|
||||||
|
PATH="${PREFIX}/bin:${PATH}" gen_profdata
|
||||||
|
return $?
|
||||||
|
fi
|
||||||
|
|
||||||
local ffmpegBin="${PREFIX}/bin/ffmpeg"
|
local ffmpegBin="${PREFIX}/bin/ffmpeg"
|
||||||
# run ffmpeg to show completion
|
# run ffmpeg to show completion
|
||||||
"${ffmpegBin}" -version
|
"${ffmpegBin}" -version || return 1
|
||||||
|
|
||||||
# suggestion for path
|
# suggestion for path
|
||||||
hash -r
|
hash -r
|
||||||
@@ -494,10 +659,21 @@ sanitize_sysroot_libs() {
|
|||||||
|
|
||||||
for lib in "${libs[@]}"; do
|
for lib in "${libs[@]}"; do
|
||||||
local libPath="${LIBDIR}/${lib}"
|
local libPath="${LIBDIR}/${lib}"
|
||||||
local useLib="${libPath}.${USE_LIB_SUFF}"
|
local foundLib=false
|
||||||
|
|
||||||
if [[ ! -f ${useLib} ]]; then
|
for useLib in "${libPath}"*"${USE_LIB_SUFF}"; do
|
||||||
echo_fail "could not find ${useLib}, something is wrong"
|
test -f "${useLib}" || continue
|
||||||
|
foundLib=true
|
||||||
|
# darwin sometimes fails to set rpath correctly
|
||||||
|
if is_darwin && [[ ${STATIC} == 'OFF' ]]; then
|
||||||
|
install_name_tool \
|
||||||
|
-id "${useLib}" \
|
||||||
|
"${useLib}" || return 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ${foundLib} == false ]]; then
|
||||||
|
echo_fail "could not find ${libPath}*${USE_LIB_SUFF}, something is wrong"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -548,11 +724,15 @@ del_pkgconfig_gcc_s() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
### RUST ###
|
### RUST ###
|
||||||
cargo_cbuild() {
|
meta_cargoc_build() {
|
||||||
local destdir="${PWD}/fb-local-install"
|
local destdir="${PWD}/fb-local-install"
|
||||||
cargo cinstall \
|
# let rust handle its own lto/pgo
|
||||||
|
local newCflags="${CFLAGS//${LTO_FLAG}/}"
|
||||||
|
newCflags="${newCflags//${PGO_FLAG}/}"
|
||||||
|
|
||||||
|
CFLAGS="${newCflags}" cargo cinstall \
|
||||||
--destdir "${destdir}" \
|
--destdir "${destdir}" \
|
||||||
"${CARGO_CINSTALL_FLAGS[@]}"
|
"${CARGO_CINSTALL_FLAGS[@]}" || return 1
|
||||||
# cargo cinstall destdir prepends with entire prefix
|
# cargo cinstall destdir prepends with entire prefix
|
||||||
# this breaks windows with msys path augmentation
|
# this breaks windows with msys path augmentation
|
||||||
# so recurse into directories until sysroot is there
|
# so recurse into directories until sysroot is there
|
||||||
@@ -562,25 +742,25 @@ cargo_cbuild() {
|
|||||||
build_hdr10plus_tool() {
|
build_hdr10plus_tool() {
|
||||||
# build libhdr10plus
|
# build libhdr10plus
|
||||||
cd hdr10plus || return 1
|
cd hdr10plus || return 1
|
||||||
cargo_cbuild || return 1
|
meta_cargoc_build || return 1
|
||||||
sanitize_sysroot_libs libhdr10plus-rs || return 1
|
sanitize_sysroot_libs libhdr10plus-rs || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_dovi_tool() {
|
build_dovi_tool() {
|
||||||
# build libdovi
|
# build libdovi
|
||||||
cd dolby_vision || return 1
|
cd dolby_vision || return 1
|
||||||
cargo_cbuild || return 1
|
meta_cargoc_build || return 1
|
||||||
sanitize_sysroot_libs libdovi || return 1
|
sanitize_sysroot_libs libdovi || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_librav1e() {
|
build_librav1e() {
|
||||||
cargo_cbuild || return 1
|
meta_cargoc_build || return 1
|
||||||
sanitize_sysroot_libs librav1e || return 1
|
sanitize_sysroot_libs librav1e || return 1
|
||||||
del_pkgconfig_gcc_s rav1e.pc || return 1
|
del_pkgconfig_gcc_s rav1e.pc || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
### CMAKE ###
|
### CMAKE ###
|
||||||
cmake_build() {
|
meta_cmake_build() {
|
||||||
local addFlags=("$@")
|
local addFlags=("$@")
|
||||||
# configure
|
# configure
|
||||||
cmake \
|
cmake \
|
||||||
@@ -598,16 +778,19 @@ cmake_build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build_cpuinfo() {
|
build_cpuinfo() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
|
-DCPUINFO_LIBRARY_TYPE="${BUILD_TYPE}" \
|
||||||
|
-DCPUINFO_RUNTIME_TYPE="${BUILD_TYPE}" \
|
||||||
-DCPUINFO_BUILD_UNIT_TESTS=OFF \
|
-DCPUINFO_BUILD_UNIT_TESTS=OFF \
|
||||||
-DCPUINFO_BUILD_MOCK_TESTS=OFF \
|
-DCPUINFO_BUILD_MOCK_TESTS=OFF \
|
||||||
-DCPUINFO_BUILD_BENCHMARKS=OFF \
|
-DCPUINFO_BUILD_BENCHMARKS=OFF \
|
||||||
|
-DCPUINFO_LOG_TO_STDIO=ON \
|
||||||
-DUSE_SYSTEM_LIBS=ON || return 1
|
-DUSE_SYSTEM_LIBS=ON || return 1
|
||||||
sanitize_sysroot_libs libcpuinfo || return 1
|
sanitize_sysroot_libs libcpuinfo || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_libsvtav1() {
|
build_libsvtav1() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
-DENABLE_AVX512=ON \
|
-DENABLE_AVX512=ON \
|
||||||
-DBUILD_TESTING=OFF \
|
-DBUILD_TESTING=OFF \
|
||||||
-DCOVERAGE=OFF || return 1
|
-DCOVERAGE=OFF || return 1
|
||||||
@@ -615,7 +798,7 @@ build_libsvtav1() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build_libsvtav1_psy() {
|
build_libsvtav1_psy() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
-DBUILD_TESTING=OFF \
|
-DBUILD_TESTING=OFF \
|
||||||
-DENABLE_AVX512=ON \
|
-DENABLE_AVX512=ON \
|
||||||
-DCOVERAGE=OFF \
|
-DCOVERAGE=OFF \
|
||||||
@@ -625,47 +808,64 @@ build_libsvtav1_psy() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build_libaom() {
|
build_libaom() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
-DENABLE_TESTS=OFF || return 1
|
-DENABLE_TESTS=OFF || return 1
|
||||||
sanitize_sysroot_libs libaom || return 1
|
sanitize_sysroot_libs libaom || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_libopus() {
|
build_libopus() {
|
||||||
cmake_build || return 1
|
meta_cmake_build || return 1
|
||||||
sanitize_sysroot_libs libopus || return 1
|
sanitize_sysroot_libs libopus || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_libvorbis() {
|
||||||
|
meta_cmake_build || return 1
|
||||||
|
sanitize_sysroot_libs \
|
||||||
|
libvorbis libvorbisenc libvorbisfile || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libogg() {
|
||||||
|
meta_cmake_build || return 1
|
||||||
|
sanitize_sysroot_libs libogg || return 1
|
||||||
|
}
|
||||||
|
|
||||||
build_libwebp() {
|
build_libwebp() {
|
||||||
cmake_build || return 1
|
if is_android; then
|
||||||
|
replace_line CMakeLists.txt \
|
||||||
|
"if(ANDROID)" \
|
||||||
|
"if(FALSE)\n"
|
||||||
|
fi
|
||||||
|
|
||||||
|
meta_cmake_build || return 1
|
||||||
sanitize_sysroot_libs libwebp libsharpyuv || return 1
|
sanitize_sysroot_libs libwebp libsharpyuv || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_libjpeg() {
|
build_libjpeg() {
|
||||||
cmake_build || return 1
|
meta_cmake_build || return 1
|
||||||
sanitize_sysroot_libs libjpeg libturbojpeg || return 1
|
sanitize_sysroot_libs libjpeg libturbojpeg || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_libpng() {
|
build_libpng() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
-DPNG_TESTS=OFF \
|
-DPNG_TESTS=OFF \
|
||||||
-DPNG_TOOLS=OFF || return 1
|
-DPNG_TOOLS=OFF || return 1
|
||||||
sanitize_sysroot_libs libpng || return 1
|
sanitize_sysroot_libs libpng || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_zlib() {
|
build_zlib() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
-DZLIB_BUILD_EXAMPLES=OFF || return 1
|
-DZLIB_BUILD_EXAMPLES=OFF || return 1
|
||||||
sanitize_sysroot_libs libz || return 1
|
sanitize_sysroot_libs libz || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_glslang() {
|
build_glslang() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
-DALLOW_EXTERNAL_SPIRV_TOOLS=ON || return 1
|
-DALLOW_EXTERNAL_SPIRV_TOOLS=ON || return 1
|
||||||
sanitize_sysroot_libs libglslang || return 1
|
sanitize_sysroot_libs libglslang || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_spirv_tools() {
|
build_spirv_tools() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
-DSPIRV-Headers_SOURCE_DIR="${PREFIX}" \
|
-DSPIRV-Headers_SOURCE_DIR="${PREFIX}" \
|
||||||
-DSPIRV_WERROR=OFF \
|
-DSPIRV_WERROR=OFF \
|
||||||
-DSPIRV_SKIP_TESTS=ON \
|
-DSPIRV_SKIP_TESTS=ON \
|
||||||
@@ -673,48 +873,18 @@ build_spirv_tools() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
build_spirv_headers() {
|
build_spirv_headers() {
|
||||||
cmake_build \
|
meta_cmake_build \
|
||||||
-G Ninja || return 1
|
-G Ninja || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# libx265 does not support cmake >= 4
|
|
||||||
build_cmake3() {
|
|
||||||
local cmakeVersion verMajor
|
|
||||||
# don't need to build if system version is below 4
|
|
||||||
IFS=$' \t' read -r _ _ cmakeVersion <<<"$(cmake --version)"
|
|
||||||
IFS='.' read -r verMajor _ _ <<<"${cmakeVersion}"
|
|
||||||
if [[ ${verMajor} -lt 4 ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# don't need to rebuild if already built
|
|
||||||
local cmake="${LOCAL_PREFIX}/bin/cmake"
|
|
||||||
if [[ -f ${cmake} ]]; then
|
|
||||||
IFS=$' \t' read -r _ _ cmakeVersion <<<"$("${cmake}" --version)"
|
|
||||||
IFS='.' read -r verMajor _ _ <<<"${cmakeVersion}"
|
|
||||||
if [[ ${verMajor} -lt 4 ]]; then
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
local overrideFlags=(
|
|
||||||
"-DCMAKE_BUILD_TYPE=Release"
|
|
||||||
"-DCMAKE_PREFIX_PATH=${LOCAL_PREFIX}"
|
|
||||||
"-DCMAKE_INSTALL_PREFIX=${LOCAL_PREFIX}"
|
|
||||||
)
|
|
||||||
# reuse variables
|
|
||||||
for flag in "${CMAKE_FLAGS[@]}"; do
|
|
||||||
if line_contains "${flag}" 'CMAKE_INSTALL_LIBDIR' ||
|
|
||||||
line_contains "${flag}" 'COMPILER_LAUNCHER'; then
|
|
||||||
overrideFlags+=("${flag}")
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
CMAKE_FLAGS='' cmake_build \
|
|
||||||
"${overrideFlags[@]}" || return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
build_libx265() {
|
build_libx265() {
|
||||||
PATH="${LOCAL_PREFIX}/bin:${PATH}" cmake_build \
|
# libx265 does not support cmake >= 4
|
||||||
|
if using_cmake_4; then
|
||||||
|
remove_line "source/CMakeLists.txt" "cmake_policy(SET CMP0025 OLD)" || return 1
|
||||||
|
remove_line "source/CMakeLists.txt" "cmake_policy(SET CMP0054 OLD)" || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
meta_cmake_build \
|
||||||
-DHIGH_BIT_DEPTH=ON \
|
-DHIGH_BIT_DEPTH=ON \
|
||||||
-DENABLE_HDR10_PLUS=OFF \
|
-DENABLE_HDR10_PLUS=OFF \
|
||||||
-S source || return 1
|
-S source || return 1
|
||||||
@@ -723,7 +893,7 @@ build_libx265() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
### MESON ###
|
### MESON ###
|
||||||
meson_build() {
|
meta_meson_build() {
|
||||||
local addFlags=("$@")
|
local addFlags=("$@")
|
||||||
meson setup \
|
meson setup \
|
||||||
"${MESON_FLAGS[@]}" \
|
"${MESON_FLAGS[@]}" \
|
||||||
@@ -742,7 +912,7 @@ build_libdav1d() {
|
|||||||
if [[ "${HOSTTYPE}:${OPT}" == "aarch64:0" ]]; then
|
if [[ "${HOSTTYPE}:${OPT}" == "aarch64:0" ]]; then
|
||||||
enableAsm=false
|
enableAsm=false
|
||||||
fi
|
fi
|
||||||
meson_build \
|
meta_meson_build \
|
||||||
-D enable_asm=${enableAsm} || return 1
|
-D enable_asm=${enableAsm} || return 1
|
||||||
sanitize_sysroot_libs libdav1d || return 1
|
sanitize_sysroot_libs libdav1d || return 1
|
||||||
}
|
}
|
||||||
@@ -751,13 +921,13 @@ build_libplacebo() {
|
|||||||
# copy downloaded glad release as "submodule"
|
# copy downloaded glad release as "submodule"
|
||||||
(
|
(
|
||||||
installDir="${PWD}/3rdparty/glad"
|
installDir="${PWD}/3rdparty/glad"
|
||||||
get_build_conf glad
|
get_build_conf glad || exit 1
|
||||||
CLEAN=OFF download_release
|
CLEAN=OFF download_release || exit 1
|
||||||
cd "${extractedDir}" || exit 1
|
cd "${extractedDir}" || exit 1
|
||||||
cp -r ./* "${installDir}"
|
cp -r ./* "${installDir}"
|
||||||
) || return 1
|
) || return 1
|
||||||
|
|
||||||
meson_build \
|
meta_meson_build \
|
||||||
-D tests=false \
|
-D tests=false \
|
||||||
-D demos=false || return 1
|
-D demos=false || return 1
|
||||||
sanitize_sysroot_libs libplacebo || return 1
|
sanitize_sysroot_libs libplacebo || return 1
|
||||||
@@ -765,10 +935,10 @@ build_libplacebo() {
|
|||||||
|
|
||||||
build_libvmaf() {
|
build_libvmaf() {
|
||||||
cd libvmaf || return 1
|
cd libvmaf || return 1
|
||||||
python3 -m virtualenv .venv
|
virtualenv .venv
|
||||||
(
|
(
|
||||||
source .venv/bin/activate
|
source .venv/bin/activate
|
||||||
meson_build \
|
meta_meson_build \
|
||||||
-D enable_float=true || exit 1
|
-D enable_float=true || exit 1
|
||||||
) || return 1
|
) || return 1
|
||||||
sanitize_sysroot_libs libvmaf || return 1
|
sanitize_sysroot_libs libvmaf || return 1
|
||||||
@@ -794,15 +964,39 @@ build_libvmaf() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_freetype() {
|
||||||
|
meta_meson_build \
|
||||||
|
-D tests=disabled || return 1
|
||||||
|
sanitize_sysroot_libs libfreetype || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
build_harfbuzz() {
|
||||||
|
meta_meson_build \
|
||||||
|
-D tests=disabled \
|
||||||
|
-D docs=disabled \
|
||||||
|
-D doc_tests=false || return 1
|
||||||
|
sanitize_sysroot_libs libharfbuzz || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
build_fribidi() {
|
||||||
|
meta_meson_build \
|
||||||
|
-D tests=false || return 1
|
||||||
|
sanitize_sysroot_libs libfribidi || return 1
|
||||||
|
}
|
||||||
|
|
||||||
### PYTHON ###
|
### PYTHON ###
|
||||||
build_glad() {
|
build_glad() {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
### AUTOTOOLS ###
|
### AUTOTOOLS ###
|
||||||
configure_build() {
|
meta_configure_build() {
|
||||||
local addFlags=("$@")
|
local addFlags=("$@")
|
||||||
local configureFlags=()
|
local configureFlags=()
|
||||||
|
# backup global variable for re-setting
|
||||||
|
# after build is complete
|
||||||
|
local cflagsBackup="${CFLAGS}"
|
||||||
|
local ldflagsBackup="${LDFLAGS}"
|
||||||
|
|
||||||
# some builds break with LTO
|
# some builds break with LTO
|
||||||
if [[ ${LTO} == 'OFF' ]]; then
|
if [[ ${LTO} == 'OFF' ]]; then
|
||||||
@@ -810,6 +1004,8 @@ configure_build() {
|
|||||||
test "${flag}" == '--enable-lto' && continue
|
test "${flag}" == '--enable-lto' && continue
|
||||||
configureFlags+=("${flag}")
|
configureFlags+=("${flag}")
|
||||||
done
|
done
|
||||||
|
CFLAGS="${CFLAGS//${LTO_FLAG}/}"
|
||||||
|
LDFLAGS="${LDFLAGS//${LTO_FLAG}/}"
|
||||||
else
|
else
|
||||||
configureFlags+=("${CONFIGURE_FLAGS[@]}")
|
configureFlags+=("${CONFIGURE_FLAGS[@]}")
|
||||||
fi
|
fi
|
||||||
@@ -819,30 +1015,52 @@ configure_build() {
|
|||||||
"${configureFlags[@]}" \
|
"${configureFlags[@]}" \
|
||||||
"${addFlags[@]}" || return 1
|
"${addFlags[@]}" || return 1
|
||||||
# build
|
# build
|
||||||
|
# attempt to build twice since build can fail due to OOM
|
||||||
|
ccache make -j"${JOBS}" ||
|
||||||
ccache make -j"${JOBS}" || return 1
|
ccache make -j"${JOBS}" || return 1
|
||||||
# install
|
# install
|
||||||
local destdir="${PWD}/fb-local-install"
|
local destdir="${PWD}/fb-local-install"
|
||||||
make -j"${JOBS}" DESTDIR="${destdir}" install || return 1
|
make -j"${JOBS}" DESTDIR="${destdir}" install || return 1
|
||||||
install_local_destdir "${destdir}" || return 1
|
install_local_destdir "${destdir}" || return 1
|
||||||
|
|
||||||
|
# reset global variables
|
||||||
|
CFLAGS="${cflagsBackup}"
|
||||||
|
LDFLAGS="${ldflagsBackup}"
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libvpx() {
|
||||||
|
meta_configure_build \
|
||||||
|
--disable-examples \
|
||||||
|
--disable-tools \
|
||||||
|
--disable-docs \
|
||||||
|
--disable-unit-tests \
|
||||||
|
--disable-decode-perf-tests \
|
||||||
|
--disable-encode-perf-tests \
|
||||||
|
--enable-vp8 \
|
||||||
|
--enable-vp9 \
|
||||||
|
--enable-vp9-highbitdepth \
|
||||||
|
--enable-better-hw-compatibility \
|
||||||
|
--enable-webm-io \
|
||||||
|
--enable-libyuv || return 1
|
||||||
|
sanitize_sysroot_libs libvpx || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_libx264() {
|
build_libx264() {
|
||||||
# libx264 does not support LTO
|
# libx264 breaks with LTO
|
||||||
LTO=OFF configure_build \
|
LTO=OFF meta_configure_build \
|
||||||
--disable-cli || return 1
|
--disable-cli \
|
||||||
|
--disable-avs \
|
||||||
|
--disable-swscale \
|
||||||
|
--disable-lavf \
|
||||||
|
--disable-ffms \
|
||||||
|
--disable-gpac || return 1
|
||||||
sanitize_sysroot_libs libx264 || return 1
|
sanitize_sysroot_libs libx264 || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
build_libmp3lame() {
|
build_libmp3lame() {
|
||||||
# https://sourceforge.net/p/lame/mailman/message/36081038/
|
meta_configure_build \
|
||||||
if is_darwin; then
|
--enable-nasm \
|
||||||
remove_line \
|
--disable-frontend || return 1
|
||||||
'include/libmp3lame.sym' \
|
|
||||||
'lame_init_old' || return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
configure_build \
|
|
||||||
--enable-nasm || return 1
|
|
||||||
sanitize_sysroot_libs libmp3lame || return 1
|
sanitize_sysroot_libs libmp3lame || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -850,10 +1068,20 @@ build_libnuma() {
|
|||||||
if ! is_linux; then return 0; fi
|
if ! is_linux; then return 0; fi
|
||||||
|
|
||||||
./autogen.sh || return 1
|
./autogen.sh || return 1
|
||||||
configure_build || return 1
|
meta_configure_build || return 1
|
||||||
sanitize_sysroot_libs libnuma || return 1
|
sanitize_sysroot_libs libnuma || return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_libunibreak() {
|
||||||
|
meta_configure_build || return 1
|
||||||
|
sanitize_sysroot_libs libunibreak || return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
build_libass() {
|
||||||
|
meta_configure_build || return 1
|
||||||
|
sanitize_sysroot_libs libass || return 1
|
||||||
|
}
|
||||||
|
|
||||||
add_project_versioning_to_ffmpeg() {
|
add_project_versioning_to_ffmpeg() {
|
||||||
# embed this project's enables/versions
|
# embed this project's enables/versions
|
||||||
# into ffmpeg with FFMPEG_BUILDER_INFO
|
# into ffmpeg with FFMPEG_BUILDER_INFO
|
||||||
@@ -876,34 +1104,10 @@ add_project_versioning_to_ffmpeg() {
|
|||||||
echo_fail "could not find ${fname} to add project versioning"
|
echo_fail "could not find ${fname} to add project versioning"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local searchFor='static void print_all_libs_info'
|
local printLibLine='print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);'
|
||||||
local foundUsageStart=0
|
local newPrintLibLine="${printLibLine} "
|
||||||
local newOptFile="${TMP_DIR}/${fname}"
|
newPrintLibLine+="$(printf 'av_log(NULL, AV_LOG_INFO, "%s\\\\n"); ' "${FFMPEG_BUILDER_INFO[@]}")"
|
||||||
test -f "${newOptFile}" && rm "${newOptFile}"
|
replace_line "${optFile}" "${printLibLine}" "${newPrintLibLine}" || return 1
|
||||||
while read -r line; do
|
|
||||||
# if we found the line previously, add the versioning
|
|
||||||
if [[ ${foundUsageStart} -eq 1 ]]; then
|
|
||||||
if line_starts_with "${line}" '}'; then
|
|
||||||
echo_info "found ${line} on ${lineNum}"
|
|
||||||
for info in "${FFMPEG_BUILDER_INFO[@]}"; do
|
|
||||||
local newline="av_log(NULL, AV_LOG_INFO, \"${info}\n\");"
|
|
||||||
echo "${newline}" >>"${newOptFile}"
|
|
||||||
lineNum=$((lineNum + 1))
|
|
||||||
done
|
|
||||||
newline="av_log(NULL, AV_LOG_INFO, \"\n\");"
|
|
||||||
echo "${newline}" >>"${newOptFile}"
|
|
||||||
foundUsageStart=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
# find the line we are searching for
|
|
||||||
if line_contains "${line}" "${searchFor}"; then
|
|
||||||
foundUsageStart=1
|
|
||||||
fi
|
|
||||||
# start building the new file
|
|
||||||
echo "${line}" >>"${newOptFile}"
|
|
||||||
done <"${optFile}"
|
|
||||||
|
|
||||||
cp "${newOptFile}" "${optFile}" || return 1
|
|
||||||
|
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@@ -930,17 +1134,24 @@ build_ffmpeg() {
|
|||||||
|
|
||||||
# lto is broken on darwin for ffmpeg only
|
# lto is broken on darwin for ffmpeg only
|
||||||
# https://trac.ffmpeg.org/ticket/11479
|
# https://trac.ffmpeg.org/ticket/11479
|
||||||
|
local ltoBackup="${LTO}"
|
||||||
if is_darwin; then
|
if is_darwin; then
|
||||||
LTO=OFF
|
LTO=OFF
|
||||||
for flag in "${FFMPEG_EXTRA_FLAGS[@]}"; do
|
for flag in "${FFMPEG_EXTRA_FLAGS[@]}"; do
|
||||||
ffmpegFlags+=("${flag// ${LTO_FLAG}/}")
|
if line_contains "${flag}" "${LTO_FLAG}"; then
|
||||||
|
# get rid of potential space on either side
|
||||||
|
flag="${flag//${LTO_FLAG} /}"
|
||||||
|
flag="${flag// ${LTO_FLAG}/}"
|
||||||
|
fi
|
||||||
|
ffmpegFlags+=("${flag}")
|
||||||
done
|
done
|
||||||
else
|
else
|
||||||
ffmpegFlags+=("${FFMPEG_EXTRA_FLAGS[@]}")
|
ffmpegFlags+=("${FFMPEG_EXTRA_FLAGS[@]}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
configure_build \
|
meta_configure_build \
|
||||||
"${ffmpegFlags[@]}" || return 1
|
"${ffmpegFlags[@]}" || return 1
|
||||||
|
LTO="${ltoBackup}"
|
||||||
${SUDO_MODIFY} cp ff*_g "${PREFIX}/bin"
|
${SUDO_MODIFY} cp ff*_g "${PREFIX}/bin"
|
||||||
sanitize_sysroot_libs \
|
sanitize_sysroot_libs \
|
||||||
libavcodec libavdevice libavfilter libswscale \
|
libavcodec libavdevice libavfilter libswscale \
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ DEFAULT_CLEAN=ON
|
|||||||
FB_COMP_OPTS_DESC['LTO']='enable link time optimization'
|
FB_COMP_OPTS_DESC['LTO']='enable link time optimization'
|
||||||
DEFAULT_LTO=ON
|
DEFAULT_LTO=ON
|
||||||
|
|
||||||
|
FB_COMP_OPTS_DESC['PGO']='enable profile guided optimization'
|
||||||
|
DEFAULT_PGO=OFF
|
||||||
|
|
||||||
FB_COMP_OPTS_DESC['OPT']='optimization level (0-3)'
|
FB_COMP_OPTS_DESC['OPT']='optimization level (0-3)'
|
||||||
DEFAULT_OPT=3
|
DEFAULT_OPT=3
|
||||||
|
|
||||||
@@ -37,13 +40,14 @@ libvmaf \
|
|||||||
libx264 \
|
libx264 \
|
||||||
libx265 \
|
libx265 \
|
||||||
libwebp \
|
libwebp \
|
||||||
|
libvpx \
|
||||||
|
libass \
|
||||||
|
libvorbis \
|
||||||
libmp3lame\
|
libmp3lame\
|
||||||
"
|
"
|
||||||
|
|
||||||
# user-overridable compile option variable names
|
# user-overridable compile option variable names
|
||||||
FB_COMP_OPTS=(
|
FB_COMP_OPTS=("${!FB_COMP_OPTS_DESC[@]}")
|
||||||
CLEAN LTO OPT STATIC ARCH PREFIX ENABLE
|
|
||||||
)
|
|
||||||
|
|
||||||
# sets FB_COMP_OPTS to allow for user-overriding
|
# sets FB_COMP_OPTS to allow for user-overriding
|
||||||
check_compile_opts_override() {
|
check_compile_opts_override() {
|
||||||
|
|||||||
@@ -11,8 +11,7 @@ DOCKER_WORKDIR='/workdir'
|
|||||||
set_docker_run_flags() {
|
set_docker_run_flags() {
|
||||||
local cargo_git="${IGN_DIR}/cargo/git"
|
local cargo_git="${IGN_DIR}/cargo/git"
|
||||||
local cargo_registry="${IGN_DIR}/cargo/registry"
|
local cargo_registry="${IGN_DIR}/cargo/registry"
|
||||||
test -d "${cargo_git}" || mkdir -p "${cargo_git}"
|
ensure_dir "${cargo_git}" "${cargo_registry}"
|
||||||
test -d "${cargo_registry}" || mkdir -p "${cargo_registry}"
|
|
||||||
DOCKER_RUN_FLAGS=(
|
DOCKER_RUN_FLAGS=(
|
||||||
--rm
|
--rm
|
||||||
-v "${cargo_git}:/root/.cargo/git"
|
-v "${cargo_git}:/root/.cargo/git"
|
||||||
@@ -20,6 +19,7 @@ set_docker_run_flags() {
|
|||||||
-v "${REPO_DIR}:${REPO_DIR}"
|
-v "${REPO_DIR}:${REPO_DIR}"
|
||||||
-w "${REPO_DIR}"
|
-w "${REPO_DIR}"
|
||||||
-e "DEBUG=${DEBUG}"
|
-e "DEBUG=${DEBUG}"
|
||||||
|
-t
|
||||||
)
|
)
|
||||||
for opt in "${FB_COMP_OPTS[@]}"; do
|
for opt in "${FB_COMP_OPTS[@]}"; do
|
||||||
declare -n defOptVal="DEFAULT_${opt}"
|
declare -n defOptVal="DEFAULT_${opt}"
|
||||||
@@ -43,10 +43,10 @@ get_docker_image_tag() {
|
|||||||
local image="$1"
|
local image="$1"
|
||||||
local tag=''
|
local tag=''
|
||||||
case "${image}" in
|
case "${image}" in
|
||||||
ubuntu) tag='ubuntu:24.04@sha256:9cbed754112939e914291337b5e554b07ad7c392491dba6daf25eef1332a22e8' ;;
|
ubuntu) tag='ubuntu:24.04@sha256:c35e29c9450151419d9448b0fd75374fec4fff364a27f176fb458d472dfc9e54' ;;
|
||||||
debian) tag='debian:13@sha256:833c135acfe9521d7a0035a296076f98c182c542a2b6b5a0fd7063d355d696be' ;;
|
debian) tag='debian:13@sha256:0d01188e8dd0ac63bf155900fad49279131a876a1ea7fac917c62e87ccb2732d' ;;
|
||||||
fedora) tag='fedora:42@sha256:6af051ad0a294182c3a957961df6203d91f643880aa41c2ffe3d1302e7505890' ;;
|
fedora) tag='fedora:42@sha256:b3d16134560afa00d7cc2a9e4967eb5b954512805f3fe27d8e70bbed078e22ea' ;;
|
||||||
archlinux) tag='ogarcia/archlinux:latest@sha256:b93f426b23cd0ea0e1befd7d58a26eaf3e6eda3c154c0e8dd75145d11c21304c' ;;
|
archlinux) tag='ogarcia/archlinux:latest@sha256:1d70273180e43b1f51b41514bdaa73c61f647891a53a9c301100d5c4807bf628' ;;
|
||||||
esac
|
esac
|
||||||
echo "${tag}"
|
echo "${tag}"
|
||||||
}
|
}
|
||||||
@@ -111,7 +111,7 @@ docker_build_image() {
|
|||||||
echo_info "sourcing package manager for ${image}"
|
echo_info "sourcing package manager for ${image}"
|
||||||
local dockerDistro="$(get_docker_image_tag "${image}")"
|
local dockerDistro="$(get_docker_image_tag "${image}")"
|
||||||
# specific file for evaluated package manager info
|
# specific file for evaluated package manager info
|
||||||
distroPkgMgr="${DOCKER_DIR}/$(bash_basename "${image}")-pkg_mgr"
|
local distroPkgMgr="${DOCKER_DIR}/$(bash_basename "${image}")-pkg_mgr"
|
||||||
# get package manager info
|
# get package manager info
|
||||||
docker run \
|
docker run \
|
||||||
"${DOCKER_RUN_FLAGS[@]}" \
|
"${DOCKER_RUN_FLAGS[@]}" \
|
||||||
@@ -122,25 +122,14 @@ docker_build_image() {
|
|||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
source "${distroPkgMgr}"
|
source "${distroPkgMgr}"
|
||||||
|
|
||||||
dockerfile="${DOCKER_DIR}/Dockerfile_$(bash_basename "${image}")"
|
local dockerfile="${DOCKER_DIR}/Dockerfile_$(bash_basename "${image}")"
|
||||||
|
local embedPath='/Dockerfile'
|
||||||
{
|
{
|
||||||
echo "FROM ${dockerDistro}"
|
echo "FROM ${dockerDistro}"
|
||||||
echo 'SHELL ["/bin/bash", "-c"]'
|
echo 'SHELL ["/bin/bash", "-c"]'
|
||||||
echo 'RUN ln -sf /bin/bash /bin/sh'
|
echo 'RUN ln -sf /bin/bash /bin/sh'
|
||||||
echo 'ENV DEBIAN_FRONTEND=noninteractive'
|
echo 'ENV DEBIAN_FRONTEND=noninteractive'
|
||||||
# arch is rolling release, so highly likely
|
echo "RUN ${pkg_mgr_update} && ${pkg_mgr_upgrade} && ${pkg_install} ${req_pkgs[*]}"
|
||||||
# an updated is required between pkg changes
|
|
||||||
if line_contains "${dockerDistro}" 'arch'; then
|
|
||||||
local archRuns=''
|
|
||||||
archRuns+="${pkg_mgr_update}"
|
|
||||||
archRuns+=" && ${pkg_mgr_upgrade}"
|
|
||||||
archRuns+=" && ${pkg_install} ${req_pkgs[*]}"
|
|
||||||
echo "RUN ${archRuns}"
|
|
||||||
else
|
|
||||||
echo "RUN ${pkg_mgr_update}"
|
|
||||||
echo "RUN ${pkg_mgr_upgrade}"
|
|
||||||
printf "RUN ${pkg_install} %s\n" "${req_pkgs[@]}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# ENV for pipx/rust
|
# ENV for pipx/rust
|
||||||
echo 'ENV PIPX_HOME=/root/.local'
|
echo 'ENV PIPX_HOME=/root/.local'
|
||||||
@@ -169,7 +158,7 @@ docker_build_image() {
|
|||||||
echo "RUN pipx install virtualenv"
|
echo "RUN pipx install virtualenv"
|
||||||
# rust
|
# rust
|
||||||
local rustupVersion='1.28.2'
|
local rustupVersion='1.28.2'
|
||||||
local rustcVersion='1.88.0'
|
local rustcVersion='1.90.0'
|
||||||
local rustupTarball="rustup-${rustupVersion}.tar.gz"
|
local rustupTarball="rustup-${rustupVersion}.tar.gz"
|
||||||
local rustupTarballPath="${DOCKER_DIR}/${rustupTarball}"
|
local rustupTarballPath="${DOCKER_DIR}/${rustupTarball}"
|
||||||
if [[ ! -f ${rustupTarballPath} ]]; then
|
if [[ ! -f ${rustupTarballPath} ]]; then
|
||||||
@@ -177,19 +166,40 @@ docker_build_image() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo "ADD ${rustupTarball} /tmp/"
|
echo "ADD ${rustupTarball} /tmp/"
|
||||||
local cargoInst="\
|
echo "RUN cd /tmp/rustup-${rustupVersion} && bash rustup-init.sh -y --default-toolchain=${rustcVersion}"
|
||||||
cd /tmp/rustup-${rustupVersion} \
|
|
||||||
&& bash rustup-init.sh -y --default-toolchain=${rustcVersion}"
|
|
||||||
echo "RUN ${cargoInst}"
|
|
||||||
# install cargo-binstall
|
# install cargo-binstall
|
||||||
echo "RUN curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash"
|
echo "RUN curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash"
|
||||||
# install cargo-c
|
# install cargo-c
|
||||||
echo "RUN cargo-binstall -y cargo-c"
|
echo "RUN cargo-binstall -y cargo-c"
|
||||||
|
|
||||||
|
# final mods for PS1
|
||||||
|
echo
|
||||||
|
echo 'USER root'
|
||||||
|
echo "RUN echo \"PS1='id=\\\$(id -u)@${image}:\w\\$ '\" >> /etc/bash.bashrc"
|
||||||
|
echo 'USER 65534:65534'
|
||||||
|
echo
|
||||||
|
|
||||||
|
# embed dockerfile into docker image itself
|
||||||
|
# shellcheck disable=SC2094
|
||||||
|
echo "COPY $(bash_basename "${dockerfile}") ${embedPath}"
|
||||||
|
|
||||||
echo "WORKDIR ${DOCKER_WORKDIR}"
|
echo "WORKDIR ${DOCKER_WORKDIR}"
|
||||||
|
|
||||||
} >"${dockerfile}"
|
} >"${dockerfile}"
|
||||||
|
|
||||||
|
# docker buildx is too aggressive with invalidating
|
||||||
|
# build layer caches. Instead of relying on docker
|
||||||
|
# to check for when to rebuild, compare the to-build
|
||||||
|
# dockerfile with the embedded dockerfile
|
||||||
|
local oldDockerfile="${dockerfile}.old"
|
||||||
|
docker_run_image "${image}" cp "${embedPath}" "${oldDockerfile}"
|
||||||
|
if diff "${dockerfile}" "${oldDockerfile}"; then
|
||||||
|
echo_pass "no dockerfile changes detected, skipping rebuild"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo_warn "dockerfile changes detected, proceeding with build"
|
||||||
|
fi
|
||||||
|
|
||||||
image_tag="$(set_distro_image_tag "${image}")"
|
image_tag="$(set_distro_image_tag "${image}")"
|
||||||
docker buildx build \
|
docker buildx build \
|
||||||
--platform "${PLATFORM}" \
|
--platform "${PLATFORM}" \
|
||||||
@@ -207,9 +217,6 @@ docker_build_image() {
|
|||||||
-f "${dockerfile}" \
|
-f "${dockerfile}" \
|
||||||
"${DOCKER_DIR}" || return 1
|
"${DOCKER_DIR}" || return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# FIXME uncomment
|
|
||||||
# docker system prune -f
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FB_FUNC_NAMES+=('docker_save_image')
|
FB_FUNC_NAMES+=('docker_save_image')
|
||||||
@@ -237,8 +244,7 @@ docker_load_image() {
|
|||||||
echo_info "loading docker image for ${image_tag}"
|
echo_info "loading docker image for ${image_tag}"
|
||||||
local archive="${DOCKER_DIR}/$(docker_image_archive_name "${image_tag}")"
|
local archive="${DOCKER_DIR}/$(docker_image_archive_name "${image_tag}")"
|
||||||
test -f "$archive" || return 1
|
test -f "$archive" || return 1
|
||||||
zstdcat -T0 "$archive" |
|
zstdcat -T0 "$archive" | docker load || return 1
|
||||||
docker load || return 1
|
|
||||||
docker system prune -f
|
docker system prune -f
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +265,7 @@ docker_run_image() {
|
|||||||
runCmd+=("${cmd[@]}")
|
runCmd+=("${cmd[@]}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
image_tag="$(set_distro_image_tag "${image}")"
|
local image_tag="$(set_distro_image_tag "${image}")"
|
||||||
|
|
||||||
# if a docker registry is defined, pull from it
|
# if a docker registry is defined, pull from it
|
||||||
if [[ ${DOCKER_REGISTRY} != '' ]]; then
|
if [[ ${DOCKER_REGISTRY} != '' ]]; then
|
||||||
@@ -269,16 +275,16 @@ docker_run_image() {
|
|||||||
docker tag "${DOCKER_REGISTRY}/${image_tag}" "${image_tag}"
|
docker tag "${DOCKER_REGISTRY}/${image_tag}" "${image_tag}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo_info "running ffmpeg build with ${image_tag}"
|
echo_info "running docker image ${image_tag}"
|
||||||
docker run \
|
docker run \
|
||||||
"${DOCKER_RUN_FLAGS[@]}" \
|
"${DOCKER_RUN_FLAGS[@]}" \
|
||||||
-u "$(id -u):$(id -g)" \
|
-u "$(id -u):$(id -g)" \
|
||||||
"${image_tag}" \
|
"${image_tag}" \
|
||||||
"${runCmd[@]}" || return 1
|
"${runCmd[@]}"
|
||||||
|
|
||||||
docker system prune -f
|
local rv=$?
|
||||||
|
docker image prune -f
|
||||||
return 0
|
return ${rv}
|
||||||
}
|
}
|
||||||
|
|
||||||
FB_FUNC_NAMES+=('build_with_docker')
|
FB_FUNC_NAMES+=('build_with_docker')
|
||||||
|
|||||||
46
lib/efg.sh
46
lib/efg.sh
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
efg_usage() {
|
efg_usage() {
|
||||||
echo "efg -i input [options]"
|
echo "efg -i input [options]"
|
||||||
|
echo -e "\t[-P NUM] set preset (default: ${PRESET})"
|
||||||
echo -e "\t[-l NUM] low value (default: ${LOW})"
|
echo -e "\t[-l NUM] low value (default: ${LOW})"
|
||||||
echo -e "\t[-s NUM] step value (default: ${STEP})"
|
echo -e "\t[-s NUM] step value (default: ${STEP})"
|
||||||
echo -e "\t[-h NUM] high value (default: ${HIGH})"
|
echo -e "\t[-h NUM] high value (default: ${HIGH})"
|
||||||
@@ -12,10 +13,11 @@ efg_usage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set_efg_opts() {
|
set_efg_opts() {
|
||||||
local opts='pl:s:h:i:IU'
|
local opts='P:pl:s:h:i:IU'
|
||||||
local numOpts=${#opts}
|
local numOpts=${#opts}
|
||||||
# default values
|
# default values
|
||||||
unset INPUT
|
unset INPUT
|
||||||
|
PRESET=10
|
||||||
LOW=0
|
LOW=0
|
||||||
STEP=1
|
STEP=1
|
||||||
HIGH=30
|
HIGH=30
|
||||||
@@ -30,18 +32,25 @@ set_efg_opts() {
|
|||||||
local OPTARG OPTIND
|
local OPTARG OPTIND
|
||||||
while getopts "${opts}" flag; do
|
while getopts "${opts}" flag; do
|
||||||
case "${flag}" in
|
case "${flag}" in
|
||||||
|
P)
|
||||||
|
if ! is_positive_integer "${OPTARG}"; then
|
||||||
|
efg_usage
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
PRESET="${OPTARG}"
|
||||||
|
;;
|
||||||
I)
|
I)
|
||||||
echo_warn "attempting install"
|
echo_warn "attempting install"
|
||||||
sudo ln -sf "${SCRIPT_DIR}/efg.sh" \
|
sudo ln -sf "${SCRIPT_DIR}/efg.sh" \
|
||||||
"${EFG_INSTALL_PATH}" || return 1
|
"${EFG_INSTALL_PATH}" || return 1
|
||||||
echo_pass "succesfull install"
|
echo_pass "succesfull install"
|
||||||
exit 0
|
return ${FUNC_EXIT_SUCCESS}
|
||||||
;;
|
;;
|
||||||
U)
|
U)
|
||||||
echo_warn "attempting uninstall"
|
echo_warn "attempting uninstall"
|
||||||
sudo rm "${EFG_INSTALL_PATH}" || return 1
|
sudo rm "${EFG_INSTALL_PATH}" || return 1
|
||||||
echo_pass "succesfull uninstall"
|
echo_pass "succesfull uninstall"
|
||||||
exit 0
|
return ${FUNC_EXIT_SUCCESS}
|
||||||
;;
|
;;
|
||||||
i)
|
i)
|
||||||
if [[ $# -lt 2 ]]; then
|
if [[ $# -lt 2 ]]; then
|
||||||
@@ -126,8 +135,7 @@ efg_segment() {
|
|||||||
local segmentBitrates=()
|
local segmentBitrates=()
|
||||||
|
|
||||||
# clean workspace
|
# clean workspace
|
||||||
test -d "${EFG_DIR}" && rm -rf "${EFG_DIR}"
|
recreate_dir "${EFG_DIR}" || return 1
|
||||||
mkdir -p "${EFG_DIR}"
|
|
||||||
|
|
||||||
# split up video into segments based on start times
|
# split up video into segments based on start times
|
||||||
for ((time = 0; time < duration; time += timeBetweenSegments)); do
|
for ((time = 0; time < duration; time += timeBetweenSegments)); do
|
||||||
@@ -170,20 +178,26 @@ efg_segment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
efg_encode() {
|
efg_encode() {
|
||||||
echo -n >"${GRAIN_LOG}"
|
local grainLogWIP="${GRAIN_LOG}.wip"
|
||||||
|
echo -n >"${grainLogWIP}"
|
||||||
for vid in "${EFG_DIR}/"*.mkv; do
|
for vid in "${EFG_DIR}/"*.mkv; do
|
||||||
echo "file: ${vid}" >>"${GRAIN_LOG}"
|
echo "file: ${vid}" >>"${grainLogWIP}"
|
||||||
for ((grain = LOW; grain <= HIGH; grain += STEP)); do
|
for ((grain = LOW; grain <= HIGH; grain += STEP)); do
|
||||||
local file="$(bash_basename "${vid}")"
|
local file="$(bash_basename "${vid}")"
|
||||||
local out="${EFG_DIR}/grain-${grain}-${file}"
|
local out="${EFG_DIR}/grain-${grain}-${file}"
|
||||||
echo_info "encoding ${file} with grain ${grain}"
|
echo_info "encoding ${file} with grain ${grain}"
|
||||||
echo_if_fail encode -P 10 -g ${grain} -i "${vid}" "${out}"
|
echo_if_fail encode -P "${PRESET}" -g ${grain} -i "${vid}" "${out}" || return 1
|
||||||
echo -e "\tgrain: ${grain}, bitrate: $(get_avg_bitrate "${out}")" >>"${GRAIN_LOG}"
|
echo -e "\tgrain: ${grain}, bitrate: $(get_avg_bitrate "${out}")" >>"${grainLogWIP}"
|
||||||
rm "${out}"
|
rm "${out}" || return 1
|
||||||
done
|
done
|
||||||
|
# remove segment once complete
|
||||||
|
rm "${vid}" || return 1
|
||||||
done
|
done
|
||||||
|
|
||||||
less "${GRAIN_LOG}"
|
# atomic move of grain log
|
||||||
|
mv "${grainLogWIP}" "${GRAIN_LOG}" || return 1
|
||||||
|
|
||||||
|
echo "$(<"${GRAIN_LOG}")"
|
||||||
}
|
}
|
||||||
|
|
||||||
efg_plot() {
|
efg_plot() {
|
||||||
@@ -245,8 +259,14 @@ efg() {
|
|||||||
# encode N highest-bitrate segments
|
# encode N highest-bitrate segments
|
||||||
ENCODE_SEGMENTS=5
|
ENCODE_SEGMENTS=5
|
||||||
|
|
||||||
set_efg_opts "$@" || return 1
|
set_efg_opts "$@"
|
||||||
test -d "${EFG_DIR}" || mkdir "${EFG_DIR}"
|
local ret=$?
|
||||||
|
if [[ ${ret} -eq ${FUNC_EXIT_SUCCESS} ]]; then
|
||||||
|
return 0
|
||||||
|
elif [[ ${ret} -ne 0 ]]; then
|
||||||
|
return ${ret}
|
||||||
|
fi
|
||||||
|
ensure_dir "${EFG_DIR}"
|
||||||
|
|
||||||
GRAIN_LOG="${EFG_DIR}/${LOW}-${STEP}-${HIGH}-grains.txt"
|
GRAIN_LOG="${EFG_DIR}/${LOW}-${STEP}-${HIGH}-grains.txt"
|
||||||
|
|
||||||
|
|||||||
@@ -99,11 +99,11 @@ get_encode_versions() {
|
|||||||
# shellcheck disable=SC2155
|
# shellcheck disable=SC2155
|
||||||
local output="$(ffmpeg -version 2>&1)"
|
local output="$(ffmpeg -version 2>&1)"
|
||||||
while read -r line; do
|
while read -r line; do
|
||||||
if line_contains "${line}" 'ffmpeg='; then
|
if line_starts_with "${line}" 'ffmpeg='; then
|
||||||
ffmpegVersion="${line}"
|
ffmpegVersion="${line}"
|
||||||
elif line_contains "${line}" 'libsvtav1_psy=' || line_contains "${line}" 'libsvtav1='; then
|
elif line_starts_with "${line}" 'libsvtav1'; then
|
||||||
videoEncVersion="${line}"
|
videoEncVersion="${line}"
|
||||||
elif line_contains "${line}" 'libopus='; then
|
elif line_starts_with "${line}" 'libopus='; then
|
||||||
audioEncVersion="${line}"
|
audioEncVersion="${line}"
|
||||||
fi
|
fi
|
||||||
done <<<"${output}"
|
done <<<"${output}"
|
||||||
@@ -154,7 +154,7 @@ encode_usage() {
|
|||||||
echo -e "\t[-d] enable dolby vision (default: ${DV_TOGGLE})"
|
echo -e "\t[-d] enable dolby vision (default: ${DV_TOGGLE})"
|
||||||
echo -e "\t[-v] print relevant version info"
|
echo -e "\t[-v] print relevant version info"
|
||||||
echo -e "\t[-s] use same container as input, default is convert to mkv"
|
echo -e "\t[-s] use same container as input, default is convert to mkv"
|
||||||
echo -e "\n\t[output] if unset, defaults to \${HOME}/av1-input-file-name.mkv"
|
echo -e "\n\t[output] if unset, defaults to \${PWD}/av1-input-file-name.mkv"
|
||||||
echo -e "\n\t[-u] update script (git pull ffmpeg-builder)"
|
echo -e "\n\t[-u] update script (git pull ffmpeg-builder)"
|
||||||
echo -e "\t[-I] system install at ${ENCODE_INSTALL_PATH}"
|
echo -e "\t[-I] system install at ${ENCODE_INSTALL_PATH}"
|
||||||
echo -e "\t[-U] uninstall from ${ENCODE_INSTALL_PATH}"
|
echo -e "\t[-U] uninstall from ${ENCODE_INSTALL_PATH}"
|
||||||
@@ -188,25 +188,25 @@ set_encode_opts() {
|
|||||||
while getopts "${opts}" flag; do
|
while getopts "${opts}" flag; do
|
||||||
case "${flag}" in
|
case "${flag}" in
|
||||||
u)
|
u)
|
||||||
encode_update
|
encode_update || return 1
|
||||||
exit $?
|
return ${FUNC_EXIT_SUCCESS}
|
||||||
;;
|
;;
|
||||||
I)
|
I)
|
||||||
echo_warn "attempting install"
|
echo_warn "attempting install"
|
||||||
sudo ln -sf "${SCRIPT_DIR}/encode.sh" \
|
sudo ln -sf "${SCRIPT_DIR}/encode.sh" \
|
||||||
"${ENCODE_INSTALL_PATH}" || return 1
|
"${ENCODE_INSTALL_PATH}" || return 1
|
||||||
echo_pass "succesfull install"
|
echo_pass "succesfull install"
|
||||||
exit 0
|
return ${FUNC_EXIT_SUCCESS}
|
||||||
;;
|
;;
|
||||||
U)
|
U)
|
||||||
echo_warn "attempting uninstall"
|
echo_warn "attempting uninstall"
|
||||||
sudo rm "${ENCODE_INSTALL_PATH}" || return 1
|
sudo rm "${ENCODE_INSTALL_PATH}" || return 1
|
||||||
echo_pass "succesfull uninstall"
|
echo_pass "succesfull uninstall"
|
||||||
exit 0
|
return ${FUNC_EXIT_SUCCESS}
|
||||||
;;
|
;;
|
||||||
v)
|
v)
|
||||||
get_encode_versions print
|
get_encode_versions print || return 1
|
||||||
exit $?
|
return ${FUNC_EXIT_SUCCESS}
|
||||||
;;
|
;;
|
||||||
i)
|
i)
|
||||||
if [[ $# -lt 2 ]]; then
|
if [[ $# -lt 2 ]]; then
|
||||||
@@ -253,7 +253,7 @@ set_encode_opts() {
|
|||||||
if ! is_positive_integer "${OPTARG}" || test ${OPTARG} -gt 63; then
|
if ! is_positive_integer "${OPTARG}" || test ${OPTARG} -gt 63; then
|
||||||
echo_fail "${OPTARG} is not a valid CRF value (0-63)"
|
echo_fail "${OPTARG} is not a valid CRF value (0-63)"
|
||||||
encode_usage
|
encode_usage
|
||||||
exit 1
|
return 1
|
||||||
fi
|
fi
|
||||||
CRF="${OPTARG}"
|
CRF="${OPTARG}"
|
||||||
OPTS_USED=$((OPTS_USED + 2))
|
OPTS_USED=$((OPTS_USED + 2))
|
||||||
@@ -271,7 +271,7 @@ set_encode_opts() {
|
|||||||
OUTPUT="${*: -1}"
|
OUTPUT="${*: -1}"
|
||||||
else
|
else
|
||||||
local basename="$(bash_basename "${INPUT}")"
|
local basename="$(bash_basename "${INPUT}")"
|
||||||
OUTPUT="${HOME}/av1-${basename}"
|
OUTPUT="${PWD}/av1-${basename}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# use same container for output
|
# use same container for output
|
||||||
@@ -339,11 +339,13 @@ gen_encode_script() {
|
|||||||
"spy-rd=1"
|
"spy-rd=1"
|
||||||
"psy-rd=1"
|
"psy-rd=1"
|
||||||
"sharpness=3"
|
"sharpness=3"
|
||||||
"enable-overlays=1"
|
"enable-overlays=0"
|
||||||
|
"hbd-mds=1"
|
||||||
"scd=1"
|
"scd=1"
|
||||||
"fast-decode=1"
|
"fast-decode=1"
|
||||||
"enable-variance-boost=1"
|
"enable-variance-boost=1"
|
||||||
"enable-qm=1"
|
"enable-qm=1"
|
||||||
|
"chroma-qm-min-10"
|
||||||
"qm-min=4"
|
"qm-min=4"
|
||||||
"qm-max=15"
|
"qm-max=15"
|
||||||
)
|
)
|
||||||
@@ -447,7 +449,7 @@ gen_encode_script() {
|
|||||||
echo 'ffmpeg "${ffmpegParams[@]}" -dolbyvision 0 "${OUTPUT}" || exit 1'
|
echo 'ffmpeg "${ffmpegParams[@]}" -dolbyvision 0 "${OUTPUT}" || exit 1'
|
||||||
|
|
||||||
# track-stats and clear title
|
# track-stats and clear title
|
||||||
if [[ ${FILE_EXT} == 'mkv' ]]; then
|
if [[ ${FILE_EXT} == 'mkv' ]] && has_cmd mkvpropedit; then
|
||||||
{
|
{
|
||||||
echo
|
echo
|
||||||
echo 'mkvpropedit "${OUTPUT}" --add-track-statistics-tags'
|
echo 'mkvpropedit "${OUTPUT}" --add-track-statistics-tags'
|
||||||
@@ -471,6 +473,12 @@ FB_FUNC_NAMES+=('encode')
|
|||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
FB_FUNC_DESCS['encode']='encode a file using libsvtav1_psy and libopus'
|
FB_FUNC_DESCS['encode']='encode a file using libsvtav1_psy and libopus'
|
||||||
encode() {
|
encode() {
|
||||||
set_encode_opts "$@" || return 1
|
set_encode_opts "$@"
|
||||||
|
local ret=$?
|
||||||
|
if [[ ${ret} -eq ${FUNC_EXIT_SUCCESS} ]]; then
|
||||||
|
return 0
|
||||||
|
elif [[ ${ret} -ne 0 ]]; then
|
||||||
|
return ${ret}
|
||||||
|
fi
|
||||||
gen_encode_script || return 1
|
gen_encode_script || return 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,3 +126,44 @@ get_stream_lang() {
|
|||||||
-of default=noprint_wrappers=1:nokey=1 \
|
-of default=noprint_wrappers=1:nokey=1 \
|
||||||
"${file}"
|
"${file}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gen_video() {
|
||||||
|
local outFile="$1"
|
||||||
|
local addFlags=()
|
||||||
|
shift
|
||||||
|
|
||||||
|
local vf="format=yuv420p10le"
|
||||||
|
for arg in "$@"; do
|
||||||
|
case "${arg}" in
|
||||||
|
'1080p') resolution='1920x1080' ;;
|
||||||
|
'2160p') resolution='3840x2160' ;;
|
||||||
|
'grain=yes') vf+=",noise=alls=15:allf=t+u" ;;
|
||||||
|
'hdr=yes')
|
||||||
|
local colorPrimaries='bt2020'
|
||||||
|
local colorTrc='smpte2084'
|
||||||
|
local colorspace='bt2020nc'
|
||||||
|
vf+=",setparams=color_primaries=${colorPrimaries}:color_trc=${colorTrc}:colorspace=${colorspace}"
|
||||||
|
addFlags+=(
|
||||||
|
-color_primaries "${colorPrimaries}"
|
||||||
|
-color_trc "${colorTrc}"
|
||||||
|
-colorspace "${colorspace}"
|
||||||
|
-metadata:s:v:0 "mastering_display_metadata=G(13250,34500)B(7500,3000)R(34000,16000)WP(15635,16450)L(10000000,1)"
|
||||||
|
-metadata:s:v:0 "content_light_level=1000,400"
|
||||||
|
)
|
||||||
|
;;
|
||||||
|
*) echo_fail "bad arg ${arg}" && return 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
echo_if_fail ffmpeg -y \
|
||||||
|
-hide_banner \
|
||||||
|
-f lavfi \
|
||||||
|
-i "testsrc2=size=${resolution}:rate=24:duration=5" \
|
||||||
|
-vf "${vf}" \
|
||||||
|
-c:v ffv1 \
|
||||||
|
-level 3 \
|
||||||
|
-g 1 \
|
||||||
|
-color_range tv \
|
||||||
|
"${addFlags[@]}" \
|
||||||
|
"${outFile}"
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,11 @@
|
|||||||
determine_pkg_mgr() {
|
determine_pkg_mgr() {
|
||||||
# sudo used externally
|
# sudo used externally
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
test "$(id -u)" -eq 0 && SUDO='' || SUDO='sudo '
|
if is_windows || test "$(id -u)" -eq 0; then
|
||||||
|
SUDO=''
|
||||||
|
else
|
||||||
|
SUDO='sudo '
|
||||||
|
fi
|
||||||
|
|
||||||
# pkg-mgr update-cmd upgrade-cmd install-cmd check-cmd
|
# pkg-mgr update-cmd upgrade-cmd install-cmd check-cmd
|
||||||
# shellcheck disable=SC2016
|
# shellcheck disable=SC2016
|
||||||
@@ -14,7 +18,6 @@ brew:brew update:brew upgrade:brew install:brew list --formula ${pkg}
|
|||||||
apt-get:${SUDO}apt-get update:${SUDO}apt-get upgrade -y:${SUDO}apt-get install -y:dpkg -l ${pkg}
|
apt-get:${SUDO}apt-get update:${SUDO}apt-get upgrade -y:${SUDO}apt-get install -y:dpkg -l ${pkg}
|
||||||
pacman:${SUDO}pacman -Syy:${SUDO}pacman -Syu --noconfirm:${SUDO}pacman -S --noconfirm --needed:pacman -Qi ${pkg}
|
pacman:${SUDO}pacman -Syy:${SUDO}pacman -Syu --noconfirm:${SUDO}pacman -S --noconfirm --needed:pacman -Qi ${pkg}
|
||||||
dnf:${SUDO}dnf check-update || true:${SUDO}dnf upgrade --refresh -y:${SUDO}dnf install -y:dnf list -q --installed ${pkg}
|
dnf:${SUDO}dnf check-update || true:${SUDO}dnf upgrade --refresh -y:${SUDO}dnf install -y:dnf list -q --installed ${pkg}
|
||||||
winget:winget update:true:${SUDO}winget install:winget list ${pkg}
|
|
||||||
'
|
'
|
||||||
local supported_pkg_mgr=()
|
local supported_pkg_mgr=()
|
||||||
unset pkg_mgr pkg_mgr_update pkg_mgr_upgrade pkg_install pkg_check
|
unset pkg_mgr pkg_mgr_update pkg_mgr_upgrade pkg_install pkg_check
|
||||||
@@ -53,34 +56,35 @@ print_req_pkgs() {
|
|||||||
local brew_pkgs=(
|
local brew_pkgs=(
|
||||||
"${common_pkgs[@]}" pkgconf
|
"${common_pkgs[@]}" pkgconf
|
||||||
mkvtoolnix pipx uutils-coreutils
|
mkvtoolnix pipx uutils-coreutils
|
||||||
|
llvm lld
|
||||||
)
|
)
|
||||||
local common_linux_pkgs=(
|
local common_linux_pkgs=(
|
||||||
"${common_pkgs[@]}" clang valgrind
|
"${common_pkgs[@]}" clang valgrind
|
||||||
curl bc lshw xxd pkgconf sudo
|
curl bc lshw xxd pkgconf sudo llvm
|
||||||
)
|
)
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
local apt_get_pkgs=(
|
local apt_get_pkgs=(
|
||||||
"${common_linux_pkgs[@]}" build-essential
|
"${common_linux_pkgs[@]}" pipx
|
||||||
git-core libass-dev libfreetype6-dev
|
build-essential libssl-dev gobjc++
|
||||||
libsdl2-dev libva-dev libvdpau-dev
|
mawk libc6-dev mediainfo ninja-build
|
||||||
libvorbis-dev libxcb1-dev pipx
|
mkvtoolnix libgtest-dev lld
|
||||||
libxcb-shm0-dev libxcb-xfixes0-dev
|
libfontconfig-dev libglib2.0-dev
|
||||||
zlib1g-dev libssl-dev ninja-build
|
|
||||||
gobjc++ mawk libnuma-dev libc6-dev
|
|
||||||
mediainfo mkvtoolnix libgtest-dev
|
|
||||||
)
|
)
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
local pacman_pkgs=(
|
local pacman_pkgs=(
|
||||||
"${common_linux_pkgs[@]}" base-devel
|
"${common_linux_pkgs[@]}" base-devel
|
||||||
python-pipx ninja numactl
|
python-pipx ninja lld mkvtoolnix-cli
|
||||||
|
glib2-devel
|
||||||
)
|
)
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
local dnf_pkgs=(
|
local dnf_pkgs=(
|
||||||
"${common_linux_pkgs[@]}" openssl-devel
|
"${common_linux_pkgs[@]}" openssl-devel
|
||||||
pipx ninja-build fontconfig-devel wget2
|
pipx ninja-build fontconfig-devel wget2
|
||||||
cpuinfo-devel glibc-static glibc-devel
|
glibc-static glibc-devel patch
|
||||||
libstdc++-static libstdc++-devel patch
|
libstdc++-static libstdc++-devel
|
||||||
numactl-devel
|
llvm-cmake-utils llvm-devel
|
||||||
|
llvm-static compiler-rt lld
|
||||||
|
mkvtoolnix glib2-static
|
||||||
)
|
)
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
local pkg_pkgs=(
|
local pkg_pkgs=(
|
||||||
@@ -90,23 +94,37 @@ print_req_pkgs() {
|
|||||||
git gnuplot bison rsync ragel
|
git gnuplot bison rsync ragel
|
||||||
zip unzip gperf build-essential
|
zip unzip gperf build-essential
|
||||||
binutils ninja ndk-multilib-native-static
|
binutils ninja ndk-multilib-native-static
|
||||||
|
libandroid-posix-semaphore
|
||||||
|
libandroid-posix-semaphore-static
|
||||||
|
libandroid-shmem
|
||||||
|
libandroid-shmem-static
|
||||||
)
|
)
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
local winget_pkgs=(
|
local msys_ucrt_pkgs=(
|
||||||
Git.Git gerardog.gsudo
|
mingw-w64-ucrt-x86_64-toolchain
|
||||||
StrawberryPerl.StrawberryPerl
|
mingw-w64-ucrt-x86_64-autotools
|
||||||
bloodrock.pkg-config-lite
|
mingw-w64-ucrt-x86_64-clang
|
||||||
Kitware.CMake mesonbuild.meson
|
mingw-w64-ucrt-x86_64-clang-libs
|
||||||
Microsoft.VisualStudio.2019.BuildTools
|
mingw-w64-ucrt-x86_64-cmake
|
||||||
Microsoft.VisualStudio.2022.BuildTools
|
mingw-w64-ucrt-x86_64-compiler-rt
|
||||||
GnuWin32.DiffUtils GnuWin32.Bison
|
mingw-w64-ucrt-x86_64-doxygen
|
||||||
GnuWin32.Gperf GnuWin32.File
|
mingw-w64-ucrt-x86_64-gcc-libs
|
||||||
GnuWin32.Tar GnuWin32.UnZip
|
mingw-w64-ucrt-x86_64-gperf
|
||||||
GnuWin32.Zip GnuWin32.Which
|
mingw-w64-ucrt-x86_64-itstool
|
||||||
Rustlang.Rustup Python.Python.3.12
|
mingw-w64-ucrt-x86_64-meson
|
||||||
Ccache.Ccache LLVM.LLVM
|
mingw-w64-ucrt-x86_64-bc
|
||||||
|
mingw-w64-ucrt-x86_64-nasm
|
||||||
|
mingw-w64-ucrt-x86_64-yasm
|
||||||
|
mingw-w64-ucrt-x86_64-ccache
|
||||||
|
mingw-w64-ucrt-x86_64-rustup
|
||||||
|
mingw-w64-ucrt-x86_64-cargo-c
|
||||||
|
mingw-w64-ucrt-x86_64-perl
|
||||||
|
mingw-w64-ucrt-x86_64-perl-modules
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if is_windows; then
|
||||||
|
local pkg_mgr='msys_ucrt'
|
||||||
|
fi
|
||||||
local req_pkgs_env_name="${pkg_mgr/-/_}_pkgs"
|
local req_pkgs_env_name="${pkg_mgr/-/_}_pkgs"
|
||||||
declare -n req_pkgs="${req_pkgs_env_name}"
|
declare -n req_pkgs="${req_pkgs_env_name}"
|
||||||
local sorted_req_pkgs=($(printf '%s\n' "${req_pkgs[@]}" | sort -u))
|
local sorted_req_pkgs=($(printf '%s\n' "${req_pkgs[@]}" | sort -u))
|
||||||
@@ -146,6 +164,7 @@ check_for_req_pkgs() {
|
|||||||
|
|
||||||
echo_pass "packages from ${pkg_mgr} installed"
|
echo_pass "packages from ${pkg_mgr} installed"
|
||||||
has_cmd pipx || echo_if_fail python3 -m pip install --user pipx || return 1
|
has_cmd pipx || echo_if_fail python3 -m pip install --user pipx || return 1
|
||||||
|
has_cmd pipx || echo_if_fail python3 -m pipx ensurepath && source ~/.bashrc || return 1
|
||||||
echo_if_fail pipx install virtualenv || return 1
|
echo_if_fail pipx install virtualenv || return 1
|
||||||
echo_if_fail pipx ensurepath || return 1
|
echo_if_fail pipx ensurepath || return 1
|
||||||
has_cmd meson || echo_if_fail pipx install meson || return 1
|
has_cmd meson || echo_if_fail pipx install meson || return 1
|
||||||
@@ -166,7 +185,7 @@ check_for_req_pkgs() {
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo_if_fail cargo install cargo-c || return 1
|
has_cmd cargo-cbuild || echo_if_fail cargo install cargo-c || return 1
|
||||||
echo_pass "cargo-c is installed"
|
echo_pass "cargo-c is installed"
|
||||||
echo_pass "all required packages installed"
|
echo_pass "all required packages installed"
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
check_for_package_cfg() {
|
check_for_package_cfg() {
|
||||||
local requiredCfg='ON:ON:3'
|
local requiredCfg='ON:ON:ON:3'
|
||||||
local currentCfg="${STATIC}:${LTO}:${OPT}"
|
local currentCfg="${STATIC}:${LTO}:${PGO}:${OPT}"
|
||||||
if [[ ${currentCfg} == "${requiredCfg}" ]]; then
|
if [[ ${currentCfg} == "${requiredCfg}" ]]; then
|
||||||
return 0
|
return 0
|
||||||
else
|
else
|
||||||
@@ -14,12 +14,10 @@ FB_FUNC_NAMES+=('package')
|
|||||||
FB_FUNC_DESCS['package']='package ffmpeg build'
|
FB_FUNC_DESCS['package']='package ffmpeg build'
|
||||||
package() {
|
package() {
|
||||||
local pkgDir="${IGN_DIR}/package"
|
local pkgDir="${IGN_DIR}/package"
|
||||||
test -d "${pkgDir}" && rm -rf "${pkgDir}"
|
recreate_dir "${pkgDir}" || return 1
|
||||||
check_for_package_cfg || return 0
|
check_for_package_cfg || return 0
|
||||||
|
|
||||||
echo_info "packaging"
|
echo_info "packaging"
|
||||||
mkdir "${pkgDir}" || return 1
|
|
||||||
|
|
||||||
set_compile_opts || return 1
|
set_compile_opts || return 1
|
||||||
cp "${PREFIX}/bin/ff"* "${pkgDir}/"
|
cp "${PREFIX}/bin/ff"* "${pkgDir}/"
|
||||||
|
|
||||||
|
|||||||
60
lib/pgo.sh
Normal file
60
lib/pgo.sh
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
PGO_DIR="${IGN_DIR}/pgo"
|
||||||
|
PGO_PROFDATA="${PGO_DIR}/prof.profdata"
|
||||||
|
gen_profdata() {
|
||||||
|
recreate_dir "${PGO_DIR}" || return 1
|
||||||
|
cd "${PGO_DIR}" || return 1
|
||||||
|
setup_pgo_clips || return 1
|
||||||
|
for vid in *.mkv; do
|
||||||
|
local args=()
|
||||||
|
# add precalculated grain amount based off of filename
|
||||||
|
line_contains "${vid}" 'grain' && args+=(-g 16)
|
||||||
|
# make fhd preset 2
|
||||||
|
line_contains "${vid}" 'fhd' && args+=(-P 2)
|
||||||
|
|
||||||
|
echo_info "encoding pgo vid: ${vid}"
|
||||||
|
LLVM_PROFILE_FILE="${PGO_DIR}/default_%p.profraw" \
|
||||||
|
echo_if_fail encode -i "${vid}" "${args[@]}" "encoded-${vid}" || return 1
|
||||||
|
done
|
||||||
|
|
||||||
|
# merge profraw into profdata
|
||||||
|
local mergeCmd=()
|
||||||
|
# darwin needs special invoke
|
||||||
|
if is_darwin; then
|
||||||
|
mergeCmd+=(xcrun)
|
||||||
|
fi
|
||||||
|
|
||||||
|
mergeCmd+=(
|
||||||
|
llvm-profdata
|
||||||
|
merge
|
||||||
|
"--output=${PGO_PROFDATA}"
|
||||||
|
)
|
||||||
|
"${mergeCmd[@]}" default*.profraw || return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_pgo_clips() {
|
||||||
|
local clips=(
|
||||||
|
"fhd-grainy.mkv 1080p,grain=yes"
|
||||||
|
"uhd.mkv 2160p"
|
||||||
|
"uhd-hdr.mkv 2160p,hdr=yes"
|
||||||
|
)
|
||||||
|
for clip in "${clips[@]}"; do
|
||||||
|
local genVid genVidArgs pgoFile genVidArgsArr
|
||||||
|
IFS=' ' read -r genVid genVidArgs <<<"${clip}"
|
||||||
|
# pgo path is separate
|
||||||
|
pgoFile="${PGO_DIR}/${genVid}"
|
||||||
|
genVid="${TMP_DIR}/${genVid}"
|
||||||
|
# create array of args split with ,
|
||||||
|
genVidArgsArr=(${genVidArgs//,/ })
|
||||||
|
# create generated vid without any profiling if needed
|
||||||
|
test -f "${genVid}" ||
|
||||||
|
LLVM_PROFILE_FILE='/dev/null' gen_video "${genVid}" "${genVidArgsArr[@]}" || return 1
|
||||||
|
# and move to the pgo directory
|
||||||
|
test -f "${pgoFile}" ||
|
||||||
|
cp "${genVid}" "${pgoFile}" || return 1
|
||||||
|
|
||||||
|
done
|
||||||
|
}
|
||||||
338
lib/utils.sh
338
lib/utils.sh
@@ -1,338 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
# shellcheck disable=SC2034
|
|
||||||
|
|
||||||
# ANSI colors
|
|
||||||
RED='\e[0;31m'
|
|
||||||
CYAN='\e[0;36m'
|
|
||||||
GREEN='\e[0;32m'
|
|
||||||
YELLOW='\e[0;33m'
|
|
||||||
NC='\e[0m'
|
|
||||||
|
|
||||||
# echo wrappers
|
|
||||||
echo_wrapper() {
|
|
||||||
local args
|
|
||||||
if [[ $1 == '-n' ]]; then
|
|
||||||
args=("$1")
|
|
||||||
shift
|
|
||||||
fi
|
|
||||||
# COLOR is override for using ${color}
|
|
||||||
# shellcheck disable=SC2153
|
|
||||||
if [[ ${COLOR} == 'OFF' ]]; then
|
|
||||||
color=''
|
|
||||||
endColor=''
|
|
||||||
else
|
|
||||||
endColor="${NC}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e "${args[@]}" "${color}${word:-''}${endColor}" "$@"
|
|
||||||
}
|
|
||||||
echo_fail() { color="${RED}" word="FAIL" echo_wrapper "$@"; }
|
|
||||||
echo_info() { color="${CYAN}" word="INFO" echo_wrapper "$@"; }
|
|
||||||
echo_pass() { color="${GREEN}" word="PASS" echo_wrapper "$@"; }
|
|
||||||
echo_warn() { color="${YELLOW}" word="WARN" echo_wrapper "$@"; }
|
|
||||||
echo_exit() {
|
|
||||||
echo_fail "$@"
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
void() { echo "$@" >/dev/null; }
|
|
||||||
|
|
||||||
echo_if_fail() {
|
|
||||||
local cmd=("$@")
|
|
||||||
local logName="${LOGNAME:-${RANDOM}}-"
|
|
||||||
local out="${TMP_DIR}/${logName}stdout"
|
|
||||||
local err="${TMP_DIR}/${logName}stderr"
|
|
||||||
|
|
||||||
# set trace to the cmdEvalTrace and open file descriptor
|
|
||||||
local cmdEvalTrace="${TMP_DIR}/${logName}cmdEvalTrace"
|
|
||||||
exec 5>"${cmdEvalTrace}"
|
|
||||||
export BASH_XTRACEFD=5
|
|
||||||
|
|
||||||
set -x
|
|
||||||
"${cmd[@]}" >"${out}" 2>"${err}"
|
|
||||||
local retval=$?
|
|
||||||
|
|
||||||
# unset and close file descriptor
|
|
||||||
set +x
|
|
||||||
exec 5>&-
|
|
||||||
|
|
||||||
# parse out relevant part of the trace
|
|
||||||
local cmdEvalLines=()
|
|
||||||
while IFS= read -r line; do
|
|
||||||
line="${line//${PS4}/}"
|
|
||||||
test "${line}" == 'set +x' && continue
|
|
||||||
test "${line}" == '' && continue
|
|
||||||
cmdEvalLines+=("${line}")
|
|
||||||
done <"${cmdEvalTrace}"
|
|
||||||
|
|
||||||
if ! test ${retval} -eq 0; then
|
|
||||||
echo
|
|
||||||
echo_fail "command failed:"
|
|
||||||
printf "%s\n" "${cmdEvalLines[@]}"
|
|
||||||
echo_warn "command output:"
|
|
||||||
tail -n 20 "${out}"
|
|
||||||
tail -n 20 "${err}"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
if [[ -z ${LOGNAME} ]]; then
|
|
||||||
rm "${out}" "${err}" "${cmdEvalTrace}"
|
|
||||||
fi
|
|
||||||
return ${retval}
|
|
||||||
}
|
|
||||||
|
|
||||||
is_root_owned() {
|
|
||||||
local path=$1
|
|
||||||
local uid
|
|
||||||
|
|
||||||
if stat --version >/dev/null 2>&1; then
|
|
||||||
# GNU coreutils (Linux)
|
|
||||||
uid=$(stat -c '%u' "$path")
|
|
||||||
else
|
|
||||||
# BSD/macOS
|
|
||||||
uid=$(stat -f '%u' "$path")
|
|
||||||
fi
|
|
||||||
|
|
||||||
test "$uid" -eq 0
|
|
||||||
}
|
|
||||||
|
|
||||||
dump_arr() {
|
|
||||||
arr_name="$1"
|
|
||||||
declare -n arr
|
|
||||||
arr="${arr_name}"
|
|
||||||
arr_exp=("${arr[@]}")
|
|
||||||
test "${#arr_exp}" -gt 0 || return 0
|
|
||||||
echo
|
|
||||||
echo_info "${arr_name}"
|
|
||||||
printf "\t%s\n" "${arr_exp[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
has_cmd() {
|
|
||||||
local cmds=("$@")
|
|
||||||
local rv=0
|
|
||||||
for cmd in "${cmds[@]}"; do
|
|
||||||
command -v "${cmd}" >/dev/null 2>&1 || rv=1
|
|
||||||
done
|
|
||||||
|
|
||||||
return ${rv}
|
|
||||||
}
|
|
||||||
|
|
||||||
missing_cmd() {
|
|
||||||
local cmds=("$@")
|
|
||||||
local rv=1
|
|
||||||
for cmd in "${cmds[@]}"; do
|
|
||||||
if ! has_cmd "${cmd}"; then
|
|
||||||
echo_warn "missing ${cmd}"
|
|
||||||
rv=0
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
return ${rv}
|
|
||||||
}
|
|
||||||
|
|
||||||
bash_dirname() {
|
|
||||||
local tmp=${1:-.}
|
|
||||||
|
|
||||||
[[ $tmp != *[!/]* ]] && {
|
|
||||||
printf '/\n'
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp=${tmp%%"${tmp##*[!/]}"}
|
|
||||||
|
|
||||||
[[ $tmp != */* ]] && {
|
|
||||||
printf '.\n'
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp=${tmp%/*}
|
|
||||||
tmp=${tmp%%"${tmp##*[!/]}"}
|
|
||||||
|
|
||||||
printf '%s\n' "${tmp:-/}"
|
|
||||||
}
|
|
||||||
|
|
||||||
bash_basename() {
|
|
||||||
local tmp
|
|
||||||
path="$1"
|
|
||||||
suffix="${2:-''}"
|
|
||||||
|
|
||||||
tmp=${path%"${path##*[!/]}"}
|
|
||||||
tmp=${tmp##*/}
|
|
||||||
tmp=${tmp%"${suffix/"$tmp"/}"}
|
|
||||||
|
|
||||||
printf '%s\n' "${tmp:-/}"
|
|
||||||
}
|
|
||||||
|
|
||||||
bash_realpath() {
|
|
||||||
local file=$1
|
|
||||||
local dir
|
|
||||||
|
|
||||||
# If the file is already absolute
|
|
||||||
[[ $file == /* ]] && {
|
|
||||||
printf '%s\n' "$file"
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
# Otherwise: split into directory + basename
|
|
||||||
dir="$(bash_dirname "${file}")"
|
|
||||||
file="$(bash_basename "${file}")"
|
|
||||||
|
|
||||||
# If no directory component, use current directory
|
|
||||||
if [[ $dir == "$file" ]]; then
|
|
||||||
dir="$PWD"
|
|
||||||
else
|
|
||||||
# Save current dir, move into target dir, capture $PWD, then return
|
|
||||||
local oldpwd="$PWD"
|
|
||||||
cd "$dir" || return 1
|
|
||||||
dir="$PWD"
|
|
||||||
cd "$oldpwd" || return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
printf '%s/%s\n' "$dir" "$file"
|
|
||||||
}
|
|
||||||
|
|
||||||
line_contains() {
|
|
||||||
local line="$1"
|
|
||||||
local substr="$2"
|
|
||||||
if [[ $line == *"${substr}"* ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
line_starts_with() {
|
|
||||||
local line="$1"
|
|
||||||
local substr="$2"
|
|
||||||
if [[ $line == "${substr}"* ]]; then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
is_linux() {
|
|
||||||
line_contains "${OSTYPE}" 'linux'
|
|
||||||
}
|
|
||||||
|
|
||||||
is_darwin() {
|
|
||||||
line_contains "$(print_os)" darwin
|
|
||||||
}
|
|
||||||
|
|
||||||
is_windows() {
|
|
||||||
line_contains "$(print_os)" windows
|
|
||||||
}
|
|
||||||
|
|
||||||
is_android() {
|
|
||||||
line_contains "$(print_os)" android
|
|
||||||
}
|
|
||||||
|
|
||||||
print_os() {
|
|
||||||
# cached response
|
|
||||||
if [[ -n ${FB_OS} ]]; then
|
|
||||||
echo "${FB_OS}"
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
unset FB_OS
|
|
||||||
if [[ -f /etc/os-release ]]; then
|
|
||||||
source /etc/os-release
|
|
||||||
FB_OS="${ID}"
|
|
||||||
if [[ ${VERSION_ID} != '' ]]; then
|
|
||||||
FB_OS+="-${VERSION_ID}"
|
|
||||||
fi
|
|
||||||
if line_starts_with "${FB_OS}" 'arch'; then
|
|
||||||
FB_OS='archlinux'
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
FB_OS="$(uname -o)"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# lowercase
|
|
||||||
FB_OS="${FB_OS,,}"
|
|
||||||
|
|
||||||
# special treatment for windows
|
|
||||||
if line_contains "${FB_OS}" 'windows' || line_contains "${FB_OS}" 'msys'; then
|
|
||||||
FB_OS='windows'
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "${FB_OS}"
|
|
||||||
}
|
|
||||||
|
|
||||||
is_positive_integer() {
|
|
||||||
local input="$1"
|
|
||||||
if [[ ${input} != ?(-)+([[:digit:]]) || ${input} -lt 0 ]]; then
|
|
||||||
echo_fail "${input} is not a positive integer"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
replace_line() {
|
|
||||||
local file="$1"
|
|
||||||
local search="$2"
|
|
||||||
local newLine="$3"
|
|
||||||
local newFile="${TMP_DIR}/$(bash_basename "${file}")"
|
|
||||||
|
|
||||||
test -f "${newFile}" && rm "${newFile}"
|
|
||||||
while read -r line; do
|
|
||||||
if line_contains "${line}" "${search}"; then
|
|
||||||
echo -en "${newLine}" >>"${newFile}"
|
|
||||||
continue
|
|
||||||
fi
|
|
||||||
echo "${line}" >>"${newFile}"
|
|
||||||
done <"${file}"
|
|
||||||
|
|
||||||
cp "${newFile}" "${file}"
|
|
||||||
}
|
|
||||||
|
|
||||||
remove_line() {
|
|
||||||
local file="$1"
|
|
||||||
local search="$2"
|
|
||||||
replace_line "${file}" "${search}" ''
|
|
||||||
}
|
|
||||||
|
|
||||||
bash_sort() {
|
|
||||||
local arr=("$@")
|
|
||||||
local n=${#arr[@]}
|
|
||||||
local i j val1 val2
|
|
||||||
|
|
||||||
# Bubble sort, numeric comparison
|
|
||||||
for ((i = 0; i < n; i++)); do
|
|
||||||
for ((j = 0; j < n - i - 1; j++)); do
|
|
||||||
read -r val1 _ <<<"${arr[j]}"
|
|
||||||
read -r val2 _ <<<"${arr[j + 1]}"
|
|
||||||
if (("${val1}" > "${val2}")); then
|
|
||||||
local tmp=${arr[j]}
|
|
||||||
arr[j]=${arr[j + 1]}
|
|
||||||
arr[j + 1]=$tmp
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
|
|
||||||
printf '%s\n' "${arr[@]}"
|
|
||||||
}
|
|
||||||
|
|
||||||
spinner() {
|
|
||||||
if [[ $1 == 'reset' ]]; then
|
|
||||||
echo -ne ' \n'
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
local spinChars=(
|
|
||||||
"-"
|
|
||||||
'\'
|
|
||||||
"|"
|
|
||||||
"/"
|
|
||||||
)
|
|
||||||
while true; do
|
|
||||||
for ((ind = 0; ind < "${#spinChars[@]}"; ind++)); do
|
|
||||||
echo -ne "${spinChars[${ind}]}" '\b\b'
|
|
||||||
sleep .25
|
|
||||||
done
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
get_pkgconfig_version() {
|
|
||||||
local pkg="$1"
|
|
||||||
pkg-config --modversion "${pkg}"
|
|
||||||
}
|
|
||||||
5
main.sh
5
main.sh
@@ -15,6 +15,11 @@ DOCKER_DIR="${IGN_DIR}/docker"
|
|||||||
PATCHES_DIR="${REPO_DIR}/patches"
|
PATCHES_DIR="${REPO_DIR}/patches"
|
||||||
export REPO_DIR IGN_DIR TMP_DIR DL_DIR BUILD_DIR CCACHE_DIR DOCKER_DIR PATCHES_DIR
|
export REPO_DIR IGN_DIR TMP_DIR DL_DIR BUILD_DIR CCACHE_DIR DOCKER_DIR PATCHES_DIR
|
||||||
|
|
||||||
|
# some functions need a way to signal early
|
||||||
|
# returns instead of failures, so if a function
|
||||||
|
# returns ${FUNC_EXIT_SUCCESS}, stop processing
|
||||||
|
test -v FUNC_EXIT_SUCCESS || readonly FUNC_EXIT_SUCCESS=9
|
||||||
|
|
||||||
# make paths if needed
|
# make paths if needed
|
||||||
IGN_DIRS=(
|
IGN_DIRS=(
|
||||||
"${TMP_DIR}"
|
"${TMP_DIR}"
|
||||||
|
|||||||
11
patches/libmp3lame/fix_lame_init_old_symbol.patch
Normal file
11
patches/libmp3lame/fix_lame_init_old_symbol.patch
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# https://sourceforge.net/p/lame/mailman/message/36081038/
|
||||||
|
diff --git a/include/libmp3lame.sym b/include/libmp3lame.sym
|
||||||
|
index ff7d318..fd120f5 100644
|
||||||
|
--- a/include/libmp3lame.sym
|
||||||
|
+++ b/include/libmp3lame.sym
|
||||||
|
@@ -1,5 +1,4 @@
|
||||||
|
lame_init
|
||||||
|
-lame_init_old
|
||||||
|
lame_set_num_samples
|
||||||
|
lame_get_num_samples
|
||||||
|
lame_set_in_samplerate
|
||||||
24
patches/libvorbis/add-lm-to-pc.patch
Normal file
24
patches/libvorbis/add-lm-to-pc.patch
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
diff --git a/vorbis.pc.in b/vorbis.pc.in
|
||||||
|
index f5ca77d..50cad9e 100644
|
||||||
|
--- a/vorbis.pc.in
|
||||||
|
+++ b/vorbis.pc.in
|
||||||
|
@@ -10,6 +10,6 @@ Description: vorbis is the primary Ogg Vorbis library
|
||||||
|
Version: @VERSION@
|
||||||
|
Requires.private: ogg
|
||||||
|
Conflicts:
|
||||||
|
-Libs: -L${libdir} -lvorbis
|
||||||
|
-Libs.private: @VORBIS_LIBS@
|
||||||
|
+Libs: -L${libdir} -lvorbis
|
||||||
|
+Libs.private: @VORBIS_LIBS@ -lm
|
||||||
|
Cflags: -I${includedir}
|
||||||
|
diff --git a/vorbisenc.pc.in b/vorbisenc.pc.in
|
||||||
|
index a412b7a..4222daf 100644
|
||||||
|
--- a/vorbisenc.pc.in
|
||||||
|
+++ b/vorbisenc.pc.in
|
||||||
|
@@ -10,5 +10,5 @@ Description: vorbisenc is a library that provides a convenient API for setting u
|
||||||
|
Version: @VERSION@
|
||||||
|
Requires.private: vorbis
|
||||||
|
Conflicts:
|
||||||
|
-Libs: -L${libdir} -lvorbisenc
|
||||||
|
+Libs: -L${libdir} -lvorbisenc -lm
|
||||||
|
Cflags: -I${includedir}
|
||||||
13
patches/libvpx/ignore-unknown-configure-options.patch
Normal file
13
patches/libvpx/ignore-unknown-configure-options.patch
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
diff --git a/build/make/configure.sh b/build/make/configure.sh
|
||||||
|
index cc5bf6c..c229965 100644
|
||||||
|
--- a/build/make/configure.sh
|
||||||
|
+++ b/build/make/configure.sh
|
||||||
|
@@ -16,8 +16,6 @@
|
||||||
|
die_unknown(){
|
||||||
|
echo "Unknown option \"$1\"."
|
||||||
|
echo "See $0 --help for available options."
|
||||||
|
- clean_temp_files
|
||||||
|
- exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
@@ -6,10 +6,10 @@ inotifywait -m -r \
|
|||||||
-e close_write \
|
-e close_write \
|
||||||
-e moved_to \
|
-e moved_to \
|
||||||
--format '%w%f' \
|
--format '%w%f' \
|
||||||
"$base/lib" \
|
"${base}/lib" \
|
||||||
"$base/scripts" \
|
"${base}/scripts" \
|
||||||
"$base/main.sh" | while read -r file; do
|
"${base}/main.sh" | while read -r file; do
|
||||||
if [[ -f $file && $file =~ .sh ]]; then
|
if [[ -f $file && $file =~ .sh ]]; then
|
||||||
shfmt --write --simplify "$file"
|
shfmt --indent 4 --write --simplify "${file}"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user