mirror of https://github.com/aseprite/aseprite.git
				
				
				
			
		
			
				
	
	
		
			498 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			498 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
| #! /usr/bin/env bash
 | |
| #
 | |
| # This is a script to help users and developers to build Aseprite.
 | |
| # Usage:
 | |
| #
 | |
| #   ./build.sh
 | |
| #   ./build.sh --reset
 | |
| #   ./build.sh --auto [--norun]
 | |
| #
 | |
| # If you run this script without parameters, you will be able to
 | |
| # follows the instructions and a configuration will be stored in a
 | |
| # ".build" directory.
 | |
| #
 | |
| # Options:
 | |
| #
 | |
| #   --reset   Deletes the configuration and you can start over
 | |
| #   --auto    Tries to build the default user configuration (release mode)
 | |
| #   --norun   Doesn't auto-run when using --auto
 | |
| #
 | |
| 
 | |
| echo "======================= BUILD ASEPRITE HELPER ========================"
 | |
| 
 | |
| # Check that we are running the script from the Aseprite clone directory.
 | |
| pwd=$(pwd)
 | |
| if [[ ! -f "$pwd/EULA.txt" || ! -f "$pwd/.gitmodules" ]] ; then
 | |
|     echo ""
 | |
|     echo "Run build script from the Aseprite directory"
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| # Use "./build.sh --reset" to reset all the configuration (deletes
 | |
| # .build directory).
 | |
| if [ "$1" == "--reset" ] ; then
 | |
|     echo ""
 | |
|     echo "Resetting $pwd/.build directory"
 | |
|     if [ -f "$pwd/.build/builds_dir" ] ; then rm $pwd/.build/builds_dir ; fi
 | |
|     if [ -f "$pwd/.build/log" ] ; then rm $pwd/.build/log ; fi
 | |
|     if [ -f "$pwd/.build/main_skia_dir" ] ; then rm $pwd/.build/main_skia_dir ; fi
 | |
|     if [ -f "$pwd/.build/beta_skia_dir" ] ; then rm $pwd/.build/beta_skia_dir ; fi
 | |
|     if [ -f "$pwd/.build/userkind" ] ; then rm $pwd/.build/userkind ; fi
 | |
|     if [ -d "$pwd/.build" ] ; then rmdir $pwd/.build ; fi
 | |
|     echo "Done"
 | |
|     exit 0
 | |
| fi
 | |
| 
 | |
| # Use "./build.sh --auto" to build the user configuration without
 | |
| # questions (downloading Skia/release mode).
 | |
| auto=
 | |
| if [ "$1" == "--auto" ] ; then
 | |
|     shift
 | |
|     auto=1
 | |
| fi
 | |
| norun=
 | |
| if [ "$1" == "--norun" ] ; then
 | |
|     shift
 | |
|     norun=1
 | |
| fi
 | |
| 
 | |
| # Check utilities.
 | |
| if ! cmake --version >/dev/null ; then
 | |
|     echo ""
 | |
|     echo "cmake utility is not available. You can get cmake from:"
 | |
|     echo ""
 | |
|     echo "  https://cmake.org/download/"
 | |
|     echo ""
 | |
|     exit 1
 | |
| fi
 | |
| if ! ninja --version >/dev/null ; then
 | |
|     echo ""
 | |
|     echo "ninja utility is not available. You can get ninja from:"
 | |
|     echo ""
 | |
|     echo "  https://github.com/ninja-build/ninja/releases"
 | |
|     echo ""
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| # Check that all submodules are checked out.
 | |
| run_submodule_update=
 | |
| for module in $(cat "$pwd/.gitmodules" | \
 | |
|                     grep '^\[submodule' | \
 | |
|                     sed -e 's/^\[.*\"\(.*\)\"\]/\1/') \
 | |
|               $(cat "$pwd/laf/.gitmodules" | \
 | |
|                     grep '^\[submodule' | \
 | |
|                     sed -e 's/^\[.*\"\(.*\)\"\]/laf\/\1/') ; do
 | |
