Skip to content

Instantly share code, notes, and snippets.

@yuygfgg
Last active May 29, 2025 00:50
Show Gist options
  • Save yuygfgg/796219ccba2efae15ad3bdc89cfcf30c to your computer and use it in GitHub Desktop.
Save yuygfgg/796219ccba2efae15ad3bdc89cfcf30c to your computer and use it in GitHub Desktop.
Build liblsmashsource for macos/ubuntu
#!/usr/bin/env bash
set -euo pipefail
# --- Argument Parsing ---
BUILD_PYTHON_FLAG=false
PLUGIN_TYPE="all" # Default to building all plugins
while [[ $# -gt 0 ]]; do
case $1 in
--build-python)
BUILD_PYTHON_FLAG=true
print_colored blue "Option: Force rebuild Python."
shift
;;
--plugin)
shift
if [[ $# -gt 0 ]]; then
case $1 in
vs | vapoursynth)
PLUGIN_TYPE="vs"
print_colored blue "Option: Build VapourSynth plugin only."
;;
avs | avisynth)
PLUGIN_TYPE="avs"
print_colored blue "Option: Build AviSynth plugin only."
;;
all)
PLUGIN_TYPE="all"
print_colored blue "Option: Build all plugins (VapourSynth and AviSynth)."
;;
*)
print_colored red "Invalid plugin option: $1"
print_colored yellow "Valid options: vs, avs, all"
exit 1
;;
esac
shift
else
print_colored red "Error: --plugin option requires an argument (vs, avs, all)"
exit 1
fi
;;
*)
print_colored red "Unknown option: $1"
print_colored yellow "Usage: $0 [--build-python] [--plugin <vs|avs|all>]"
exit 1
;;
esac
done
# --- Define color output functions ---
print_colored() {
local color="$1"
local text="$2"
case "$color" in
green) tput setab 2 ;;
blue) tput setaf 4 ;;
yellow) tput setaf 3 ;;
red) tput setaf 1 ;;
esac
echo -n "$text"
tput sgr0
echo
}
# --- Detect OS and Set Environment ---
OS_TYPE=""
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
OS_TYPE="linux"
NPROC=$(nproc)
SED_I="sed -i"
elif [[ "$OSTYPE" == "darwin"* ]]; then
OS_TYPE="macos"
NPROC=$(sysctl -n hw.ncpu)
SED_I="sed -i ''"
else
print_colored red "Unsupported OS: $OSTYPE"
exit 1
fi
print_colored blue "Detected OS: $OS_TYPE"
print_colored blue "Using $NPROC cores for build."
# --- Set Paths ---
export HOME_DIR="$HOME"
export OWN_PREFIX="$HOME_DIR/lsmash_build"
mkdir -p "$OWN_PREFIX" "$OWN_PREFIX/lib" "$OWN_PREFIX/include" "$OWN_PREFIX/lib/pkgconfig" "$OWN_PREFIX/lib/vapoursynth"
export MYLDPH="$OWN_PREFIX/lib"
export MYICPH="$OWN_PREFIX/include"
export MYPKGPH="$OWN_PREFIX/lib/pkgconfig"
export VSPLGPH="$OWN_PREFIX/lib/vapoursynth"
export VSFUNCPH=""
export PKG_CONFIG_PATH="$MYPKGPH${PKG_CONFIG_PATH:+:$PKG_CONFIG_PATH}"
export PATH="$OWN_PREFIX/bin:$PATH"
export LDFLAGS="-L$MYLDPH ${LDFLAGS:-}"
export CPPFLAGS="-I$MYICPH ${CPPFLAGS:-}"
export CFLAGS="-I$MYICPH -fPIC ${CFLAGS:-}"
export CXXFLAGS="-I$MYICPH -fPIC ${CXXFLAGS:-}"
# --- Platform-Specific Setup ---
print_colored blue "Starting Platform-Specific Setup..."
if [[ "$OS_TYPE" == "linux" ]]; then
print_colored green " APT Install (Ubuntu) "
if command -v sudo &>/dev/null; then
sudo apt update
sudo apt install -y build-essential gdb lcov pkg-config \
libbz2-dev libffi-dev libgdbm-dev libgdbm-compat-dev liblzma-dev \
libncurses5-dev libreadline-dev libsqlite3-dev libssl-dev \
lzma-dev tk-dev uuid-dev zlib1g-dev libzstd-dev \
libmfx-dev libva-dev libvdpau-dev \
cmake ninja-build meson git autoconf automake libtool nasm yasm gettext
else
print_colored red "sudo not found. Please install prerequisites manually."
exit 1
fi
export CFLAGS="$CFLAGS -fno-semantic-interposition"
export CXXFLAGS="$CXXFLAGS -fno-semantic-interposition"
elif [[ "$OS_TYPE" == "macos" ]]; then
print_colored green " Homebrew Install (macOS) "
if ! command -v brew &>/dev/null; then
print_colored red "Homebrew not found. Please install Homebrew first."
exit 1
fi
brew install pkg-config bzip2 libffi gdbm xz ncurses readline sqlite openssl@3 tcl-tk zstd \
gettext cmake ninja meson git autoconf automake libtool nasm yasm lcov zlib
export LDFLAGS="-L$(brew --prefix gettext)/lib ${LDFLAGS}"
export CPPFLAGS="-I$(brew --prefix gettext)/include ${CPPFLAGS}"
export PKG_CONFIG_PATH="$(brew --prefix gettext)/lib/pkgconfig:${PKG_CONFIG_PATH:-}"
export LDFLAGS="-L$(brew --prefix openssl@3)/lib ${LDFLAGS}"
export CPPFLAGS="-I$(brew --prefix openssl@3)/include ${CPPFLAGS}"
export PKG_CONFIG_PATH="$(brew --prefix openssl@3)/lib/pkgconfig:${PKG_CONFIG_PATH}"
export LDFLAGS="-L$(brew --prefix readline)/lib ${LDFLAGS}"
export CPPFLAGS="-I$(brew --prefix readline)/include ${CPPFLAGS}"
export PKG_CONFIG_PATH="$(brew --prefix readline)/lib/pkgconfig:${PKG_CONFIG_PATH}"
export LDFLAGS="-L$(brew --prefix tcl-tk)/lib ${LDFLAGS}"
export CPPFLAGS="-I$(brew --prefix tcl-tk)/include ${CPPFLAGS}"
export PKG_CONFIG_PATH="$(brew --prefix tcl-tk)/lib/pkgconfig:${PKG_CONFIG_PATH}"
export LDFLAGS="-L$(brew --prefix zlib)/lib ${LDFLAGS}"
export CPPFLAGS="-I$(brew --prefix zlib)/include ${CPPFLAGS}"
export PKG_CONFIG_PATH="$(brew --prefix zlib)/lib/pkgconfig:${PKG_CONFIG_PATH}"
export LDFLAGS="-L$(brew --prefix bzip2)/lib ${LDFLAGS}"
export CPPFLAGS="-I$(brew --prefix bzip2)/include ${CPPFLAGS}"
export PKG_CONFIG_PATH="$(brew --prefix bzip2)/lib/pkgconfig:${PKG_CONFIG_PATH}"
fi
print_colored blue "Finished Platform-Specific Setup."
TMP_OWN_PREFIX=$(echo "$OWN_PREFIX" | sed 's#\/#\\\/#g')
# --- Setup Python Environment ---
print_colored blue "Setting up Python Environment..."
export PYTHON_BIN="$OWN_PREFIX/bin/python3.12"
export PIP_BIN="$OWN_PREFIX/bin/pip3.12"
export VSFUNCPH="$OWN_PREFIX/lib/python3.12/site-packages"
SHOULD_BUILD_PYTHON=false
if [ ! -f "$PYTHON_BIN" ]; then
SHOULD_BUILD_PYTHON=true
elif [ "$BUILD_PYTHON_FLAG" = true ]; then
SHOULD_BUILD_PYTHON=true
fi
if [ "$SHOULD_BUILD_PYTHON" = true ]; then
print_colored green " Building Python 3.12.10 "
rm -rf Python-3.12.10 Python-3.12.10.tar.xz # Clean before downloading
wget -q https://www.python.org/ftp/python/3.12.10/Python-3.12.10.tar.xz
tar xf Python-3.12.10.tar.xz
pushd Python-3.12.10
print_colored blue "Configuring Python..."
ORIG_LDFLAGS_PY="${LDFLAGS}"
if [[ "$OS_TYPE" == "macos" ]]; then
export LDFLAGS="$LDFLAGS -lintl"
fi
if [[ "$OS_TYPE" == "macos" ]]; then
./configure --prefix="$OWN_PREFIX" --with-openssl="$(brew --prefix openssl@3)" \
LDFLAGS="${LDFLAGS}" CPPFLAGS="${CPPFLAGS}" \
&>"$OWN_PREFIX/python312_10_conf.log"
else
./configure --prefix="$OWN_PREFIX" \
LDFLAGS="${LDFLAGS}" CPPFLAGS="${CPPFLAGS}" \
&>"$OWN_PREFIX/python312_10_conf.log"
fi
print_colored blue "Building Python (make)..."
make -j"$NPROC" 2>&1 | tee "$OWN_PREFIX/python312_10_make.log"
print_colored blue "Installing Python (make altinstall)..."
make altinstall &>"$OWN_PREFIX/python312_10_install.log"
print_colored blue "Cleaning Python build..."
make clean -j"$NPROC"
export LDFLAGS="${ORIG_LDFLAGS_PY}"
popd
rm -rf Python-3.12.10 Python-3.12.10.tar.xz
print_colored green " Finished Python build "
else
print_colored yellow "Python 3.12 already exists. Skipping build."
fi
PIP_INSTALL_ARGS="--user"
export PYTHONUSERBASE="$OWN_PREFIX"
print_colored blue "Finished Python Environment Setup."
# --- Build zimg ---
print_colored green " Building zimg "
rm -rf zimg
git clone https://github.com/sekrit-twc/zimg.git --depth 1 --recurse-submodules --shallow-submodules
pushd zimg
./autogen.sh
./configure --prefix="$OWN_PREFIX"
make -j"$NPROC"
make install -j"$NPROC"
make clean -j"$NPROC"
popd
rm -rf zimg
print_colored green " Finished zimg "
# --- Build VapourSynth ---
if [[ "$PLUGIN_TYPE" == "vs" || "$PLUGIN_TYPE" == "all" ]]; then
print_colored green " Building VapourSynth "
"$PIP_BIN" install -U pip
"$PIP_BIN" install -U cython setuptools wheel pypng zstandard fonttools $PIP_INSTALL_ARGS
rm -rf vapoursynth
git clone --recursive https://github.com/vapoursynth/vapoursynth.git
pushd vapoursynth
git checkout 40608b5552b035a8599e0a5fe57272287f9cf640 # R71
ORIG_LDFLAGS_VS="${LDFLAGS}"
VS_LDFLAGS_TEMP="${LDFLAGS}"
if [[ "$OS_TYPE" == "macos" ]]; then
VS_LDFLAGS_TEMP="$VS_LDFLAGS_TEMP -lintl"
print_colored blue "Temporarily added -lintl for VapourSynth build."
fi
./autogen.sh
LDFLAGS="${VS_LDFLAGS_TEMP}" ./configure --prefix="$OWN_PREFIX"
make LDFLAGS="${VS_LDFLAGS_TEMP}" -j"$NPROC"
make LDFLAGS="${VS_LDFLAGS_TEMP}" install -j"$NPROC"
"$PYTHON_BIN" setup.py sdist -d sdist
mkdir -p empty && pushd empty
PKG_CONFIG_PATH=$MYPKGPH LDFLAGS="${VS_LDFLAGS_TEMP}" "$PIP_BIN" install vapoursynth --no-index --find-links ../sdist $PIP_INSTALL_ARGS
popd
make clean -j"$NPROC"
export LDFLAGS="${ORIG_LDFLAGS_VS}"
print_colored blue "Restored original LDFLAGS after VapourSynth build."
popd
rm -rf vapoursynth
print_colored green " Finished VapourSynth "
else
print_colored yellow " Skipping VapourSynth build "
fi
# --- Build dav1d ---
print_colored green " Building dav1d "
rm -rf dav1d
git clone https://code.videolan.org/videolan/dav1d.git --branch 1.5.1 --depth 1
pushd dav1d
mkdir -p build && pushd build
meson setup --prefix="$OWN_PREFIX" --libdir="$MYLDPH" -Denable_tools=false -Denable_tests=false --default-library=static --buildtype release . ..
ninja
ninja install
ninja clean
popd
popd
rm -rf dav1d
print_colored green " Finished dav1d "
# --- Install nv-codec-headers (Linux Only) ---
if [[ "$OS_TYPE" == "linux" ]]; then
print_colored green " Installing nv-codec-headers "
rm -rf nv-codec-headers
git clone --recursive https://github.com/FFmpeg/nv-codec-headers --depth 1
pushd nv-codec-headers
$SED_I "s#/usr/local#${TMP_OWN_PREFIX}#g" Makefile
make install -j"$NPROC"
popd
rm -rf nv-codec-headers
print_colored green " Finished nv-codec-headers "
else
print_colored yellow " Skipping nv-codec-headers (Linux Only) "
fi
# --- Build libvpx ---
print_colored green " Building libvpx "
rm -rf libvpx
git clone --recursive https://github.com/webmproject/libvpx.git --branch v1.15.1 --depth 1
mkdir -p libvpx/builds && pushd libvpx/builds
../configure --prefix="$OWN_PREFIX" --as=nasm --enable-vp9-highbitdepth --disable-docs --disable-tools --disable-examples --disable-webm-io --disable-vp8-encoder --disable-vp9-encoder --enable-pic
make -j"$NPROC"
make install -j"$NPROC"
make clean
popd
rm -rf libvpx
print_colored green " Finished libvpx "
# --- Build libxml2 ---
print_colored green " Building libxml2 "
rm -rf libxml2
git clone https://gitlab.gnome.org/GNOME/libxml2.git --branch v2.14.2 --depth 1
pushd libxml2
./autogen.sh
./configure --prefix="$OWN_PREFIX" --enable-static --without-python
make -j"$NPROC"
make install -j"$NPROC"
make clean
popd
rm -rf libxml2
print_colored green " Finished libxml2 "
# --- Build obuparse ---
print_colored green " Building obuparse "
rm -rf obuparse
git clone --recursive https://github.com/dwbuiten/obuparse --depth 1
pushd obuparse
$SED_I "s#/usr/local#${TMP_OWN_PREFIX}#g" Makefile
if [[ "$OS_TYPE" == "macos" ]]; then
print_colored blue "Patching obuparse Makefile for macOS (removing --version-script)..."
$SED_I 's/-Wl,--version-script,obuparse.v//g' Makefile
fi
make clean
PREFIX="$OWN_PREFIX" make CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" -j"$NPROC" && make install -j"$NPROC"
popd
rm -rf obuparse
print_colored green " Finished obuparse "
# --- Build l-smash static-libs ---
print_colored green " Building l-smash static-libs "
rm -rf l-smash # Clean up first
git clone --recursive https://github.com/yuygfgg/l-smash.git --depth 1
pushd l-smash
mv configure configure.old
sed 's/-Wl,--version-script,liblsmash.ver//g' configure.old >configure
chmod +x configure
export CFLAGS_LSMASH="-I. ${CFLAGS}"
export CPPFLAGS_LSMASH="-I. ${CPPFLAGS}"
print_colored blue "Configuring l-smash..."
./configure --prefix="$OWN_PREFIX" --extra-cflags="${CFLAGS_LSMASH}" --extra-ldflags="${LDFLAGS}"
print_colored blue "Building l-smash (make static-lib)..."
make CFLAGS="${CFLAGS_LSMASH}" CPPFLAGS="${CPPFLAGS_LSMASH}" static-lib -j"$NPROC"
print_colored blue "Installing l-smash..."
make install-lib -j"$NPROC"
print_colored blue "Cleaning l-smash..."
make clean
popd
rm -rf l-smash
print_colored green " Finished l-smash "
# --- Build AviSynth ---
if [[ "$PLUGIN_TYPE" == "avs" || "$PLUGIN_TYPE" == "all" ]]; then
print_colored green " Building AviSynth "
rm -rf AviSynthPlus
git clone --recursive https://github.com/AviSynth/AviSynthPlus --branch 3.7 --depth 1
pushd AviSynthPlus
cmake -S . -B build -GNinja -DCMAKE_PREFIX_PATH="$OWN_PREFIX" -DCMAKE_BUILD_TYPE=Release -DENABLE_PLUGINS=OFF -DENABLE_INTEL_SIMD=OFF -DCMAKE_INSTALL_LIBDIR=lib -DCMAKE_C_FLAGS="${CFLAGS}" -DCMAKE_CXX_FLAGS="${CXXFLAGS}"
cmake --build build
cmake --install build --prefix "$OWN_PREFIX"
ninja -C build clean
popd
rm -rf AviSynthPlus
print_colored green " Finished AviSynth "
else
print_colored yellow " Skipping AviSynth build "
fi
# --- Build FFmpeg for L-SMASH-Works ---
print_colored green " Building FFmpeg for L-SMASH-Works "
rm -rf L-SMASH-Works-temp # Clean up temporary directory
git clone --recursive https://github.com/HomeOfAviSynthPlusEvolution/L-SMASH-Works --depth 1 --branch master L-SMASH-Works-temp
pushd L-SMASH-Works-temp/FFmpeg
FFMPEG_LDFLAGS="${LDFLAGS}"
FFMPEG_CFLAGS="${CFLAGS}"
./configure --prefix="$OWN_PREFIX" --enable-gpl --enable-version3 \
--disable-debug --disable-hwaccels --disable-encoders \
--disable-avisynth --disable-doc --disable-network --disable-programs \
--disable-muxers --enable-avcodec --enable-avformat --enable-swresample \
--enable-swscale --enable-libdav1d --enable-libvpx --enable-libxml2 \
--extra-cflags="$FFMPEG_CFLAGS" --extra-ldflags="$FFMPEG_LDFLAGS" \
--pkg-config-flags="--static" --enable-pic
make -j"$NPROC"
make install
make clean
popd # FFmpeg
# --- Build L-SMASH-Works plugins ---
print_colored green " Building L-SMASH-Works plugins "
VS_LDFLAGS="${LDFLAGS}"
if [[ "$OS_TYPE" == "linux" ]]; then
VS_LDFLAGS="$VS_LDFLAGS -Wl,-Bsymbolic"
elif [[ "$OS_TYPE" == "macos" ]]; then
print_colored blue "Adding macOS specific frameworks and libs to LDFLAGS..."
GETTEXT_PREFIX=$(brew --prefix gettext)
GETTEXT_STATIC_LIB="$GETTEXT_PREFIX/lib/libintl.a"
MACOS_LIBS="-framework AudioToolbox -framework CoreFoundation -framework CoreVideo -framework VideoToolbox -lbz2"
if [ -f "$GETTEXT_STATIC_LIB" ]; then
print_colored blue "Found static gettext (libintl.a), attempting static link."
MACOS_LIBS="$MACOS_LIBS $GETTEXT_STATIC_LIB -liconv"
else
print_colored yellow "Static gettext not found, linking shared (-lintl)."
MACOS_LIBS="$MACOS_LIBS -lintl -liconv"
fi
VS_LDFLAGS="$VS_LDFLAGS $MACOS_LIBS"
fi
# VapourSynth plugin
if [[ "$PLUGIN_TYPE" == "vs" || "$PLUGIN_TYPE" == "all" ]]; then
print_colored green " Building VapourSynth plugin "
rm -rf L-SMASH-Works-vs
git clone --recursive https://github.com/HomeOfAviSynthPlusEvolution/L-SMASH-Works --depth 1 L-SMASH-Works-vs
pushd L-SMASH-Works-vs
CMAKE_ARGS=(-S . -G Ninja -B build_vs
-DCMAKE_PREFIX_PATH="$OWN_PREFIX"
-DCMAKE_INSTALL_PREFIX="$OWN_PREFIX"
-DCMAKE_INSTALL_LIBDIR="$VSPLGPH"
-DENABLE_VULKAN=OFF
-DBUILD_AVS_PLUGIN=OFF
-DCMAKE_C_FLAGS="${CFLAGS}"
-DCMAKE_CXX_FLAGS="${CXXFLAGS}"
-DCMAKE_EXE_LINKER_FLAGS="$VS_LDFLAGS"
-DCMAKE_SHARED_LINKER_FLAGS="$VS_LDFLAGS")
if [[ "$OS_TYPE" == "macos" ]]; then
print_colored blue "Disabling MFX for macOS L-SMASH-Works CMake build..."
CMAKE_ARGS+=(-DENABLE_MFX=OFF)
fi
cmake "${CMAKE_ARGS[@]}"
cmake --build build_vs --config Release -j"$NPROC"
if [[ "$OS_TYPE" == "linux" ]]; then
cp build_vs/liblsmashsource.1.so "$VSPLGPH/"
elif [[ "$OS_TYPE" == "macos" ]]; then
cp build_vs/liblsmashsource.1.dylib "$VSPLGPH/"
fi
popd
rm -rf L-SMASH-Works-vs
print_colored green " Finished VapourSynth plugin "
fi
# AviSynth plugin
if [[ "$PLUGIN_TYPE" == "avs" || "$PLUGIN_TYPE" == "all" ]]; then
print_colored green " Building AviSynth plugin "
rm -rf L-SMASH-Works-avs
git clone --recursive https://github.com/HomeOfAviSynthPlusEvolution/L-SMASH-Works --depth 1 L-SMASH-Works-avs
pushd L-SMASH-Works-avs
CMAKE_ARGS=(-S . -G Ninja -B build_avs
-DCMAKE_PREFIX_PATH="$OWN_PREFIX"
-DCMAKE_INSTALL_PREFIX="$OWN_PREFIX"
-DCMAKE_INSTALL_LIBDIR="$OWN_PREFIX/lib"
-DENABLE_VULKAN=OFF
-DBUILD_AVS_PLUGIN=ON
-DBUILD_VS_PLUGIN=OFF
-DCMAKE_C_FLAGS="${CFLAGS}"
-DCMAKE_CXX_FLAGS="${CXXFLAGS}"
-DCMAKE_EXE_LINKER_FLAGS="$VS_LDFLAGS"
-DCMAKE_SHARED_LINKER_FLAGS="$VS_LDFLAGS")
if [[ "$OS_TYPE" == "macos" ]]; then
print_colored blue "Disabling MFX for macOS L-SMASH-Works CMake build..."
CMAKE_ARGS+=(-DENABLE_MFX=OFF)
fi
cmake "${CMAKE_ARGS[@]}"
cmake --build build_avs --config Release -j"$NPROC"
# Copy the built plugin to the AviSynth plugins directory
if [[ "$OS_TYPE" == "linux" ]]; then
mkdir -p "$OWN_PREFIX/lib/avisynth"
cp build_avs/liblsmashsource.1.so "$OWN_PREFIX/lib/avisynth/"
elif [[ "$OS_TYPE" == "macos" ]]; then
mkdir -p "$OWN_PREFIX/lib/avisynth"
cp build_avs/liblsmashsource.1.dylib "$OWN_PREFIX/lib/avisynth/"
fi
popd
rm -rf L-SMASH-Works-avs
print_colored green " Finished AviSynth plugin "
fi
# clean up
pushd L-SMASH-Works-temp/FFmpeg
make uninstall -j"$NPROC"
popd
rm -rf L-SMASH-Works-temp
print_colored green " Build process completed! "
print_colored blue "All files installed in: $OWN_PREFIX"
if [[ "$PLUGIN_TYPE" == "vs" || "$PLUGIN_TYPE" == "all" ]]; then
print_colored blue "VapourSynth plugin installed in: $VSPLGPH"
fi
if [[ "$PLUGIN_TYPE" == "avs" || "$PLUGIN_TYPE" == "all" ]]; then
print_colored blue "AviSynth plugin installed in: $OWN_PREFIX/lib/avisynth"
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment