Building Nile SODP Kernels

Recently I decided to do some personal kernel work on my discovery, aka Sony Xperia XA2 Ultra, which is part of the “nile” family of devices. I use the Sony Open Device Project trees and kernel, because regardless of what they think of me, I think they do exceptionally great work.

Unfortunately, the SODP build instructions for kernel building are just a little out of date, as Google has depreciated using GCC in favor of Clang. If you built your kernel for a nile device with clang, it will actually have issues with the camera, as you can read about in the issue tracker for SODP.

So, since I walked through it, I decided I would write down what I did in case anyone else needs a little help with this. I’m writing it in the same order the SODP instructions use, so it will be very clear when reviewing with the written instructions on their website.

Step 1: Unlock the boot loader per the SODP instructions.

Step 2: Download a cross compiler.

This is the part where things go awry. If you follow the instructions, you get the version of GCC tool-chain that Google removed half of it’s contents, causing it not to work, since they are depreciating it. You need to download this version: https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/+archive/606f80986096476912e04e5c2913685a8f2c3b65.tar.gz because it is the last version to have all of the tools in it.

Also, while you are only compiling a 64 bit kernel, if you don’t have the 32 bit tool-chain, you will have to trick the compiler when compiling stand alone (e.g., outside of Android source code). So, I recommend you also download this 32 bit tool-chain to keep GCC and the scripts from trying to use your system one: https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/+/refs/tags/android-cts-10.0_r6

Both of these should be extracted into their respective folder. In my case I made the 64 bit one called android, and the 32 bit one called android32. You can name the folder anything you want.

Step 3: Export the cross compiler.

Again, this would work, except that as stated, the scripts will call for a 32 bit tool-chain version, so if you follow the steps exactly, you will be left unable to build until you either edit the arch/arm64/Makefile on line 83, or declare one from the get-go. I recommend the latter.

$ export CROSS_COMPILE_ARM32=/mnt/719a5453-f8d5-4282-b4d9-f73a127316da/SonyXA2ultraKernel/android32/bin/arm-linux-androideabi-
$ export CROSS_COMPILE=/mnt/719a5453-f8d5-4282-b4d9-f73a127316da/SonyXA2ultraKernel/android/bin/aarch64-linux-android-

Make sure you use your folder names and locations.

Steps 4 through 10 can be done per the SODP instructions.

Overall, it’s only 2 small steps that need a little tweaking, but it’s very difficult to get through it if you don’t know what to do. Hopefully this will help the next guy, and I hope the SODP will keep up their great work!

Linux – keep it simple.

Which C++ standard is it, anyways?

One interesting thing about my C++ course is that the instructor never specified which standard he is using for the course. There are many standards in the C++ universe, and they don’t all have the same functions.

Originally, when I attempted to build my game without specifying a standard, it failed to build. So a little research led me to an article that gave me the idea to try the 2011 standard by adding “-std=c++11” to my build script. Since that worked, I erroneously thought that the course must use the (now old) 2011 standard instead of the newer 2014 or 2017 standards. Turns out I was wrong.

By default, my compiler will compile with the 1997 standard. How do I know this? Well, try this command:

$ g++ -dM -E -x c++ /dev/null | grep -F __cplusplus

Here was the output:

#define __cplusplus 199711L

Then, watch what happens when I specify a standard to use:

alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~$ g++ -std=c++11 -dM -E -x c++ /dev/null | grep -F __cplusplus
#define __cplusplus 201103L
alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~$ g++ -std=c++1z -dM -E -x c++ /dev/null | grep -F __cplusplus
#define __cplusplus 201500L
alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~$ g++ -std=c++14 -dM -E -x c++ /dev/null | grep -F __cplusplus
#define __cplusplus 201402L

So, when I specify a standard, it uses that standard, when I don’t it tries to compile with the 1997 standard, which is really outdated! I’m not sure why they set the default to such an old standard. Obviously, my compiler is new enough for the 2014+ standards:

alaskalinuxuser@alaskalinuxuser-OptiPlex-7010:~$ g++ –version
g++ (Ubuntu 5.4.0-6ubuntu1~16.04.9) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Even still, my compiler is a bit out of date. It’s 2018 and the newest I can use is the completed 2014, or the pre 2017 (which reads 2015, as that was the latest available when my compiler was put together).

termc++

In any event, it would appear that my course can compile and run just fine on the newest standard available to my compiler, so the course material must not be that old. However, since it will fully compile on the 2011 standard, it must have been written before 2014, or not use any of the 2014 functions.

Interesting. Very interesting….

Linux – keep it simple.