#!/usr/bin/env bash

# --------------------------------------
# -------- FOLDERS DEFINED HERE --------

if [ ! "${CUSTOM_DIRECTORY}" == "YES" ]; then
   # Build Directory
   BUILD_DIR=~/build
   # Prefix Directory
   PREFIX_DIR=~/dev
   # Source Directory
   SOURCE_DIR=~/src
   # Qt Directories
   QT_SHARE_DIR="${PREFIX_DIR}/share"
   QT_SYSCONF_DIR="${PREFIX_DIR}/etc/xdg"
fi

# --------------------------------------
# -------- VERSION DEFINED HERE --------

if [ ! "${CUSTOM_VERSION}" == "YES" ]; then
   # Third Party
   ZLIB_VERSION=1.2.11
   LIBPNG_VERSION=1.6.37
   LIBJPEGTURBO_VERSION=2.0.6
   LIBRESSL_VERSION=3.2.4
   OPENSSL_VERSION=1.1.1j
   ICU_VERSION=68.2
   HB_VERSION=2.7.4 # HarfBuzz

   # Qt Framework
   QT_SERIES=5.15 # (x.x).y
   QT_BUILD=2 # x.x.(y)
fi

# --------------------------------------
# ---------- CUSTOM SSL FLAGS ----------

if [ ! "${CUSTOM_SSL}" == "YES" ]; then
   # Custom OpenSSL installation method
   CUSTOM_OPENSSL_INSTALL=YES

   # Use OpenSSL instead of LibreSSL
   USE_OPENSSL=YES
fi

# --------------------------------------
# ----------- QT BUILD FLAGS -----------

if [ ! "${CUSTOM_QT_FLAGS}" == "YES" ]; then
   QT_FLAGS="-qt-freetype"
fi
if [ ! "${CUSTOM_QT_SKIP_FLAGS}" == "YES" ]; then
   QT_SKIP_FLAGS="-skip qtactiveqt -skip qtconnectivity -skip qtlocation -skip qtwebengine -skip qtwebglplugin"
fi
if [ ! "${CUSTOM_QT_NOMAKE_FLAGS}" == "YES" ]; then
   QT_NOMAKE_FLAGS="-nomake tests -nomake examples"
fi
if [ ! "${CUSTOM_QT_NOFEATURE_FLAGS}" == "YES" ]; then
   QT_NOFEATURE_FLAGS="-no-feature-d3d12"
fi
if [ ! "${CUSTOM_QT_OPENGL_FLAGS}" == "YES" ]; then
   QT_OPENGL_FLAGS="-opengl desktop"
fi
if [ ! "${CUSTOM_QT_BUILDTYPE_FLAGS}" == "YES" ]; then
   QT_BUILDTYPE_FLAGS="-release"
fi

# --------------------------------------
# --------- CPU VARIABLES HERE ---------

if [ "${CPU_THREADS}" == "" ]; then
   NPROC_PATH=$(command -v nproc)
   if [ ! "${NPROC_PATH}" == "" ]; then
      CPU_THREADS=$(nproc --all)
   else
      CPU_THREADS=4
   fi
fi

# --------------------------------------
# --------- CUSTOM BUILD FLAGS ---------

if [ ! "${CUSTOM_BUILD}" == "YES" ]; then
   # Projects being build
   BUILD_ZLIB=YES
   BUILD_PNG=YES
   BUILD_JPG=YES
   BUILD_SSL=YES
   BUILD_ICU=NO
   BUILD_HB=NO
   BUILD_QT=YES
fi

# --------------------------------------
# ----------- CUSTOM LINKING -----------

if [ ! "${CUSTOM_LINK}" == "YES" ]; then
   # Projects being linked
   LINK_ZLIB=YES
   LINK_PNG=YES
   LINK_JPG=YES
   LINK_SSL=YES
   LINK_ICU=NO
   LINK_HB=NO
fi

# --------------------------------------
# ----- DON'T EDIT BELOW THIS LINE -----
# --------------------------------------

# shared make script

function shared_init {
   local SM_PROJECT_NAME=$1
   local SM_PROJECT_VERSION=$2
   local SM_TARGET_TYPE=$3
   if [ "${BUILD_MODE}" == "TL" ]; then
      local SM_BUILD_DIR="${BUILD_DIR}/${SM_PROJECT_NAME}-${SM_PROJECT_VERSION}_${TARGET_PLATFORM}"
   else
      local SM_BUILD_DIR="${BUILD_DIR}/${SM_PROJECT_NAME}-${SM_PROJECT_VERSION}_${TARGET_PLATFORM}_${SM_TARGET_TYPE}"
   fi
   mkdir -p "${SM_BUILD_DIR}"
   cd "${SM_BUILD_DIR}"
}

function shared_clean {
   local SM_PROJECT_NAME=$1
   local SM_PROJECT_VERSION=$2
   local SM_TARGET_TYPE=$3
   if [ "${BUILD_MODE}" == "TL" ]; then
      local SM_BUILD_DIR="${BUILD_DIR}/${SM_PROJECT_NAME}-${SM_PROJECT_VERSION}_${TARGET_PLATFORM}"
   else
      local SM_BUILD_DIR="${BUILD_DIR}/${SM_PROJECT_NAME}-${SM_PROJECT_VERSION}_${TARGET_PLATFORM}_${SM_TARGET_TYPE}"
   fi
   cd "${SM_BUILD_DIR}"
   rm -rf "${SM_BUILD_DIR}"
}

# automake script

function automake_init {
   shared_init $1 $2 $3
}

function automake_build {
   local AM_PROJECT_DIR=$1
   local AM_PROJECT_NAME=$2
   local AM_PROJECT_VERSION=$3
   local AM_TARGET_TYPE=$4
   local AM_TARGET_SUFFIX=$5
   if [ "${BUILD_MODE}" == "TL" ]; then
      local AM_BUILD_DIR="${BUILD_DIR}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}_${TARGET_PLATFORM}"
      local AM_TARGET_TYPE=static
   else
      local AM_BUILD_DIR="${BUILD_DIR}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}_${TARGET_PLATFORM}_${AM_TARGET_TYPE}"
   fi
   cd "${AM_BUILD_DIR}"
   if [ "${AM_TARGET_TYPE}" == "static" ]; then
      local AM_EXTRA_FLAGS=--disable-shared
   else
      local AM_EXTRA_FLAGS=
   fi
   if [ "${USE_CLANG}" == "YES" ]; then
      local CC=${COMPILER}-clang
      local CXX=${COMPILER}-clang++
   elif [ "${USE_GCC}" == "YES" ]; then
      local CC=${COMPILER}-gcc
      local CXX=${COMPILER}-g++
   else
      local CC=${COMPILER}-cc
      local CXX=${COMPILER}-c++
   fi
   if [ "${AM_PROJECT_NAME}" == "libpng" ] && [ ! "${ZLIB_LDFLAGS}" == "" ] && [ ! "${ZLIB_CPPFLAGS}" == "" ]; then
      local LDFLAGS=${ZLIB_LDFLAGS}
      local CPPFLAGS=${ZLIB_CPPFLAGS}
   else
      local LDFLAGS=
      local CPPFLAGS=
   fi
   if [ "${AM_PROJECT_NAME}" == "zlib" ]; then
      if [ "${AM_TARGET_TYPE}" == "static" ]; then
         local AM_EXTRA_FLAGS=--static
      fi
      CC=${CC} CXX=${CXX} CHOST=${COMPILER} "${AM_PROJECT_DIR}/configure" ${AM_EXTRA_FLAGS} --prefix "${PREFIX_DIR}/lib/${COMPILER}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}${AM_TARGET_SUFFIX}" --libdir="${PREFIX_DIR}/lib/${COMPILER}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}${AM_TARGET_SUFFIX}/lib" --includedir="${PREFIX_DIR}/include/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}"
   else
      CC=${CC} CXX=${CXX} CPPFLAGS=${CPPFLAGS} LDFLAGS=${LDFLAGS} "${AM_PROJECT_DIR}/configure" --host=${COMPILER} ${AM_EXTRA_FLAGS} --prefix "${PREFIX_DIR}/lib/${COMPILER}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}${AM_TARGET_SUFFIX}" --bindir="${PREFIX_DIR}/lib/${COMPILER}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}${AM_TARGET_SUFFIX}/bin" --libdir="${PREFIX_DIR}/lib/${COMPILER}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}${AM_TARGET_SUFFIX}/lib" --includedir="${PREFIX_DIR}/include/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}"
   fi
   ${MAKE_GENERATOR}
}

