#!/bin/bash # created by vector sigma on July 15 2019 # modified by LAbyOne on My 2021 # github version # Linux users should be able to use this wrapper, although the following are needed: # (Ubuntu alike) # sudo apt-get install build-essential uuid-dev iasl git gcc-10 nasm python3-distutils # $1 argument override MYTOOLCHAIN variable, in case you want GCC53 for example # ====== COLORS ====== COL_BLACK="\x1b[30;01m" COL_RED="\x1b[31;01m" COL_GREEN="\x1b[32;01m" COL_YELLOW="\x1b[33;01m" COL_MAGENTA="\x1b[35;01m" COL_CYAN="\x1b[36;01m" COL_WHITE="\x1b[37;01m" COL_BLUE="\x1b[34;01m" COL_RESET="\x1b[39;49;00m" cd "$(dirname $([ -L $0 ] && readlink $0 || echo $0))" declare -r CLOVERROOT="$PWD" declare -r SYSNAME="$(uname)" MYTOOLCHAIN=${1:-GCC53} # Functions pathmunge() { if [[ ! $PATH =~ (^|:)$1(:|$) ]]; then if [[ "${2:-}" = "after" ]]; then export PATH=$PATH:$1 else export PATH=$1:$PATH fi fi } checkXCODE() { echo "[CHECK XCODE]" if [[ ! -x /usr/bin/xcodebuild ]]; then echo "ERROR: Install Xcode Tools from Apple before using this script." exit 1 fi if [[ ! -d "$(xcode-select --print-path)" ]]; then echo "ERROR: Xcode Command Line Tools not selected:" echo " open Xcode.app and go in Preferences->Locations," echo " and select the Command Line Tools" exit 1 fi } checkGETTEXT() { exportPaths local locations=($(which msgmerge)) if [ "${#locations[@]}" -eq 0 ]; then export GETTEXT_PREFIX="${TOOLCHAIN_DIR}" "${CLOVERROOT}"/buildgettext.sh else # export gettex prefix to ensure buildpkg.sh will use it # without the need to install it again export GETTEXT_PREFIX="$(dirname "${locations[0]}")" fi } exportPaths() { if [[ "$SYSNAME" == Linux ]]; then TOOLCHAIN_DIR=${TOOLCHAIN_DIR:-/usr} elif [[ "$SYSNAME" == Darwin ]]; then pathmunge "$(xcode-select --print-path)"/usr/bin if [[ -d ~/src/opt/local ]]; then TOOLCHAIN_DIR=~/src/opt/local else TOOLCHAIN_DIR=${TOOLCHAIN_DIR:-"$CLOVERROOT"/toolchain} fi fi pathmunge "$TOOLCHAIN_DIR"/bin export TOOLCHAIN_DIR=$TOOLCHAIN_DIR export DIR_MAIN=${DIR_MAIN:-"$CLOVERROOT"/toolchain} export DIR_TOOLS=${DIR_TOOLS:-$DIR_MAIN/tools} export DIR_DOWNLOADS=${DIR_DOWNLOADS:-$DIR_TOOLS/download} export DIR_LOGS=${DIR_LOGS:-$DIR_TOOLS/logs} export PREFIX=${TOOLCHAIN_DIR} } checkTools() { # export any env vars before building anything if [[ "$SYSNAME" == Darwin ]]; then checkXCODE exportPaths local GCC53_BIN="$PREFIX/cross/bin/x86_64-clover-linux-gnu-gcc" if [[ $MYTOOLCHAIN == GCC* ]] && [[ ! -x "${GCC53_BIN}" ]]; then if [[ $MYTOOLCHAIN == GCC53 ]]; then cd "${CLOVERROOT}" ./build_gcc10.sh else MYTOOLCHAIN=XCODE8 fi fi else exportPaths fi } updateClover() { echo "[UPDATE CLOVER]" cd "${CLOVERROOT}" if [[ -d .git ]]; then git fetch --all --recurse-submodules git pull --recurse-submodules origin master else echo "Error: this is not a git repository, can't update!" fi } updateResetClover() { echo "[UPDATE RESET CLOVER]" cd "${CLOVERROOT}" if [[ -d .git ]]; then git fetch --all --recurse-submodules git submodule foreach --recursive git clean -d -f -f git clean -d -f -f git submodule foreach --recursive git reset --hard origin/master git reset --hard origin/master git pull --recurse-submodules origin master else echo "Error: this is not a git repository, can't update!" fi } buildCloverHFSPlus() { if [[ -f "${CLOVERROOT}"/FileSystems/HFSPlus/X64/HFSPlus.efi ]]; then echo "building Clover with HFSPlus" buildClover HFSPlus else echo "${CLOVERROOT}/FileSystems/HFSPlus/X64/HFSPlus.efi: no such file!" sleep 3 menu fi } buildCCPV() { revision=r$(git describe --tags $(git rev-list --tags --max-count=1)) if [[ -d "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator ]]; then rm -Rf "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator fi mkdir -p "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator cd "${CLOVERROOT}"/Xcode/CloverConfigPlistValidator xcodebuild -project ./CloverConfigPlistValidator.xcodeproj -quiet CONFIGURATION_BUILD_DIR="${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator mv -f "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator/CloverConfigPlistValidator "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator/ccpv rm -r "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator/*.dSYM } BLC() { if [[ ! -d "${CLOVERROOT}"/CloverPackage/BootLoaderChooser ]]; then mkdir -p "${CLOVERROOT}"/CloverPackage/BootLoaderChooser fi curl -sLq https://github.com/jief666/BootloaderChooser/releases/download/0.5/BootX64.efi > "${CLOVERROOT}"/CloverPackage/BootLoaderChooser/BootX64.efi chmod 775 "${CLOVERROOT}"/CloverPackage/BootLoaderChooser/BootX64.efi #open "${CLOVERROOT}"/CloverPackage/BootLoaderChooser } buildClover() { checkTools # to force recreation of the Conf folder. You can still use a custom CONF_PATH if you don't want recreation. rm -rf "$CLOVERROOT"/Conf mkdir "$CLOVERROOT"/Conf cd "${CLOVERROOT}" if [[ -z "$WORKSPACE" ]]; then export EDK_TOOLS_PATH="${PWD}"/BaseTools set +u source ./edksetup.sh BaseTools set -u cd "$CLOVERROOT" WORKSPACE="${PWD}" fi echo "[BUILD CLOVER]" # Run a custom build script if exist (~/src/tools/Scripts/build.sh) # This allow the user to run ebuild.sh with own parameters if [[ -x "${DIR_TOOLS}"/Scripts/build.sh ]]; then echo "Running custom build script" "${DIR_TOOLS}"/Scripts/build.sh "${CLOVERROOT}" $MYTOOLCHAIN else local parameter=${1:-none} if [[ "${parameter}" == HFSPlus ]]; then ./ebuild.sh -fr -mc --no-usb -D NO_GRUB_DRIVERS_EMBEDDED -D USE_APPLE_HFSPLUS_DRIVER -t $MYTOOLCHAIN ./ebuild.sh -fr -D NO_GRUB_DRIVERS_EMBEDDED -D USE_APPLE_HFSPLUS_DRIVER -t $MYTOOLCHAIN else ./ebuild.sh -fr -mc --no-usb -D NO_GRUB_DRIVERS_EMBEDDED -t $MYTOOLCHAIN ./ebuild.sh -fr -D NO_GRUB_DRIVERS_EMBEDDED -D LESS_DEBUG -t $MYTOOLCHAIN fi fi # Run a post build script if exist (~/src/tools/Scripts/postbuild.sh) if [[ -x "${DIR_TOOLS}"/Scripts/postbuild.sh ]]; then echo "Running postbuild script" "${DIR_TOOLS}"/Scripts/postbuild.sh "${CLOVERROOT}" $MYTOOLCHAIN fi } buildCloverTest() { checkTools cd "${CLOVERROOT}" if [[ -z "$WORKSPACE" ]]; then export EDK_TOOLS_PATH="${PWD}"/BaseTools set +u source ./edksetup.sh BaseTools set -u cd "$CLOVERROOT" WORKSPACE="${PWD}" fi echo "[BUILD CLOVER TEST]" ./ebuild.sh -nb -t $MYTOOLCHAIN } buildPkg() { if [[ "$SYSNAME" == Darwin ]]; then cd "${CLOVERROOT}"/CloverPackage echo "[BUILD PKG]" checkXCODE checkGETTEXT make pkg else echo && echo "can't build pkg on a non Darwin OS!" fi } buildApp() { local withClover=${1-"none"} if [[ "$SYSNAME" == Darwin ]]; then if [[ -f "${CLOVERROOT}"/CloverPackage/CloverV2/EFI/CLOVER/CLOVERX64.efi ]]; then rm -f "${CLOVERROOT}"/CloverPackage/sym/.withV2 mkdir -p "${CLOVERROOT}"/CloverPackage/sym if [[ $withClover == withV2 ]]; then touch "${CLOVERROOT}"/CloverPackage/sym/.withV2 fi cd "${CLOVERROOT}"/CloverApp echo "[BUILD APP]" checkXCODE make else echo && echo "please, build Clover first!" sleep 3 fi else echo && echo "Clover.app can only be built in macOS!" fi } buildIso() { cd "${CLOVERROOT}"/CloverPackage echo "[BUILD ISO]" make iso } checkStatus() { cd "${CLOVERROOT}" if [[ -d .git ]]; then git fetch --recurse-submodules origin git log -n 1 git status git submodule foreach --recursive "git log -n 1 && git status" else echo "Error: this is not a git repository, can't get info!" fi } showdiff() { cd "${CLOVERROOT}" if [[ -d .git ]]; then git fetch --recurse-submodules origin git diff else echo "Error: this is not a git repository, can't get info!" fi } cleanBaseTools() { cd "${CLOVERROOT}"/BaseTools make clean } ## Utilities buildCPV() { revision=r$(git describe --tags $(git rev-list --tags --max-count=1)) if [[ -d "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator ]]; then rm -Rf "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator fi mkdir -p "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator cd "${CLOVERROOT}"/Xcode/CloverConfigPlistValidator xcodebuild -project ./CloverConfigPlistValidator.xcodeproj -quiet CONFIGURATION_BUILD_DIR="${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator mv -f "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator/CloverConfigPlistValidator "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator/CloverConfigPlistValidator_${revision} rm -r "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator/*.dSYM open "${CLOVERROOT}"/CloverPackage/CloverConfigPlistValidator } PlistEDPlus() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && curl -qsSLk https://github.com/ic005k/PlistEDPlus/releases/download/1.0.52/PlistEDPlus_Mac.dmg > PlistEDPlus_Mac.dmg hdiutil attach -quiet -noverify -nobrowse PlistEDPlus_Mac.dmg && cp -Rf /Volumes/bin\:release\:PlistEDPlus/PlistEDPlus.app $HOME/Desktop/ClovUtils hdiutil detach -force /Volumes/bin\:release\:PlistEDPlus rm -r $HOME/Desktop/ClovUtils/PlistEDPlus_Mac.dmg && open $HOME/Desktop/ClovUtils } Hackintool() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && curl -sLq https://github.com/headkaze/Hackintool/releases/download/3.5.2/Hackintool.zip -o Hackintool.zip unzip -q Hackintool.zip && rm -r Hackintool.zip && open $HOME/Desktop/ClovUtils } BitmaskDecode() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && git clone -q https://github.com/corpnewt/BitmaskDecode && open $HOME/Desktop/ClovUtils } MaciASL() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && curl -sLq https://github.com/acidanthera/MaciASL/releases/download/1.6.1/MaciASL-1.6.1-RELEASE.dmg > MaciASL-1.6.1-RELEASE.dmg hdiutil attach -quiet -noverify -nobrowse MaciASL-1.6.1-RELEASE.dmg && cp -Rf /Volumes/MaciASL/MaciASL.app $HOME/Desktop/ClovUtils hdiutil detach -force /Volumes/MaciASL rm -r $HOME/Desktop/ClovUtils/MaciASL-1.6.1-RELEASE.dmg && open $HOME/Desktop/ClovUtils } dmidecode() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils/dmidecode fi cd $HOME/Desktop/ClovUtils && git clone -q https://github.com/acidanthera/dmidecode dmi-decode && xcodebuild -project ./dmi-decode/dmidecode.xcodeproj -quiet cp -r dmi-decode/dmidecode $HOME/Desktop/ClovUtils/dmidecode && rm -Rf $HOME/Desktop/ClovUtils/dmi-decode && open $HOME/Desktop/ClovUtils } Get-IOReg-Devices() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && git clone -q https://github.com/LAbyOne/Get-IOReg-Devices mv -f Get-IOReg-Devices/Get\ IOReg\ Devices $HOME/Desktop/ClovUtils/Get\ IOReg-Devices && chmod a+x $HOME/Desktop/ClovUtils/Get\ IOReg-Devices/*.command rm -rf Get-IOReg-Devices && open $HOME/Desktop/ClovUtils } NDBrightness () { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && git clone -q https://github.com/KAMIKAZEUA/NativeDisplayBrightness NDBrightness xcodebuild -project ./NDBrightness/NativeDisplayBrightness.xcodeproj -quiet -configuration Release clean build ARCHS=x86_64 ONLY_ACTIVE_ARCH=YES CONFIGURATION_BUILD_DIR=$HOME/Desktop/ClovUtils rm -Rf $HOME/Desktop/ClovUtils/NDBrightness && rm -r $HOME/Desktop/ClovUtils/*.dSYM && open $HOME/Desktop/ClovUtils } SSDTTime() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && git clone -q https://github.com/corpnewt/SSDTTime && open $HOME/Desktop/ClovUtils } USBMap() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && git clone -q https://github.com/corpnewt/USBMap open $HOME/Desktop/ClovUtils } QtiASL() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && curl -sLq https://github.com/ic005k/QtiASL/releases/download/1.0.60/QtiASL_Mac.dmg > QtiASL_Mac.dmg hdiutil attach -quiet -noverify -nobrowse QtiASL_Mac.dmg && cp -Rf /Volumes/bin\:release\:QtiASL/QtiASL.app $HOME/Desktop/ClovUtils hdiutil detach -force /Volumes/bin\:release\:QtiASL rm -r $HOME/Desktop/ClovUtils/QtiASL_Mac.dmg && open $HOME/Desktop/ClovUtils } CsrDecode() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils/CsrDecode fi cd $HOME/Desktop/ClovUtils && git clone -q https://github.com/corpnewt/CsrDecode && open $HOME/Desktop/ClovUtils } gibMacOS() { if [[ ! -d $HOME/Desktop/ClovUtils ]]; then mkdir -p $HOME/Desktop/ClovUtils fi cd $HOME/Desktop/ClovUtils && git clone -q https://github.com/corpnewt/gibMacOS && open $HOME/Desktop/ClovUtils } Utilities() { echo echo -e $COL_GREEN"-----------------------------------------------------------"$COL_RESET cd "${CLOVERROOT}" local lsha1="not a git repo" if [[ -d .git ]]; then lsha1=$(git rev-parse --short HEAD) fi echo -e " 🍀$COL_GREEN Clover r$(git describe --tags $(git rev-list --tags --max-count=1))$COL_WHITE (SHA: $lsha1)"$COL_RESET echo -e $COL_CYAN" $COL_CYAN Utilities "$COL_RESET echo -e $COL_GREEN"-----------------------------------------------------------"$COL_RESET echo && echo echo && echo echo && echo echo && echo echo && echo PS3=' Files will be put on Desktop/ClovUtils: ' options=( 'Get CloverConfigPlistValidator' 'Get PlistEDPlus' 'Get Hackintool' 'Get BitmaskDecode' 'Get MaciASL' 'Get dmidecode' 'Get IOReg-Devices' 'Get NativeDisplayBrightness' 'Get SSDTTime' 'Get USBMap' 'Get QtiASL' 'Get CsrDecode' 'Get gibMacOS' 'back to main') select opt in "${options[@]}" do case $opt in "Get CloverConfigPlistValidator") buildCPV break ;; "Get PlistEDPlus") PlistEDPlus break ;; "Get Hackintool") Hackintool break ;; "Get BitmaskDecode") BitmaskDecode break ;; "Get MaciASL") MaciASL break ;; "Get dmidecode") dmidecode break ;; "Get IOReg-Devices") Get-IOReg-Devices break ;; "Get NativeDisplayBrightness") NDBrightness break ;; "Get SSDTTime") SSDTTime break ;; "Get USBMap") USBMap break ;; "Get QtiASL") QtiASL break ;; "Get CsrDecode") CsrDecode break ;; "Get gibMacOS") gibMacOS break ;; "back to main") menu break ;; *) echo "invalid option $REPLY" break ;; esac done Utilities } menu() { echo echo -e $COL_GREEN"-----------------------------------------------------------"$COL_RESET cd "${CLOVERROOT}" local lsha1="not a git repo" if [[ -d .git ]]; then lsha1=$(git rev-parse --short HEAD) fi echo -e " 🍀$COL_GREEN Clover r$(git describe --tags $(git rev-list --tags --max-count=1))$COL_WHITE (SHA: $lsha1)"$COL_RESET echo -e "$COL_CYAN TOOLCHAIN: $MYTOOLCHAIN (override example: './buildme XCODE8')" echo -e $COL_GREEN"-----------------------------------------------------------"$COL_RESET echo PS3=' Please enter your choice: ' options=( 'build Clover' 'build Clover with HFSPlus' 'make pkg' 'make app' 'make app (with Clover)' 'make iso' 'build all' 'test build (no autogen, no boot files)' 'status' 'update Clover' 'show diff' 'open CloverV2/EFI/CLOVER directory' 'update Clover (reset changes)' 'clean BaseTools' 'Utilities' 'quit') select opt in "${options[@]}" do case $opt in "build Clover") buildClover break ;; "build Clover with HFSPlus") buildCloverHFSPlus break ;; "make pkg") buildCCPV BLC buildPkg break ;; "make app") buildApp break ;; "make app (with Clover)") buildApp withV2 break ;; "make iso") buildIso break ;; "build all") buildCCPV BLC buildClover buildPkg buildIso buildApp break ;; "test build (no autogen, no boot files)") buildCloverTest break ;; "update Clover") updateClover break ;; "update Clover (reset changes)") read -p "Are you sure? (type y to confirm or any other to negate) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then updateResetClover fi break ;; "status") checkStatus break ;; "show diff") showdiff break ;; "open CloverV2/EFI/CLOVER directory") if [[ -d "${CLOVERROOT}"/CloverPackage/CloverV2/EFI/CLOVER ]]; then open "${CLOVERROOT}"/CloverPackage/CloverV2/EFI/CLOVER else echo && echo "Directory not found. Compile Clover first!!" sleep 2 fi break ;; "clean BaseTools") read -p "Are you sure? (type y to confirm or any other to negate) " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then cleanBaseTools fi break ;; "Utilities") Utilities break ;; "quit") exit 0 ;; *) echo "invalid option $REPLY" break ;; esac done menu } # Main set -e if [[ "$2" == ci ]]; then buildClover buildPkg buildIso buildApp buildCPV else menu fi