Android Q: Compiling Kernels in-tree

TL;DR - Kernel fixes

For an example of how to update your kernel makefile for Q, see Sony Kernel: Update makefiles for Android Q and clang

Q Build system changes

The main changes in Android Q are:

  • New $PATH restrictions
  • GCC 4.9 deprecation
  • Removal of ccache
  • PHONY target enforcement

For more information, see AOSP: Build System Changes for Android.mk Writers.

PHONY targets

For more information, see .PHONY rule enforcement.

Real output files cannot be marked PHONY any more, the build system will complain if PHONY targets have slashes in them.

warning: PHONY target "out/.../foo" looks like a real file (contains a "/")

Just remove the attribute if an output file isn’t really PHONY.

-.PHONY: $(PRODUCT_OUT)/kernel
-$(PRODUCT_OUT)/kernel: $(KERNEL_BIN) | $(ACP)
-        cp $(KERNEL_BIN) $(PRODUCT_OUT)/kernel
+$(PRODUCT_OUT)/kernel: $(KERNEL_BIN)
+    $(ACP) $(KERNEL_BIN) $(PRODUCT_OUT)/kernel

Also, you cannot depend on intermediates being PHONY any more if your final target is non-PHONY, but that’s standard make for you.

Output directory restrictions

These will come to bite you if you rely on build targets with absolute filenames.

Example:

KERNEL_OUT: $(PWD)/$(OUT)/obj/KERNEL_OBJ
$(KERNEL_OUT)/drivers:
	make -C $(KERNEL_SRC) -O $(KERNEL_OUT) drivers

Throws

warning: writing to readonly directory: "/home/[...]/out/[...]/KERNEL_OBJ/drivers"

That is because the make target $(KERNEL_OUT)/drivers does not begin with out/target/... but rather is an absolute path; the build system is not smart enough to recognize that the path should still be allowed.

Use a relative-path KERNEL_OUT for a make target and an absolute-pathKERNEL_OUT_ABS for invoking the “real” make command:

KERNEL_OUT: $(OUT)/obj/KERNEL_OBJ
KERNEL_OUT_ABS: $(PWD)/$(OUT)/obj/KERNEL_OBJ
$(KERNEL_OUT)/drivers:
	make -C $(KERNEL_SRC) -O $(KERNEL_OUT_ABS) drivers

GCC is broken for host compilation

Even with correct PATH supplied for cc1, the prebuilt GCC 4.9 still fails at compiling the host scripts:

  HOSTCC  scripts/basic/fixdep
  [...]/kernel/scripts/basic/fixdep.c:105:23:
    fatal error: sys/types.h: No such file or directory
     #include <sys/types.h>

It’s better to use clang for HOSTCC:

# Android.mk
CLANG_HOST_TOOLCHAIN := $(PWD)/prebuilts/clang/host/linux-x86/clang-r365631/bin
CLANG_HOSTCC := $(CLANG_HOST_TOOLCHAIN)/clang
[...]
KERNEL_CROSS_COMPILE += HOSTCC="$(CLANG_HOSTCC)"
[...]
my-target:
	make $(MAKE_FLAGS) -C $(KERNEL_SRC_ABS) O=$(KERNEL_OUT_ABS) \
		ARCH=$(KERNEL_ARCH) $(KERNEL_CROSS_COMPILE)

Makefile:

-HOSTCC       = gcc
-HOSTCXX      = g++
+HOSTCC       = $(HOSTCC)
+HOSTCXX      = $(HOSTCXX)

Absolute paths for invoking build tools

CLANG_HOST_TOOLCHAIN := $(PWD)/prebuilts/clang/host/linux-x86/clang-r365631/bin
KERNEL_HOSTCC := $(CLANG_HOST_TOOLCHAIN)/clang
KERNEL_TOOLCHAIN := $(PWD)/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin
KERNEL_TOOLCHAIN_PREFIX := aarch64-linux-android-
KERNEL_TOOLCHAIN_PATH := $(KERNEL_TOOLCHAIN)/$(KERNEL_TOOLCHAIN_PREFIX)
KERNEL_CROSS_COMPILE :=
KERNEL_CROSS_COMPILE += CC="$(CLANG_CC)"
KERNEL_CROSS_COMPILE += CLANG_TRIPLE="aarch64-linux-gnu"
KERNEL_CROSS_COMPILE += HOSTCC="$(KERNEL_HOSTCC)"
KERNEL_CROSS_COMPILE += CROSS_COMPILE="$(KERNEL_TOOLCHAIN_PATH)"
KERNEL_CROSS_COMPILE += CROSS_COMPILE_ARM32="$(KERNEL_TOOLCHAIN_32BITS_PATH)"

No relying on tools being in PATH

You cannot rely on make, perl, gcc etc. being in $PATH.
For more information, see Android Q Changes: PATH restrictions.

Perl is no longer allowed as a PATH tool:

# Android.mk
KERNEL_PERL := /usr/bin/perl
[...]
KERNEL_CROSS_COMPILE += PERL=$(KERNEL_PERL)

Makefile:

-PERL= perl
+PERL= $(PERL)

lib/Makefile:

-      cmd_build_OID_registry = perl $(srctree)/$(src)/build_OID_registry $< $@
+      cmd_build_OID_registry = $(PERL) $(srctree)/$(src)/build_OID_registry $< $@

make is no longer an allowed PATH tool, and you need to supply an extra PATH for host binutils:

GCC_PREBUILTS := $(PWD)/prebuilts/gcc/linux-x86/host
KERNEL_HOST_TOOLCHAIN := \
    $(GCC_PREBUILTS)/x86_64-linux-glibc2.17-4.8/x86_64-linux/bin
KERNEL_HOST_TOOLCHAIN_LIBEXEC := \
    $(GCC_PREBUILTS)/libexec/gcc/x86_64-linux/4.8.3
KERNEL_PREBUILT_MAKE := $(PWD)/prebuilts/build-tools/linux-x86/bin/make
# clang/GCC (glibc) host toolchain needs to be prepended to $PATH for certain
# host bootstrap tools to be built. Also, binutils such as `ld` and `ar` are
# needed for now.
KERNEL_MAKE_EXTRA_PATH := $(KERNEL_HOST_TOOLCHAIN)
ifneq ($(TARGET_KERNEL_USE_CLANG),true)
  KERNEL_MAKE_EXTRA_PATH := \
      "$(KERNEL_HOST_TOOLCHAIN):$(KERNEL_HOST_TOOLCHAIN_LIBEXEC)"
endif
KERNEL_MAKE := \
	PATH="$(KERNEL_MAKE_EXTRA_PATH):$$PATH" \
	$(KERNEL_PREBUILT_MAKE)

Published by