aboutsummaryrefslogtreecommitdiff
path: root/configure.sh
diff options
context:
space:
mode:
authorOmniTroid <davidskoland@gmail.com>2024-07-31 13:40:43 +0200
committerGitHub <noreply@github.com>2024-07-31 13:40:43 +0200
commit0e45f3c0ee556d4dee3bc81a577e4998232f491a (patch)
treee920f9706466f3ea8bc0d1fc82f29b0d6527bb2a /configure.sh
parent4d1b0517e3d5704b26df7d8a9a492d182d36ea4b (diff)
Universal configure script (#1022)
* Init configure.sh * echo detected platform * Implement check_command * Implement install_bass_macos, plus checks * Ignore tmp * Add configure main function and bass installs * Less functions * Reformat file, add some stuff * Start adding automatic qt detection * Curl is more portable it seems * Try finding Qt's bundled cmake * fix cmake command checking * Reorder to windows first * do not download deps if already present * Add configure clean * Fix basic command checks * cmd fixes * thank you bash, very cool! * fix file shenanigans * unneccessary comment * Use qt_path instead of qt_cmake * Ignore apng folder * Rework with QT_PATH * Move find_qt to the top * move check_command near the top * Tidy up command checking * Rename QT_PATH to QT_ROOT and call the qt installation path QT_PATH instead * only clone qtapng if no dir * Cmake shenanigans * Fix build with ninja * Fix apng cp cmd * Fix apng check * Just call it cmake * Run cmake in configure.sh * Ignore generated files * Comment out mega cmake command * Fix apng check * more cmake stuff * make the cmake command we use very clear * ignore cmake_cmd.txt * Note that linux and macos is not supported * Update README * Add some stuff to windeployqt * Clone themes * macos fixes * Only call windeployqt on windows * Linux fixes * Remove linux todo comment * Remove git stuff from themes checkout * Note about vanilla content.. * Add note about formatting in readme * Remove e flag so script doesn't stop with no error messages * Note about toolchains on unix-likes * Fix cmake path on linux * Rework get_zip for better error handling and less unzipping unnecessary files * Adjust get_zip calls * Hopefully make error handling more robust * Fix bassopus on linux * linux bassopus pathing fix * Fix discord rpc linux * Add note about opengl * Ignore test_aopacket * Tidy up readme a bit again * Remove old configure scripts
Diffstat (limited to 'configure.sh')
-rwxr-xr-xconfigure.sh500
1 files changed, 500 insertions, 0 deletions
diff --git a/configure.sh b/configure.sh
new file mode 100755
index 00000000..3ec2dc24
--- /dev/null
+++ b/configure.sh
@@ -0,0 +1,500 @@
+#!/bin/bash
+
+set -euo pipefail
+
+SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
+cd "${SCRIPT_DIR}" || { echo "Failed to cd to pwd"; exit 1; }
+
+detect_platform() {
+ unameOut="$(uname -s)"
+ case "${unameOut}" in
+ CYGWIN*|MINGW*|MSYS*) platform=windows;;
+ Linux*) platform=linux;;
+ Darwin*) platform=macos;;
+ *) platform=unknown;;
+ esac
+ echo "${platform}"
+}
+
+# Basic data such as platform can be global
+PLATFORM=$(detect_platform)
+BUILD_CONFIG="Debug"
+QT_VERSION="6.5.3"
+
+print_help() {
+ echo "Usage: $0 [options]"
+ echo "Options:"
+ echo " -h, --help: Print this help message"
+ echo " clean: Remove all files from lib, bin and tmp"
+ echo " QT_ROOT=path: Specify the root path to where Qt is installed (eg. /c/Qt/)"
+}
+
+# Check if a given command returns a non-zero exit code
+check_command() {
+ # Hack to not make the whole script exit..
+ set +e
+ if ! "$@" &> /dev/null; then
+ set -e
+ return 1
+ fi
+ set -e
+ return 0
+}
+
+find_qt() {
+ local qt_root=""
+
+ # Function to check if a dir exists
+ check_path() {
+ if [[ -d "$1" ]]; then
+ qt_root="$1"
+ return 0
+ else
+ return 1
+ fi
+ }
+
+ # Check common Qt installation paths on different OSes
+ if [[ "$PLATFORM" == "windows" ]]; then
+ # Windows paths, maybe check for more in the future
+ check_path "/c/Qt"
+ elif [[ "$PLATFORM" == "linux" ]]; then
+ check_path "$HOME/Qt"
+ elif [[ "$PLATFORM" == "macos" ]]; then
+ check_path "$HOME/Qt"
+ fi
+
+ # If qt-cmake is found, print the path
+ if [[ -n "$qt_root" ]]; then
+ echo "$qt_root"
+ else
+ echo ""
+ return 1
+ fi
+}
+
+find_qtpath() {
+ local qt_path=""
+
+ check_path() {
+ if [[ -d "$1" ]]; then
+ qt_path="$1"
+ return 0
+ else
+ return 1
+ fi
+ }
+
+ if [[ "$PLATFORM" == "windows" ]]; then
+ check_path "${QT_ROOT}/${QT_VERSION}/mingw_64"
+ elif [[ "$PLATFORM" == "linux" ]]; then
+ check_path "${QT_ROOT}/${QT_VERSION}/gcc_64"
+ elif [[ "$PLATFORM" == "macos" ]]; then
+ check_path "${QT_ROOT}/${QT_VERSION}/macos"
+ fi
+
+ echo "$qt_path"
+}
+
+find_cmake() {
+ local cmake_path=""
+
+ # Function to check if a file exists
+ check_path() {
+ if [[ -f "$1" ]]; then
+ cmake_path="$1"
+ return 0
+ else
+ return 1
+ fi
+ }
+
+ # See if we can find the cmake bundled with Qt
+ if [[ "$PLATFORM" == "windows" ]]; then
+ check_path "${QT_ROOT}/Tools/CMake_64/bin/cmake.exe"
+ elif [[ "$PLATFORM" == "linux" ]]; then
+ check_path "${QT_ROOT}/Tools/CMake/bin/cmake"
+ elif [[ "$PLATFORM" == "macos" ]]; then
+ check_path "${QT_ROOT}/Tools/CMake/CMake.app/Contents/bin/cmake"
+ else
+ echo "Unsupported platform: ${PLATFORM}"
+ return 1
+ fi
+
+ # If cmake is found, print the path
+ if [[ -n "$cmake_path" ]]; then
+ echo "$cmake_path"
+ return 0
+ else
+ echo ""
+ return 1
+ fi
+}
+
+find_mingw() {
+ # Find a mingw installation bundled with Qt
+
+ QT_TOOLS_PATH="${QT_ROOT}/Tools"
+
+ mingw_dir=$(find "${QT_TOOLS_PATH}" -maxdepth 1 -type d -name "mingw*" -print0 | xargs -0 ls -td | head -n 1)
+
+ # Find returns . if the directory is not found
+ if [[ "$mingw_dir" == "." ]]; then
+ mingw_dir=""
+ fi
+
+ echo "$mingw_dir"
+}
+
+find_ninja() {
+ # Find a ninja installation bundled with Qt
+ QT_TOOLS_PATH="${QT_ROOT}/Tools"
+
+ local ninja_path=""
+
+ if [[ "$PLATFORM" == "windows" ]]; then
+ ninja_path="${QT_TOOLS_PATH}/Ninja/ninja.exe"
+ else
+ ninja_path="${QT_TOOLS_PATH}/Ninja/ninja"
+ fi
+
+ echo "$ninja_path"
+}
+
+get_zip() {
+ # Check if at least two arguments are provided
+ if [ "$#" -lt 2 ]; then
+ echo "Usage: get_zip <url> <sourcefile:destination> [<sourcefile:destination> ...]"
+ return 1
+ fi
+
+ mkdir -p ./tmp
+
+ # URL of the zip file
+ url="$1"
+ shift
+
+ zip_filename=$(basename "$url")
+
+ # Temporary file to store the downloaded zip
+ tmp_zip=./tmp/"$zip_filename"
+
+ # Download the zip file
+ curl -L "$url" -o "$tmp_zip"
+ if [ $? -ne 0 ]; then
+ echo "Failed to download the zip file from $url"
+ rm -f "$tmp_zip"
+ return 1
+ fi
+
+ # Sanity check: zip file is there
+ if [ ! -f "$tmp_zip" ]; then
+ echo "Error: The zip file '$tmp_zip' does not exist."
+ return 1
+ fi
+
+ # First, check that all the specified files exist in the zip archive
+ for arg in "$@" ; do
+ src_file="${arg%%:*}"
+ if ! unzip -l "$tmp_zip" | grep -q "$src_file"; then
+ echo "Error: The file '$src_file' does not exist in the zip archive $tmp_zip."
+ return 1
+ fi
+ done
+
+ # Extract the specified files to their destinations
+ while [ "$#" -gt 0 ]; do
+ src_dst="$1"
+ src_file="${src_dst%%:*}"
+ dst_dir="${src_dst##*:}"
+
+ # Create the destination directory if it doesn't exist
+ mkdir -p "$dst_dir"
+
+ unzip -j "$tmp_zip" "$src_file" -d "$dst_dir"
+
+ shift
+ done
+
+ # Clean up the temporary zip file
+ rm -rf "$tmp_zip"
+}
+
+get_bass() {
+ echo "Checking for BASS..."
+ # If lib/bass.h exists, assume that BASS is already present
+ if [ -f "./lib/bass.h" ]; then
+ echo "BASS is installed."
+ return 0
+ fi
+
+ echo "Downloading BASS..."
+ if [[ "$PLATFORM" == "windows" ]]; then
+ get_zip https://www.un4seen.com/files/bass24.zip \
+ c/bass.h:./lib \
+ c/x64/bass.lib:./lib \
+ x64/bass.dll:./bin
+ elif [[ "$PLATFORM" == "linux" ]]; then
+ get_zip https://www.un4seen.com/files/bass24-linux.zip \
+ bass.h:./lib \
+ libs/x86_64/libbass.so:./lib \
+ libs/x86_64/libbass.so:./bin
+ elif [[ "$PLATFORM" == "macos" ]]; then
+ get_zip https://www.un4seen.com/files/bass24-osx.zip \
+ bass.h:./lib \
+ libbass.dylib:./lib
+ fi
+}
+
+get_bassopus() {
+ echo "Checking for BASSOPUS..."
+ # If lib/bassopus.h exists, assume that BASSOPUS is already present
+ if [ -f "./lib/bassopus.h" ]; then
+ echo "BASSOPUS is installed."
+ return 0
+ fi
+
+ echo "Downloading BASSOPUS..."
+ if [[ "$PLATFORM" == "windows" ]]; then
+ get_zip https://www.un4seen.com/files/bassopus24.zip \
+ c/bassopus.h:./lib \
+ c/x64/bassopus.lib:./lib \
+ x64/bassopus.dll:./bin
+ elif [[ "$PLATFORM" == "linux" ]]; then
+ get_zip https://www.un4seen.com/files/bassopus24-linux.zip \
+ bassopus.h:./lib \
+ libs/x86_64/libbassopus.so:./lib \
+ libs/x86_64/libbassopus.so:./bin
+ elif [[ "$PLATFORM" == "macos" ]]; then
+ get_zip https://www.un4seen.com/files/bassopus24-osx.zip \
+ bassopus.h:./lib \
+ libbassopus.dylib:./lib
+ fi
+}
+
+get_discordrpc() {
+ echo "Checking for Discord RPC..."
+ # If lib/discord_rpc.h exists, assume that Discord RPC is already present
+ if [ -f "./lib/discord_rpc.h" ]; then
+ echo "Discord RPC is installed."
+ return 0
+ fi
+
+ echo "Downloading Discord RPC..."
+ if [[ "$PLATFORM" == "windows" ]]; then
+ get_zip https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-win.zip \
+ discord-rpc/win64-dynamic/lib/discord-rpc.lib:./lib \
+ discord-rpc/win64-dynamic/bin/discord-rpc.dll:./bin \
+ discord-rpc/win64-dynamic/include/discord_rpc.h:./lib \
+ discord-rpc/win64-dynamic/include/discord_register.h:./lib
+ elif [[ "$PLATFORM" == "linux" ]]; then
+ get_zip https://github.com/discordapp/discord-rpc/releases/download/v3.4.0/discord-rpc-linux.zip \
+ discord-rpc/linux-dynamic/lib/libdiscord-rpc.so:./lib \
+ discord-rpc/linux-dynamic/lib/libdiscord-rpc.so:./bin \
+ discord-rpc/linux-dynamic/include/discord_rpc.h:./lib \
+ discord-rpc/linux-dynamic/include/discord_register.h:./lib
+ elif [[ "$PLATFORM" == "macos" ]]; then
+ get_zip https://github.com/discord/discord-rpc/releases/download/v3.4.0/discord-rpc-osx.zip \
+ discord-rpc/osx-dynamic/lib/libdiscord-rpc.dylib:./lib \
+ discord-rpc/osx-dynamic/include/discord_rpc.h:./lib \
+ discord-rpc/osx-dynamic/include/discord_rpc.h:./lib
+ fi
+}
+
+get_qtapng() {
+ echo "Checking for Qt apng plugin..."
+ apng_build_dir="./qtapng/plugins/imageformats"
+ imageformats_dir="./bin/imageformats"
+ APNG_LIB=""
+ if [[ "$PLATFORM" == "windows" ]]; then
+ APNG_LIB="qapng.dll"
+ elif [[ "$PLATFORM" == "linux" ]]; then
+ APNG_LIB="libqapng.so"
+ elif [[ "$PLATFORM" == "macos" ]]; then
+ APNG_LIB="libqapng.dylib"
+ else
+ echo "Unsupported platform: ${PLATFORM}"
+ return 1
+ fi
+
+ apng_dst_path="${imageformats_dir}/${APNG_LIB}"
+
+ if [ -f "$apng_dst_path" ]; then
+ echo "Qt apng plugin is installed."
+ return 0
+ fi
+
+ if [ ! -d "./qtapng" ]; then
+ git clone git@github.com:jurplel/QtApng.git ./qtapng
+ fi
+
+ cd ./qtapng
+
+ $CMAKE . \
+ -G Ninja \
+ -DCMAKE_MAKE_PROGRAM="$NINJA" \
+ -DCMAKE_PREFIX_PATH="$QT_PATH" \
+ -DCMAKE_C_COMPILER="$CC" \
+ -DCMAKE_CXX_COMPILER="$CXX"
+
+ $NINJA
+
+ cd "${SCRIPT_DIR}"
+
+ mkdir -p "$imageformats_dir"
+
+ apng_src_path="${apng_build_dir}/${APNG_LIB}"
+
+ cp "$apng_src_path" "$apng_dst_path"
+}
+
+get_themes() {
+ echo "Checking for themes..."
+ if [ -d "./bin/base/themes" ]; then
+ echo "Themes are installed."
+ return 0
+ fi
+
+ echo "Downloading themes..."
+ git clone git@github.com:AttorneyOnline/AO2-Themes.git ./bin/base/themes
+
+ rm -rf ./bin/base/themes/.gitignore
+ rm -rf ./bin/base/themes/.gitattributes
+ rm -rf ./bin/base/themes/.git
+}
+
+configure() {
+ # If -h is passed, print help
+ if [ "$#" -gt 0 ] && { [ "$1" = "-h" ] || [ "$1" = "--help" ]; }; then
+ print_help
+ exit 0
+ fi
+
+ # If clean is passed, remove all files from lib, bin and tmp
+ if [ "$#" -gt 0 ] && { [ "$1" = "clean" ]; }; then
+ echo "Cleaning up... removing lib, bin and tmp"
+ rm -rf ./lib/*
+ rm -rf ./bin/*
+ rm -rf ./tmp/*
+ rm -rf ./qtapng/
+ exit 0
+ fi
+
+ echo "Platform: ${PLATFORM}"
+
+ # If platform is unknown, terminate
+ if [ "$PLATFORM" == "unknown" ]; then
+ echo "Unknown platform. Aborting."
+ exit 1
+ fi
+
+ # Now we look for qt
+ QT_ROOT=""
+
+ # If QT_ROOT=path is passed, use that
+ if [ "$#" -gt 0 ] && [ "${1%%=*}" = "QT_ROOT" ]; then
+ QT_ROOT="${1#*=}"
+ shift
+ # Try to find it otherwise
+ else
+ QT_ROOT=$(find_qt)
+ if [ -z "$QT_ROOT" ]; then
+ echo "Qt not found. Aborting."; exit 1;
+ fi
+ fi
+ if [ ! -d "$QT_ROOT" ]; then
+ echo "$QT_ROOT is not a directory. Aborting."
+ exit 1
+ fi
+ echo "Using Qt root: $QT_ROOT"
+
+ QT_PATH=$(find_qtpath)
+ if [ ! -d "$QT_PATH" ]; then
+ echo "$QT_PATH is not a directory. Aborting."
+ exit 1
+ fi
+ echo "Using Qt installation: $QT_PATH"
+
+ # Check for cmake, and prefer the one bundled with Qt
+ CMAKE=$(find_cmake)
+ if [ -z "$CMAKE" ]; then
+ echo "No cmake bundled with Qt found. Trying path..."
+ if ! check_command cmake ; then
+ echo "CMake not found. Aborting."
+ exit 1
+ fi
+ CMAKE="cmake"
+ fi
+
+ check_command "$CMAKE" --version || { echo "cmake not working. Aborting."; exit 1; }
+ echo "Using cmake: $CMAKE"
+
+ # Find the compiler bundled in Qt
+ CC=""
+ CXX=""
+ # If we're on Windows, find mingw
+ if [[ "$PLATFORM" == "windows" ]]; then
+ MINGW_PATH=$(find_mingw)
+ if [ -z "$MINGW_PATH" ]; then
+ echo "MinGW not found. Aborting."
+ exit 1
+ fi
+ CC="${MINGW_PATH}/bin/gcc.exe"
+ CXX="${MINGW_PATH}/bin/g++.exe"
+ else
+ # On non-Windows platforms, use the system compiler, as it's usually safe
+ CC="gcc"
+ CXX="g++"
+ fi
+ check_command "$CC" --version || { echo "CC not working. Aborting"; exit 1; }
+ echo "Using CC: $CC"
+
+ check_command "$CXX" --version || { echo "CXX not working. Aborting"; exit 1; }
+ echo "Using CXX: $CXX"
+
+ NINJA=""
+ NINJA=$(find_ninja)
+ check_command "$NINJA" --version || { echo "Ninja not working. Aborting"; exit 1; }
+ echo "Using Ninja: $NINJA"
+
+ # Check basic dependencies
+ check_command curl --help || { echo "Command curl not found. Aborting"; exit 1; }
+ check_command unzip --help || { echo "Command unzip not found. Aborting"; exit 1; }
+
+ # Make sure key folders exist
+ mkdir -p ./tmp/
+ mkdir -p ./lib/
+ mkdir -p ./bin/
+
+ # Get the dependencies
+ get_bass
+ get_bassopus
+ get_discordrpc
+ get_qtapng
+ get_themes
+
+ # Typically, IDEs like running cmake themselves, but we need the binary to fix dependencies correctly
+ FULL_CMAKE_CMD="\
+$CMAKE . \
+-G Ninja \
+-DCMAKE_MAKE_PROGRAM=${NINJA} \
+-DCMAKE_PREFIX_PATH=${QT_PATH} \
+-DCMAKE_BUILD_TYPE=${BUILD_CONFIG} \
+-DCMAKE_C_COMPILER=${CC} \
+-DCMAKE_CXX_COMPILER=${CXX}"
+
+ $FULL_CMAKE_CMD
+ $NINJA
+
+ if [[ "$PLATFORM" == "windows" ]]; then
+ echo "Fixing dependencies..."
+ windeployqt="${QT_PATH}/bin/windeployqt.exe"
+ "$windeployqt" --no-quick-import --no-translations --no-compiler-runtime --no-opengl-sw ./bin/Attorney_Online.exe
+ fi
+
+ echo "Configuration and build complete."
+ echo "Full cmake cmd: $FULL_CMAKE_CMD"
+ echo "$FULL_CMAKE_CMD" > cmake_cmd.txt
+}
+
+configure "$@"