function automake_install {
   local AM_PROJECT_NAME=$1
   local AM_PROJECT_VERSION=$2
   local AM_TARGET_TYPE=$3
   local AM_TARGET_SUFFIX=$4
   if [ "${BUILD_MODE}" == "TL" ]; then
      local AM_BUILD_DIR="${BUILD_DIR}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}_${TARGET_PLATFORM}"
   else
      local AM_BUILD_DIR="${BUILD_DIR}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}_${TARGET_PLATFORM}_${AM_TARGET_TYPE}"
   fi
   cd "${AM_BUILD_DIR}"
   ${MAKE_GENERATOR_INSTALL}
   if [ ! -L "${PREFIX_DIR}/lib/${COMPILER}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}${AM_TARGET_SUFFIX}/include" ]; then
      ln -sf "${PREFIX_DIR}/include/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}" "${PREFIX_DIR}/lib/${COMPILER}/${AM_PROJECT_NAME}-${AM_PROJECT_VERSION}${AM_TARGET_SUFFIX}/include"
   fi
}

function automake_clean {
   shared_clean $1 $2 $3
}

# cmake script

function cmake_init {
   shared_init $1 $2 $3
}

function cmake_build {
   local CM_PROJECT_DIR=$1
   local CM_PROJECT_NAME=$2
   local CM_PROJECT_VERSION=$3
   local CM_TARGET_TYPE=$4
   local CM_TARGET_SUFFIX=$5
   if [ "${BUILD_MODE}" == "TL" ]; then
      local CM_BUILD_DIR="${BUILD_DIR}/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}_${TARGET_PLATFORM}"
      local CM_TARGET_TYPE=static
   else
      local CM_BUILD_DIR="${BUILD_DIR}/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}_${TARGET_PLATFORM}_${CM_TARGET_TYPE}"
   fi
   if [ "${CM_PROJECT_NAME}" == "libjpeg-turbo" ] && [ "${CM_TARGET_TYPE}" == "static" ]; then
      local CM_EXTRA_FLAGS=-DENABLE_SHARED=OFF
   elif [ "${CM_PROJECT_NAME}" == "harfbuzz" ]; then
      local CM_EXTRA_FLAGS=-DHB_BUILD_SUBSET=OFF
   else
      local CM_EXTRA_FLAGS=
   fi
   cd "${CM_BUILD_DIR}"
   cmake ${CMAKE_GENERATOR_FLAGS} -DCMAKE_BUILD_TYPE=Release ${CM_EXTRA_FLAGS} -DCMAKE_INSTALL_PREFIX="${PREFIX_DIR}/lib/${COMPILER}/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}${CM_TARGET_SUFFIX}" -DCMAKE_INSTALL_INCLUDEDIR="${PREFIX_DIR}/include/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}" "${CMAKE_TOOLCHAIN_FLAGS}" "${CM_PROJECT_DIR}"
   ${CMAKE_GENERATOR}
}

function cmake_install {
   local CM_PROJECT_NAME=$1
   local CM_PROJECT_VERSION=$2
   local CM_TARGET_TYPE=$3
   local CM_TARGET_SUFFIX=$4
   if [ "${BUILD_MODE}" == "TL" ]; then
      local CM_BUILD_DIR="${BUILD_DIR}/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}_${TARGET_PLATFORM}"
   else
      local CM_BUILD_DIR="${BUILD_DIR}/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}_${TARGET_PLATFORM}_${CM_TARGET_TYPE}"
   fi
   cd "${CM_BUILD_DIR}"
   ${CMAKE_GENERATOR_INSTALL}
   if [ ! -L "${PREFIX_DIR}/lib/${COMPILER}/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}${CM_TARGET_SUFFIX}/include" ]; then
      ln -sf "${PREFIX_DIR}/include/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}" "${PREFIX_DIR}/lib/${COMPILER}/${CM_PROJECT_NAME}-${CM_PROJECT_VERSION}${CM_TARGET_SUFFIX}/include"
   fi
}

function cmake_clean {
   shared_clean $1 $2 $3
}

# libjpeg-turbo script

function libjpegturbo_init {
   cmake_init libjpeg-turbo ${LIBJPEGTURBO_VERSION}
}

function libjpegturbo_build {
   cmake_build "${SOURCE_DIR_LIBJPEGTURBO}" libjpeg-turbo ${LIBJPEGTURBO_VERSION}
}

function libjpegturbo_install {
   cmake_install libjpeg-turbo ${LIBJPEGTURBO_VERSION}
}

function libjpegturbo_clean {
   cmake_clean libjpeg-turbo ${LIBJPEGTURBO_VERSION}
}

function libjpegturbo_strip {
   cd "${PREFIX_DIR}/lib/${COMPILER}/libjpeg-turbo-${LIBJPEGTURBO_VERSION}"
   rm -rf bin share
}

function libjpegturbo_register {
   QT_LIBS_FLAGS="${QT_LIBS_FLAGS} -system-libjpeg -L ${PREFIX_DIR}/lib/${COMPILER}/libjpeg-turbo-${LIBJPEGTURBO_VERSION}/lib -I ${PREFIX_DIR}/include/libjpeg-turbo-${LIBJPEGTURBO_VERSION}"
}

function libjpegturbo_source {
   local VERSION=$1
   local ARCHIVE=libjpeg-turbo-${VERSION}
   mkdir -p "${SOURCE_DIR}"
   cd "${SOURCE_DIR}"
   if [ ! -d "${ARCHIVE}" ]; then
      wget -O ${ARCHIVE}.tar.gz "https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${VERSION}.tar.gz"
      tar xfz ${ARCHIVE}.tar.gz
   fi
   SOURCE_DIR_LIBJPEGTURBO="${SOURCE_DIR}/${ARCHIVE}"
}

# zlib script

function zlib_init {
   if [ ! "${TARGET_OS}" == "Windows" ]; then
      automake_init zlib ${ZLIB_VERSION}
   fi
}

function zlib_build {
   if [ "${TARGET_OS}" == "Windows" ]; then
      ${MAKE_GENERATOR} -fwin32/Makefile.gcc --directory="${SOURCE_DIR_ZLIB}" PREFIX=${COMPILER}- || \
         rm -rf "${SOURCE_DIR_ZLIB}" || \
         zlib_source ${ZLIB_VERSION} || \
         ${MAKE_GENERATOR} -fwin32/Makefile.gcc --directory="${SOURCE_DIR_ZLIB}" PREFIX=${COMPILER}-
   else
      automake_build "${SOURCE_DIR_ZLIB}" zlib ${ZLIB_VERSION}
   fi
}

function zlib_install {
   if [ "${TARGET_OS}" == "Windows" ]; then
      ${MAKE_GENERATOR_INSTALL} -fwin32/Makefile.gcc --directory="${SOURCE_DIR_ZLIB}" BINARY_PATH="${PREFIX_DIR}/lib/${COMPILER}/zlib-${ZLIB_VERSION}/bin" LIBRARY_PATH="${PREFIX_DIR}/lib/${COMPILER}/zlib-${ZLIB_VERSION}/lib" INCLUDE_PATH="${PREFIX_DIR}/include/zlib-${ZLIB_VERSION}"
      if [ ! -L "${PREFIX_DIR}/lib/${COMPILER}/zlib-${ZLIB_VERSION}/include" ]; then
         ln -sf "${PREFIX_DIR}/include/zlib-${ZLIB_VERSION}" "${PREFIX_DIR}/lib/${COMPILER}/zlib-${ZLIB_VERSION}/include"
      fi
   else
      automake_install zlib ${ZLIB_VERSION}
   fi
}

