#!/usr/bin/env sh set -e cd "$(dirname "$0")" mode="${1}" no_ask="${2}" network="rtl8139" qemu_with_flags() { if [ "${mode}" = "image" ] || [ "${mode}" = "image_debug" ]; then # TODO: Find out why kvm install is incredibly slow SDL_VIDEO_X11_DGAMOUSE=0 qemu-system-i386 -no-reboot -vga std -smp "$(nproc)" -serial mon:stdio -rtc base=localtime -m 256M -net nic,model=${network},macaddr=42:42:42:42:42:42 -net user "$@" else SDL_VIDEO_X11_DGAMOUSE=0 qemu-system-i386 -no-reboot -vga std -serial stdio -rtc base=localtime -m 256M -net nic,model=${network},macaddr=42:42:42:42:42:42 -net user "$@" fi } make_genext2fs() { if [ "$(genext2fs -V | awk '{print $2}')" = "1.4.2" ]; then echo "genext2fs is already the newest version" else if [ "$no_ask" != "-y" ]; then printf "Melvix requires the newest genext2fs version, would you like to install it? [y/n] " read -r answer fi if [ "$answer" != "${answer#[Yy]}" ] || [ "$no_ask" = "-y" ]; then echo "Building genext2fs..." git clone --quiet https://github.com/bestouff/genext2fs.git >/dev/null cd genext2fs >/dev/null git checkout --quiet 000e369 >/dev/null mv README.md README >/dev/null touch ChangeLog >/dev/null bash autogen.sh >/dev/null ./configure >/dev/null sudo make install >/dev/null cd .. >/dev/null rm -rf genext2fs >/dev/null echo "Success!" else echo "This probably won't compile..." fi fi } make_cross() { if [ ! -d "./cross/" ]; then # Create directory mkdir -p cross cd cross DIR=$(pwd) # Get sources mkdir "${DIR}/src" && cd "${DIR}/src" echo "Downloading..." curl -sSL "https://ftp.gnu.org/gnu/binutils/binutils-2.34.tar.xz" | tar xJ curl -sSL "https://ftp.gnu.org/gnu/gcc/gcc-9.3.0/gcc-9.3.0.tar.xz" | tar xJ # Prepare compiling mkdir -p "${DIR}/opt/bin" export PREFIX="${DIR}/opt" export TARGET=i686-elf export PATH="$PREFIX/bin:$PATH" # Compile binutils mkdir "${DIR}/src/build-binutils" && cd "${DIR}/src/build-binutils" ../binutils-2.34/configure --target="$TARGET" --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror make make install # Compile GCC mkdir "${DIR}/src/build-gcc" && cd "${DIR}/src/build-gcc" ../gcc-9.3.0/configure --target="$TARGET" --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers make all-gcc make all-target-libgcc make install-gcc make install-target-libgcc cd "${DIR}/.." else cd cross DIR=$(pwd) export PREFIX="${DIR}/opt" export TARGET=i686-elf export PATH="$PREFIX/bin:$PATH" cd .. fi } make_build() { mkdir -p build/ disk/bin/ echo "Building..." cd build/ cmake .. >/dev/null make cd .. # Create disk image # make_genext2fs # mkdir ./mnt/ # mkdir -p ./mnt/etc/ # mkdir -p ./mnt/usr/ # mkdir -p ./mnt/bin/ # cp ./build/res/font.bin ./mnt/bin/font # cp ./build/user/* ./mnt/bin/ # echo "Hello world, ext2!" | tee -a ./mnt/etc/test # /usr/local/bin/genext2fs -B 4096 -d mnt -U -N 4096 -b 65536 ./build/disk.img # rm -r mnt/ printf "Build finshed successfully!\n\n" } make_test() { qemu_with_flags -cdrom ./build/melvix.iso# -hda ./build/disk.img } make_debug() { objcopy --only-keep-debug ./build/kernel/kernel.bin ./build/kernel/debug qemu-system-i386 -vga std -S -s -cdrom ./build/melvix.iso -hda ./build/disk.img & sleep 2 ( echo target remote 127.0.0.1:1234 cat ) | gdb -s ./build/kernel/debug ./build/kernel/kernel.bin pkill "qemu*" } make_disasm() { objdump -drwC -Mintel ./build/kernel/kernel.bin --visualize-jumps=color | less -R } make_image() { #start=$(date +%s.%N) #qemu_with_flags -nographic -cdrom ./build/melvix.iso -drive file=./build/hdd10M.img,format=raw >install.log #end=$(date +%s.%N) #cat install.log #printf "[LOG END]\n\n" #tail install.log | grep -q "Installation successful!" && echo Booted and installed within "$(echo "$end - $start" | bc -l)" seconds || echo Installation failed! && exit 1 #rm install.log echo "This test is currently disabled" } make_sync() { rm tags compile_commands.json ctags -R --exclude=.git --exclude=build --exclude=iso --exclude=cross . mkdir -p build cd build cmake .. >/dev/null mv compile_commands.json .. cd .. } make_tidy() { find ./src -type f -name "*.sh" | xargs -l -i sh -c 'shfmt -w {}' shfmt -w ./run find ./src -type f -regex '.*\.\(c\|h\)' -exec clang-format -i {} \; find ./src -type f | xargs -l -i sh -c 'printf %s "$(< {})" > {}' } make_font() { cd ./src/resources/ sh conv.sh cd ../../ } make_clean() { rm -rf ./iso ./build/ } if [ "${mode}" = "cross" ]; then make_cross elif [ "${mode}" = "build" ]; then make_cross make_clean make_build elif [ "${mode}" = "clean" ]; then make_clean elif [ "${mode}" = "test" ]; then make_cross make_build make_sync & make_test elif [ "${mode}" = "again" ]; then make_test elif [ "${mode}" = "debug" ]; then make_cross make_build make_debug elif [ "${mode}" = "disasm" ]; then make_cross make_build make_disasm elif [ "${mode}" = "image" ]; then make_cross make_build make_image elif [ "${mode}" = "sync" ]; then make_sync elif [ "${mode}" = "tidy" ]; then make_tidy elif [ "${mode}" = "font" ]; then make_font make_tidy make_sync & elif [ "${mode}" = "" ]; then # TODO: Prevent code duplication in build script via functions? make_cross make_build make_sync & make_test else echo "Please use the following syntax:" echo "./run {cross | build | clean | test | debug | disasm | image | sync | tidy | font} [-y]" echo "The default option is 'test'" fi