[LG V30 Guides, News, & Discussion] Caffination:
COMPILE KERNEL

If you've followed this guide top to bottom as written, we may be a bit ahead of ourselves. I recommend trying the following steps on the 30d stock files FIRST, and then once you're sure of your methods on the original files you can try your hand at compiling your merged CAF tagged version. This helps isolate issues between your process and your code.

Switch back over to the pristine stock branch.

git checkout LG.H932.30d_stock

Unless you're doing this from a 64-bit Raspberry Pi (AND 64-bit OS!) or similar platform you'll need to grab the cross-compile toolchain for arm64 (here called aarch64) from Google. There's a slight problem with using the latest release though. Commit fc97ce6abfe822403eb219dcbd1067a53c49e4f1 removed the GCC compiler completely!

Checking back through the git log we can see where they've made changes to GCC, so let's roll back to a version more suitable for our platform. I found the last commit that contains GCC before they started introducing the deprication warnings - 22f053ccdfd0d73aafcceff3419a5fe3c01e878b. We'll leave the msm-4.4 directory first so this toolchain isn't downloaded into our code.

cd ../..
git clone https://android.googlesource.com/platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9
cd aarch64-linux-android-4.9
git checkout 22f053ccdfd0d73aafcceff3419a5fe3c01e878b
git reset --hard HEAD

You can verify that we have gcc again by checking the ./bin/ directory here.

ls -lah ./bin | grep gcc

While we're here we need to set some environment variables so the compiler will know to use this location. You'll have to redo this from this directory any time you close your shell (in this case, the terminal probably), if you want to recompile the kernel.

export CROSS_COMPILE=$(pwd)/bin/aarch64-linux-android-
export ARCH=arm64 && export SUBARCH=arm64

Head back into the msm-4.4 directory for punishment time.

cd ../kernel/msm-4.4

This next part I'm pretty sure is not the correct way to perform it. I'm not a C developer - just a sysadmin - so I've worked out a way to get it running at least. Yes, this does mean that the code is no longer pristine. Someone let me know how to get the stock code compiling without modification. Click the button below for my steps that are -extremely- specific to the h932 30d image.

In ./Makefile, Remove the gcc-wrapper script from the equation. All it does is stop the build on warnings. Google made a similar change with their commit e7fb62baa7c8b803d7e3b3f3d8bf4e2b916b659d. Change this line:

REAL_CC	= $(CROSS_COMPILE)gcc

to this:

CC	= $(CROSS_COMPILE)gcc

And remove this line:

CC	= $(srctree)/scripts/gcc-wrapper.py $(REAL_CC)

-OR- if you really like stopping on compiler warnings, you need to make the wrapper executable.

chmod 755 ./scripts/gcc-wrapper.py

Note that this wrapper breaks newer GCC toolchains so it's advised you choose to remove it.

./arch/arm64/kernel/vdso/gen_vdso_offsets.sh has incorrect permissions. It needs to be executable.

chmod 755 ./arch/arm64/kernel/vdso/gen_vdso_offsets.sh

You're going to need to apply a Linux kernel commit from 4.4.218 (commit ce513359d8507123e63f34b56e67ad558074be22) to prevent compile errors about "multiple definition of `yylloc'". Remove the line "YYLTYPE yylloc;" (or in later versions "extern YYLTYPE yylloc;") from two files:

# ./scripts/dtc/dtc-lexer.l
# ./scripts/dtc/dtc-lexer.lex.c_shipped

Go into the ./arch/arm64/boot/dts/ directory. Delete the qcom file and make it a link instead. This fixes a missing file error that msm8998-joan_tmo_us_rev-0.dts otherwise runs into.

cd arch/arm64/boot/dts/
rm qcom
ln -s ../../../../arch/arm/boot/dts/qcom qcom
cd ../../../..

