#!/bin/bash # created by vector sigma on July 15 2019 # 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 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 } 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 } menu() { echo echo '------------------------------------------------------------------------' cd "${CLOVERROOT}" local lsha1="not a git repo" if [[ -d .git ]]; then lsha1=$(git rev-parse --short HEAD) fi echo "buildme, Clover r$(git describe --tags $(git rev-list --tags --max-count=1)) (SHA: $lsha1)" echo "TOOLCHAIN: $MYTOOLCHAIN (override example: './buildme XCODE8')" 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' 'quit') select opt in "${options[@]}" do case $opt in "build Clover") buildClover break ;; "build Clover with HFSPlus") buildCloverHFSPlus break ;; "make pkg") buildPkg break ;; "make app") buildApp break ;; "make app (with Clover)") buildApp withV2 break ;; "make iso") buildIso break ;; "build all") 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 ;; "quit") exit 0 ;; *) echo "invalid option $REPLY" break ;; esac done menu } # Main set -e if [[ "$2" == ci ]]; then buildClover buildPkg buildIso buildApp else menu fi