#!/bin/bash -x BUILD_ROOT="$(pwd)" ROOT_LOG_FOLDER="$BUILD_ROOT/Logs" VERIFY="true" PLATFORM="AppleTVOS" PLATFORM_LOWER="appletvos" SDK_VERSION="$(xcrun --show-sdk-version --sdk $PLATFORM_LOWER)" ROOT_PREFIX="fs/jb/usr" SKEL_PREFIX="$BUILD_ROOT/skel" ALREADY_BUILT="$BUILD_ROOT/tracked" CLANG_PATH="$(xcrun -f clang)" CLANGPLUS_PATH="$(xcrun -f clang++)" MIN_VERSION="-mappletvos-version-min=13.0" ARCH="arm64" SDK_PATH="$(xcrun --sdk $PLATFORM_LOWER --show-sdk-path)" SPEAK="false" EXTRA_LD_FLAGS="" HOST="aarch64" FORCE="false" LOG_VERBOSE="" OPEN_LOG="false" usage() { echo "usage: $0 [-s|--speak-updates] [-i|--insecure] [-v|--verbose] [-f|--force] [-o|--open-active-log]" trap - INT TERM EXIT exit 0 } while test $# -gt 0; do case "$1" in -h|--help) usage ;; -v|--verbose) LOG_VERBOSE="verbose" shift ;; -i|--insecure|--no-verify) VERIFY="false" echo "Working without verifying packages..." echo "YOU BETTER KNOW WHAT YOU'RE DOING" sleep 2 #Give them a couple seconds to think about what they're about to do shift ;; -f|--force) shift FORCE="true" shift ;; -s|--speak-updates|--speak) shift SPEAK="true" shift ;; -o|--open-log|--open) shift OPEN_LOG="true" shift ;; *) break ;; esac done printPreprocessor() { $(xcrun --sdk $PLATFORM_LOWER --find clang) -E - - -dM < /dev/null } sayIfVerbal() { if [[ $SPEAK == "true" ]]; then say $1 fi } splitName() { IN=$1 i=0 while [ "$IN" != "$iter" ] ;do # extract the substring from start of string up to delimiter. iter=${IN%%-*} # delete this first "element" AND next separator, from $IN. IN="${IN#$iter-}" ((i=i+1)) if [[ $i == 1 ]]; then echo "set RAW_NAME var to $iter" RAW_NAME=$iter elif [[ $i == 2 ]]; then VERSION=$iter echo "set VERSION var to $iter" fi #echo $iter at $i done } spinner() { local pid=$! local delay=0.75 local spinstr='|/-\' while [ "$(ps a | awk '{print $1}' | grep $pid)" ]; do local temp=${spinstr#?} printf " [%c]" "$spinstr" local spinstr=$temp${spinstr%"$temp"} sleep $delay printf "\b\b\b\b\b" done wait $pid return $? } setBuilt() { DIRECTORY_NAME=$1 FULL=$ALREADY_BUILT/$DIRECTORY_NAME touch "$FULL" } checkStatus() { PKG=$1 STATUS=$2 FINISHED=$3 if [[ $STATUS != 0 ]]; then echo "configure or make $PKG returned with non zero: $STATUS check $LOG_FILE for errors!" sayIfVerbal "configure or make of $PKG returned with non zero: $STATUS" open $LOG_FILE printPreprocessor exit $STATUS else #echo "make returned with zero" if [[ $FINISHED == "true" ]]; then setBuilt $PKG fi fi } checkBuilt() { if [[ "$FORCE" == "true" ]]; then return 0 fi DIRECTORY_NAME=$1 FULL=$ALREADY_BUILT/$DIRECTORY_NAME if [[ ! -f $FULL ]]; then return 0 fi return 1 } notifyProgress() { echo "$1" sayIfVerbal "$1" } checkSHA256() { if [[ "$VERIFY" == "true" ]]; then FILE="$1" VALID_SHA="$2" VERIFY_TEST="`shasum -a 256 $FILE | cut -c 1-64`" if [[ "$VERIFY_TEST" != "$VALID_SHA" ]]; then echo "Failed to validate SHA256 signature for $FILE" trap - INT TERM EXIT exit 127 fi echo "*** VALID SIGNATURE" fi } checkPGPSig() { if [[ "$VERIFY" == "true" ]]; then SIGFILE="$1" FILE="$2" local VERIFY_TEST="`gpg --verify $SIGFILE $FILE 2>&1 | grep 'Good signature'`" if [[ "$VERIFY_TEST" == "" ]]; then echo "Failed to validate PGP signature for $FILE" trap - INT TERM EXIT exit 127 fi echo "*** VALID SIGNATURE" fi } buildProduct() { PKG_NAME=$1 EXTRA_CFG=$2 LOG_FILE="$ROOT_LOG_FOLDER/$PKG_NAME.log" touch $LOG_FILE echo $PKG_NAME echo "build output going to: " $LOG_FILE echo $EXTRA_CFG export SDKROOT=$(xcrun --sdk $PLATFORM_LOWER --show-sdk-path) export VER_MIN=13.0 export CC=$(xcrun --sdk $PLATFORM_LOWER --find clang) export CXX=$(xcrun --sdk $PLATFORM_LOWER --find clang++) export LD=$(xcrun --sdk $PLATFORM_LOWER --find ld) export AR=$(xcrun --sdk $PLATFORM_LOWER --find ar) export CPP="$(xcrun --sdk $PLATFORM_LOWER -f clang) -E -D__arm__ -D__arm64__ -I$SKEL_PREFIX/$ROOT_PREFIX/include/ -I$SDKROOT/usr/include -arch arm64" export CXXCPP="$(xcrun --sdk $PLATFORM_LOWER -f clang++) -E -D__arm__ -D__arm64__ -I$SKEL_PREFIX/$ROOT_PREFIX/include/ -I$SDKROOT/usr/include -arch arm64" export RANLIB=$(xcrun --sdk $PLATFORM_LOWER --find ranlib) export LIBTOOL=$(xcrun --sdk $PLATFORM_LOWER --find libtool) export STRIP=$(xcrun --sdk $PLATFORM_LOWER --find strip) export CFLAGS="-arch arm64 -isysroot $SDKROOT -m$PLATFORM_LOWER-version-min=$VER_MIN -I$SKEL_PREFIX/$ROOT_PREFIX/include/ -DARM -DARM64 -D__arm64__ -Wno-unused-command-line-argument" export CXXFLAGS=$CFLAGS export LDFLAGS="-arch arm64 -isysroot $SDKROOT -L$SKEL_PREFIX/$ROOT_PREFIX/lib/ $EXTRA_LD_FLAGS" notifyProgress "configuring $PKG_NAME" if [[ $LOG_VERBOSE == "verbose"* ]]; then ./configure --prefix=/$ROOT_PREFIX --host=$HOST-apple-darwin --target=$HOST-apple-darwin --disable-dependency-tracking --without-manpages --disable-tests $EXTRA_CFG | tee "${LOG_FILE}" EC=$(grep "configure: error:" -i "${LOG_FILE}" -c) checkStatus $PKG_NAME $EC "false" else (./configure --prefix=/$ROOT_PREFIX --host=$HOST-apple-darwin --target=$HOST-apple-darwin --disable-dependency-tracking --without-manpages --disable-tests $EXTRA_CFG > "${LOG_FILE}" 2>&1) checkStatus $PKG_NAME $? "false" if [[ $OPEN_LOG == "true" ]]; then open "${LOG_FILE}" fi fi notifyProgress "making $PKG_NAME" echo -e "\n\nPOST CONFIGURE\n\n" >> "$LOG_FILE" if [[ $LOG_VERBOSE == "verbose"* ]]; then make -j8 DESTDIR="$SKEL_PREFIX" install | tee -a "${LOG_FILE}" EC=$(grep "fatal error:" -i "${LOG_FILE}" -c) checkStatus $PKG_NAME $EC "true" else (make -j8 DESTDIR="$SKEL_PREFIX" install >> "${LOG_FILE}" 2>&1) #& spinner checkStatus $PKG_NAME $? "true" fi cd "$BUILD_ROOT" } downloadProduct() { cd "$BUILD_ROOT" DOWNLOAD_LINK=$1 FILENAME=$(basename $DOWNLOAD_LINK) SIG_DOWNLOAD=$2 RAW_NAME=$3 VERSION=$4 FILE_EXTENSION="${FILENAME##*.}" DIRECTORY_NAME="$RAW_NAME-$VERSION" SIG_FILE=$(basename $SIG_DOWNLOAD) if [[ ! -e $FILENAME ]]; then echo "Downloading $FILENAME" curl -LO $DOWNLOAD_LINK if [[ ! $SIG_FILE == "-" ]]; then curl -LO $SIG_DOWNLOAD checkPGPSig $SIG_FILE $FILENAME fi else echo "Using existing $FILENAME" fi rm -rf $DIRECTORY_NAME if [[ $FILE_EXTENSION == "gz" ]]; then echo "is gz file!" tar xzvf $FILENAME fi if [[ $FILE_EXTENSION == "xz" ]]; then echo "is lzma file!" tar xJvf $FILENAME fi if [[ $FILE_EXTENSION == "bz2" ]]; then echo "is bzip2 file!" tar xjvf $FILENAME fi WORKING_DIR=$DIRECTORY_NAME PKG_VERSION=$VERSION-1 cd "$WORKING_DIR" #buildProduct } patchBash() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- 's|^#undef HAVE_SYS_SIGLIST$|#define HAVE_SYS_SIGLIST 1|' config.h.in fi } patchDpkg() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- "s|#define ARCHITECTURE \"darwin-arm\"|#define ARCHITECTURE \"$PLATFORM_LOWER-$ARCH\"|" config.h sed -i -- 's|gtar|tar|' config.h fi } # DONT USE UNLESS YOU ARE ON 11+; OVERWRITE BASH (or any other apple-signed file, for that matter), LEAD TO BRICK # 10.2 and up buildBashAndFriends() { notifyProgress "Building readline" buildReadline notifyProgress "Building ncurses" buildNcurses notifyProgress "Building bash" buildBash } buildReadline() { PKG_NAME="readline-7.0" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct http://gnu.askapache.com/readline/readline-7.0.tar.gz http://gnu.askapache.com/readline/readline-7.0.tar.gz.sig $RAW_NAME $VERSION buildProduct $PKG_NAME fi } fixSystem() { FILE="$1" echo '#define PROC_PIDPATHINFO_MAXSIZE (1024)' >> "$FILE" echo 'static int file_exist(const char *filename) {' >> "$FILE" echo ' struct stat buffer;' >> "$FILE" echo ' int r = stat(filename, &buffer);' >> "$FILE" echo ' return (r == 0);' >> "$FILE" echo '}' >> "$FILE" echo '' >> "$FILE" echo 'static char *searchpath(const char *binaryname){' >> "$FILE" echo ' if (strstr(binaryname, "/") != NULL){' >> "$FILE" echo ' if (file_exist(binaryname)){' >> "$FILE" echo ' char *foundpath = malloc((strlen(binaryname) + 1) * (sizeof(char)));' >> "$FILE" echo ' strcpy(foundpath, binaryname);' >> "$FILE" echo ' return foundpath;' >> "$FILE" echo ' } else {' >> "$FILE" echo ' return NULL;' >> "$FILE" echo ' }' >> "$FILE" echo ' }' >> "$FILE" echo ' ' >> "$FILE" echo ' char *pathvar = getenv("PATH");' >> "$FILE" echo ' ' >> "$FILE" echo ' char *dir = strtok(pathvar,":");' >> "$FILE" echo ' while (dir != NULL){' >> "$FILE" echo ' char searchpth[PROC_PIDPATHINFO_MAXSIZE];' >> "$FILE" echo ' strcpy(searchpth, dir);' >> "$FILE" echo ' strcat(searchpth, "/");' >> "$FILE" echo ' strcat(searchpth, binaryname);' >> "$FILE" echo ' ' >> "$FILE" echo ' if (file_exist(searchpth)){' >> "$FILE" echo ' char *foundpath = malloc((strlen(searchpth) + 1) * (sizeof(char)));' >> "$FILE" echo ' strcpy(foundpath, searchpth);' >> "$FILE" echo ' return foundpath;' >> "$FILE" echo ' }' >> "$FILE" echo ' ' >> "$FILE" echo ' dir = strtok(NULL, ":");' >> "$FILE" echo ' }' >> "$FILE" echo ' return NULL;' >> "$FILE" echo '}' >> "$FILE" echo '' >> "$FILE" echo 'static int isShellScript(const char *path){' >> "$FILE" echo ' FILE *file = fopen(path, "r");' >> "$FILE" echo ' uint8_t header[2];' >> "$FILE" echo ' if (fread(header, sizeof(uint8_t), 2, file) == 2){' >> "$FILE" echo " if (header[0] == '#' && header[1] == '!'){" >> "$FILE" echo ' fclose(file);' >> "$FILE" echo ' return 1;' >> "$FILE" echo ' }' >> "$FILE" echo ' }' >> "$FILE" echo ' fclose(file);' >> "$FILE" echo ' return -1;' >> "$FILE" echo '}' >> "$FILE" echo '' >> "$FILE" echo 'static char *getInterpreter(char *path){' >> "$FILE" echo ' FILE *file = fopen(path, "r");' >> "$FILE" echo ' char *interpreterLine = NULL;' >> "$FILE" echo ' unsigned long lineSize = 0;' >> "$FILE" echo ' getline(&interpreterLine, &lineSize, file);' >> "$FILE" echo ' ' >> "$FILE" echo ' char *rawInterpreter = (interpreterLine+2);' >> "$FILE" echo ' rawInterpreter = strtok(rawInterpreter, " ");' >> "$FILE" echo ' rawInterpreter = strtok(rawInterpreter, "\n");' >> "$FILE" echo ' ' >> "$FILE" echo ' char *interpreter = malloc((strlen(rawInterpreter)+1) * sizeof(char));' >> "$FILE" echo ' strcpy(interpreter, rawInterpreter);' >> "$FILE" echo ' ' >> "$FILE" echo ' free(interpreterLine);' >> "$FILE" echo ' fclose(file);' >> "$FILE" echo ' return interpreter;' >> "$FILE" echo '}' >> "$FILE" echo '' >> "$FILE" echo 'static char *fixedCmd(const char *cmdStr){' >> "$FILE" echo ' char *cmdCpy = malloc((strlen(cmdStr)+1) * sizeof(char));' >> "$FILE" echo ' strcpy(cmdCpy, cmdStr);' >> "$FILE" echo ' ' >> "$FILE" echo ' char *cmd = strtok(cmdCpy, " ");' >> "$FILE" echo ' ' >> "$FILE" echo ' uint8_t size = strlen(cmd) + 1;' >> "$FILE" echo ' ' >> "$FILE" echo ' char *args = cmdCpy + size;' >> "$FILE" echo ' if ((strlen(cmdStr) - strlen(cmd)) == 0)' >> "$FILE" echo ' args = NULL;' >> "$FILE" echo ' ' >> "$FILE" echo ' char *abs_path = searchpath(cmd);' >> "$FILE" echo ' if (abs_path){' >> "$FILE" echo ' int isScript = isShellScript(abs_path);' >> "$FILE" echo ' if (isScript == 1){' >> "$FILE" echo ' char *interpreter = getInterpreter(abs_path);' >> "$FILE" echo ' ' >> "$FILE" echo ' uint8_t commandSize = strlen(interpreter) + 1 + strlen(abs_path);' >> "$FILE" echo ' ' >> "$FILE" echo ' if (args){' >> "$FILE" echo ' commandSize += 1 + strlen(args);' >> "$FILE" echo ' }' >> "$FILE" echo ' ' >> "$FILE" echo ' char *rawCommand = malloc(sizeof(char) * (commandSize + 1));' >> "$FILE" echo ' strcpy(rawCommand, interpreter);' >> "$FILE" echo ' strcat(rawCommand, " ");' >> "$FILE" echo ' strcat(rawCommand, abs_path);' >> "$FILE" echo ' ' >> "$FILE" echo ' if (args){' >> "$FILE" echo ' strcat(rawCommand, " ");' >> "$FILE" echo ' strcat(rawCommand, args);' >> "$FILE" echo ' }' >> "$FILE" echo ' rawCommand[(commandSize)+1] = "\0";' >> "$FILE" echo ' ' >> "$FILE" echo ' free(interpreter);' >> "$FILE" echo ' free(abs_path);' >> "$FILE" echo ' free(cmdCpy);' >> "$FILE" echo ' ' >> "$FILE" echo ' return rawCommand;' >> "$FILE" echo ' } else {' >> "$FILE" echo ' uint8_t commandSize = strlen(abs_path);' >> "$FILE" echo ' ' >> "$FILE" echo ' if (args){' >> "$FILE" echo ' commandSize += 1 + strlen(args);' >> "$FILE" echo ' }' >> "$FILE" echo ' ' >> "$FILE" echo ' char *rawCommand = malloc(sizeof(char) * (commandSize + 1));' >> "$FILE" echo ' strcat(rawCommand, abs_path);' >> "$FILE" echo ' ' >> "$FILE" echo ' if (args){' >> "$FILE" echo ' strcat(rawCommand, " ");' >> "$FILE" echo ' strcat(rawCommand, args);' >> "$FILE" echo ' }' >> "$FILE" echo ' rawCommand[(commandSize)+1] = "\0";' >> "$FILE" echo ' ' >> "$FILE" echo ' free(abs_path);' >> "$FILE" echo ' free(cmdCpy);' >> "$FILE" echo ' ' >> "$FILE" echo ' return rawCommand;' >> "$FILE" echo ' }' >> "$FILE" echo ' }' >> "$FILE" echo ' return cmdCpy;' >> "$FILE" echo '}' >> "$FILE" echo '' >> "$FILE" echo 'int RunCmd(const char *cmd) {' >> "$FILE" echo ' pid_t pid;' >> "$FILE" echo ' char *rawCmd = fixedCmd(cmd);' >> "$FILE" echo ' char *argv[] = {"sh", "-c", (char*)rawCmd, NULL};' >> "$FILE" echo ' int status;' >> "$FILE" echo ' status = posix_spawn(&pid, "/fs/jb/bin/sh", NULL, NULL, argv, environ);' >> "$FILE" echo ' if (status == 0) {' >> "$FILE" echo ' if (waitpid(pid, &status, 0) == -1) {' >> "$FILE" echo ' perror("waitpid");' >> "$FILE" echo ' }' >> "$FILE" echo ' } else {' >> "$FILE" echo ' printf("posix_spawn: %s\n", strerror(status));' >> "$FILE" echo ' }' >> "$FILE" echo ' free(rawCmd);' >> "$FILE" echo ' return status;' >> "$FILE" echo '}' >> "$FILE" } patchNcurses() { PKG_NAME=$1 echo "patchNCurses PKG_NAME: $PKG_NAME" if [[ "$PLATFORM" == "AppleTVOS" ]]; then if [[ "$PKG_VERSION" == "6.0-1" ]]; then # LEFT ERROR ON environ)' no ; # For some reason, building never fails on the error... # But still, tput is in /usr/bin... so.... ?? cat progs/tput.c | head -n 55 > tput.patched.c echo "#include " >> tput.patched.c echo "#include " >> tput.patched.c echo "#include " >> tput.patched.c echo "#include " >> tput.patched.c echo "#include " >> tput.patched.c echo "" >> tput.patched.c echo "extern char **environ;" >> tput.patched.c echo "" >> tput.patched.c cat progs/tput.c | tail -n 350 | head -n 50 >> tput.patched.c fixSystem "tput.patched.c" cat progs/tput.c | tail -n 301 | sed 's/system(init_prog)/RunCmd(init_prog)/g' >> tput.patched.c cp tput.patched.c progs/tput.c fi fi #sed -i -- 's|#include |\n#if !defined(__arm64__)\n#define __arm64__\n#endif\n\n#include |' ncurses/build.priv.h # CURSES_PRIV="$SKEL_PREFIX/$ROOT_PREFIX/include/curses.priv.h" # FIFO="$SKEL_PREFIX/$ROOT_PREFIX/include/fifo_defs.h" # BUILD_P="$SKEL_PREFIX/$ROOT_PREFIX/include/build.priv.h" # if [[ ! -f "$CURSES_PRIV" ]]; then # cp $BUILD_ROOT/$1/ncurses/*.h "$SKEL_PREFIX/$ROOT_PREFIX/include/" #cp "$BUILD_ROOT/$1/ncurses/fifo_defs.h" "$FIFO" #cp "$BUILD_ROOT/$1/ncurses/build.priv.h" "$BUILD_P" # fi } #http://gnu.mirror.constant.com/ncurses/ncurses-6.0.tar.gz #https://git.elucubratus.com/elucubratus/elucubratus/-/raw/master/data/ncurses/ncurses_6.1+20181013.orig.tar.gz buildNcurses() { PKG_NAME="ncurses-6.1-20181013" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." #splitName $PKG_NAME downloadProduct https://git.elucubratus.com/elucubratus/elucubratus/-/raw/master/data/ncurses/ncurses_6.1+20181013.orig.tar.gz - ncurses 6.1-20181013 patchNcurses $PKG_NAME export HOST="arm" buildProduct $PKG_NAME export HOST="aarch64" fi } #https://git.elucubratus.com/elucubratus/elucubratus/-/raw/master/data/bash/bash-5.0.tar.gz buildBash() { PKG_NAME="bash-5.0" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct https://git.elucubratus.com/elucubratus/elucubratus/-/raw/master/data/bash/bash-5.0.tar.gz - $RAW_NAME $VERSION patchBash buildProduct $PKG_NAME "--disable-nls --with-installed-readline --disable-largefile bash_cv_dev_fd=absent bash_cv_sys_named_pipes=present bash_cv_job_control_missing=present bash_cv_func_sigsetjmp=present bash_cv_func_ctype_nonascii=no bash_cv_must_reinstall_sighandlers=no bash_cv_func_strcoll_broken=yes ac_cv_c_stack_direction=-1 ac_cv_func_mmap_fixed_mapped=yes gt_cv_int_divbyzero_sigfpe=no ac_cv_func_setvbuf_reversed=no ac_cv_func_strcoll_works=yes ac_cv_func_working_mktime=yes ac_cv_type_getgroups=gid_t bash_cv_dup2_broken=no ac_cv_prog_cc_g=no ac_cv_rl_version=6.0" fi } buildSed() { PKG_NAME="sed-4.4" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct https://ftp.gnu.org/gnu/sed/sed-4.4.tar.xz https://ftp.gnu.org/gnu/sed/sed-4.4.tar.xz.sig $RAW_NAME $VERSION buildProduct $PKG_NAME fi } buildGrep() { PKG_NAME="grep-3.0" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct https://ftp.gnu.org/gnu/grep/grep-3.0.tar.xz https://ftp.gnu.org/gnu/grep/grep-3.0.tar.xz.sig $RAW_NAME $VERSION buildProduct $PKG_NAME fi } patchCoreutils() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- 's|#undef HAVE_CLOCK_GETTIME||' lib/config.hin sed -i -- 's|#undef HAVE_CLOCK_SETTIME||' lib/config.hin sed -i -- 's|#undef HAVE_FDATASYNC||' lib/config.hin sed -i -- 's|# define __stpncpy stpncpy||' lib/stpncpy.c if [[ ! -d "$SKEL_PREFIX/$ROOT_PREFIX/include" ]]; then mkdir -p "$SKEL_PREFIX/$ROOT_PREFIX/include" fi if [[ ! -e "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" ]]; then echo "#include " >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" echo "" >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" echo "__BEGIN_DECLS" >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" echo "extern char ***_NSGetArgv(void);" >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" echo "extern int *_NSGetArgc(void);" >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" echo "extern char ***_NSGetEnviron(void);" >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" echo "extern char **_NSGetProgname(void);" >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" echo "extern struct mach_header *_NSGetMachExecuteHeader(void);" >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" echo "__END_DECLS" >> "$SKEL_PREFIX/$ROOT_PREFIX/include/crt_externs.h" fi fi } buildCoreutils() { PKG_NAME="coreutils-8.9" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct http://gnu.mirror.constant.com/coreutils/coreutils-8.9.tar.xz http://gnu.mirror.constant.com/coreutils/coreutils-8.9.tar.xz.sig $RAW_NAME $VERSION patchCoreutils export HOST="arm" buildProduct $PKG_NAME export HOST="aarch64" fi } buildFindUtils() { PKG_NAME="findutils-4.6.0" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct http://mirror.keystealth.org/gnu/findutils/findutils-4.6.0.tar.gz - $RAW_NAME $VERSION buildProduct $PKG_NAME fi } buildDiffUtils() { PKG_NAME="diffutils-3.6" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct http://ftp.gnu.org/gnu/diffutils/diffutils-3.6.tar.xz http://ftp.gnu.org/gnu/diffutils/diffutils-3.6.tar.xz.sig $RAW_NAME $VERSION buildProduct $PKG_NAME fi } downloadDarwinTools() { if [[ ! -d DarwinToolsARM ]]; then echo "Fetching DarwinTools" mkdir -p DarwinToolsARM cd DarwinToolsARM curl -LO https://opensource.apple.com/source/DarwinTools/DarwinTools-1/sw_vers.c #Not built yet curl -LO https://opensource.apple.com/source/launchd/launchd-842.92.1/support/launchctl.c #sw_vers.c checkSHA256 sw_vers.c 55aab510b465f7687b8ebe23f0e51926606fd5316da138778838b2dac3e7c7e0 else echo "Using existing DarwinTools" cd DarwinToolsARM fi WORKING_DIR="DarwinToolsARM" PKG_NAME="darwintools" PKG_VERSION="1.0-1" } patchDarwinTools() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- 's|#include |extern CFDictionaryRef _CFCopySystemVersionDictionary(void);\ extern CFDictionaryRef _CFCopyServerVersionDictionary(void);|' sw_vers.c sed -i -- 's|_kCFSystemVersionProductNameKey|CFSTR(\"ProductName\")|g' sw_vers.c sed -i -- 's|_kCFSystemVersionProductVersionKey|CFSTR(\"ProductVersion\")|g' sw_vers.c sed -i -- 's|_kCFSystemVersionBuildVersionKey|CFSTR(\"ProductBuildVersion\")|g' sw_vers.c fi } #darwintools #Notes: # This only builds a striped down version of the one on iOS # If you're building for a non-appletv platform, you may need to fix things here. buildDarwinTools() { downloadDarwinTools patchDarwinTools "$CLANG_PATH" -arch "$ARCH" -isysroot"$SDK_PATH" -framework CoreFoundation "$MIN_VERSION" -o "sw_vers" sw_vers.c #codesign "$BUILD_ROOT/$WORKING_DIR/sw_vers" cp sw_vers "$SKEL_PREFIX/$ROOT_PREFIX/bin/" cd "$BUILD_ROOT" } #Download uikittools downloadUIKitTools() { if [[ ! -d uikittools ]]; then echo "Fetching uikittools" git clone git://git.saurik.com/uikittools.git else echo "Using existing uikittools" fi WORKING_DIR="uikittools" PKG_NAME="uikittools" PKG_VERSION="1.1.12-1" cd "$WORKING_DIR" git checkout tags/v1.1.12 } #uikittools #Notes: # This only builds a striped down version of the one on iOS # If you're building for a non-appletv platform, you may need to fix things here. buildUIKitTools() { downloadUIKitTools "$CLANGPLUS_PATH" -arch "$ARCH" -isysroot"$SDK_PATH" -Os -Werror -framework CoreFoundation -framework Foundation "$MIN_VERSION" -o cfversion cfversion.mm "$CLANGPLUS_PATH" -arch "$ARCH" -isysroot"$SDK_PATH" -Os -Werror -framework CoreFoundation -framework Foundation "$MIN_VERSION" -o gssc gssc.mm "$CLANGPLUS_PATH" -arch "$ARCH" -isysroot"$SDK_PATH" -Os -Werror -framework CoreFoundation -framework Foundation -framework UIKit "$MIN_VERSION" -o uiduid uiduid.mm #odesign "$BUILD_ROOT/$WORKING_DIR/cfversion" #codesign "$BUILD_ROOT/$WORKING_DIR/gssc" #codesign "$BUILD_ROOT/$WORKING_DIR/uiduid" cp gssc cfversion uiduid "$SKEL_PREFIX/$ROOT_PREFIX/bin/" cd "$BUILD_ROOT" } buildBasicUtils() { notifyProgress "Building sed" buildSed notifyProgress "Building grep" buildGrep notifyProgress "Building coreutils" buildCoreutils notifyProgress "Building findutils" buildFindUtils notifyProgress "Building diffutils" buildDiffUtils notifyProgress "Building DarwinTools" buildDarwinTools notifyProgress "Building UIKitTools" buildUIKitTools } mkdirIfNecessary() { MK_DIR="$1" if [[ ! -d $MK_DIR ]]; then mkdir -p $MK_DIR fi } removeIfNecessary() { REMOVE_FILE="$1" if [[ -f $REMOVE_FILE ]]; then rm -rf $REMOVE_FILE fi } #===================== #DPKG and Dependencies #--------------------- #Download zlib downloadZLib() { #Download zlib if [[ ! -d zlib ]]; then echo "Downloading zlib git" git clone https://github.com/madler/zlib.git else echo "Using existing zlib" fi WORKING_DIR="zlib" PKG_NAME="zlib" PKG_VERSION="1.2.11-1" cd "$WORKING_DIR" git checkout tags/v1.2.11 removeIfNecessary build mkdirIfNecessary build cd build WORKING_DIR="$WORKING_DIR/build" } #zlib buildZLib() { PKG_NAME="lzib-1.2.11" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else downloadZLib cmake -DCMAKE_INSTALL_NAME_DIR="/$ROOT_PREFIX/lib" -DCMAKE_OSX_SYSROOT="$SDK_PATH/" -DCMAKE_C_FLAGS="-arch $ARCH" -DCMAKE_INSTALL_PREFIX="/$ROOT_PREFIX" .. checkStatus $PKG_NAME $? "false" make -j8 DESTDIR="$SKEL_PREFIX" install checkStatus $PKG_NAME $? "true" cd "$BUILD_ROOT" fi } patchXZ() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- 's|#undef HAVE_CLOCK_GETTIME||' config.h.in fi } patchTar() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- 's|#undef HAVE_CLOCK_GETTIME||' config.h.in fi } patchOpenSSL() { sed -i -- "s|-arch $ARCH -mios-version-min=7.0.0|-arch $ARCH $MIN_VERSION|" Configurations/10-main.conf } patchBZip2() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then #fix up our makefile... sed -i -- 's|CC=gcc|CC=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang|' Makefile sed -i -- 's|AR=ar|AR=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ar|' Makefile sed -i -- 's|RANLIB=ranlib|RANLIB=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ranlib|' Makefile sed -i -- "s|LDFLAGS=|LDFLAGS=$MIN_VERSION -isysroot \"$SDK_PATH\" -arch $ARCH|" Makefile sed -i -- "s|CFLAGS=|CFLAGS=$MIN_VERSION -isysroot \"$SDK_PATH\" -arch $ARCH |" Makefile sed -i -- 's|all:\(.*\) test$|all: \1|' Makefile sed -i -- 's|ln -s -f \$(PREFIX)/bin/|ln -s -f |g' Makefile fi } patchCurl() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then #(Forcibly) Remove that dirty clock_gettime #TODO: Determine if this is the best way sed -i -- 's|#undef HAVE_CLOCK_GETTIME_MONOTONIC||' lib/curl_config.h.in fi } buildXZ() { PKG_NAME="xz-5.2.3" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct http://tukaani.org/xz/xz-5.2.3.tar.gz http://tukaani.org/xz/xz-5.2.3.tar.gz.sig $RAW_NAME $VERSION patchXZ buildProduct $PKG_NAME fi } buildBZip2() { PKG_NAME="bzip2-1.0.6" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct https://gigenet.dl.sourceforge.net/project/bzip2/bzip2-1.0.6.tar.gz - $RAW_NAME $VERSION patchBZip2 make -j8 install PREFIX="$SKEL_PREFIX/$ROOT_PREFIX" checkStatus $PKG_NAME $? "true" cd "$BUILD_ROOT" fi } buildLZ4() { PKG_NAME="lz4-1.7.5" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct https://github.com/lz4/lz4/archive/v1.7.5.tar.gz - $RAW_NAME $VERSION cd contrib/cmake_unofficial/ mkdirIfNecessary build cd build cmake -DCMAKE_INSTALL_NAME_DIR="/$ROOT_PREFIX/lib" -DCMAKE_OSX_SYSROOT="$SDK_PATH/" -DCMAKE_C_FLAGS="-arch $ARCH" -DCMAKE_INSTALL_PREFIX="/$ROOT_PREFIX" .. checkStatus $PKG_NAME $? "false" make -j8 make -j8 DESTDIR="$SKEL_PREFIX" install checkStatus $PKG_NAME $? "true" cd "$BUILD_ROOT" fi } downloadOpenSSL() { if [[ ! -d openssl ]]; then git clone -b OpenSSL_1_1_0-stable https://github.com/openssl/openssl.git else echo "Using existing openssl repo" fi WORKING_DIR="openssl" PKG_NAME="openssl" PKG_VERSION="1.1.0-1" cd "$WORKING_DIR" } buildOpenSSL() { PKG_NAME="openssl" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else LOG_FILE="$ROOT_LOG_FOLDER/openssl.log" touch $LOG_FILE downloadOpenSSL patchOpenSSL export AR="" export PLATFORM="$PLATFORM" export BUILD_TOOLS="$(xcode-select --print-path)" export CC="clang -fembed-bitcode" export CROSS_COMPILE="$(xcode-select --print-path)/Toolchains/XcodeDefault.xctoolchain/usr/bin/" export CROSS_TOP="$(xcode-select --print-path)/Platforms/$PLATFORM.platform/Developer" export CROSS_SDK="$(echo $SDK_PATH | sed 's/.*\///g')" notifyProgress "Configuring openSSL" if [[ $LOG_VERBOSE == "verbose"* ]]; then ./Configure ios64-cross no-dso no-hw no-engine --prefix="/$ROOT_PREFIX" | tee "${LOG_FILE}" EC=$(grep "configure: error:" -i "${LOG_FILE}" -c) checkStatus $PKG_NAME $EC "false" else (./Configure ios64-cross no-dso no-hw no-engine --prefix="/$ROOT_PREFIX" > "$LOG_FILE" 2>&1) checkStatus $PKG_NAME $? "false" if [[ $OPEN_LOG == "true" ]]; then open "${LOG_FILE}" fi fi echo -e "\n\nPOST CONFIGURE\n\n" >> "$LOG_FILE" notifyProgress "making openSSL" if [[ $LOG_VERBOSE == "verbose"* ]]; then make DESTDIR="$SKEL_PREFIX" install | tee -a "${LOG_FILE}" EC=$(grep "fatal error:" -i "${LOG_FILE}" -c) checkStatus $PKG_NAME $EC "true" else (make DESTDIR="$SKEL_PREFIX" install >> "${LOG_FILE}" 2>&1) checkStatus $PKG_NAME $? "true" fi cd "$BUILD_ROOT" fi } buildCurl() { PKG_NAME="curl-7.50.1" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct https://curl.haxx.se/download/curl-7.50.1.tar.gz - $RAW_NAME $VERSION patchCurl buildProduct $PKG_NAME fi } patchBerkeleyDB() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- 's|#undef HAVE_CLOCK_GETTIME||' ../dist/config.hin #if [[ "$PKG_VERSION" == "6.2.23-1" ]]; then cat ../lang/sql/sqlite/src/shell.c | head -n 14 > shell.patched.c echo "#include " >> shell.patched.c echo "#include " >> shell.patched.c echo "#include " >> shell.patched.c echo "#include " >> shell.patched.c echo "#include " >> shell.patched.c echo "#include " >> shell.patched.c echo "" >> shell.patched.c echo "extern char **environ;" >> shell.patched.c echo "" >> shell.patched.c cat ../lang/sql/sqlite/src/shell.c | tail -n 4847 | head -n 2622 >> shell.patched.c fixSystem "shell.patched.c" cat ../lang/sql/sqlite/src/shell.c | tail -n 2226 | sed 's/system(zCmd)/RunCmd(zCmd)/g' >> shell.patched.c cp shell.patched.c ../lang/sql/sqlite/src/shell.c #fi fi } buildBerkeleyDB() { PKG_NAME="db-6.2.23" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." LOG_FILE="$ROOT_LOG_FOLDER/$PKG_NAME.log" touch $LOG_FILE splitName $PKG_NAME DOWNLOAD_URL="http://download.oracle.com/berkeley-db/db-6.2.23.tar.gz" downloadProduct $DOWNLOAD_URL - $RAW_NAME $VERSION cd build_unix patchBerkeleyDB export CPP="" export CXXCPP="" export PLATFORM="$PLATFORM" #TODO: Maybe necessary? Need to test. export BUILD_TOOLS="$(xcode-select --print-path)" export CC="clang" export CROSS_COMPILE="$(xcode-select --print-path)/Toolchains/XcodeDefault.xctoolchain/usr/bin/" export CROSS_TOP="$(xcode-select --print-path)/Platforms/$PLATFORM.platform/Developer" export CROSS_SDK="$(echo $SDK_PATH | sed 's/.*\///g')" export CFLAGS="-arch $ARCH -pipe -Os -gdwarf-2 -isysroot $SDK_PATH $MIN_VERSION" export CXXFLAGS="-arch $ARCH -pipe -Os -gdwarf-2 -isysroot $SDK_PATH $MIN_VERSION" export LDFLAGS="-arch $ARCH -isysroot $SDK_PATH" # -L${SKEL_PREFIX}/lib" #buildProduct $PKG_NAME if [[ $LOG_VERBOSE == "verbose"* ]]; then ../dist/configure --disable-debug --disable-test --disable-atomicsupport --enable-cxx--enable-compact185 --enable-sql --enable-sql_codegen --enable-dbm --enable-slt --disable-java --host=arm-apple-darwin --prefix="/$ROOT_PREFIX" | tee "${LOG_FILE}" else (../dist/configure --disable-debug --disable-test --disable-atomicsupport --enable-cxx--enable-compact185 --enable-sql --enable-sql_codegen --enable-dbm --enable-slt --disable-java --host=arm-apple-darwin --prefix="/$ROOT_PREFIX" > "$LOG_FILE" 2>&1) if [[ $OPEN_LOG == "true" ]]; then open "${LOG_FILE}" fi fi checkStatus $PKG_NAME $? "false" if [[ $LOG_VERBOSE == "verbose"* ]]; then make DESTDIR="$SKEL_PREFIX" install | tee "${LOG_FILE}" else (make DESTDIR="$SKEL_PREFIX" install >> "${LOG_FILE}" 2>&1) fi checkStatus $PKG_NAME $? "true" fi } buildTar(){ PKG_NAME="tar-1.33" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct http://ftp.gnu.org/gnu/tar/tar-1.33.tar.xz - $RAW_NAME $VERSION patchTar buildProduct $PKG_NAME fi } #Download dpkg downloadDpkg() { if [[ ! -d dpkg ]]; then echo "Downlading dpkg" git clone https://git.nito.tv/NitoTV/dpkg.git else echo "Using existing dpkg" fi WORKING_DIR="dpkg" PKG_NAME="dpkg" PKG_VERSION="1.18.23-1" #FIXME cd "$WORKING_DIR" } #dpkg buildDpkg() { PKG_NAME="dpkg-1.18.23" LOG_FILE="$ROOT_LOG_FOLDER/$PKG_NAME.log" touch $LOG_FILE checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else downloadDpkg local dont_die_here=$(./autogen.sh) # need to clear these preprocessor flags or they get all wonky export CPP="" export CXXCPP="" export LZMA_LIBS="$SKEL_PREFIX/$ROOT_PREFIX/lib/liblzma.dylib" export CC=$(xcrun --sdk $PLATFORM_LOWER --find clang) export CXX=$(xcrun --sdk $PLATFORM_LOWER --find clang++) export CFLAGS="-isysroot $SDK_PATH -I$SDK_PATH/usr/include -I$SKEL_PREFIX/$ROOT_PREFIX/include/ -arch $ARCH" export CXXFLAGS=$CFLAGS export LDFLAGS="-isysroot $SDK_PATH -L$SKEL_PREFIX/$ROOT_PREFIX/lib/ -arch $ARCH" export CPPFLAGS="-isysroot $SDK_PATH -I$SKEL_PREFIX/$ROOT_PREFIX/include/ -arch $ARCH" export CXXFLAGS=$CFLAGS export LDFLAGS="-isysroot $SDK_PATH -L$SKEL_PREFIX/$ROOT_PREFIX/lib/ -arch $ARCH" if [[ $LOG_VERBOSE == "verbose"* ]]; then ./configure --prefix="/$ROOT_PREFIX" --disable-start-stop-daemon --host=aarch64-apple-darwin --disable-dependency-tracking PERL_LIBDIR='$(prefix)/lib/' --disable-dselect --localstatedir="/var/" --sysconfdir="/fs/jb/etc" | tee "${LOG_FILE}" EC=$(grep "configure: error:" -i "${LOG_FILE}" -c) checkStatus $PKG_NAME $EC "false" else (./configure --prefix="/$ROOT_PREFIX" --disable-start-stop-daemon --host=aarch64-apple-darwin --disable-dependency-tracking PERL_LIBDIR='$(prefix)/lib/' --disable-dselect --localstatedir="/var/" --sysconfdir="/fs/jb/etc" > "${LOG_FILE}" 2>&1) if [[ $OPEN_LOG == "true" ]]; then open "${LOG_FILE}" fi fi checkStatus $PKG_NAME $? "false" patchDpkg #Must be after configure for now. I'll deal with this later if [[ $LOG_VERBOSE == "verbose"* ]]; then make -j8 DESTDIR="$SKEL_PREFIX" install | tee "${LOG_FILE}" EC=$(grep "fatal error:" -i "${LOG_FILE}" -c) checkStatus $PKG_NAME $EC "true" else (make -j8 DESTDIR="$SKEL_PREFIX" install >> "${LOG_FILE}" 2>&1) checkStatus $PKG_NAME $? "true" fi #lzma conflicts with built in libraries when running in certian conditions. #we make -j8 a symlink our version of lzma in the xz build process #here we change dpkg-deb to look for this version instead #if we do not do this, apt-get/dpkg* will fail from our setuid tool install_name_tool -change /usr/lib/liblzma.5.dylib /usr/local/lib/liblzma.5.dylib "$SKEL_PREFIX/$ROOT_PREFIX/bin/dpkg-deb" echo "appletvos-arm64" >> "$BUILD_ROOT/dpkg/deb/var/lib/dpkg/arch" echo "darwin-arm64" >> "$BUILD_ROOT/dpkg/deb/var/lib/dpkg/arch" #Get rid of cross-compile artifacts sed -i -- "s|$SKEL_PREFIX||g" "$BUILD_ROOT/$WORKING_DIR/deb/$ROOT_PREFIX/lib/libdpkg.la" sed -i -- "s|$SKEL_PREFIX||g" "$BUILD_ROOT/$WORKING_DIR/deb/$ROOT_PREFIX/lib/pkgconfig/libdpkg.pc" rm -rf "$BUILD_ROOT/$WORKING_DIR/deb/$ROOT_PREFIX/lib/libdpkg.la--" rm -rf "$BUILD_ROOT/$WORKING_DIR/deb/$ROOT_PREFIX/lib/pkgconfig/libdpkg.pc--" cd "$BUILD_ROOT" fi } buildDPKGAndDependencies() { notifyProgress "Building zlib" buildZLib notifyProgress "Building xz" buildXZ notifyProgress "Building bzip2" buildBZip2 notifyProgress "Building lz4" buildLZ4 notifyProgress "Building openSSL" buildOpenSSL notifyProgress "Building curl" buildCurl notifyProgress "Building BerkeleyDB" buildBerkeleyDB notifyProgress "Building tar" buildTar notifyProgress "Building dpkg" buildDpkg } buildGpgError() { PKG_NAME="libgpg-error-1.32" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." #splitName $PKG_NAME DOWNLOAD_URL="https://www.gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-1.32.tar.bz2" downloadProduct $DOWNLOAD_URL $DOWNLOAD_URL.sig libgpg-error 1.32 #sed -i -- 's|#include |\n#if !defined(__arm64__)\n#define __arm64__\n#endif\n\n#include |' ncurses/build.priv.h #echo -e "\n#if !defined(__arm64__)\n#define __arm64__\n#endif\n\n" >> config.h.in #export HOST="arm" buildProduct $PKG_NAME "--enable-threads=posix" #export HOST="aarch64" fi } patchGcrypt() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then #if [[ "$PKG_VERSION" == "1.8.2-1" ]]; then cat tests/random.c | head -n 39 > random.patched.c echo "#include " >> random.patched.c echo "#include " >> random.patched.c echo "#include " >> random.patched.c echo "#include " >> random.patched.c echo "#include " >> random.patched.c echo "#include " >> random.patched.c echo "" >> random.patched.c echo "extern char **environ;" >> random.patched.c echo "" >> random.patched.c fixSystem "random.patched.c" cat tests/random.c | tail -n 727 | sed 's/system (cmdline)/RunCmd(cmdline)/g' >> random.patched.c cp random.patched.c tests/random.c #fi fi } buildGcrypt() { PKG_NAME="libgcrypt-1.8.2" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME downloadProduct https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.8.2.tar.bz2 https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-1.8.2.tar.bz2.sig $RAW_NAME $VERSION patchGcrypt export HOST="arm" buildProduct $PKG_NAME "--with-libgpg-error-prefix=$SKEL_PREFIX/$ROOT_PREFIX/" export HOST="aarch64" fi } patchKSBA() { sed -i -- 's|#include |#include \n#include "ksba.h"\n|' src/asn1-gentables.c sed -i -- "s|$(CC_FOR_BUILD) -I$(srcdir)|$(CC_FOR_BUILD) -I$(srcdir) -I$SKEL_PREFIX/$ROOT_PREFIX/include/|" src/Makefile.in sed -i -- 's|const char \*gpg_strerror|//const char \*gpg_strerror|' src/gen-help.h } buildKSBA() { PKG_NAME="libksba-1.3.5" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME DOWNLOAD_URL="https://www.gnupg.org/ftp/gcrypt/libksba/libksba-1.3.5.tar.bz2" downloadProduct $DOWNLOAD_URL $DOWNLOAD_URL.sig $RAW_NAME $VERSION patchKSBA buildProduct $PKG_NAME "--with-libgpg-error-prefix=$SKEL_PREFIX/$ROOT_PREFIX/" fi } patchNpth() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- 's|#undef HAVE_CLOCK_GETTIME||' config.h.in #if [[ "$PKG_VERSION" == "1.5-1" ]]; then cat src/npth.c | head -n 19 > npth.patched.c echo "#include " >> npth.patched.c echo "#include " >> npth.patched.c echo "#include " >> npth.patched.c echo "#include " >> npth.patched.c echo "#include " >> npth.patched.c echo "" >> npth.patched.c echo "extern char **environ;" >> npth.patched.c echo "" >> npth.patched.c cat src/npth.c | tail -n 757 | head -n 537 >> npth.patched.c fixSystem "npth.patched.c" cat src/npth.c | tail -n 220 | sed 's/system(cmd)/RunCmd(cmd)/g' >> npth.patched.c cp npth.patched.c src/npth.c #fi fi } buildNpth() { PKG_NAME="npth-1.5" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME DOWNLOAD_URL="https://www.gnupg.org/ftp/gcrypt/npth/npth-1.5.tar.bz2" downloadProduct $DOWNLOAD_URL $DOWNLOAD_URL.sig $RAW_NAME $VERSION patchNpth buildProduct $PKG_NAME fi } #https://www.gnupg.org/ftp/gcrypt/libassuan/libassuan-2.5.1.tar.bz2 buildAssuan() { PKG_NAME="libassuan-2.5.1" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME DOWNLOAD_URL="https://www.gnupg.org/ftp/gcrypt/libassuan/libassuan-2.5.1.tar.bz2" downloadProduct $DOWNLOAD_URL $DOWNLOAD_URL.sig $RAW_NAME $VERSION buildProduct $PKG_NAME "--with-libgpg-error-prefix=$SKEL_PREFIX/$ROOT_PREFIX/" fi } patchNtbtls() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then # this is required because prior dependencies write /$ROOT_PREFIX/lib/libgpg-error.la as a dependency in the .la file sed -i -- "s|/$ROOT_PREFIX/lib/libgpg-error.la|$SKEL_PREFIX/$ROOT_PREFIX/lib/libgpg-error.la|g" "$SKEL_PREFIX/$ROOT_PREFIX/lib/libgcrypt.la" sed -i -- "s|/$ROOT_PREFIX/lib/libgpg-error.la|$SKEL_PREFIX/$ROOT_PREFIX/lib/libgpg-error.la|g" "$SKEL_PREFIX/$ROOT_PREFIX/lib/libksba.la" rm -f "$SKEL_PREFIX/$ROOT_PREFIX/lib/libgcrypt.la--" rm -f "$SKEL_PREFIX/$ROOT_PREFIX/lib/libksba.la--" fi } buildNtbtls() { PKG_NAME="ntbtls-0.1.2" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME DOWNLOAD_URL="https://www.gnupg.org/ftp/gcrypt/ntbtls/ntbtls-0.1.2.tar.bz2" downloadProduct $DOWNLOAD_URL $DOWNLOAD_URL.sig $RAW_NAME $VERSION patchNtbtls buildProduct $PKG_NAME "--with-libgpg-error-prefix=$SKEL_PREFIX/$ROOT_PREFIX/ --with-libgcrypt-prefix=$SKEL_PREFIX/$ROOT_PREFIX --with-ksba-prefix=$SKEL_PREFIX/$ROOT_PREFIX" fi } patchGpg() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then #if [[ "$PKG_VERSION" == "2.2.3-1" ]]; then cat "g10/exec.c" | head -n 54 > "exec.patched.c" echo "#include " >> "exec.patched.c" echo "#include " >> "exec.patched.c" echo "#include " >> "exec.patched.c" echo "#include " >> "exec.patched.c" echo "#include " >> "exec.patched.c" echo "" >> "exec.patched.c" echo "extern char **environ;" >> "exec.patched.c" echo "" >> "exec.patched.c" cat "g10/exec.c" | head -n 111 | tail -n 57 >> "exec.patched.c" fixSystem "exec.patched.c" cat "g10/exec.c" | tail -n 524 | sed 's/=system(info->command)/=RunCmd(info->command)/g' >> "exec.patched.c" cp "exec.patched.c" "g10/exec.c" #fi fi } # buildGpg() { PKG_NAME="gnupg-2.2.3" checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else echo "building $PKG_NAME..." splitName $PKG_NAME DOWNLOAD_URL="https://www.gnupg.org/ftp/gcrypt/gnupg/gnupg-2.2.3.tar.bz2" downloadProduct $DOWNLOAD_URL $DOWNLOAD_URL.sig $RAW_NAME $VERSION patchGpg buildProduct $PKG_NAME "--with-libgpg-error-prefix=$SKEL_PREFIX/$ROOT_PREFIX/ --with-libgcrypt-prefix=$SKEL_PREFIX/$ROOT_PREFIX/ --with-libassuan-prefix=$SKEL_PREFIX/$ROOT_PREFIX/ --with-ksba-prefix=$SKEL_PREFIX/$ROOT_PREFIX/ --with-npth-prefix=$SKEL_PREFIX/$ROOT_PREFIX/ --with-ntbtls-prefix=$SKEL_PREFIX/$ROOT_PREFIX/" fi } patchAPT() { if [[ "$PLATFORM" == "AppleTVOS" ]]; then sed -i -- '/^INCLUDE_DIRECTORIES/d' ../CMakeLists.txt sed -i -- '/^LINK_DIRECTORIES/d' ../CMakeLists.txt cat ../CMakeLists.txt | head -n 15 > newCmakeLists.txt echo "INCLUDE_DIRECTORIES($SKEL_PREFIX/$ROOT_PREFIX/include)" >> newCmakeLists.txt echo "LINK_DIRECTORIES($SKEL_PREFIX/$ROOT_PREFIX/lib)" >> newCmakeLists.txt echo "" >> newCmakeLists.txt cat ../CMakeLists.txt | tail -n 217 >> newCmakeLists.txt mv newCmakeLists.txt ../CmakeLists.txt #sed -i -- "s|/Users/jaywalker/RnD/ATV/packages/test/skel/|$SKEL_PREFIX/|g" ../CMakeLists.txt fi } downloadApt() { if [[ ! -d apt ]]; then echo "Downlading apt" git clone https://git.nito.tv/NitoTV/apt.git else echo "Using existing apt" fi WORKING_DIR="apt" cd "$WORKING_DIR" removeIfNecessary build mkdirIfNecessary build cd build WORKING_DIR="$WORKING_DIR/build" } buildAPT() { PKG_NAME="apt7-0.7.25.3" LOG_FILE="$ROOT_LOG_FOLDER/$PKG_NAME.log" touch $LOG_FILE checkBuilt $PKG_NAME if [[ $? != 0 ]]; then echo "$PKG_NAME already exists, skipping!" else downloadApt patchAPT echo "build output going to: " $LOG_FILE if [[ $LOG_VERBOSE == "verbose"* ]]; then cmake -DCMAKE_LOCALSTATEDIR="/private/var" -DCMAKE_INSTALL_NAME_DIR="/$ROOT_PREFIX/lib" -DCMAKE_INSTALL_RPATH="/$ROOT_PREFIX/" -DCMAKE_OSX_SYSROOT="$SDK_PATH" -DCMAKE_CXX_FLAGS="-arch $ARCH -Wno-unused-parameter -Wno-unused-private-field -Wno-unknown-warning-option -Wno-writable-strings" -DCMAKE_C_FLAGS="-arch $ARCH -Wno-unused-parameter -Wno-unused-private-field -Wno-unknown-warning-option -Wno-writable-strings" -DCMAKE_INSTALL_PREFIX="/$ROOT_PREFIX/" -DCMAKE_SHARED_LINKER_FLAGS="-lresolv -L$SKEL_PREFIX/$ROOT_PREFIX/lib/" -DCURL_INCLUDE_DIR="$SKEL_PREFIX/$ROOT_PREFIX/include" -DCURL_LIBRARIES="$SKEL_PREFIX/$ROOT_PREFIX/lib/libcurl.4.dylib" -DLZ4_INCLUDE_DIRS="$SKEL_PREFIX/$ROOT_PREFIX/include/" -DLZ4_LIBRARIES="$SKEL_PREFIX/$ROOT_PREFIX/lib/liblz4.dylib" -DLZMA_INCLUDE_DIRS="$SKEL_PREFIX/$ROOT_PREFIX/include/" -DLZMA_LIBRARIES="$SKEL_PREFIX/$ROOT_PREFIX/lib/liblzma.dylib" -DCURRENT_VENDOR=debian -DUSE_NLS=0 -DWITH_DOC=0 -DBERKELEY_DB_INCLUDE_DIRS="$SKEL_PREFIX/$ROOT_PREFIX/include" -DBERKELEY_DB_LIBRARIES="$SKEL_PREFIX/$ROOT_PREFIX/lib/libdb.dylib" -DCMAKE_FIND_ROOT_PATH="$SKEL_PREFIX" .. | tee "${LOG_FILE}" #FIXME : need status / error checking here! else (cmake -DCMAKE_LOCALSTATEDIR="/private/var" -DCMAKE_INSTALL_NAME_DIR="/$ROOT_PREFIX/lib" -DCMAKE_INSTALL_RPATH="/$ROOT_PREFIX/" -DCMAKE_OSX_SYSROOT="$SDK_PATH" -DCMAKE_CXX_FLAGS="-arch $ARCH -Wno-unused-parameter -Wno-unused-private-field -Wno-unknown-warning-option -Wno-writable-strings" -DCMAKE_C_FLAGS="-arch $ARCH -Wno-unused-parameter -Wno-unused-private-field -Wno-unknown-warning-option -Wno-writable-strings" -DCMAKE_INSTALL_PREFIX="/$ROOT_PREFIX/" -DCMAKE_SHARED_LINKER_FLAGS="-lresolv -L$SKEL_PREFIX/$ROOT_PREFIX/lib/" -DCURL_INCLUDE_DIR="$SKEL_PREFIX/$ROOT_PREFIX/include" -DCURL_LIBRARIES="$SKEL_PREFIX/$ROOT_PREFIX/lib/libcurl.4.dylib" -DLZ4_INCLUDE_DIRS="$SKEL_PREFIX/$ROOT_PREFIX/include/" -DLZ4_LIBRARIES="$SKEL_PREFIX/$ROOT_PREFIX/lib/liblz4.dylib" -DLZMA_INCLUDE_DIRS="$SKEL_PREFIX/$ROOT_PREFIX/include/" -DLZMA_LIBRARIES="$SKEL_PREFIX/$ROOT_PREFIX/lib/liblzma.dylib" -DCURRENT_VENDOR=debian -DUSE_NLS=0 -DWITH_DOC=0 -DBERKELEY_DB_INCLUDE_DIRS="$SKEL_PREFIX/$ROOT_PREFIX/include" -DBERKELEY_DB_LIBRARIES="$SKEL_PREFIX/$ROOT_PREFIX/lib/libdb.dylib" -DCMAKE_FIND_ROOT_PATH="$SKEL_PREFIX" .. > "${LOG_FILE}" 2>&1) checkStatus $PKG_NAME $? "false" if [[ $OPEN_LOG == "true" ]]; then open "${LOG_FILE}" fi fi sed -i -- "s|#define COMMON_ARCH \"darwin-amd64\"|#define COMMON_ARCH \"$PLATFORM_LOWER-$ARCH\"|" include/config.h if [[ $LOG_VERBOSE == "verbose"* ]]; then make -j8 DESTDIR="$SKEL_PREFIX" install | tee "${LOG_FILE}" EC=$(grep "fatal error:" -i "${LOG_FILE}" -c) checkStatus $PKG_NAME $EC "true" else (make -j8 DESTDIR="$SKEL_PREFIX" install >> "${LOG_FILE}" 2>&1) checkStatus $PKG_NAME $? "true" fi #lzma conflicts with built in libraries we make -j8 an extra copy of our version of lzma in the xz build process #here we change libapt-pkg*.dylib to look for this version instead #if we do not do this, apt-get will fail from our helper tool install_name_tool -change /usr/lib/liblzma.5.dylib /usr/local/lib/liblzma.5.dylib $SKEL_PREFIX/$ROOT_PREFIX/lib/libapt-pkg.5.0.1.dylib cd "$BUILD_ROOT" fi } buildAPTAndDependencies() { notifyProgress "Building gpg-error" buildGpgError notifyProgress "Building gcrypt" buildGcrypt notifyProgress "Building KSBA" buildKSBA notifyProgress "Building npth" buildNpth notifyProgress "Building Assuan" buildAssuan notifyProgress "Building ntbtls" buildNtbtls notifyProgress "Building gpg" buildGpg notifyProgress "Building apt" buildAPT } prepSDK() { if [[ ! -e "$SDK_PATH/usr/include/sys/ttydev.h" ]]; then echo "Missing . Moving it in from MacOSX SDK (with sudo)" sudo cp "$(xcrun --sdk macosx --show-sdk-path)/usr/include/sys/ttydev.h" "$SDK_PATH/usr/include/sys/ttydev.h" fi if [[ ! -e "$SDK_PATH/usr/include/lockdown.h" ]]; then echo "Missing lockdown.h! Generating the bare essentials for apt to build..." echo "#ifndef LOCKDOWN_LOCKDOWN_H" >> "$SDK_PATH/usr/include/lockdown.h" echo "#define LOCKDOWN_LOCKDOWN_H" >> "$SDK_PATH/usr/include/lockdown.h" echo "" >> "$SDK_PATH/usr/include/lockdown.h" echo "#include " >> "$SDK_PATH/usr/include/lockdown.h" echo "" >> "$SDK_PATH/usr/include/lockdown.h" echo "#ifdef __cplusplus" >> "$SDK_PATH/usr/include/lockdown.h" echo "extern \"C\" {" >> "$SDK_PATH/usr/include/lockdown.h" echo "#endif" >> "$SDK_PATH/usr/include/lockdown.h" echo "" >> "$SDK_PATH/usr/include/lockdown.h" echo "extern CFStringRef kLockdownUniqueDeviceIDKey;" >> "$SDK_PATH/usr/include/lockdown.h" echo "" >> "$SDK_PATH/usr/include/lockdown.h" echo "extern void *lockdown_connect(void);" >> "$SDK_PATH/usr/include/lockdown.h" echo "extern CFStringRef lockdown_copy_value(void *lockdown, void *null, CFStringRef key);" >> "$SDK_PATH/usr/include/lockdown.h" echo "extern void lockdown_disconnect(void *lockdown);" >> "$SDK_PATH/usr/include/lockdown.h" echo "" >> "$SDK_PATH/usr/include/lockdown.h" echo "#ifdef __cplusplus" >> "$SDK_PATH/usr/include/lockdown.h" echo "}" >> "$SDK_PATH/usr/include/lockdown.h" echo "#endif" >> "$SDK_PATH/usr/include/lockdown.h" echo "" >> "$SDK_PATH/usr/include/lockdown.h" echo "#endif/*LOCKDOWN_LOCKDOWN_H*/" >> "$SDK_PATH/usr/include/lockdown.h" fi IOKIT_MATCH="`find ~/Library/Developer/Xcode/tvOS\ DeviceSupport/ -name IOKit.framework | grep "$SDK_VERSION" -m 1`" echo "IOKit match: $IOKIT_MATCH" echo "IOKit: $SDK_PATH/System/Library/Frameworks/IOKit.framework" if [[ ! -d "$SDK_PATH/System/Library/Frameworks/IOKit.framework" ]]; then if [[ ! -z "$IOKIT_MATCH" ]]; then echo "we do indeed have an IOKit match and IOKit is missing!!" echo "cp -r $IOKIT_MATCH $SDK_PATH/System/Library/Frameworks/" cp -r "$IOKIT_MATCH" "$SDK_PATH/System/Library/Frameworks/" fi fi # patch fork to be available in tvOS sed -i -- "s|__TVOS_PROHIBITED| |" $SDK_PATH/usr/include/unistd.h # patch 'system' in places where it isnt patched out and replaced by our own version (ie cdromtools etc) sed -i -- "s|__TVOS_PROHIBITED| |" $SDK_PATH/usr/include/stdlib.h sed -i -- "s|__API_AVAILABLE(macos(10.0))|__API_AVAILABLE(macos(10.0), tvos(9.0))|" $SDK_PATH/usr/include/stdlib.h } if [[ $LOG_VERBOSE == "verbose"* ]]; then set -x fi if [[ "$VERIFY" == "true" ]]; then command -v gpg >/dev/null 2>&1 || { echo >&2 "Missing GPG. Cannot verify. Dying."; exit 127 ; } echo "Importing necessary PGP keys" gpg --recv-key 69184620 7C0135FB088AAF6C66C650B9BB5869F064EA74AB 702353E0F7E48EDB 7FD9FCCB000BEEEE A15B725964A95EE5 D8692123C4065DEA5E0F3AB5249B39D24F25E3B6 031EC2536E580D8EA286A9F22071B08A33BD3F06 9D5EAAF69013B842 fi cleanBootstrap() { # Get rid of the docs rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/docs" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/share/doc" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/share/info" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/share/man" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/man" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/share/gnupg" #TODO: See if the keys in this folder are needed rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/share/readline" # Get rid of dev stuff rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/include" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/share/aclocal" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/share/pkgconfig" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/share/common-lisp" # remove all the static and libtool libraries from the bootstrap, they take up a LOT of space cd "$SKEL_PREFIX/$ROOT_PREFIX/lib" rm *.a rm *.la rmdir "$SKEL_PREFIX/$ROOT_PREFIX/var" #Get rid of non-skel packages which were needed to compile rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/bin/gpg-error-config" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/bin/libgcrypt-config" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/lib/pkgconfig" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/bin/curl-config" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/bin/ncurses6-config" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/bin/npth-config" rm -rf "$SKEL_PREFIX/$ROOT_PREFIX/bin/ntbtls-config" } mkdirIfNecessary $ROOT_LOG_FOLDER mkdirIfNecessary $ALREADY_BUILT # Ensure our SDK has all the required "extras" installed/setup prepSDK buildBashAndFriends buildBasicUtils buildDPKGAndDependencies buildAPTAndDependencies # comment the below in to clean up aftewards to slim down the bootstrap #cleanBootstrap echo -e "\nDone!\n" sayIfVerbal "Finished!"