Go into the ./include/uapi/linux/ directory. We're going to delete some files and link them instead. This fixes ambiguous errors like: "../include/uapi/linux/oneshot_sync.h:1:1: error: expected identifier or '(' before '.' token". It's LITERALLY parsing the link in the file. Make it a link instead.

cd ./include/uapi/linux/
rm oneshot_sync.h
ln -s ../../../drivers/staging/android/uapi/oneshot_sync.h oneshot_sync.h
rm sync.h
ln -s ../../../drivers/staging/android/uapi/sync.h sync.h
cd ../../..

Edit the #include statements in ./arch/arm/boot/dts/qcom/msm8998.dtsi to point to the current file locations. Leave the first #include alone! Change the other three to:

#include <../../../../../include/dt-bindings/clock/msm-clocks-8998.h>
#include <../../../../../include/dt-bindings/regulator/qcom,rpm-smd-regulator.h>
#include <../../../../../include/dt-bindings/interrupt-controller/arm-gic.h>

Another #include needs to be fixed in ./include/dt-bindings/interrupt-controller/arm-gic.h

#include "irq.h"

Two #includes in ./arch/arm/boot/dts/qcom/msm-pmi8998.dtsi

#include <../../../../../include/dt-bindings/interrupt-controller/irq.h>
#include <../../../../../include/dt-bindings/spmi/spmi.h>

The same thing in reverse on ./arch/arm/boot/dts/qcom/msm-pm8005.dtsi

#include <../../../../../include/dt-bindings/spmi/spmi.h>
#include <../../../../../include/dt-bindings/interrupt-controller/irq.h>

Some common culprits over in ./arch/arm/boot/dts/qcom/msm8998-regulator.dtsi

#include <../../../../../include/dt-bindings/clock/msm-clocks-8998.h>
#include <../../../../../include/dt-bindings/interrupt-controller/arm-gic.h>

ANOTHER set of #includes in ./arch/arm/boot/dts/qcom/msm-pm8998.dtsi

#include <../../../../../include/dt-bindings/spmi/spmi.h>
#include <../../../../../include/dt-bindings/interrupt-controller/irq.h>
#include <../../../../../include/dt-bindings/msm/power-on.h>

One in the similarly namned ./arch/arm/boot/dts/qcom/msm8998-pm.dtsi

#include <../../../../../include/dt-bindings/interrupt-controller/arm-gic.h>

Seeing a pattern yet? The include directory must be defined in something I've missed. Another over in ./arch/arm/boot/dts/qcom/msm-arm-smmu-8998.dtsi

#include <../../../../../include/dt-bindings/clock/msm-clocks-8998.h>
#include <../../../../../include/dt-bindings/msm/msm-bus-ids.h>
#include <../../../../../include/dt-bindings/interrupt-controller/arm-gic.h>

Moar. ./arch/arm/boot/dts/qcom/msm8998-vidc.dtsi

#include <../../../../../include/dt-bindings/interrupt-controller/arm-gic.h>
#include <../../../../../include/dt-bindings/msm/msm-bus-ids.h>
#include <../../../../../include/dt-bindings/clock/msm-clocks-8998.h>

Moar. ./arch/arm/boot/dts/qcom/msm8998-bus.dtsi

#include <../../../../../include/dt-bindings/msm/msm-bus-ids.h>

Moar. ./arch/arm/boot/dts/qcom/msm-smb138x.dtsi

#include <../../../../../include/dt-bindings/interrupt-controller/irq.h>

Moar. ./arch/arm64/boot/dts/lge/msm8998-joan/msm8998-joan_tmo_us/msm8998-joan_tmo_us.dtsi

Only the first #include on this file needs to be changed.

#include <../../../../include/dt-bindings/interrupt-controller/irq.h>

Locate the devconfig file you'd like to use for your device under the directory ./arch/arm64/configs/.

ls -lah ./arch/arm64/configs/

The closest in my instance will be the "joan_tmo_us-perf_defconfig" file. Joan is the codename for the LG V30, T-Mobile's my carrier, US is my country, and while using the stock ROM the uname -r command returns "4.4.153-perf+" so I assume they used the perf config. The defconfig will instruct the compiler what options to include in the kernel. We're going with the LG stock options to start with.

Make a few directories for the clean/mrproper scripts. The build process throws some (harmless) errors otherwise.

mkdir -p out/drivers/staging/qcacld-3.0
mkdir -p out/drivers/staging/qca-wifi-host-cmn
mkdir -p out/arch/arm64/boot/dts

Now run through the make steps. Clean, prepare the environment, prep the make with your devconfig, then run the actual make specifying that it use all the cores your PC has to speed things up. You can change that to a manually specified number like 3 cores if you're using the PC for other stuff with "-j3".

make O=./out clean
make O=./out mrproper
make O=./out joan_tmo_us-perf_defconfig
make O=./out KERNEL_COMPRESSION_SUFFIX=gz -j$(nproc)

Your kernel should compile successfully and output the file "./out/arch/arm64/boot/Image.gz-dtb". AnyKernel3 will need this so your kernel can be included in the installer.

PACKAGE & FLASH KERNEL

Download the latest AnyKernel3. Make sure you're not in your kernel directory.

cd ~
wget https://github.com/osm0sis/AnyKernel3/archive/master.zip

Unzip the archive and go into the AnyKernel3 directory.

unzip master.zip
cd AnyKernel3-master

Place your Image.gz-dtb file into the AnyKernel3-master folder.

Edit the anykernel.sh file, it comes pre-populated with demo values. Copy my example below for the V30 and feel free to change kernel.string (make sure not to use a ' though). If you aren't using a V30 and therefore not making a Joan kernel, change the device.name1 and block lines for your device. You can either pull the values from another kernel for your device, or boot into TWRP or similar, go to the terminal, and try a find /dev/block -name boot to see if you can garnish any clues as to where your real boot is. Some devices just hard specify this under /fstab.${devicecodename} - ours is at /fstab.joan but has no /boot/.

# AnyKernel3 Ramdisk Mod Script
# osm0sis @ xda-developers

## AnyKernel setup
# begin properties
properties() { '
kernel.string=CAF Test Kernel
do.devicecheck=1
do.modules=0
do.systemless=1
do.cleanup=1
do.cleanuponabort=0
device.name1=joan
'; } # end properties

# shell variables
block=/dev/block/bootdevice/by-name/boot;
is_slot_device=0;
ramdisk_compression=auto;

## AnyKernel methods (DO NOT CHANGE)
# import patching functions/variables - see for reference
. tools/ak3-core.sh;

## AnyKernel install
dump_boot;
write_boot;
## end install

Finally, pack up the entire folder.

zip -r9 UPDATE-AnyKernel3.zip * -x .git README.md *placeholder

You've created your first kernel release! Most XDA users would know what to do with this file at this point. Remember that if you're using a Pie release like we are that not all versions of TWRP support the newer standard of encryption. I'm using 3.3.1 personally.

That first flash is perilous. You'll swear it's the slowest your phone has ever booted and there's no way this could be working. Patience. If it doesn't work and you have no access to another kernel for your device you'll have to reflash a working image, find out what you did wrong, fix it, and try again.

Once you have a known working kernel the other flashes are much less risky - if it doesn't work, just go back into TWRP and flash the working one.

SWITCHING TOOLCHAINS

Switching between Google Android 4.9 builds

I've pulled some of the commits from the aarch64-linux-android-4.9 git logs which correlate to when they introduced new build versions. Might help someone track down an errant compiler issue or two.

93092903254cba0b6950c94170332973a85b450f - final gcc build 5790414 + very long delays added to dissuade use
22f053ccdfd0d73aafcceff3419a5fe3c01e878b - build 4983606 - last version before warnings
e7c51da4d09616dcff4a9d0f1190c3403079c462 - build 4682334
ce9d77505072450d2f16a4bf06673f31d8d67ff0 - build 3335333
2d6950d80de80ab7b1252816a2f543d07180deeb - build 2734602
d65210cccc244bf9a92a1ff56953314e9908e0fd - build 2617618
b5845835b5e6a5266c56d554c0c1f282d30f8c3f - build 2492827
8f7279e3d34a45f084fdb23bd434c01d5e598bf4 - they don't mention the builds this early

For anything older checkout this last commit and do: git log --grep 'prebuilts for aarch64'

You can change which gcc build your toolchain is on by going into your aarch64-linux-android-4.9 directory and performing the following commands, making sure to replace the commit with the one reflecting the build you'd like.

git checkout 22f053ccdfd0d73aafcceff3419a5fe3c01e878b

git reset --hard HEAD

Switching to Alternatives

From what I understand reading around XDA, it's best practice to try to compile your kernel with Google's aarch64-linux-android-4.9 toolchain first to make sure that nothing's wrong with it. Relative to the Linux community however, Google has been extremely conservative with its toolchain. If you're looking to bleed every last drop of performance out of your platform you should try a few different toolchains and see which one results in code that's most efficient for your workflow.

There are LOTS of toolchains out there. XDA has entire threads on dedicated to this topic. On Linux your distribution also probably bundles a premade toolchain for aarch64, Arch Linux is currently on GCC 10 (aarch64-linux-gnu-gcc)!

I'm going to focus on a popular performance-focused toolchain here, Linaro. They produce an aarch64 toolchain for most of the GCC release versions with enhancements specific to ARM based targets. Their latest release as of this writing is 7.5.0.

Go back to your home directory and download the aarch64-7.5.0 release of Linaro, then unpack.

cd ~
wget https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-linux-gnu/gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz
tar -xf gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu.tar.xz

Now, whenever you want to compile your kernel following the steps in this guide, you'll go into this directory instead of your previous aarch64-linux-android-4.9 one. Then you'll need to set your CROSS_COMPILE variable a different string which corresponds to Linaro 7.5.0's file structure.

cd gcc-linaro-7.5.0-2019.12-x86_64_aarch64-linux-gnu
export CROSS_COMPILE=$(pwd)/bin/aarch64-linux-gnu-

I've tested this on my LA.UM.7.4.r1-03500-8x98.0+H932.30d and it completes albeit with a few warnings. Coding standards and compilers evolve as time moves on and code that isn't maintained can find itself stranded with the ancients - these warnings are to help developers work in the right direction so that doesn't happen to their projects.

To that end, to actually compile a functional kernel using a GCC 7.x+ toolchain there's a flag that needs to be added to your ./Makefile: "-fno-store-merging". I found this tidbit over at https://github.com/nathanchance/angler/commit/406d54a7f006142372157d4fb49d7e76a5564d00

Add the following at line 634 in ./Makefile:

# Needed to unbreak GCC 7.x and above
KBUILD_CFLAGS += $(call cc-option,-fno-store-merging,)