#!/bin/bash # this script is used to download and build all non-system-provided dependencies # used by musikcube. they are configured with only the features that are strictly # necessary for the app to function, and processed in stage in such a way that they # have no external dependencies except for each other, libc, libc++ and libz. # # this script can also be configured to cross-compile the aforementioned dependencies # for use with raspberry pi; simply set the CROSSCOMPILE=rpi to do so. # # the script will create a "vendor" subdirectory in the current path, and stage # all final files in "vendor/lib". # # dependencies: boost, openssl, curl, libmicrohttpd, ffmpeg, lame, libopenmpt # set -x # # vars # export CFLAGS="-fPIC" export CXXFLAGS="-fPIC" RPATH="@rpath" OS=$(uname) ARCH=$(uname -m) SCRIPTDIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) BOOST_VERSION_URL_PATH="1.79.0" BOOST_VERSION="1_79_0" OPENSSL_VERSION="3.0.2" CURL_VERSION="7.83.0" LIBMICROHTTPD_VERSION="0.9.75" FFMPEG_VERSION="5.0.1" LAME_VERSION="3.100" LIBOPENMPT_VERSION="0.6.2" OUTDIR="$(pwd)/vendor/bin" LIBDIR="$OUTDIR/lib" JOBS="-j8" if [[ $OS == "Darwin" ]]; then JOBS="-j$(sysctl -n hw.ncpu)" fi OPENSSL_TYPE="linux-${ARCH}" if [[ $OS == "Darwin" ]]; then OPENSSL_TYPE="darwin64-${ARCH}-cc" fi # update cross-compile vars, if specified. if [[ $CROSSCOMPILE == "rpi" ]]; then OPENSSL_VERSION="1.1.1n" ARM_ROOT="/build/rpi/sysroot" export CPPFLAGS="-I${ARM_ROOT}/usr/include" export CXXFLAGS="$CXXFLAGS -I${ARM_ROOT}/usr/include" export LDFLAGS="$LDFLAGS --sysroot=${ARM_ROOT} -L${ARM_ROOT}/lib/arm-linux-gnueabihf/" OPENSSL_TYPE="linux-generic32" OPENSSL_CROSSCOMPILE_PREFIX="--cross-compile-prefix=arm-linux-gnueabihf-" GENERIC_CONFIGURE_FLAGS="--build=x86_64-pc-linux-gnu --host=arm-linux-gnueabihf --with-sysroot=${ARM_ROOT}" FFMPEG_CONFIGURE_FLAGS="--arch=${ARCH} --target-os=linux --cross-prefix=arm-linux-gnueabihf-" BOOST_TOOLSET="toolset=gcc-arm" PKG_CONFIG_PATH="${LIBDIR}/pkgconfig/:${ARM_ROOT}/usr/lib/arm-linux-gnueabihf/pkgconfig/" printf "\n\ndetected CROSSCOMPILE=${CROSSCOMPILE}\n" printf " CFLAGS=${CFLAGS}\n CXXFLAGS=${CXXFLAGS}\n LDFLAGS=${LDFLAGS}\n GENERIC_CONFIGURE_FLAGS=${GENERIC_CONFIGURE_FLAGS}\n" printf " BOOST_TOOLSET=${BOOST_TOOLSET}\n OPENSSL_TYPE=${OPENSSL_TYPE}\n OPENSSL_CROSSCOMPILE_PREFIX=${OPENSSL_CROSSCOMPILE_PREFIX}\n" printf " FFMPEG_CONFIGURE_FLAGS=${FFMPEG_CONFIGURE_FLAGS}\n PKG_CONFIG_PATH=${PKG_CONFIG_PATH}\n\n" sleep 3 fi function clean() { rm -rf vendor mkdir vendor } # # download deps # function copy_or_download { url_path=$1 fn=$2 wget_cache="/tmp/musikcube_build_wget_cache" mkdir -p wget_cache 2> /dev/null if [[ -f "$wget_cache/$fn" ]]; then cp "$wget_cache/$fn" . else wget -P $wget_cache "$url_path/$fn" || exit $? cp "$wget_cache/$fn" . || exit $? fi } function fetch_packages() { # no trailing slash on url dirs! copy_or_download https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION_URL_PATH}/source boost_${BOOST_VERSION}.tar.bz2 copy_or_download https://www.openssl.org/source openssl-${OPENSSL_VERSION}.tar.gz copy_or_download https://curl.se/download curl-${CURL_VERSION}.tar.gz copy_or_download https://ftp.gnu.org/gnu/libmicrohttpd libmicrohttpd-${LIBMICROHTTPD_VERSION}.tar.gz copy_or_download https://ffmpeg.org/releases ffmpeg-${FFMPEG_VERSION}.tar.bz2 copy_or_download https://downloads.sourceforge.net/project/lame/lame/3.100 lame-${LAME_VERSION}.tar.gz copy_or_download https://lib.openmpt.org/files/libopenmpt/src libopenmpt-${LIBOPENMPT_VERSION}+release.autotools.tar.gz } # # boost # function build_boost() { BOOST_CXX_FLAGS="-fPIC" if [[ $OS == "Darwin" ]]; then BOOST_CXX_FLAGS="-fPIC -std=c++14 -stdlib=libc++" fi tar xvfj boost_${BOOST_VERSION}.tar.bz2 cd boost_${BOOST_VERSION} if [[ $CROSSCOMPILE == "rpi" ]]; then printf "creating ~/user-config.jam with arm compiler\n" echo "using gcc : arm : arm-linux-gnueabihf-g++ ;" > ~/user-config.jam else printf "removing ~/user-config.jam\n" rm ~/user-config.jam 2> /dev/null fi ./bootstrap.sh --with-libraries=atomic,chrono,date_time,filesystem,system,thread || exit $? ./b2 headers || exit $? ./b2 -d ${JOBS} -sNO_LZMA=1 -sNO_ZSTD=1 ${BOOST_TOOLSET} threading=multi link=shared cxxflags="${BOOST_CXX_FLAGS}" --prefix=${OUTDIR} install || exit $? cd .. } # # openssl # function build_openssl() { tar xvfz openssl-${OPENSSL_VERSION}.tar.gz cd openssl-${OPENSSL_VERSION} perl ./Configure --prefix=${OUTDIR} no-ssl3 no-ssl3-method no-zlib ${OPENSSL_TYPE} ${OPENSSL_CROSSCOMPILE_PREFIX} || exit $? make make install_sw cd .. if [ -d "bin/lib64" ]; then mv bin/lib64/pkgconfig/* bin/lib/pkgconfig/ mv bin/lib64/* bin/lib/ rm -rf bin/lib64 perl -i.bak -0pe "s|lib64|lib|" bin/lib/pkgconfig/libcrypto.pc perl -i.bak -0pe "s|lib64|lib|" bin/lib/pkgconfig/libssl.pc perl -i.bak -0pe "s|lib64|lib|" bin/lib/pkgconfig/open.pc fi } # # curl # function build_curl() { rm -rf curl-${CURL_VERSION} tar xvfz curl-${CURL_VERSION}.tar.gz cd curl-${CURL_VERSION} ./configure --enable-shared \ --with-pic \ --with-openssl="${OUTDIR}" \ --enable-optimize \ --enable-http \ --enable-proxy \ --enable-ipv6 \ --disable-rtsp \ --disable-ftp \ --disable-ftps \ --disable-gopher \ --disable-gophers \ --disable-pop3 \ --disable-pop3s \ --disable-smb \ --disable-smbs \ --disable-smtp \ --disable-telnet \ --disable-tftp \ --disable-hsts \ --disable-imap \ --disable-mqtt \ --disable-dict \ --disable-ldap \ --without-librtmp \ --without-zstd \ --without-brotli \ --without-libidn2 \ --without-nghttp2 \ ${GENERIC_CONFIGURE_FLAGS} \ --prefix=${OUTDIR} || exit $? make ${JOBS} || exit $? make install cd .. } # # libmicrohttpd # function build_libmicrohttpd() { rm -rf libmicrohttpd-${LIBMICROHTTPD_VERSION} tar xvfz libmicrohttpd-${LIBMICROHTTPD_VERSION}.tar.gz cd libmicrohttpd-${LIBMICROHTTPD_VERSION} ./configure --enable-shared --with-pic --enable-https=no --disable-curl --prefix=${OUTDIR} ${GENERIC_CONFIGURE_FLAGS} make -j8 || exit $? make install cd .. } # # ffmpeg # function build_ffmpeg() { # fix for cross-compile: https://github.com/NixOS/nixpkgs/pull/76915/files rm -rf ffmpeg-${FFMPEG_VERSION} tar xvfj ffmpeg-${FFMPEG_VERSION}.tar.bz2 cd ffmpeg-${FFMPEG_VERSION} ./configure \ --prefix=${OUTDIR} \ --pkg-config="pkg-config" \ --enable-rpath \ --disable-asm \ --enable-pic \ --enable-shared \ --disable-everything \ --disable-programs \ --disable-doc \ --disable-debug \ --disable-dxva2 \ --disable-avdevice \ --disable-avfilter \ --disable-swscale \ --disable-ffplay \ --disable-network \ --disable-muxers \ --disable-demuxers \ --disable-zlib \ --disable-bzlib \ --disable-iconv \ --disable-bsfs \ --disable-filters \ --disable-parsers \ --disable-indevs \ --disable-outdevs \ --disable-encoders \ --disable-decoders \ --disable-hwaccels \ --disable-nvenc \ --disable-xvmc \ --disable-videotoolbox \ --disable-audiotoolbox \ --disable-filters \ --disable-libxcb \ --disable-libxcb-shm \ --disable-libxcb-xfixes \ --disable-libxcb-shape \ --disable-sdl2 \ --disable-securetransport \ --disable-vaapi \ --disable-xlib \ --enable-libopus \ --enable-libvorbis \ --enable-demuxer=aac \ --enable-demuxer=ac3 \ --enable-demuxer=aiff \ --enable-demuxer=ape \ --enable-demuxer=asf \ --enable-demuxer=au \ --enable-demuxer=avi \ --enable-demuxer=flac \ --enable-demuxer=flv \ --enable-demuxer=matroska \ --enable-demuxer=m4v \ --enable-demuxer=mp3 \ --enable-demuxer=mpc \ --enable-demuxer=mpc8 \ --enable-demuxer=ogg \ --enable-demuxer=mov \ --enable-demuxer=pcm_alaw \ --enable-demuxer=pcm_mulaw \ --enable-demuxer=pcm_f64be \ --enable-demuxer=pcm_f64le \ --enable-demuxer=pcm_f32be \ --enable-demuxer=pcm_f32le \ --enable-demuxer=pcm_s32be \ --enable-demuxer=pcm_s32le \ --enable-demuxer=pcm_s24be \ --enable-demuxer=pcm_s24le \ --enable-demuxer=pcm_s16be \ --enable-demuxer=pcm_s16le \ --enable-demuxer=pcm_s8 \ --enable-demuxer=pcm_u32be \ --enable-demuxer=pcm_u32le \ --enable-demuxer=pcm_u24be \ --enable-demuxer=pcm_u24le \ --enable-demuxer=pcm_u16be \ --enable-demuxer=pcm_u16le \ --enable-demuxer=pcm_u8 \ --enable-demuxer=wav \ --enable-demuxer=wv \ --enable-demuxer=xwma \ --enable-demuxer=dsf \ --enable-decoder=aac \ --enable-decoder=aac_latm \ --enable-decoder=ac3 \ --enable-decoder=alac \ --enable-decoder=als \ --enable-decoder=ape \ --enable-decoder=atrac1 \ --enable-decoder=atrac3 \ --enable-decoder=eac3 \ --enable-decoder=flac \ --enable-decoder=mp1 \ --enable-decoder=mp1float \ --enable-decoder=mp2 \ --enable-decoder=mp2float \ --enable-decoder=mp3 \ --enable-decoder=mp3adu \ --enable-decoder=mp3adufloat \ --enable-decoder=mp3float \ --enable-decoder=mp3on4 \ --enable-decoder=mp3on4float \ --enable-decoder=mpc7 \ --enable-decoder=mpc8 \ --enable-decoder=opus \ --enable-decoder=vorbis \ --enable-decoder=wavpack \ --enable-decoder=wmalossless \ --enable-decoder=wmapro \ --enable-decoder=wmav1 \ --enable-decoder=wmav2 \ --enable-decoder=wmavoice \ --enable-decoder=pcm_alaw \ --enable-decoder=pcm_bluray \ --enable-decoder=pcm_dvd \ --enable-decoder=pcm_f32be \ --enable-decoder=pcm_f32le \ --enable-decoder=pcm_f64be \ --enable-decoder=pcm_f64le \ --enable-decoder=pcm_lxf \ --enable-decoder=pcm_mulaw \ --enable-decoder=pcm_s8 \ --enable-decoder=pcm_s8_planar \ --enable-decoder=pcm_s16be \ --enable-decoder=pcm_s16be_planar \ --enable-decoder=pcm_s16le \ --enable-decoder=pcm_s16le_planar \ --enable-decoder=pcm_s24be \ --enable-decoder=pcm_s24daud \ --enable-decoder=pcm_s24le \ --enable-decoder=pcm_s24le_planar \ --enable-decoder=pcm_s32be \ --enable-decoder=pcm_s32le \ --enable-decoder=pcm_s32le_planar \ --enable-decoder=pcm_u8 \ --enable-decoder=pcm_u16be \ --enable-decoder=pcm_u16le \ --enable-decoder=pcm_u24be \ --enable-decoder=pcm_u24le \ --enable-decoder=pcm_u32be \ --enable-decoder=pcm_u32le \ --enable-decoder=dsd_lsbf \ --enable-decoder=dsd_msbf \ --enable-decoder=dsd_lsbf_planar \ --enable-decoder=dsd_msbf_planar \ --enable-parser=aac \ --enable-parser=aac_latm \ --enable-parser=ac3 \ --enable-parser=cook \ --enable-parser=dca \ --enable-parser=flac \ --enable-parser=mpegaudio \ --enable-parser=opus \ --enable-parser=vorbis \ --enable-muxer=adts \ --enable-muxer=flac \ --enable-muxer=ogg \ --enable-muxer=opus \ --enable-muxer=webm \ --enable-muxer=webp \ --enable-muxer=mov \ --enable-muxer=mp4 \ --enable-encoder=aac \ --enable-encoder=alac \ --enable-encoder=flac \ --enable-encoder=mpeg4 \ --enable-encoder=libopus \ --enable-encoder=wavpack \ --enable-encoder=wmav1 \ --enable-encoder=wmav2 \ --enable-encoder=libvorbis \ ${FFMPEG_CONFIGURE_FLAGS} \ --build-suffix=-musikcube || exit $? make ${JOBS} || exit $? make install cd .. } # # lame # function build_lame() { rm -rf lame-${LAME_VERSION} tar xvfz lame-${LAME_VERSION}.tar.gz cd lame-${LAME_VERSION} # https://sourceforge.net/p/lame/mailman/message/36081038/ perl -i.bak -0pe "s|lame_init_old\n||" include/libmp3lame.sym ./configure --disable-dependency-tracking --disable-debug --enable-nasm --prefix=${OUTDIR} ${GENERIC_CONFIGURE_FLAGS} || exit $? make ${JOBS} || exit $? make install cd .. } # # libopenmpt # function build_libopenmpt() { rm -rf libopenmpt-${LIBOPENMPT_VERSION}+release.autotools tar xvfz libopenmpt-${LIBOPENMPT_VERSION}+release.autotools.tar.gz cd libopenmpt-${LIBOPENMPT_VERSION}+release.autotools ./configure \ --disable-dependency-tracking \ --enable-shared \ --disable-openmpt123 \ --disable-examples \ --disable-tests \ --disable-doxygen-doc \ --disable-doxygen-html \ --without-mpg123 \ --without-ogg \ --without-vorbis \ --without-vorbisfile \ --without-portaudio \ --without-portaudiocpp \ --without-sndfile \ --without-flac \ ${GENERIC_CONFIGURE_FLAGS} \ --prefix=${OUTDIR} || exit $? make ${JOBS} || exit $? make install cd .. } # # macOS dylib rpaths # function stage_prebuilt_libraries() { if [[ $OS == "Darwin" ]]; then BREW=$(brew --prefix) LIBOPUS="$BREW/opt/opus/lib/libopus.0.dylib" LIBOGG="$BREW/opt/libogg/lib/libogg.0.dylib" LIBVORBIS="$BREW/opt/libvorbis/lib/libvorbis.0.dylib" LIBVORBISENC="$BREW/opt/libvorbis/lib/libvorbisenc.2.dylib" mkdir -p bin/lib/ cp ${LIBOPUS} ${LIBOGG} ${LIBVORBIS} ${LIBVORBISENC} bin/lib/ chmod 755 bin/lib/*.dylib fi } function relink_dynamic_libraries() { node ${SCRIPTDIR}/relink-dynamic-libraries.js bin/lib } function delete_unused_libraries() { cd bin/lib/ rm *.a 2> /dev/null rm *.la 2> /dev/null if [[ $OS == "Darwin" ]]; then mv libavcodec-musikcube.59.18.100.dylib libavcodec-musikcube.59.dylib rm libavcodec-musikcube.dylib ln -s libavcodec-musikcube.59.dylib libavcodec-musikcube.dylib mv libavformat-musikcube.59.16.100.dylib libavformat-musikcube.59.dylib rm libavformat-musikcube.dylib ln -s libavformat-musikcube.59.dylib libavformat-musikcube.dylib mv libavutil-musikcube.57.17.100.dylib libavutil-musikcube.57.dylib rm libavutil-musikcube.dylib ln -s libavutil-musikcube.57.dylib libavutil-musikcube.dylib mv libswresample-musikcube.4.3.100.dylib libswresample-musikcube.4.dylib rm libswresample-musikcube.dylib ln -s libswresample-musikcube.4.dylib libswresample-musikcube.dylib fi cd ../../ } clean mkdir vendor cd vendor stage_prebuilt_libraries fetch_packages build_boost build_openssl build_curl build_libmicrohttpd build_ffmpeg build_lame build_libopenmpt delete_unused_libraries relink_dynamic_libraries cd .. if [[ $CROSSCOMPILE == "rpi" ]]; then mv vendor vendor-${CROSSCOMPILE} else mv vendor vendor-$(uname -m) fi printf "\n\ndone!\n\n"