|     if [[ ! -f "$module/CMakeLists.txt" &&
 | |
|           ! -f "$module/Makefile" &&
 | |
|           ! -f "$module/makefile" &&
 | |
|           ! -f "$module/Makefile.am" ]] ; then
 | |
|         echo ""
 | |
|         echo "Module $module doesn't exist."
 | |
|         if [ $auto ] ; then
 | |
|             run_submodule_update=1
 | |
|             break
 | |
|         else
 | |
|             echo "Run:"
 | |
|             echo ""
 | |
|             echo "  git submodule update --init --recursive"
 | |
|             echo ""
 | |
|             exit 1
 | |
|         fi
 | |
|     fi
 | |
| done
 | |
| if [ $run_submodule_update ] ; then
 | |
|     echo "Running:"
 | |
|     echo ""
 | |
|     echo "  git submodule update --init --recursive"
 | |
|     echo ""
 | |
|     if ! git submodule update --init --recursive ; then
 | |
|         echo "Failed, try again"
 | |
|         exit 1
 | |
|     fi
 | |
|     echo "Done"
 | |
| fi
 | |
| 
 | |
| # Platform.
 | |
| if ! source "$pwd/laf/misc/platform.sh" ; then
 | |
|     exit $?
 | |
| fi
 | |
| 
 | |
| if [ $is_win ] ; then
 | |
|     # Check MSVC compiler.
 | |
|     if ! cl.exe >/dev/null 2>/dev/null ; then
 | |
|         echo ""
 | |
|         echo "MSVC compiler (cl.exe) not found in PATH"
 | |
|         echo ""
 | |
|         echo "  PATH=$PATH"
 | |
|         echo ""
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| # Create the directory to store the configuration.
 | |
| if [ ! -d "$pwd/.build" ] ; then
 | |
|     mkdir "$pwd/.build"
 | |
| fi
 | |
| 
 | |
| # Kind of user (User or Developer).
 | |
| # For users we simplify the process (no multiple builds), for
 | |
| # developers we have more options (debug mode, etc.).
 | |
| if [ ! -f "$pwd/.build/userkind" ] ; then
 | |
|     if [ $auto ] ; then
 | |
|         echo "user" > $pwd/.build/userkind
 | |
|     else
 | |
|         echo ""
 | |
|         echo "Select what kind of user you are (press U or D key and then Enter):"
 | |
|         echo ""
 | |
|         echo "  [U]ser: give a try to Aseprite"
 | |
|         echo "  [D]eveloper: develop/modify Aseprite"
 | |
|         echo ""
 | |
|         read -p "[U/D]? "
 | |
|         REPLY=$(echo $REPLY | tr '[:upper:]' '[:lower:]')
 | |
|         if [[ "$REPLY" == "d" || "$REPLY" == "dev" || "$REPLY" == "developer" ]] ; then
 | |
|             echo "developer" > $pwd/.build/userkind
 | |
|         elif [[ "$REPLY" == "u" || "$REPLY" == "user" ]] ; then
 | |
|             echo "user" > $pwd/.build/userkind
 | |
|         else
 | |
|             echo "Use U or D keys (and press Enter) to select kind of user/build process"
 | |
|             exit 1
 | |
|         fi
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| userkind=$(cat $pwd/.build/userkind)
 | |
| if [ "$userkind" == "developer" ] ; then
 | |
|     echo "======================= BUILDING FOR DEVELOPER ======================="
 | |
| else
 | |
|     echo "========================= BUILDING FOR USER =========================="
 | |
| fi
 | |
| 
 | |
| # Get the builds_dir location.
 | |
| if [ ! -f "$pwd/.build/builds_dir" ] ; then
 | |
|     if [ "$userkind" == "developer" ] ; then
 | |
|         # The "builds" folder is a place where all possible combination/builds
 | |
|         # will be stored. If the ASEPRITE_BUILD environment variable is
 | |
