summaryrefslogtreecommitdiff
path: root/dlkm/Build_external_kernelmodule.mk
blob: 6e586b1df4651b4fdf7c693403cb668e495e5658 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
DISABLE_THIS_DLKM := $(strip $(TARGET_KERNEL_DLKM_DISABLE))

## Input Arguments:
# LOCAL_MODULE: name of the .ko to be generated (e.g. kp_module.ko)
# LOCAL_MODULE_PATH: location to put the module, $(KERNEL_MODULES_OUT)
#                    for a common output directory
# LOCAL_MODULE_KBUILD_NAME: name of the .ko that is generated by kbuild (see below)
# LOCAL_ADDITIONAL_DEPENDENCIES: just that
# KBUILD_OPTIONS: Additional parameters to give to kbuild when compiling module

ifeq ($(DISABLE_THIS_DLKM),true)
ifneq (,$(filter $(LOCAL_MODULE),$(TARGET_KERNEL_DLKM_OVERRIDE)))
    DISABLE_THIS_DLKM = false
else
endif
endif

ifeq ($(DISABLE_THIS_DLKM),true)
$(warning DLKM '$(LOCAL_MODULE)' disabled for target)
else

# Assign external kernel modules to the DLKM class
LOCAL_MODULE_CLASS := DLKM

# Set the default install path to system/lib/modules
LOCAL_MODULE_PATH := $(strip $(LOCAL_MODULE_PATH))
ifeq ($(LOCAL_MODULE_PATH),)
  LOCAL_MODULE_PATH := $(TARGET_OUT)/lib/modules
endif

# LOCAL_MODULE_KBUILD_NAME is the name of the .ko that kernel makefiles generate
# for instance, one could write my_device.ko, but want it to be called
# the_device.ko on vendor image (and rest of Android build system)
ifeq ($(LOCAL_MODULE_KBUILD_NAME),)
    LOCAL_MODULE_KBUILD_NAME := $(LOCAL_MODULE)
endif
LOCAL_MODULE_KBUILD_NAME := $(strip $(LOCAL_MODULE_KBUILD_NAME))

include $(BUILD_SYSTEM)/base_rules.mk

################################################################################
KERNEL_PLATFORM_PATH:=kernel_platform
KERNEL_PLATFORM_OUT_DIR:=$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ

ifeq ($(wildcard $(KERNEL_PLATFORM_OUT_DIR)/),)
$(error "$(KERNEL_PLATFORM_OUT_DIR) doesn't exist. Have you run kernel_platform/build/android/prepare.sh?")
endif
################################################################################
# Intermediate directory where the kernel modules are created
# by the kernel platform. Ideally this would be the same
# directory as LOCAL_BUILT_MODULE, but because we're using
# relative paths for both O= and M=, we don't have much choice
MODULE_KP_OUT_DIR := $(KERNEL_PLATFORM_OUT_DIR)/$(LOCAL_PATH)

# The kernel build system doesn't support parallel kernel module builds
# that share the same output directory. Thus, in order to build multiple
# kernel modules that reside in a single directory (and therefore have
# the same output directory), there must be just one invocation of the
# kernel build system that builds all the modules of a given directory.
#
# Therefore, all kernel modules must depend on the same, unique target
# that invokes the kernel build system and builds all of the modules
# for the directory. The $(MODULE_KP_COMBINED_TARGET) target serves this purpose.
MODULE_KP_COMBINED_TARGET := $(MODULE_KP_OUT_DIR)/buildko.timestamp
# When MODULE_KP_COMBINED_TARGET is built, then out pops the MODULE_KP_TARGET (by essentially running `make modules`)
MODULE_KP_TARGET := $(MODULE_KP_OUT_DIR)/$(LOCAL_MODULE_KBUILD_NAME)

# The final built module for Android Build System
$(LOCAL_BUILT_MODULE): $(MODULE_KP_TARGET) | $(ACP)
	$(transform-prebuilt-to-target)

# To build the module inside kernel_platform, depend on the kbuild_target
$(MODULE_KP_TARGET): $(MODULE_KP_COMBINED_TARGET)
$(MODULE_KP_TARGET): $(LOCAL_ADDITIONAL_DEPENDENCIES)

# Ensure the kernel module created by the kernel build system, as
# well as all the other intermediate files, are removed during a clean.
$(cleantarget): PRIVATE_CLEAN_FILES := $(PRIVATE_CLEAN_FILES) $(MODULE_KP_OUT_DIR)

# Since this file will be included more than once for directories
# with more than one kernel module, the shared KBUILD_TARGET rule should
# only be defined once to avoid "overriding commands ..." warnings.
ifndef $(MODULE_KP_COMBINED_TARGET)_RULE
$(MODULE_KP_COMBINED_TARGET)_RULE := 1

# Kernel modules have to be built after:
#  * the kernel config has been created
#  * host executables, like scripts/basic/fixdep, have been built
#    (otherwise parallel invocations of the kernel build system will
#    fail as they all try to compile these executables at the same time)
#  * a full kernel build (to make module versioning work)
$(MODULE_KP_COMBINED_TARGET): local_path     := $(LOCAL_PATH)
$(MODULE_KP_COMBINED_TARGET): kbuild_options := $(KBUILD_OPTIONS)
$(MODULE_KP_COMBINED_TARGET): $(LOCAL_ADDITIONAL_DEPENDENCIES) $(LOCAL_SRC_FILES)
	# Create a symlink so that Kernel Platform thinks module source lives inside
	# kernel platform directory structure.
	# this makes finding the output much less confusing and helps prevent
	# possibility of conflicting output folders if we were to use relative path
	# outside the kernel_platform directory structure. Kbuild output goes to:
	# $(KERNEL_PLATFORM_OUT_DIR)/$(MODULE_KP_SYMLINK)/$(LOCAL_PATH)
	(cd $(KERNEL_PLATFORM_PATH) && \
	    EXT_MODULES=la/$(local_path) \
	    ./build/build_module.sh $(kbuild_options) \
	    ANDROID_BUILD_TOP=$$(realpath $$(pwd)/$(KERNEL_PLATFORM_TO_ROOT)) \
	)
	touch $@

endif
endif

# Once the KBUILD_OPTIONS variable has been used for the target
# that's specific to the LOCAL_PATH, clear it. If this isn't done,
# then every kernel module would need to explicitly set KBUILD_OPTIONS,
# or the variable would have to be cleared in 'include $(CLEAR_VARS)'
# which would require a change to build/core.
KBUILD_OPTIONS :=
LOCAL_ADDITIONAL_DEPENDENCIES :=
LOCAL_MODULE_KBUILD_NAME :=