function zlib_clean {
   if [ "${TARGET_OS}" == "Windows" ]; then
      ${MAKE_GENERATOR_CLEAN} -fwin32/Makefile.gcc --directory="${SOURCE_DIR_ZLIB}"
   else
      automake_clean zlib ${ZLIB_VERSION}
   fi
}

function zlib_strip {
   if [ ! "${TARGET_OS}" == "Windows" ]; then
      cd "${PREFIX_DIR}/lib/${COMPILER}/zlib-${ZLIB_VERSION}${TARGET_SUFFIX}"
      rm -rf share
   fi
}

function zlib_register {
   ZLIB_CPPFLAGS="-I${PREFIX_DIR}/include/zlib-${ZLIB_VERSION}"
   ZLIB_LDFLAGS="-L${PREFIX_DIR}/lib/${COMPILER}/zlib-${ZLIB_VERSION}/lib"
   QT_LIBS_FLAGS="${QT_LIBS_FLAGS} -system-zlib -L ${PREFIX_DIR}/lib/${COMPILER}/zlib-${ZLIB_VERSION}/lib -I ${PREFIX_DIR}/include/zlib-${ZLIB_VERSION}"
}

function zlib_source {
   local VERSION=$1
   local ARCHIVE=zlib-${VERSION}
   mkdir -p "${SOURCE_DIR}"
   cd "${SOURCE_DIR}"
   if [ ! -d "${ARCHIVE}" ]; then
      wget -O ${ARCHIVE}.tar.gz "https://www.zlib.net/zlib-${VERSION}.tar.gz"
      tar xfz ${ARCHIVE}.tar.gz
   fi
   SOURCE_DIR_ZLIB="${SOURCE_DIR}/${ARCHIVE}"
}

# libpng script

function libpng_init {
   automake_init libpng ${LIBPNG_VERSION}
}

function libpng_build {
   automake_build "${SOURCE_DIR_LIBPNG}" libpng ${LIBPNG_VERSION}
}

function libpng_install {
   automake_install libpng ${LIBPNG_VERSION}
}

function libpng_clean {
   automake_clean libpng ${LIBPNG_VERSION}
}

function libpng_strip {
   cd "${PREFIX_DIR}/lib/${COMPILER}/libpng-${LIBPNG_VERSION}"
   rm -rf bin share
}

function libpng_register {
   QT_LIBS_FLAGS="${QT_LIBS_FLAGS} -system-libpng -L ${PREFIX_DIR}/lib/${COMPILER}/libpng-${LIBPNG_VERSION}/lib -I ${PREFIX_DIR}/include/libpng-${LIBPNG_VERSION}"
}

function libpng_source {
   local VERSION=$1
   local ARCHIVE=libpng-${VERSION}
   mkdir -p "${SOURCE_DIR}"
   cd "${SOURCE_DIR}"
   if [ ! -d "${ARCHIVE}" ]; then
      wget -O ${ARCHIVE}.tar.xz "https://download.sourceforge.net/libpng/libpng-${VERSION}.tar.xz"
      tar xfJ ${ARCHIVE}.tar.xz
   fi
   SOURCE_DIR_LIBPNG="${SOURCE_DIR}/${ARCHIVE}"
}

# LibreSSL script

function libressl_init {
   automake_init libressl ${LIBRESSL_VERSION} ${TARGET_TYPE}
}

function libressl_build {
   automake_build "${SOURCE_DIR_LIBRESSL}" libressl ${LIBRESSL_VERSION} ${TARGET_TYPE} ${TARGET_SUFFIX}
}

function libressl_install {
   automake_install libressl ${LIBRESSL_VERSION} ${TARGET_TYPE} ${TARGET_SUFFIX}
}

function libressl_clean {
   automake_clean libressl ${LIBRESSL_VERSION} ${TARGET_TYPE}
}

