From 9ea4ab8dabd83a724ac11713b36b1d1a0eb134ff Mon Sep 17 00:00:00 2001 From: Jammmmm Date: Wed, 12 Feb 2020 12:51:44 -0800 Subject: [PATCH] Build instructions (#103) * Update to build instructions * Makefile no longer hardcodes ARM_HOME * Revert "Makefile no longer hardcodes ARM_HOME" This reverts commit 45834e6fe3edcbc71c4e361a8a2068ae70ea4bcd. * Revert "Update to build instructions" This reverts commit 5879b106e9e7991dae862a9e2d2cde1fb828cb03. * make_all.sh no longer hardcodes ARM_HOME * Build instruction updates --- BUILDING.md | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 41 ++--------------- make_all.sh | 29 ++++++++---- 3 files changed, 151 insertions(+), 45 deletions(-) create mode 100644 BUILDING.md diff --git a/BUILDING.md b/BUILDING.md new file mode 100644 index 00000000..ee131724 --- /dev/null +++ b/BUILDING.md @@ -0,0 +1,126 @@ +# Build Instructions + +These instructions have been tested on Debian/Ubuntu/Mint distributions. If you are using a different platform or distribution, adjust accordingly. For example, changing *apt* to *yum* on CentOS. + +---- +## Prerequisites +1. If your system doesn't already have them, install all of the regular build tools: + + sudo apt-get install git build-essential automake autoconf libtool pkg-config autoconf-archive autotools-dev + +2. Install the 65xx cross assembler: + + sudo apt-get install xa65 + + +---- +## Downloading The Required Files + +1. Clone the repo: + + cd /path/to/store/files/ + git clone https://github.com/randyrossi/bmc64.git --recursive + +2. Download and unpack the *GNU Embedded Toolchain for Arm*: + + * Visit [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) + * Download the package for your system. For example, at the time of writing [gcc-arm-none-eabi-9-2019-q4-major-x86\_64-linux.tar.bz2](https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-x86_64-linux.tar.bz2?revision=108bd959-44bd-4619-9c19-26187abf5225&la=en&hash=E788CE92E5DFD64B2A8C246BBA91A249CB8E2D2D) was available for Linux x86\_64. + * Once downloaded, extract the file somewhere. Note down the path to the extracted directory. This will be used later. + * In the extracted directory, find the /lib/gcc/arm-none-eabi/ directory and note down the version number. This will be used later. + + +---- +## Building + +1. Set the ARM_HOME environment variable to point to the extracted Arm toolchain directory: + + export ARM_HOME=/path/to/extracted/toolchain/directory + +2. Set the PATH environment variable to point to the Arm toolchain's *bin* directory: + + export PATH=$PATH:$ARM_HOME/bin + +3. Set the ARM_VERSION environment variable to the version number you noted previously: + + export ARM_VERSION=9.2.1 + +4. If this is your first time building, run *clean_all.sh* from the bmc64 directory: + + cd /path/to/store/files/bmc64/ + ./clean_all.sh + +5. Run *make_all.sh* from the bmc64 directory to build the third party libraries and kernel: + + cd /path/to/store/files/bmc64/ + ./make_all.sh [pi0|pi2|pi3] + + NOTE: In the above, set the required Pi version, such as ./make_all.sh pi3 + +6. Run *make_machines.sh* to build the kernel images for each machine (C64, C128, etc): + + cd /path/to/store/files/bmc64/ + ./make_machines.sh [pi0|pi2|pi3] + + NOTE: In the above, set the required Pi version, such as ./make_machines.sh pi3 + + +---- +## Output +Once the *make_all.sh* build is complete, you will have a kernel file for the Pi version that you built for: + +* *Raspberry Pi Zero*: kernel.img +* *Raspberry Pi 2*: kernel7.img +* *Raspberry Pi 3*: kernel8-32.img + +Once the *make_machines.sh* build is complete, you will have kernel files with a suffix (.c64, .c128, .vic20, etc) for the Pi version that you built for. For example, if pi3 was used you might get the following files: + +* kernel8-32.img.c128 +* kernel8-32.img.c64 +* kernel8-32.img.pet +* kernel8-32.img.plus4 +* kernel8-32.img.plus4emu +* kernel8-32.img.vic20 + + +---- +## More About The Build Files + +* *clean\_all.sh*: Cleans everything +* *make\_all.sh [pi0|pi2|pi3]*: Builds third party libraries (Vice/Circle) and will also build a C64 image for the selected Pi model. This step will likely fail if you don't run *clean\_all.sh* first. +* *make\_machines.sh [pi0|pi2|pi3]*: Builds all machines for the selected Pi model. This step will likely fail if you don't run *make\_all.sh* first. + + +---- +## Problems +1. When you run *make\_all.sh* you get an error such as '#error " not supported"' + + Ensure you have all of the build tools installed from the prerequisites step + +2. When you run one of the build scripts (*clean\_all.sh*, *make\_all.sh* or *make\_machines.sh*), you get an error such as 'arm-eabi-g++: Command not found' + + Before you build, set the PREFIX environment variable so arm-none-eabi-g++ is used instead since the *GNU Embedded Toolchain for Arm* download seems to only have the commands with "none" in the filenames. For example: export PREFIX=arm-none-eabi- + +3. I have a different build issue... + + * Ensure you have set all environment variables in the "Building" step. For example, if you forget to set the ARM\_HOME and ARM\_VERSION variables, *make\_all.sh* will default to "$HOME/gcc-arm-none-eabi-7-2018-q2-update" with a version of "7.3.1" which may or may not exist on your system. + * Ensure you have all prerequisites installed. + * Ensure you follow each step above. + * Ensure you run the build scripts in the following order: *clean\_all.sh*, *make\_all.sh*, *make\_machines.sh* + + +---- +## Resources + +* [https://github.com/raspberrypi/tools](https://github.com/raspberrypi/tools) +* [https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads) + + +---- +## Dependencies + +These are the git hashes for the repos under circle-stdlib this project is known to work with. If the patches don't apply successfully, it's possible those projects have moved forward causing incompatibilities. If that happens, reset these repos using "git reset HASH --hard" commands in the following directories: + +* circle-stdlib: dda16112cdb5470240cd51fb33bf72b311634340 +* libs/circle: fe24b6bebd1532f2a0ee981af12eaf50cc9e97fb +* libs/circle-newlib: c01f95bcb08278d9e00f9795c7641284d4f89931 +* libs/mbedtls: d81c11b8ab61fd5b2da8133aa73c5fe33a0633eb \ No newline at end of file diff --git a/README.md b/README.md index 8133b0c9..c555c9da 100644 --- a/README.md +++ b/README.md @@ -590,28 +590,7 @@ On Linux, this command will work: truncate -s +3584 petrescue.d64 -# Build Instructions - -Pre-reqs: - - sudo apt-get install xa65 - -First get this repo: - - git clone https://github.com/randyrossi/bmc64.git --recursive - -From the top level dir: - -./clean_all.sh - will clean everything -./make_all.sh [pi0|pi2|pi3] - build third party libs (vice/circle) and a C64 image for a Pi model -./make_machines.sh [pi0|pi2|pi3] - build all machines for a Pil model (depends on make_all.sh having been run once) - -The make_all.sh script will make kernel.img for RPI0, kernel7.img for RPI2, kernel8-32.img for RPI3 -The make_machines.sh script will make kernels for each machine with a suffix (.c64, .c128, .vic20, etc) - -NOTE: There is no incremental build and the make_all.sh script will likely fail if run without a clean_all.sh before. - -What to put on the SDcard: +Q. What do I put on the SDcard? C64/ kernal @@ -735,20 +714,8 @@ What to put on the SDcard: tmp/ (used by the emulator sometimes) -# Resources - - https://github.com/raspberrypi/tools - https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads - -# Dependencies - -These are the git hashes for the repos under circle-stdlib this project is known to work with. -If the patches don't apply successfully, it's possible those projects have moved forward causing incompatibilities. -If that happens, reset these repos using "git reset HASH --hard" commands in the following directories: +# Build Instructions - circle-stdlib dda16112cdb5470240cd51fb33bf72b311634340 - libs/circle fe24b6bebd1532f2a0ee981af12eaf50cc9e97fb - libs/circle-newlib c01f95bcb08278d9e00f9795c7641284d4f89931 - libs/mbedtls d81c11b8ab61fd5b2da8133aa73c5fe33a0633eb +Refer to BUILDING.md for instructions. -# Performance numbers can be found at https://accentual.com/bmc64 +# Performance numbers can be found at https://accentual.com/bmc64 \ No newline at end of file diff --git a/make_all.sh b/make_all.sh index c6a811c9..956cdfa9 100755 --- a/make_all.sh +++ b/make_all.sh @@ -1,5 +1,18 @@ #!/bin/bash + +# Set directory variables +SRC_DIR=`pwd` +CIRCLE_HOME="$SRC_DIR/third_party/circle-stdlib" +COMMON_HOME="$SRC_DIR/third_party/common" +if [ ! -n "$ARM_HOME" ]; then + ARM_HOME="$HOME/gcc-arm-none-eabi-7-2018-q2-update" +fi +if [ ! -n "$ARM_VERSION" ]; then + ARM_VERSION="7.3.1" +fi + + BOARD=$1 if [ "$BOARD" = "pi2" ] @@ -27,7 +40,7 @@ echo Must be run from BMC64 root dir. exit fi -SRC_DIR=`pwd` + cd $SRC_DIR/third_party/circle-stdlib @@ -133,24 +146,24 @@ DIRS="src/resid src/teensy-resid" for d in $DIRS do cd $d -CIRCLE_HOME="$SRC/third_party/circle-stdlib" ARM_HOME="$HOME/gcc-arm-none-eabi-7-2018-q2-update" CXXFLAGS="-std=c++11 -funsafe-math-optimizations -fno-exceptions -fno-rtti -nostdinc++ -ffreestanding -nostdlib -DAARCH=32 -march=armv6k -mtune=arm1176jzf-s -marm -mfpu=vfp -mfloat-abi=hard --specs=nosys.specs -O3 -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include-fixed" LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" ./configure --host=arm-none-eabi +CXXFLAGS="-std=c++11 -funsafe-math-optimizations -fno-exceptions -fno-rtti -nostdinc++ -ffreestanding -nostdlib -DAARCH=32 -march=armv6k -mtune=arm1176jzf-s -marm -mfpu=vfp -mfloat-abi=hard --specs=nosys.specs -O3 -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include-fixed" LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" ./configure --host=arm-none-eabi cd ../.. done -COMMON_HOME="$SRC_DIR/third_party/common" CIRCLE_HOME="$SRC_DIR/third_party/circle-stdlib" ARM_HOME="$HOME/gcc-arm-none-eabi-7-2018-q2-update" LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" CXXFLAGS="-std=c++11 -O3 -ffreestanding -DAARCH=32 -march=armv6k -mtune=arm1176jzf-s -marm -mfpu=vfp -mfloat-abi=hard -fno-exceptions -fno-rtti -nostdinc++ --specs=nosys.specs" CFLAGS="-O3 -I$COMMON_HOME -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include-fixed -I$CIRCLE_HOME/libs/circle/addon/fatfs -fno-exceptions --specs=nosys.specs -mfloat-abi=hard -ffreestanding -nostdlib -march=armv6k -mtune=arm1176jzf-s -marm -mfpu=vfp -nostdinc" ./configure --host=arm-none-eabi --disable-realdevice --disable-ipv6 --disable-ssi2001 --disable-catweasel --disable-hardsid --disable-parsid --disable-portaudio --disable-ahi --disable-bundle --disable-lame --disable-rs232 --disable-midi --disable-hidmgr --disable-hidutils --without-oss --without-alsa --without-pulse --without-zlib --disable-sdlui --disable-sdlui2 --enable-raspiui --enable-raspilite +LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" CXXFLAGS="-std=c++11 -O3 -ffreestanding -DAARCH=32 -march=armv6k -mtune=arm1176jzf-s -marm -mfpu=vfp -mfloat-abi=hard -fno-exceptions -fno-rtti -nostdinc++ --specs=nosys.specs" CFLAGS="-O3 -I$COMMON_HOME -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include-fixed -I$CIRCLE_HOME/libs/circle/addon/fatfs -fno-exceptions --specs=nosys.specs -mfloat-abi=hard -ffreestanding -nostdlib -march=armv6k -mtune=arm1176jzf-s -marm -mfpu=vfp -nostdinc" ./configure --host=arm-none-eabi --disable-realdevice --disable-ipv6 --disable-ssi2001 --disable-catweasel --disable-hardsid --disable-parsid --disable-portaudio --disable-ahi --disable-bundle --disable-lame --disable-rs232 --disable-midi --disable-hidmgr --disable-hidutils --without-oss --without-alsa --without-pulse --without-zlib --disable-sdlui --disable-sdlui2 --enable-raspiui --enable-raspilite elif [ "$BOARD" = "pi2" ] then cd src/resid -CIRCLE_HOME="$SRC/third_party/circle-stdlib" ARM_HOME="$HOME/gcc-arm-none-eabi-7-2018-q2-update" CXXFLAGS="-std=c++11 -funsafe-math-optimizations -fno-exceptions -fno-rtti -nostdinc++ -mfloat-abi=hard -ffreestanding -nostdlib -march=armv7-a -marm -mfpu=neon-vfpv4 --specs=nosys.specs -O3 -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include-fixed" LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" ./configure --host=arm-none-eabi +CXXFLAGS="-std=c++11 -funsafe-math-optimizations -fno-exceptions -fno-rtti -nostdinc++ -mfloat-abi=hard -ffreestanding -nostdlib -march=armv7-a -marm -mfpu=neon-vfpv4 --specs=nosys.specs -O3 -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include-fixed" LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" ./configure --host=arm-none-eabi cd ../.. -COMMON_HOME="$SRC_DIR/third_party/common" CIRCLE_HOME="$SRC_DIR/third_party/circle-stdlib" ARM_HOME="$HOME/gcc-arm-none-eabi-7-2018-q2-update" LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" CXXFLAGS="-std=c++11 -O3 -mfloat-abi=hard -ffreestanding -march=armv7-a -marm -mfpu=neon-vfpv4 -fno-exceptions -fno-rtti -nostdinc++ --specs=nosys.specs" CFLAGS="-O3 -I$COMMON_HOME -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include-fixed -I$CIRCLE_HOME/libs/circle/addon/fatfs -fno-exceptions --specs=nosys.specs -mfloat-abi=hard -ffreestanding -nostdlib -march=armv7-a -marm -mfpu=neon-vfpv4 -nostdinc" ./configure --host=arm-none-eabi --disable-realdevice --disable-ipv6 --disable-ssi2001 --disable-catweasel --disable-hardsid --disable-parsid --disable-portaudio --disable-ahi --disable-bundle --disable-lame --disable-rs232 --disable-midi --disable-hidmgr --disable-hidutils --without-oss --without-alsa --without-pulse --without-zlib --disable-sdlui --disable-sdlui2 --enable-raspiui +LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" CXXFLAGS="-std=c++11 -O3 -mfloat-abi=hard -ffreestanding -march=armv7-a -marm -mfpu=neon-vfpv4 -fno-exceptions -fno-rtti -nostdinc++ --specs=nosys.specs" CFLAGS="-O3 -I$COMMON_HOME -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include-fixed -I$CIRCLE_HOME/libs/circle/addon/fatfs -fno-exceptions --specs=nosys.specs -mfloat-abi=hard -ffreestanding -nostdlib -march=armv7-a -marm -mfpu=neon-vfpv4 -nostdinc" ./configure --host=arm-none-eabi --disable-realdevice --disable-ipv6 --disable-ssi2001 --disable-catweasel --disable-hardsid --disable-parsid --disable-portaudio --disable-ahi --disable-bundle --disable-lame --disable-rs232 --disable-midi --disable-hidmgr --disable-hidutils --without-oss --without-alsa --without-pulse --without-zlib --disable-sdlui --disable-sdlui2 --enable-raspiui elif [ "$BOARD" = "pi3" ] then -COMMON_HOME="$SRC_DIR/third_party/common" CIRCLE_HOME="$SRC_DIR/third_party/circle-stdlib" ARM_HOME="$HOME/gcc-arm-none-eabi-7-2018-q2-update" LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" CXXFLAGS="-O3 -std=c++11 -fno-exceptions -march=armv8-a -mtune=cortex-a53 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard -ffreestanding -nostdlib" CFLAGS="-O3 -I$COMMON_HOME -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$CIRCLE_HOME/libs/circle/addon/fatfs -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include-fixed -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include -fno-exceptions -march=armv8-a -mtune=cortex-a53 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard -ffreestanding -nostdlib" ./configure --host=arm-none-eabi --disable-realdevice --disable-ipv6 --disable-ssi2001 --disable-catweasel --disable-hardsid --disable-parsid --disable-portaudio --disable-ahi --disable-bundle --disable-lame --disable-rs232 --disable-midi --disable-hidmgr --disable-hidutils --without-oss --without-alsa --without-pulse --without-zlib --disable-sdlui --disable-sdlui2 --enable-raspiui +LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" CXXFLAGS="-O3 -std=c++11 -fno-exceptions -march=armv8-a -mtune=cortex-a53 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard -ffreestanding -nostdlib" CFLAGS="-O3 -I$COMMON_HOME -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$CIRCLE_HOME/libs/circle/addon/fatfs -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include-fixed -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include -fno-exceptions -march=armv8-a -mtune=cortex-a53 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard -ffreestanding -nostdlib" ./configure --host=arm-none-eabi --disable-realdevice --disable-ipv6 --disable-ssi2001 --disable-catweasel --disable-hardsid --disable-parsid --disable-portaudio --disable-ahi --disable-bundle --disable-lame --disable-rs232 --disable-midi --disable-hidmgr --disable-hidutils --without-oss --without-alsa --without-pulse --without-zlib --disable-sdlui --disable-sdlui2 --enable-raspiui elif [ "$BOARD" = "pi4" ] then -COMMON_HOME="$SRC_DIR/third_party/common" CIRCLE_HOME="$SRC_DIR/third_party/circle-stdlib" ARM_HOME="$HOME/gcc-arm-none-eabi-7-2018-q2-update" LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" CXXFLAGS="-O3 -std=c++11 -fno-exceptions -march=armv8-a -mtune=cortex-a72 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard -ffreestanding -nostdlib" CFLAGS="-O3 -I$COMMON_HOME -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$CIRCLE_HOME/libs/circle/addon/fatfs -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include-fixed -I$ARM_HOME/lib/gcc/arm-none-eabi/7.3.1/include -fno-exceptions -march=armv8-a -mtune=cortex-a72 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard -ffreestanding -nostdlib" ./configure --host=arm-none-eabi --disable-realdevice --disable-ipv6 --disable-ssi2001 --disable-catweasel --disable-hardsid --disable-parsid --disable-portaudio --disable-ahi --disable-bundle --disable-lame --disable-rs232 --disable-midi --disable-hidmgr --disable-hidutils --without-oss --without-alsa --without-pulse --without-zlib --disable-sdlui --disable-sdlui2 --enable-raspiui +LDFLAGS="-L$CIRCLE_HOME/install/arm-none-circle/lib" CXXFLAGS="-O3 -std=c++11 -fno-exceptions -march=armv8-a -mtune=cortex-a72 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard -ffreestanding -nostdlib" CFLAGS="-O3 -I$COMMON_HOME -I$CIRCLE_HOME/install/arm-none-circle/include/ -I$CIRCLE_HOME/libs/circle/addon/fatfs -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include-fixed -I$ARM_HOME/lib/gcc/arm-none-eabi/$ARM_VERSION/include -fno-exceptions -march=armv8-a -mtune=cortex-a72 -marm -mfpu=neon-fp-armv8 -mfloat-abi=hard -ffreestanding -nostdlib" ./configure --host=arm-none-eabi --disable-realdevice --disable-ipv6 --disable-ssi2001 --disable-catweasel --disable-hardsid --disable-parsid --disable-portaudio --disable-ahi --disable-bundle --disable-lame --disable-rs232 --disable-midi --disable-hidmgr --disable-hidutils --without-oss --without-alsa --without-pulse --without-zlib --disable-sdlui --disable-sdlui2 --enable-raspiui else echo "I don't know what to do for $BOARD" exit @@ -173,4 +186,4 @@ echo ============================================================== cd $SRC_DIR make clean -BOARD=$BOARD make -f Makefile-C64 +BOARD=$BOARD make -f Makefile-C64 \ No newline at end of file