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)