|         # defined, that's the directory, in other case for a regular "user"
 | |
|         # the folder will be this same directory where Aseprite was cloned.
 | |
|         if [[ "$ASEPRITE_BUILD" != "" ]] ; then
 | |
|             if [ $is_win ] ; then
 | |
|                 builds_dir=$(cygpath "$ASEPRITE_BUILD")
 | |
|             else
 | |
|                 builds_dir="$ASEPRITE_BUILD"
 | |
|             fi
 | |
| 
 | |
|             if [ -d "$builds_dir" ] ; then
 | |
|                 echo ""
 | |
|                 echo "Using ASEPRITE_BUILD environment variable for builds directory."
 | |
|             else
 | |
|                 if ! mkdir "$builds_dir" ; then
 | |
|                     echo ""
 | |
|                     echo "The ASEPRITE_BUILD is defined but we weren't able to create the directory:"
 | |
|                     echo ""
 | |
|                     echo "  ASEPRITE_BUILD=$builds_dir"
 | |
|                     echo ""
 | |
|                     echo "To solve this issue delete the ASEPRITE_BUILD variable or point it to a valid path."
 | |
|                     exit 1
 | |
|                 fi
 | |
|             fi
 | |
|         else
 | |
|             # Default location for developers
 | |
|             builds_dir=$HOME/builds
 | |
| 
 | |
|             echo ""
 | |
|             echo "Select a folder where to leave all builds:"
 | |
|             echo "  builds_dir/"
 | |
|             echo "    release-x64/..."
 | |
|             echo "    debug-x64/..."
 | |
|             echo ""
 | |
|             echo "builds_dir [$builds_dir]? "
 | |
|             read builds_dir_read
 | |
|             if [ "$builds_dir_read" != "" ] ; then
 | |
|                 builds_dir="$builds_dir_read"
 | |
|             fi
 | |
|         fi
 | |
|     else
 | |
|         # Default location for users
 | |
|         builds_dir="$pwd"
 | |
| 
 | |
|         echo ""
 | |
|         echo "We'll build Aseprite in $builds_dir/build directory"
 | |
|     fi
 | |
|     echo "$builds_dir" > "$pwd/.build/builds_dir"
 | |
| fi
 | |
| # Overwrite $builds_dir variable from the config content.
 | |
| builds_dir="$(cat $pwd/.build/builds_dir)"
 | |
| 
 | |
| # List all builds.
 | |
| builds_list="$(mktemp)"
 | |
| n=1
 | |