function libressl_strip {
   cd "${PREFIX_DIR}/lib/${COMPILER}/libressl-${LIBRESSL_VERSION}${TARGET_SUFFIX}"
   if [ "${TARGET_OS}" == "Windows" ]; then
      rm -rf bin/*.exe etc share
   else
      rm -rf etc share
   fi
}

function libressl_register {
   export OPENSSL_LIBS="-L${PREFIX_DIR}/lib/${COMPILER}/libressl-${LIBRESSL_VERSION}${TARGET_SUFFIX} -lssl -lcrypto"
   QT_LIBS_FLAGS="${QT_LIBS_FLAGS} -openssl-linked -L ${PREFIX_DIR}/lib/${COMPILER}/libressl-${LIBRESSL_VERSION}${TARGET_SUFFIX}/lib -I ${PREFIX_DIR}/include/libressl-${LIBRESSL_VERSION}"
}

function libressl_source {
   local VERSION=$1
   local ARCHIVE=libressl-${VERSION}
   mkdir -p "${SOURCE_DIR}"
   cd "${SOURCE_DIR}"
   if [ ! -d "${ARCHIVE}" ]; then
      wget -O ${ARCHIVE}.tar.gz "https://fastly.cdn.openbsd.org/pub/OpenBSD/LibreSSL/${ARCHIVE}.tar.gz"
      tar xfz ${ARCHIVE}.tar.gz
   fi
   SOURCE_DIR_LIBRESSL="${SOURCE_DIR}/${ARCHIVE}"
   SOURCE_DIR_SSL="${SOURCE_DIR}/${ARCHIVE}"
}

# OpenSSL script

function openssl_init {
   mkdir -p "${BUILD_DIR}/openssl-${OPENSSL_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   cd "${BUILD_DIR}/openssl-${OPENSSL_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
}

function openssl_build {
   cd "${BUILD_DIR}/openssl-${OPENSSL_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   if [ "${TARGET_TYPE}" == "shared" ]; then
      local EXTRA_FLAGS=shared
   else
      local EXTRA_FLAGS=no-shared
   fi
   if [ "${USE_CLANG}" == "YES" ]; then
      local CC=clang
      local CXX=clang++
   elif [ "${USE_GCC}" == "YES" ]; then
      local CC=gcc
      local CXX=g++
   else
      local CC=cc
      local CXX=c++
   fi
   CC=${CC} CXX=${CXX} "${SOURCE_DIR_OPENSSL}/Configure" ${SSL_PLATFORM} ${EXTRA_FLAGS} --cross-compile-prefix=${COMPILER}- --prefix="${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}"
   ${MAKE_GENERATOR}
}

function openssl_install {
   cd "${BUILD_DIR}/openssl-${OPENSSL_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   if [ "${CUSTOM_OPENSSL_INSTALL}" == "YES" ]; then
      mkdir -p "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}" \
      "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib" \
      "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib/pkgconfig" \
      "${PREFIX_DIR}/include/openssl-${OPENSSL_VERSION}" \
      "${PREFIX_DIR}/include/openssl-${OPENSSL_VERSION}/openssl"
      if [ "${TARGET_TYPE}" == "shared" ]; then
         if [ "${TARGET_OS}" == "Windows" ]; then
            mkdir -p "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/bin"
            cp -Rf lib*.dll "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/bin/"
            cp -Rf libcrypto.dll.a libssl.dll.a "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib/"
         else
            cp -Rf lib*.so* "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib/"
         fi
      fi
      cp -Rf libcrypto.a libssl.a "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib/"
      cp -Rf libcrypto.pc libssl.pc openssl.pc "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib/pkgconfig/"
      cp -Rf include/openssl/*.h "${PREFIX_DIR}/include/openssl-${OPENSSL_VERSION}/openssl/"
      cd "${SOURCE_DIR_OPENSSL}"
      cp -Rf include/openssl/*.h "${PREFIX_DIR}/include/openssl-${OPENSSL_VERSION}/openssl/"
      cd "${BUILD_DIR}/openssl-${OPENSSL_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
      if [ ! -L "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/include" ]; then
         ln -sf "${PREFIX_DIR}/include/openssl-${OPENSSL_VERSION}" "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/include" 
      fi
   else
      ${MAKE_GENERATOR_INSTALL}
      if [ ! -L "${PREFIX_DIR}/include/openssl-${OPENSSL_VERSION}" ]; then
         ln -sf "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/include" "${PREFIX_DIR}/include/openssl-${OPENSSL_VERSION}"
      fi
   fi
}

function openssl_clean {
   cd "${BUILD_DIR}/openssl-${OPENSSL_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   rm -rf "${BUILD_DIR}/openssl-${OPENSSL_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
}

function openssl_strip {
   cd "${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}"
   if [ ! "${CUSTOM_OPENSSL_INSTALL}" == "YES" ]; then
      if [ "${TARGET_OS}" == "Windows" ]; then
         rm -rf bin/*.exe bin/c_rehash etc share
      else
         rm -rf bin etc share ssl
      fi
   fi
}

function openssl_register {
   if [ "${TARGET_OS}" == "Windows" ] && [ "${TARGET_TYPE}" == "static" ]; then
      local EXTRA_SSLLIBS="-lws2_32 -lgdi32 -lcrypt32"
   else
      local EXTRA_SSLLIBS=
   fi
   export OPENSSL_LIBS="-L${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib -lssl -lcrypto ${EXTRA_SSLLIBS}"
   if [ "${CUSTOM_OPENSSL_INSTALL}" == "YES" ]; then
      QT_LIBS_FLAGS="${QT_LIBS_FLAGS} -openssl-linked -L ${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib -I ${PREFIX_DIR}/include/openssl-${OPENSSL_VERSION}"
   else
      QT_LIBS_FLAGS="${QT_LIBS_FLAGS} -openssl-linked -L ${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/lib -I ${PREFIX_DIR}/lib/${COMPILER}/openssl-${OPENSSL_VERSION}${TARGET_SUFFIX}/include"
   fi
}

function openssl_source {
   local VERSION=$1
   local ARCHIVE=openssl-${VERSION}
   mkdir -p "${SOURCE_DIR}"
   cd "${SOURCE_DIR}"
   if [ ! -d "${ARCHIVE}" ]; then
      wget -O ${ARCHIVE}.tar.gz "https://www.openssl.org/source/${ARCHIVE}.tar.gz"
      tar xfz ${ARCHIVE}.tar.gz
   fi
   SOURCE_DIR_OPENSSL="${SOURCE_DIR}/${ARCHIVE}"
   SOURCE_DIR_SSL="${SOURCE_DIR}/${ARCHIVE}"
}

# ICU script

function icu_init {
   mkdir -p "${BUILD_DIR}/icu4c-${ICU_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}" \
      "${BUILD_DIR}/icu4c-${ICU_VERSION}_native" \
      "${BUILD_DIR}/icu4c-${ICU_VERSION}_stdthreads_${TARGET_PLATFORM}"
   cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
}

function icu_build_native {
   cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_native"
   "${SOURCE_DIR_ICU}/configure" --disable-samples --disable-tests
   ${MAKE_GENERATOR}
}

function icu_build_stdthreads {
   cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_stdthreads_${TARGET_PLATFORM}"
   cmake ${CMAKE_GENERATOR_FLAGS} -DMINGW_STDTHREADS_GENERATE_STDHEADERS=ON "${CMAKE_TOOLCHAIN_FLAGS}" "${SOURCE_DIR_ICU_MINGW_STD_THREADS}"
   ${CMAKE_GENERATOR}
}

function icu_build {
   icu_build_native
   cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   if [ "${TARGET_TYPE}" == "static" ]; then
      local EXTRA_FLAGS=--disable-shared
      local DATA_PACKAGING=static
   else
      local EXTRA_FLAGS=
      local DATA_PACKAGING=library
   fi
   if [ "${USE_CLANG}" == "YES" ]; then
      local CC=${COMPILER}-clang
      local CXX=${COMPILER}-clang++
   elif [ "${USE_GCC}" == "YES" ]; then
      local CC=${COMPILER}-gcc
      local CXX=${COMPILER}-g++
   else
      local CC=${COMPILER}-cc
      local CXX=${COMPILER}-c++
   fi
   if [ "${TARGET_OS}" == "Windows" ]; then
      icu_build_stdthreads
      local CXXFLAGS="-I${BUILD_DIR}/icu4c-${ICU_VERSION}_stdthreads_${TARGET_PLATFORM}/cmake_stdheaders_generator/cmake_stdheaders_generator"
      cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   else
      local CXXFLAGS=
   fi
   CC=${CC} CXX=${CXX} CXXFLAGS=${CXXFLAGS} "${SOURCE_DIR_ICU}/configure" --host=${COMPILER} ${EXTRA_FLAGS} --disable-samples --disable-tests --prefix="${PREFIX_DIR}/lib/${COMPILER}/icu4c-${ICU_VERSION}${TARGET_SUFFIX}" --includedir="${PREFIX_DIR}/include/icu4c-${ICU_VERSION}" --with-cross-build="${BUILD_DIR}/icu4c-${ICU_VERSION}_native" --with-data-packaging=${DATA_PACKAGING}
   ${MAKE_GENERATOR}
}

function icu_install {
   cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   ${MAKE_GENERATOR_INSTALL}
   if [ ! -L "${PREFIX_DIR}/lib/${COMPILER}/icu4c-${ICU_VERSION}${TARGET_SUFFIX}/include" ]; then
      ln -sf "${PREFIX_DIR}/include/icu4c-${ICU_VERSION}" "${PREFIX_DIR}/lib/${COMPILER}/icu4c-${ICU_VERSION}${TARGET_SUFFIX}/include"
   fi
}

function icu_clean_native {
   cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_native"
   rm -rf "${BUILD_DIR}/icu4c-${ICU_VERSION}_native"
}

function icu_clean_stdthreads {
   cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_stdthreads_${TARGET_PLATFORM}"
   rm -rf "${BUILD_DIR}/icu4c-${ICU_VERSION}_stdthreads_${TARGET_PLATFORM}"
}

function icu_clean {
   cd "${BUILD_DIR}/icu4c-${ICU_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   rm -rf "${BUILD_DIR}/icu4c-${ICU_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   icu_clean_native
   if [ "${TARGET_OS}" == "Windows" ]; then
      icu_clean_stdthreads
   fi
}

function icu_strip {
   cd "${PREFIX_DIR}/lib/${COMPILER}/icu4c-${ICU_VERSION}${TARGET_SUFFIX}"
   if [ "${TARGET_OS}" == "Windows" ]; then
      rm -rf bin lib/icu share
   else
      rm -rf bin lib/icu sbin share
   fi
}

function icu_register {
   export ICU_LIBS="-L${PREFIX_DIR}/lib/${COMPILER}/icu4c-${ICU_VERSION}${TARGET_SUFFIX} -licuin -licuuc -licudt"
   QT_LIBS_FLAGS="${QT_LIBS_FLAGS} -icu -L ${PREFIX_DIR}/lib/${COMPILER}/icu4c-${ICU_VERSION}${TARGET_SUFFIX}/lib -I ${PREFIX_DIR}/include/icu4c-${ICU_VERSION}"
}

function icu_source {
   local VERSION=$1
   local ARCHIVE=icu4c-${VERSION}
   mkdir -p "${SOURCE_DIR}" \
      "${SOURCE_DIR}/${ARCHIVE}"
   cd "${SOURCE_DIR}"
   if [ ! -d "${ARCHIVE}/icu" ]; then
      local LVERSION=$(echo ${VERSION} | sed -e "s/\./-/g")
      local UVERSION=$(echo ${VERSION} | sed -e "s/\./_/g")
      wget -O ${ARCHIVE}.tar.gz "https://github.com/unicode-org/icu/releases/download/release-${LVERSION}/icu4c-${UVERSION}-src.tgz"
      tar xfz ${ARCHIVE}.tar.gz --directory "${SOURCE_DIR}/${ARCHIVE}"
   fi
   if [ -d "${ARCHIVE}/mingw-std-threads" ]; then
      cd ${ARCHIVE}/mingw-std-threads
      git reset --hard
      git pull
      cd "${SOURCE_DIR}"
   else
      git clone "https://github.com/Syping/mingw-std-threads.git" ${ARCHIVE}/mingw-std-threads
   fi
   SOURCE_DIR_ICU="${SOURCE_DIR}/${ARCHIVE}/icu/source"
   SOURCE_DIR_ICU_MINGW_STD_THREADS="${SOURCE_DIR}/${ARCHIVE}/mingw-std-threads"
}

# HB script

function hb_init {
   cmake_init harfbuzz ${HB_VERSION} ${TARGET_TYPE}
}

function hb_build {
   cmake_build "${SOURCE_DIR_HB}" harfbuzz ${HB_VERSION} ${TARGET_TYPE} ${TARGET_SUFFIX}
}

function hb_install {
   cmake_install harfbuzz ${HB_VERSION} ${TARGET_TYPE} ${TARGET_SUFFIX}
}

function hb_clean {
   cmake_clean harfbuzz ${HB_VERSION} ${TARGET_TYPE}
}

function hb_strip {
   return 0
}

function hb_register {
   QT_LIBS_FLAGS="${QT_LIBS_FLAGS} -system-harfbuzz -L ${PREFIX_DIR}/lib/${COMPILER}/harfbuzz-${HB_VERSION}/lib -I ${PREFIX_DIR}/include/harfbuzz-${HB_VERSION}"
}

function hb_source {
   local VERSION=$1
   local ARCHIVE=harfbuzz-${VERSION}
   mkdir -p "${SOURCE_DIR}"
   cd "${SOURCE_DIR}"
   if [ ! -d "${ARCHIVE}" ]; then
      wget -O ${ARCHIVE}.tar.xz "https://github.com/harfbuzz/harfbuzz/releases/download/${VERSION}/harfbuzz-${VERSION}.tar.xz"
      tar xfJ ${ARCHIVE}.tar.xz
   fi
   SOURCE_DIR_HB="${SOURCE_DIR}/${ARCHIVE}"
}

# Qt script

function qt_init {
   mkdir -p "${BUILD_DIR}/qt_${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   cd "${BUILD_DIR}/qt_${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
}

function qt_build {
   cd "${BUILD_DIR}/qt_${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   if [ -f "config.cache" ]; then
      rm -rf *
   fi
   "${SOURCE_DIR_QT}/configure" -prefix "${PREFIX_DIR}/lib/${COMPILER}/qt_${QT_VERSION}${TARGET_SUFFIX}" -headerdir "${PREFIX_DIR}/include/qt_${QT_VERSION}" -datadir "${QT_SHARE_DIR}/qt_${QT_VERSION}" -sysconfdir "${QT_SYSCONF_DIR}" -device-option CROSS_COMPILE=${COMPILER}- -xplatform ${QT_XPLATFORM} ${QT_BUILDTYPE_FLAGS} -${TARGET_TYPE} ${QT_FLAGS} ${QT_LIBS_FLAGS} ${QT_SKIP_FLAGS} ${QT_NOMAKE_FLAGS} ${QT_NOFEATURE_FLAGS} ${QT_OPENGL_FLAGS} ${TARGET_FLAGS} -opensource -confirm-license ${QT_EXTRA_FLAGS}
   ${MAKE_GENERATOR}
}

function qt_install {
   cd "${BUILD_DIR}/qt_${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   ${MAKE_GENERATOR_INSTALL}
   if [ ! -L "${PREFIX_DIR}/lib/${COMPILER}/qt_${QT_VERSION}${TARGET_SUFFIX}/include" ]; then
      ln -sf "${PREFIX_DIR}/include/qt_${QT_VERSION}" "${PREFIX_DIR}/lib/${COMPILER}/qt_${QT_VERSION}${TARGET_SUFFIX}/include"
   fi
}

function qt_clean {
   cd "${BUILD_DIR}/qt_${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   rm -rf "${BUILD_DIR}/qt_${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
}

function qt_strip {
   cd "${PREFIX_DIR}/lib/${COMPILER}/qt_${QT_VERSION}${TARGET_SUFFIX}"
   rm -rf bin/*.exe doc
}

function qt_source {
   local SERIES=$1
   local BUILD=$2
   local VERSION=${SERIES}.${BUILD}
   if [ "$1" == "5.6" ] || [ "$1" == "5.9" ]; then
      local ARCHIVE=qt-everywhere-opensource-src-${VERSION}
   else
      local ARCHIVE=qt-everywhere-src-${VERSION}
   fi
   mkdir -p "${SOURCE_DIR}"
   cd "${SOURCE_DIR}"
   if [ ! -d "${ARCHIVE}" ]; then
      wget -O ${ARCHIVE}.tar.xz "https://download.qt.io/official_releases/qt/${SERIES}/${VERSION}/single/${ARCHIVE}.tar.xz"
      tar xfJ ${ARCHIVE}.tar.xz
   fi
   # Create Linux armhf g++ mkspec when not already exists
   if [ ! -d "${ARCHIVE}/qtbase/mkspecs/linux-arm-gnueabihf-g++" ]; then
      mkdir -p "${ARCHIVE}/qtbase/mkspecs/linux-arm-gnueabihf-g++"
      echo -e "MAKEFILE_GENERATOR=UNIX\nCONFIG+=incremental\nQMAKE_INCREMENTAL_STYLE=sublib\ninclude(../common/linux.conf)\ninclude(../common/gcc-base-unix.conf)\ninclude(../common/g++-unix.conf)\nQMAKE_CC=arm-linux-gnueabihf-gcc\nQMAKE_CXX=arm-linux-gnueabihf-g++\nQMAKE_LINK=arm-linux-gnueabihf-g++\nQMAKE_LINK_SHLIB=arm-linux-gnueabihf-g++\nQMAKE_AR=arm-linux-gnueabihf-ar cqs\nQMAKE_OBJCOPY=arm-linux-gnueabihf-objcopy\nQMAKE_NM=arm-linux-gnueabihf-nm -P\nQMAKE_STRIP=arm-linux-gnueabihf-strip\nload(qt_config)" > "${ARCHIVE}/qtbase/mkspecs/linux-arm-gnueabihf-g++/qmake.conf"
      echo -e "#include \"../linux-g++/qplatformdefs.h\"" > "${ARCHIVE}/qtbase/mkspecs/linux-arm-gnueabihf-g++/qplatformdefs.h"
   fi
   # Create Linux aarch64 g++ mkspec when not already exists
   if [ ! -d "${ARCHIVE}/qtbase/mkspecs/linux-aarch64-gnu-g++" ]; then
      mkdir -p "${ARCHIVE}/qtbase/mkspecs/linux-aarch64-gnu-g++"
      echo -e "MAKEFILE_GENERATOR=UNIX\nCONFIG+=incremental\nQMAKE_INCREMENTAL_STYLE=sublib\ninclude(../common/linux.conf)\ninclude(../common/gcc-base-unix.conf)\ninclude(../common/g++-unix.conf)\nQMAKE_CC=aarch64-linux-gnu-gcc\nQMAKE_CXX=aarch64-linux-gnu-g++\nQMAKE_LINK=aarch64-linux-gnu-g++\nQMAKE_LINK_SHLIB=aarch64-linux-gnu-g++\nQMAKE_AR=aarch64-linux-gnu-ar cqs\nQMAKE_OBJCOPY=aarch64-linux-gnu-objcopy\nQMAKE_NM=aarch64-linux-gnu-nm -P\nQMAKE_STRIP=aarch64-linux-gnu-strip\nload(qt_config)" > "${ARCHIVE}/qtbase/mkspecs/linux-aarch64-gnu-g++/qmake.conf"
      echo -e "#include \"../linux-g++/qplatformdefs.h\"" > "${ARCHIVE}/qtbase/mkspecs/linux-aarch64-gnu-g++/qplatformdefs.h"
   fi
   # Patch Qt 5.15.0 DirectWrite bug
   if [ "$VERSION" == "5.15.0" ]; then
      wget -q -O "${ARCHIVE}/qtbase/src/platformsupport/fontdatabases/windows/qwindowsfontenginedirectwrite.cpp" "https://gist.githubusercontent.com/Syping/d6c3cb1a8cfa678f959252a7faae5f9c/raw/qwindowsfontenginedirectwrite.cpp"
   fi
   QT_VERSION=${VERSION}
   SOURCE_DIR_QT="${SOURCE_DIR}/${ARCHIVE}"
}

function qt_patch {
   cd "${SOURCE_DIR_QT}"
   if [ -f "qtbase/config.tests/openssl/openssl.cpp" ]; then
     rm -f qtbase/config.tests/openssl/openssl.cpp
     echo -e "#include <openssl/opensslv.h>\n#if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER-0 < 0x0090700fL\n#error \"OpenSSL >= 0.9.7 is required\"\n#endif\n#include <openssl/ssl.h>\n#if OPENSSL_VERSION_NUMBER-0 >= 0x10002000L && !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES)\n#error \"OpenSSL was reported as >= 1.0.2 but is missing required features, possibly it's libressl which is unsupported\"\n#endif\nint main(){}" > qtbase/config.tests/openssl/openssl.cpp
   fi
}

# QtStylePlugins script

function qtstyleplugins_init {
   mkdir -p "${BUILD_DIR}/qtstyleplugins-${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   cd "${BUILD_DIR}/qtstyleplugins-${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
}

function qtstyleplugins_build {
   cd "${BUILD_DIR}/qtstyleplugins-${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   "${PREFIX_DIR}/lib/${COMPILER}/qt_${QT_VERSION}${TARGET_SUFFIX}/bin/qmake" "${SOURCE_DIR_QTSTYLEPLUGINS}/qtstyleplugins.pro"
   ${MAKE_GENERATOR}
}

function qtstyleplugins_install {
   cd "${BUILD_DIR}/qtstyleplugins-${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   ${MAKE_GENERATOR_INSTALL}
}

function qtstyleplugins_clean {
   cd "${BUILD_DIR}/qtstyleplugins-${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
   rm -rf "${BUILD_DIR}/qtstyleplugins-${QT_VERSION}_${TARGET_PLATFORM}_${TARGET_TYPE}"
}

function qtstyleplugins_source {
   mkdir -p "${SOURCE_DIR}"
   cd "${SOURCE_DIR}"
   if [ -d "qtstyleplugins-${QT_VERSION}" ]; then
      cd qtstyleplugins-${QT_VERSION}
      git reset --hard
      git pull
      cd "${SOURCE_DIR}"
   else
      git clone "https://code.qt.io/qt/qtstyleplugins.git" "qtstyleplugins-${QT_VERSION}"
   fi
   SOURCE_DIR_QTSTYLEPLUGINS="${SOURCE_DIR}/qtstyleplugins-${QT_VERSION}"
}

# Dependency checking script

function manage_dependency {
   local TAR_PATH=$(command -v tar)
   if [ "${TAR_PATH}" == "" ]; then
      echo "Missing tar dependency, please install it!"
      exit 1
   fi
   local GZIP_PATH=$(command -v gzip)
   if [ "${GZIP_PATH}" == "" ]; then
      echo "Missing gzip dependency, please install it!"
      exit 1
   fi
   local XZ_PATH=$(command -v xz)
   if [ "${XZ_PATH}" == "" ]; then
      echo "Missing xz-utils dependency, please install it!"
      exit 1
   fi
   local NINJA_PATH=$(command -v ninja)
   if [ "${NINJA_PATH}" == "" ]; then
      local GMAKE_PATH=$(command -v gmake)
      if [ "${GMAKE_PATH}" == "" ]; then
         local MAKE_PATH=$(command -v make)
         if [ "${MAKE_PATH}" == "" ]; then
            echo "Missing make generators, please install one!"
            exit 1
         else
            CMAKE_GENERATOR="${MAKE_PATH} -j${CPU_THREADS}"
            CMAKE_GENERATOR_CLEAN="${MAKE_PATH} clean"
            CMAKE_GENERATOR_INSTALL="${MAKE_PATH} install"
         fi
      else
         CMAKE_GENERATOR="${GMAKE_PATH} -j${CPU_THREADS}"
         CMAKE_GENERATOR_CLEAN="${GMAKE_PATH} clean"
         CMAKE_GENERATOR_INSTALL="${GMAKE_PATH} install"
      fi
   else
      CMAKE_GENERATOR_FLAGS="-GNinja"
      CMAKE_GENERATOR="${NINJA_PATH}"
      CMAKE_GENERATOR_CLEAN="${NINJA_PATH} clean"
      CMAKE_GENERATOR_INSTALL="${NINJA_PATH} install"
   fi
   local GMAKE_PATH=$(command -v gmake)
   if [ "${GMAKE_PATH}" == "" ]; then
      local MAKE_PATH=$(command -v make)
      if [ "${MAKE_PATH}" == "" ]; then
         echo "Missing make generators, please install one!"
         exit 1
      else
         MAKE_GENERATOR="${MAKE_PATH} -j${CPU_THREADS}"
         MAKE_GENERATOR_CLEAN="${MAKE_PATH} clean"
         MAKE_GENERATOR_INSTALL="${MAKE_PATH} install"
      fi
   else
      MAKE_GENERATOR="${GMAKE_PATH} -j${CPU_THREADS}"
      MAKE_GENERATOR_CLEAN="${GMAKE_PATH} clean"
      MAKE_GENERATOR_INSTALL="${GMAKE_PATH} install"
   fi
   if [ "${BUILD_JPG}" == "YES" ]; then
      local CMAKE_PATH=$(command -v cmake)
      if [ "${CMAKE_PATH}" == "" ]; then
         echo "libjpeg-turbo missing CMake dependency, please install it!"
         exit 1
      fi
      local NASM_PATH=$(command -v nasm)
      if [ "${NASM_PATH}" == "" ]; then
         echo "libjpeg-turbo missing NASM dependency, please install it!"
         exit 1
      fi
   fi
   if [ "${BUILD_SSL}" == "YES" ]; then
      if [ "${USE_OPENSSL}" == "YES" ]; then
         local PERL_PATH=$(command -v perl)
         if [ "${PERL_PATH}" == "" ]; then
            echo "OpenSSL missing Perl dependency, please install it!"
            exit 1
         fi
      fi
   fi
   if [ "${BUILD_ICU}" == "YES" ]; then
      local CMAKE_PATH=$(command -v cmake)
      if [ "${CMAKE_PATH}" == "" ]; then
         echo "ICU missing CMake dependency, please install it!"
         exit 1
      fi
      local GIT_PATH=$(command -v git)
      if [ "${GIT_PATH}" == "" ]; then
         echo "ICU missing git dependency, please install it!"
         exit 1
      fi
      local CC_PATH=$(command -v cc)
      if [ "${CC_PATH}" == "" ]; then
         echo "ICU missing C Compiler, please install one!"
         exit 1
      fi
      local CXX_PATH=$(command -v c++)
      if [ "${CXX_PATH}" == "" ]; then
         echo "ICU missing C++ Compiler, please install one!"
         exit 1
      fi
   fi
   if [ "${BUILD_HB}" == "YES" ]; then
      local CMAKE_PATH=$(command -v cmake)
      if [ "${CMAKE_PATH}" == "" ]; then
         echo "harfbuzz missing CMake dependency, please install it!"
         exit 1
      fi
   fi
   if [ "${BUILD_QT}" == "YES" ]; then
      local GIT_PATH=$(command -v git)
      if [ "${GIT_PATH}" == "" ]; then
         echo "Qt missing git dependency, please install it!"
         exit 1
      fi
      local PERL_PATH=$(command -v perl)
      if [ "${PERL_PATH}" == "" ]; then
         echo "Qt missing Perl dependency, please install it!"
         exit 1
      fi
      local PYTHON_PATH=$(command -v python)
      if [ "${PYTHON_PATH}" == "" ]; then
         echo "Qt missing Python dependency, please install it!"
         exit 1
      fi
      local CC_PATH=$(command -v cc)
      if [ "${CC_PATH}" == "" ]; then
         echo "Qt missing C Compiler, please install one!"
         exit 1
      fi
      local CXX_PATH=$(command -v c++)
      if [ "${CXX_PATH}" == "" ]; then
         echo "Qt missing C++ Compiler, please install one!"
         exit 1
      fi
   fi
}

# General build script

function build_init {
   mkdir -p "${BUILD_DIR}"
   cd "${BUILD_DIR}"
   if [ "${BUILD_ZLIB}" == "YES" ]; then
      zlib_source ${ZLIB_VERSION}
   fi
   if [ "${BUILD_PNG}" == "YES" ]; then
      libpng_source ${LIBPNG_VERSION}
   fi
   if [ "${BUILD_JPG}" == "YES" ]; then
      libjpegturbo_source ${LIBJPEGTURBO_VERSION}
   fi
   if [ "${BUILD_SSL}" == "YES" ]; then
      if [ "${USE_OPENSSL}" == "YES" ]; then
         openssl_source ${OPENSSL_VERSION}
      else
         libressl_source ${LIBRESSL_VERSION}
      fi
   fi
   if [ "${BUILD_ICU}" == "YES" ]; then
      icu_source ${ICU_VERSION}
   fi
   if [ "${BUILD_HB}" == "YES" ]; then
      hb_source ${HB_VERSION}
   fi
   if [ "${BUILD_QT}" == "YES" ]; then
      qt_source ${QT_SERIES} ${QT_BUILD}
      if [ ! "${USE_OPENSSL}" == "YES" ]; then
         qt_patch
      fi
      qtstyleplugins_source
   fi
}

function build_type {
   TARGET_PLATFORM=$1
   if [ "${TARGET_PLATFORM}" == "mingw32" ] || [ "${TARGET_PLATFORM}" == "i686-w64-mingw32" ]; then
      TARGET_PLATFORM=mingw32
      COMPILER=i686-w64-mingw32
      if [ "${MINGW_USE_CLANG}" == "YES" ]; then
         USE_CLANG=YES
         QT_XPLATFORM=win32-clang-g++
         local SET_CC=$(command -v ${COMPILER}-clang)
         local SET_CXX=$(command -v ${COMPILER}-clang++)
      else
         USE_GCC=YES
         QT_XPLATFORM=win32-g++
         local SET_CC=$(command -v ${COMPILER}-gcc)
         local SET_CXX=$(command -v ${COMPILER}-g++)
      fi
      SSL_PLATFORM=mingw
      TARGET_OS=Windows
      TARGET_CPU=x86
      local SET_RC=$(command -v ${COMPILER}-windres)
      if [ "${SET_CC}" == "" ] || [ "${SET_CXX}" == "" ] || [ "${SET_RC}" == "" ]; then
         echo "Incomplete or missing ${TARGET_PLATFORM} compiler for current build, please install one!"
         exit 1
      fi
      echo -e "set(CMAKE_SYSTEM_NAME ${TARGET_OS})\nset(CMAKE_SYSTEM_PROCESSOR ${TARGET_CPU})\nset(CMAKE_C_COMPILER ${SET_CC})\nset(CMAKE_CXX_COMPILER ${SET_CXX})\nset(CMAKE_RC_COMPILER ${SET_RC})" > "${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
      CMAKE_TOOLCHAIN_FLAGS="-DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
   elif [ "${TARGET_PLATFORM}" == "mingw64" ] || [ "${TARGET_PLATFORM}" == "x86_64-w64-mingw32" ]; then
      TARGET_PLATFORM=mingw64
      COMPILER=x86_64-w64-mingw32
      if [ "${MINGW_USE_CLANG}" == "YES" ]; then
         USE_CLANG=YES
         QT_XPLATFORM=win32-clang-g++
         local SET_CC=$(command -v ${COMPILER}-clang)
         local SET_CXX=$(command -v ${COMPILER}-clang++)
      else
         USE_GCC=YES
         QT_XPLATFORM=win32-g++
         local SET_CC=$(command -v ${COMPILER}-gcc)
         local SET_CXX=$(command -v ${COMPILER}-g++)
      fi
      SSL_PLATFORM=mingw64
      TARGET_OS=Windows
      TARGET_CPU=amd64
      local SET_RC=$(command -v ${COMPILER}-windres)
      if [ "${SET_CC}" == "" ] || [ "${SET_CXX}" == "" ] || [ "${SET_RC}" == "" ]; then
         echo "Incomplete or missing ${TARGET_PLATFORM} compiler for current build, please install one!"
         exit 1
      fi
      echo -e "set(CMAKE_SYSTEM_NAME ${TARGET_OS})\nset(CMAKE_SYSTEM_PROCESSOR ${TARGET_CPU})\nset(CMAKE_C_COMPILER ${SET_CC})\nset(CMAKE_CXX_COMPILER ${SET_CXX})\nset(CMAKE_RC_COMPILER ${SET_RC})" > "${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
      CMAKE_TOOLCHAIN_FLAGS="-DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
   elif [ "${TARGET_PLATFORM}" == "linux-armhf" ] || [ "${TARGET_PLATFORM}" == "arm-linux-gnueabihf" ]; then
      TARGET_PLATFORM=linux-armhf
      COMPILER=arm-linux-gnueabihf
      if [ "${LINUX_ARMHF_USE_CLANG}" == "YES" ]; then
         USE_CLANG=YES
         QT_XPLATFORM=linux-clang
         local SET_CC=$(command -v ${COMPILER}-clang)
         local SET_CXX=$(command -v ${COMPILER}-clang++)
      else
         USE_GCC=YES
         QT_XPLATFORM=linux-arm-gnueabihf-g++
         local SET_CC=$(command -v ${COMPILER}-gcc)
         local SET_CXX=$(command -v ${COMPILER}-g++)
      fi
      SSL_PLATFORM=linux-armv4
      TARGET_OS=Linux
      TARGET_CPU=armhf
      if [ "${SET_CC}" == "" ] || [ "${SET_CXX}" == "" ]; then
         echo "Incomplete or missing ${TARGET_PLATFORM} compiler for current build, please install one!"
         exit 1
      fi
      echo -e "set(CMAKE_SYSTEM_NAME ${TARGET_OS})\nset(CMAKE_SYSTEM_PROCESSOR ${TARGET_CPU})\nset(CMAKE_C_COMPILER ${SET_CC})\nset(CMAKE_CXX_COMPILER ${SET_CXX})" > "${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
      CMAKE_TOOLCHAIN_FLAGS="-DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
   elif [ "${TARGET_PLATFORM}" == "linux-aarch64" ] || [ "${TARGET_PLATFORM}" == "aarch64-linux-gnu" ]; then
      TARGET_PLATFORM=linux-aarch64
      COMPILER=aarch64-linux-gnu
      if [ "${LINUX_AARCH64_USE_CLANG}" == "YES" ]; then
         USE_CLANG=YES
         QT_XPLATFORM=linux-clang
         local SET_CC=$(command -v ${COMPILER}-clang)
         local SET_CXX=$(command -v ${COMPILER}-clang++)
      else
         USE_GCC=YES
         QT_XPLATFORM=linux-aarch64-gnu-g++
         local SET_CC=$(command -v ${COMPILER}-gcc)
         local SET_CXX=$(command -v ${COMPILER}-g++)
      fi
      SSL_PLATFORM=linux-aarch64
      TARGET_OS=Linux
      TARGET_CPU=aarch64
      if [ "${SET_CC}" == "" ] || [ "${SET_CXX}" == "" ]; then
         echo "Incomplete or missing ${TARGET_PLATFORM} compiler for current build, please install one!"
         exit 1
      fi
      echo -e "set(CMAKE_SYSTEM_NAME ${TARGET_OS})\nset(CMAKE_SYSTEM_PROCESSOR ${TARGET_CPU})\nset(CMAKE_C_COMPILER ${SET_CC})\nset(CMAKE_CXX_COMPILER ${SET_CXX})" > "${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
      CMAKE_TOOLCHAIN_FLAGS="-DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
   else
      COMPILER=${TARGET_PLATFORM}
      if [ "${CUSTOM_USE_CLANG}" == "YES" ]; then
         USE_CLANG=YES
         local SET_CC=$(command -v ${COMPILER}-clang)
         local SET_CXX=$(command -v ${COMPILER}-clang++)
      elif [ "${CUSTOM_USE_GCC}" == "YES" ]; then
         USE_GCC=YES
         local SET_CC=$(command -v ${COMPILER}-gcc)
         local SET_CXX=$(command -v ${COMPILER}-g++)
      else
         local SET_CC=$(command -v ${COMPILER}-cc)
         local SET_CXX=$(command -v ${COMPILER}-c++)
      fi
      if [ "${SET_CC}" == "" ] || [ "${SET_CXX}" == "" ]; then
         echo "Incomplete or missing ${TARGET_PLATFORM} compiler for current build, please install one!"
         exit 1
      fi
      if [ "${BUILD_QT}" == "YES" ]; then
         if [ "${QT_XPLATFORM}" == "" ]; then
            echo "QT_XPLATFORM environment value not set, please set!"
            exit 1
         fi
      fi
      if [ "${BUILD_SSL}" == "YES" ]; then
         if [ "${USE_OPENSSL}" == "YES" ]; then
            if [ "${SSL_PLATFORM}" == "" ]; then
               echo "SSL_PLATFORM environment value not set, please set!"
               exit 1
            fi
         fi
      fi
      if [ "${TARGET_OS}" == "" ]; then
         echo "TARGET_OS environment value not set, please set!"
         exit 1
      fi
      if [ "${TARGET_CPU}" == "" ]; then
         echo "TARGET_CPU environment value not set, please set!"
         exit 1
      fi
      echo -e "set(CMAKE_SYSTEM_NAME ${TARGET_OS})\nset(CMAKE_SYSTEM_PROCESSOR ${TARGET_CPU})\nset(CMAKE_C_COMPILER ${SET_CC})\nset(CMAKE_CXX_COMPILER ${SET_CXX})" > "${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
      CMAKE_TOOLCHAIN_FLAGS="-DCMAKE_TOOLCHAIN_FILE=${BUILD_DIR}/cmake.${TARGET_PLATFORM}.toolchain"
   fi
   TARGET_TYPE=$2
   TARGET_SUFFIX=$3
}

function build_clean_env {
   # Clear environment values
   export ICU_LIBS=
   export OPENSSL_LIBS=
   QT_LIBS_FLAGS=
   ZLIB_CPPFLAGS=
   ZLIB_LDFLAGS=
   USE_CLANG=
   USE_GCC=

   local EXTRA_COMMAND=$1
   if [ "${EXTRA_COMMAND}" == "reregister" ]; then
      if [ "${LINK_ZLIB}" == "YES" ]; then
         zlib_register
      fi
      if [ "${LINK_PNG}" == "YES" ]; then
         libpng_register
      fi
      if [ "${LINK_JPG}" == "YES" ]; then
         libjpegturbo_register
      fi
      if [ "${LINK_HB}" == "YES" ]; then
         hb_register
      fi
   fi
}

function build_tl_set {
   BUILD_MODE=TL
   build_type $1

   if [ "${BUILD_ZLIB}" == "YES" ]; then
      zlib_init
      zlib_build
      zlib_install
      zlib_strip
      zlib_clean
   fi
   if [ "${LINK_ZLIB}" == "YES" ]; then
      zlib_register
   fi
   
   if [ "${BUILD_PNG}" == "YES" ]; then
      libpng_init
      libpng_build
      libpng_install
      libpng_strip
      libpng_clean
   fi
   if [ "${LINK_PNG}" == "YES" ]; then
      libpng_register
   fi

   if [ "${BUILD_JPG}" == "YES" ]; then
      libjpegturbo_init
      libjpegturbo_build
      libjpegturbo_install
      libjpegturbo_strip
      libjpegturbo_clean
   fi
   if [ "${LINK_JPG}" == "YES" ]; then
      libjpegturbo_register
   fi
   
   if [ "${BUILD_HB}" == "YES" ]; then
      hb_init
      hb_build
      hb_install
      hb_strip
      hb_clean
   fi
   if [ "${LINK_HB}" == "YES" ]; then
      hb_register
   fi
}

function build_set {
   BUILD_MODE=DEFAULT
   build_type $1 $2 $3

   if [ "${BUILD_SSL}" == "YES" ]; then
      if [ "${USE_OPENSSL}" == "YES" ]; then
         openssl_init
         openssl_build
         openssl_install
         openssl_strip
         openssl_clean
      else
         libressl_init
         libressl_build
         libressl_install
         libressl_strip
         libressl_clean
      fi
   fi
   if [ "${LINK_SSL}" == "YES" ]; then
      if [ "${USE_OPENSSL}" == "YES" ]; then
         openssl_register
      else
         libressl_register
      fi
   fi

   if [ "${BUILD_ICU}" == "YES" ]; then
      icu_init
      icu_build
      icu_install
      icu_strip
      icu_clean
   fi
   if [ "${LINK_ICU}" == "YES" ]; then
      icu_register
   fi

   if [ "${BUILD_QT}" == "YES" ]; then
      qt_init
      qt_build
      qt_install
      qt_strip
      qt_clean

      if [ "${TARGET_TYPE}" == "shared" ]; then
         qtstyleplugins_init
         qtstyleplugins_build
         qtstyleplugins_install
         qtstyleplugins_clean
      fi
   fi
}

# Runtime execution script

set -e
manage_dependency
build_init

# Custom build

if [ "${CUSTOM_SET}" == "YES" ]; then
   build_clean_env
   build_tl_set ${TARGET_PLATFORM}
   if [ "${CUSTOM_SET_TYPE}" == "all" ]; then
      build_clean_env reregister
      build_set ${TARGET_PLATFORM} shared _d
      build_clean_env reregister
      build_set ${TARGET_PLATFORM} static _s
   elif [ "${CUSTOM_SET_TYPE}" == "mshared" ]; then
      build_clean_env reregister
      build_set ${TARGET_PLATFORM} shared _d
   elif [ "${CUSTOM_SET_TYPE}" == "mstatic" ]; then
      build_clean_env reregister
      build_set ${TARGET_PLATFORM} static _s
   elif [ "${CUSTOM_SET_TYPE}" == "static" ]; then
      build_clean_env reregister
      build_set ${TARGET_PLATFORM} static
   else
      build_clean_env reregister
      build_set ${TARGET_PLATFORM} shared
   fi
fi

# Windows 32-Bit builds

if [ ! "${BUILD_MINGW32_SHARED}" == "NO" ] || [ ! "${BUILD_MINGW32_STATIC}" == "NO" ]; then
   build_clean_env
   build_tl_set mingw32
fi
if [ ! "${BUILD_MINGW32_SHARED}" == "NO" ]; then
   build_clean_env reregister
   build_set mingw32 shared _d
fi
if [ ! "${BUILD_MINGW32_STATIC}" == "NO" ]; then
   build_clean_env reregister
   build_set mingw32 static _s
fi

# Windows 64-Bit builds

if [ ! "${BUILD_MINGW64_SHARED}" == "NO" ] || [ ! "${BUILD_MINGW64_STATIC}" == "NO" ]; then
   build_clean_env
   build_tl_set mingw64
fi
if [ ! "${BUILD_MINGW64_SHARED}" == "NO" ]; then
   build_clean_env reregister
   build_set mingw64 shared _d
fi
if [ ! "${BUILD_MINGW64_STATIC}" == "NO" ]; then
   build_clean_env reregister
   build_set mingw64 static _s
fi

# Linux armhf builds

if [ "${BUILD_LINUX_ARMHF_SHARED}" == "YES" ] || [ "${BUILD_LINUX_ARMHF_STATIC}" == "YES" ]; then
   build_clean_env
   build_tl_set linux-armhf
fi
if [ "${BUILD_LINUX_ARMHF_SHARED}" == "YES" ]; then
   build_clean_env reregister
   build_set linux-armhf shared _d
fi
if [ "${BUILD_LINUX_ARMHF_STATIC}" == "YES" ]; then
   build_clean_env reregister
   build_set linux-armhf static _s
fi

# Linux aarch64 builds

if [ "${BUILD_LINUX_AARCH64_SHARED}" == "YES" ] || [ "${BUILD_LINUX_AARCH64_STATIC}" == "YES" ]; then
   build_clean_env
   build_tl_set linux-aarch64
fi
if [ "${BUILD_LINUX_AARCH64_SHARED}" == "YES" ]; then
   build_clean_env reregister
   build_set linux-aarch64 shared _d
fi
if [ "${BUILD_LINUX_AARCH64_STATIC}" == "YES" ]; then
   build_clean_env reregister
   build_set linux-aarch64 static _s
fi