| for file in $(ls $builds_dir/*/CMakeCache.txt 2>/dev/null | sort) ; do
 | |
|     if cat "$file" | grep -q "CMAKE_PROJECT_NAME:STATIC=aseprite" ; then
 | |
|         if [ $n -eq 1 ] ; then
 | |
|             echo "-- AVAILABLE BUILDS --"
 | |
|         fi
 | |
|         echo "$file" >> $builds_list
 | |
|         echo "$n. $file"
 | |
|         n=$(($n+1))
 | |
|     fi
 | |
| done
 | |
| 
 | |
| # New build configuration.
 | |
| build_type=RelWithDebInfo
 | |
| 
 | |
| # No builds, so this is the first build.
 | |
| if [[ $n -eq 1 ]] ; then
 | |
|     echo "-- FIRST BUILD --"
 | |
|     if [ "$userkind" == "developer" ] ; then
 | |
|         active_build_dir="$builds_dir/aseprite-release"
 | |
|     else
 | |
|         active_build_dir="$builds_dir/build"
 | |
|     fi
 | |
|     echo "First build directory: $active_build_dir"
 | |
| else
 | |
|     echo "N. New build (N key)"
 | |
|     echo "U. Update Visual Studio/Windows Kit/macOS SDK version (U key)"
 | |
|     read -p "Select an option or number to build? " build_n
 | |
| 
 | |
|     # New build
 | |
|     if [[ "$build_n" == "n" || "$build_n" == "N" ]] ; then
 | |
|         read -p "Select build type [RELEASE/debug]? "
 | |
|         REPLY=$(echo $REPLY | tr '[:upper:]' '[:lower:]')
 | |
|         if [[ "${REPLY}" == "debug" ]] ; then
 | |
|             build_type=Debug
 | |
|             new_build_name=aseprite-debug
 | |
|         else
 | |
|             build_type=RelWithDebInfo
 | |
|             new_build_name=aseprite-release
 | |
|         fi
 | |
| 
 | |
|         read -p "Select a name [$new_build_name]? "
 | |
|         if [[ "$REPLY" != "" ]] ; then
 | |
|             new_build_name=$REPLY
 | |
|         fi
 | |
|         active_build_dir="$builds_dir/$new_build_name"
 | |
| 
 | |
|     # Update SDK
 | |
|     elif [[ "$build_n" == "u" || "$build_n" == "U" ]] ; then
 | |
|         echo "Update SDK dirs..."
 | |
|         if [ $is_win ] ; then
 | |
|             newclver=$(echo $VCToolsInstallDir | sed -e 's_^.*\\\([0-9\.]*\)\\$_\1_')
 | |
| 
 | |
|             function update_file {
 | |
|                 file=$1
 | |
|                 echo "--- Updating $file ---" | tee -a "$pwd/.build/log"
 | |
|                 mv "$file" "$file-old"
 | |
|                 cat "$file-old" | sed -e 's_^\(.*/VC/Tools/MSVC/\)\([0-9\.]*\)\(.*$\)_\1'$newclver'\3_' > "$file"
 | |
|                 diff -w -u3 "$file-old" "$file" >> "$pwd/.build/log"
 | |
|                 echo "--- End $file ---" >> "$pwd/.build/log"
 | |
|             }
 | |
| 
 | |
|             echo "New VC version: $newclver"
 | |
|             for file in $(cat $builds_list) ; do
 | |
|                 build_dir=$(dirname $file)
 | |
|                 echo "--- Updating $build_dir ---"
 | |
|                 update_file "$file"
 | |
|                 for other_file in "$build_dir/CMakeFiles/rules.ninja" \
 | |
|                                   "$build_dir"/CMakeFiles/*/*.cmake \
 | |
|                                   "$build_dir/third_party/libpng/scripts/genout.cmake" ; do
 | |
|                     update_file "$other_file"
 | |
|                 done
 | |
|             done
 | |
|         fi
 | |
|         echo "Done"
 | |
|         exit
 | |
| 
 | |
|     else # Build the selected dir
 | |
|         n=1
 | |
|         for file in $(cat $builds_list) ; do
 | |
|             if [ "$n" == "$build_n" ] ; then
 | |
|                 active_build_dir=$(dirname $file)
 | |
|                 build_type=$(cat $active_build_dir/CMakeCache.txt | grep CMAKE_BUILD_TYPE | cut -d "=" -f2)
 | |
|                 break
 | |
|             fi
 | |
|             n=$(($n+1))
 | |
|         done
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| if [ "$active_build_dir" == "" ] ; then
 | |
|     echo "No build selected"
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| if [ -f "$active_build_dir/CMakeCache.txt" ] ; then
 | |
|     source_dir=$(cat $active_build_dir/CMakeCache.txt | grep aseprite_SOURCE_DIR | cut -d "=" -f2)
 | |
| else
 | |
|     source_dir="$pwd"
 | |
| fi
 | |
| branch_name=$(git --git-dir="$source_dir/.git" rev-parse --abbrev-ref HEAD)
 | |
| 
 | |
| if [[ "$branch_name" == "main" || "$branch_name" == "beta" ]] ; then
 | |
|     base_branch_name="$branch_name"
 | |
| else
 | |
|     # Get the origin (or first remote) name
 | |
|     remote=$(git --git-dir="$source_dir/.git" remote | grep origin)
 | |
|     if [ "$remote" == "" ] ; then
 | |
|         remote=$(git --git-dir="$source_dir/.git" remote | head -n1)
 | |
|     fi
 | |
| 
 | |
|     if git --git-dir="$source_dir/.git" branch --contains "$remote/beta" | grep -q "^\* $branch_name\$" ; then
 | |
|         base_branch_name=beta
 | |
|     elif git --git-dir="$source_dir/.git" branch --contains "$remote/main" | grep -q "^\* $branch_name\$" ; then
 | |
|         base_branch_name=main
 | |
|     else
 | |
|         base_branch_name=$branch_name
 | |
|     fi
 | |
| fi
 | |
| 
 | |
| echo "=========================== CONFIGURATION ============================"
 | |
| echo "Build type: $build_type"
 | |
| echo "Build dir: \"$active_build_dir\""
 | |
| echo "Source dir: \"$source_dir\""
 | |
| if [ "$branch_name" != "$base_branch_name" ] ; then
 | |
|     echo "Branch name: $base_branch_name > $branch_name"
 | |
| else
 | |
|     echo "Branch name: $base_branch_name"
 | |
| fi
 | |
| 
 | |
| # Required Skia for the base branch.
 | |
| skia_tag=$(cat "$pwd/laf/misc/skia-tag.txt")
 | |
| possible_skia_dir_name=skia-$(echo $skia_tag | cut -d "-" -f 1)
 | |
| file_skia_dir="$base_branch_name"_skia_dir
 | |
| 
 | |
| # Check Skia dependency.
 | |
| if [ ! -f "$pwd/.build/$file_skia_dir" ] ; then
 | |
|     # Try "C:/deps/skia" or "$HOME/deps/skia"
 | |
|     if [[ $is_win ]] ; then
 | |
|         skia_dir="C:/deps/$possible_skia_dir_name"
 | |
|     else
 | |
|         skia_dir="$HOME/deps/$possible_skia_dir_name"
 | |
|     fi
 | |
| 
 | |
|     # Set default location if not found
 | |
|     if [ ! -d "$skia_dir" ] ; then
 | |
|         # Use .deps directory to download Skia for users (which is a
 | |
|         # simple setup). In case of developers we'd prefer the shared
 | |
|         # directory by default.
 | |
|         if [ "$userkind" == "user" ] ; then
 | |
|             skia_dir="$pwd/.deps/$possible_skia_dir_name"
 | |
|         fi
 | |
| 
 | |
|         if [ ! -d "$skia_dir" ] ; then
 | |
|             echo ""
 | |
|             echo "Skia directory wasn't found."
 | |
|             echo ""
 | |
| 
 | |
|             echo "Select Skia directory to create [$skia_dir]? "
 | |
|             if [ ! $auto ] ; then
 | |
|                 read skia_dir_read
 | |
|                 if [ "$skia_dir_read" != "" ] ; then
 | |
|                     skia_dir="$skia_dir_read"
 | |
|                 fi
 | |
|             fi
 | |
|             mkdir -p $skia_dir || exit 1
 | |
|         fi
 | |
|     fi
 | |
|     echo $skia_dir > "$pwd/.build/$file_skia_dir"
 | |
| fi
 | |
| skia_dir=$(cat $pwd/.build/$file_skia_dir)
 | |
| if [ ! -d "$skia_dir" ] ; then
 | |
|     mkdir "$skia_dir"
 | |
| fi
 | |
| 
 | |
| # Only on Windows we need the Debug version of Skia to compile the
 | |
| # Debug version of Aseprite.
 | |
| if [[ $is_win && "$build_type" == "Debug" ]] ; then
 | |
|     skia_library_dir="$skia_dir/out/Debug-x64"
 | |
| else
 | |
|     skia_library_dir="$skia_dir/out/Release-$cpu"
 | |
| fi
 | |
| 
 | |
| # If the library directory is not available, we can try to download
 | |
| # the pre-built package.
 | |
| if [ ! -d "$skia_library_dir" ] ; then
 | |
|     echo ""
 | |
|     echo "Skia library wasn't found."
 | |
|     echo ""
 | |
|     if [ ! $auto ] ; then
 | |
|         read -p "Download pre-compiled Skia automatically [Y/n]? "
 | |
|         # Convert the Enter key as the default option: an empty string
 | |
|         REPLY=$(echo $REPLY | tr '[:upper:]' '[:lower:]')
 | |
|     fi
 | |
|     if [[ $auto || "$REPLY" == "" || "$REPLY" == "y" || "$REPLY" == "yes" ]] ; then
 | |
|         if [[ $is_win && "$build_type" == "Debug" ]] ; then
 | |
|             skia_build=Debug
 | |
|         else
 | |
|             skia_build=Release
 | |
|         fi
 | |
|         skia_url=$(bash laf/misc/skia-url.sh $skia_build)
 | |
|         skia_file=$(basename $skia_url)
 | |
|         if [ ! -f "$skia_dir/$skia_file" ] ; then
 | |
|             curl --ssl-revoke-best-effort -L -o "$skia_dir/$skia_file" "$skia_url"
 | |
|         fi
 | |
|         if [ ! -d "$skia_library_dir" ] ; then
 | |
|             unzip -n -d "$skia_dir" "$skia_dir/$skia_file"
 | |
|         fi
 | |
|     else
 | |
|         echo "Please follow these instructions to compile Skia manually:"
 | |
|         echo ""
 | |
|         echo "  https://github.com/aseprite/skia?tab=readme-ov-file#skia-for-aseprite-and-laf"
 | |
|         echo ""
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| echo "================================ SKIA ================================"
 | |
| echo "Skia directory: \"$skia_dir\""
 | |
| echo "Skia library directory: \"$skia_library_dir\""
 | |
| if [ ! -d "$skia_library_dir" ] ; then
 | |
|     echo "  But the Skia library directory wasn't found."
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| # Building
 | |
| echo "=============================== CMAKE ================================"
 | |
| if [ ! -f "$active_build_dir/ninja.build" ] ; then
 | |
|     echo ""
 | |
|     echo "We are going to run cmake and then build the project."
 | |
|     echo "This will take some minutes."
 | |
|     echo ""
 | |
|     if [ ! $auto ] ; then
 | |
|         read -p "Press Enter to continue."
 | |
|     fi
 | |
| 
 | |
|     if [ $is_macos ] ; then
 | |
|         osx_deployment_target="-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0"
 | |
|     else
 | |
|         osx_deployment_target=
 | |
|     fi
 | |
| 
 | |
|     echo "Configuring Aseprite..."
 | |
|     if ! cmake -B "$active_build_dir" -S "$source_dir" -G Ninja \
 | |
|          -DCMAKE_BUILD_TYPE=$build_type \
 | |
|          $osx_deployment_target \
 | |
|          -DLAF_BACKEND=skia \
 | |
|          -DSKIA_DIR="$skia_dir" \
 | |
|          -DSKIA_LIBRARY_DIR="$skia_library_dir" | \
 | |
|             tee -a "$pwd/.build/log" ; then
 | |
|         echo "Error running cmake."
 | |
|         exit 1
 | |
|     fi
 | |
| fi
 | |
| echo "============================== BUILDING =============================="
 | |
| if ! cmake --build "$active_build_dir" -- aseprite | tee -a "$pwd/.build/log" ; then
 | |
|     echo "Error building Aseprite."
 | |
|     exit 1
 | |
| fi
 | |
| 
 | |
| echo "================================ DONE ================================"
 | |
| if [ $is_win ] ; then exe=.exe ; else exe= ; fi
 | |
| echo "Run Aseprite with the following command:"
 | |
| echo ""
 | |
| echo "  $active_build_dir/bin/aseprite$exe"
 | |
| echo ""
 | |
| 
 | |
| # Run Aseprite in --auto mode
 | |
| if [[ $auto && ! $norun ]] ; then
 | |
|     $active_build_dir/bin/aseprite$exe
 | |
| fi
 |