forked from gentoo/gentoo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
kernel-build.eclass
238 lines (199 loc) · 6.99 KB
/
kernel-build.eclass
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
# Copyright 2020-2021 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
# @ECLASS: kernel-build.eclass
# @MAINTAINER:
# Distribution Kernel Project <[email protected]>
# @AUTHOR:
# Michał Górny <[email protected]>
# @SUPPORTED_EAPIS: 7
# @BLURB: Build mechanics for Distribution Kernels
# @DESCRIPTION:
# This eclass provides the logic to build a Distribution Kernel from
# source and install it. Post-install and test logic is inherited
# from kernel-install.eclass.
#
# The ebuild must take care of unpacking the kernel sources, copying
# an appropriate .config into them (e.g. in src_prepare()) and setting
# correct S. The eclass takes care of respecting savedconfig, building
# the kernel and installing it along with its modules and subset
# of sources needed to build external modules.
if [[ ! ${_KERNEL_BUILD_ECLASS} ]]; then
case "${EAPI:-0}" in
0|1|2|3|4|5|6)
die "Unsupported EAPI=${EAPI:-0} (too old) for ${ECLASS}"
;;
7)
;;
*)
die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
;;
esac
PYTHON_COMPAT=( python3_{7..9} )
inherit python-any-r1 savedconfig toolchain-funcs kernel-install
BDEPEND="
${PYTHON_DEPS}
sys-devel/bc
sys-devel/flex
virtual/libelf
virtual/yacc"
# @FUNCTION: kernel-build_src_configure
# @DESCRIPTION:
# Prepare the toolchain for building the kernel, get the default .config
# or restore savedconfig, and get build tree configured for modprep.
kernel-build_src_configure() {
debug-print-function ${FUNCNAME} "${@}"
# force ld.bfd if we can find it easily
local LD="$(tc-getLD)"
if type -P "${LD}.bfd" &>/dev/null; then
LD+=.bfd
fi
tc-export_build_env
MAKEARGS=(
V=1
HOSTCC="$(tc-getBUILD_CC)"
HOSTCXX="$(tc-getBUILD_CXX)"
HOSTCFLAGS="${BUILD_CFLAGS}"
HOSTLDFLAGS="${BUILD_LDFLAGS}"
CROSS_COMPILE=${CHOST}-
AS="$(tc-getAS)"
CC="$(tc-getCC)"
LD="${LD}"
AR="$(tc-getAR)"
NM="$(tc-getNM)"
STRIP=":"
OBJCOPY="$(tc-getOBJCOPY)"
OBJDUMP="$(tc-getOBJDUMP)"
# we need to pass it to override colliding Gentoo envvar
ARCH=$(tc-arch-kernel)
)
restore_config .config
[[ -f .config ]] || die "Ebuild error: please copy default config into .config"
if [[ -z "${KV_LOCALVERSION}" ]]; then
KV_LOCALVERSION=$(sed -n -e 's#^CONFIG_LOCALVERSION="\(.*\)"$#\1#p' \
.config)
fi
mkdir -p "${WORKDIR}"/modprep || die
mv .config "${WORKDIR}"/modprep/ || die
emake O="${WORKDIR}"/modprep "${MAKEARGS[@]}" olddefconfig
emake O="${WORKDIR}"/modprep "${MAKEARGS[@]}" modules_prepare
cp -pR "${WORKDIR}"/modprep "${WORKDIR}"/build || die
}
# @FUNCTION: kernel-build_src_compile
# @DESCRIPTION:
# Compile the kernel sources.
kernel-build_src_compile() {
debug-print-function ${FUNCNAME} "${@}"
emake O="${WORKDIR}"/build "${MAKEARGS[@]}" all
}
# @FUNCTION: kernel-build_src_test
# @DESCRIPTION:
# Test the built kernel via qemu. This just wraps the logic
# from kernel-install.eclass with the correct paths.
kernel-build_src_test() {
debug-print-function ${FUNCNAME} "${@}"
local targets=( modules_install )
# on arm or arm64 you also need dtb
if use arm || use arm64; then
targets+=( dtbs_install )
fi
emake O="${WORKDIR}"/build "${MAKEARGS[@]}" \
INSTALL_MOD_PATH="${T}" INSTALL_PATH="${ED}/boot" "${targets[@]}"
local ver="${PV}${KV_LOCALVERSION}"
kernel-install_test "${ver}" \
"${WORKDIR}/build/$(dist-kernel_get_image_path)" \
"${T}/lib/modules/${ver}"
}
# @FUNCTION: kernel-build_src_install
# @DESCRIPTION:
# Install the built kernel along with subset of sources
# into /usr/src/linux-${PV}. Install the modules. Save the config.
kernel-build_src_install() {
debug-print-function ${FUNCNAME} "${@}"
# do not use 'make install' as it behaves differently based
# on what kind of installkernel is installed
local targets=( modules_install )
# on arm or arm64 you also need dtb
if use arm || use arm64; then
targets+=( dtbs_install )
fi
emake O="${WORKDIR}"/build "${MAKEARGS[@]}" \
INSTALL_MOD_PATH="${ED}" INSTALL_PATH="${ED}/boot" "${targets[@]}"
# note: we're using mv rather than doins to save space and time
# install main and arch-specific headers first, and scripts
local kern_arch=$(tc-arch-kernel)
local ver="${PV}${KV_LOCALVERSION}"
dodir "/usr/src/linux-${ver}/arch/${kern_arch}"
mv include scripts "${ED}/usr/src/linux-${ver}/" || die
mv "arch/${kern_arch}/include" \
"${ED}/usr/src/linux-${ver}/arch/${kern_arch}/" || die
# some arches need module.lds linker script to build external modules
if [[ -f arch/${kern_arch}/kernel/module.lds ]]; then
insinto "/usr/src/linux-${ver}/arch/${kern_arch}/kernel"
doins "arch/${kern_arch}/kernel/module.lds"
fi
# remove everything but Makefile* and Kconfig*
find -type f '!' '(' -name 'Makefile*' -o -name 'Kconfig*' ')' \
-delete || die
find -type l -delete || die
cp -p -R * "${ED}/usr/src/linux-${ver}/" || die
cd "${WORKDIR}" || die
# strip out-of-source build stuffs from modprep
# and then copy built files as well
find modprep -type f '(' \
-name Makefile -o \
-name '*.[ao]' -o \
'(' -name '.*' -a -not -name '.config' ')' \
')' -delete || die
rm modprep/source || die
cp -p -R modprep/. "${ED}/usr/src/linux-${ver}"/ || die
# install the kernel and files needed for module builds
insinto "/usr/src/linux-${ver}"
doins build/{System.map,Module.symvers}
local image_path=$(dist-kernel_get_image_path)
cp -p "build/${image_path}" "${ED}/usr/src/linux-${ver}/${image_path}" || die
# building modules fails with 'vmlinux has no symtab?' if stripped
use ppc64 && dostrip -x "/usr/src/linux-${ver}/${image_path}"
# strip empty directories
find "${D}" -type d -empty -exec rmdir {} + || die
# fix source tree and build dir symlinks
dosym ../../../usr/src/linux-${ver} /lib/modules/${ver}/build
dosym ../../../usr/src/linux-${ver} /lib/modules/${ver}/source
save_config build/.config
}
# @FUNCTION: kernel-build_pkg_postinst
# @DESCRIPTION:
# Combine postinst from kernel-install and savedconfig eclasses.
kernel-build_pkg_postinst() {
kernel-install_pkg_postinst
savedconfig_pkg_postinst
}
# @FUNCTION: kernel-build_merge_configs
# @USAGE: [distro.config...]
# @DESCRIPTION:
# Merge the config files specified as arguments (if any) into
# the '.config' file in the current directory, then merge
# any user-supplied configs from ${BROOT}/etc/kernel/config.d/*.config.
# The '.config' file must exist already and contain the base
# configuration.
kernel-build_merge_configs() {
debug-print-function ${FUNCNAME} "${@}"
[[ -f .config ]] || die "${FUNCNAME}: .config does not exist"
has .config "${@}" &&
die "${FUNCNAME}: do not specify .config as parameter"
local shopt_save=$(shopt -p nullglob)
shopt -s nullglob
local user_configs=( "${BROOT}"/etc/kernel/config.d/*.config )
shopt -u nullglob
if [[ ${#user_configs[@]} -gt 0 ]]; then
elog "User config files are being applied:"
local x
for x in "${user_configs[@]}"; do
elog "- ${x}"
done
fi
./scripts/kconfig/merge_config.sh -m -r \
.config "${@}" "${user_configs[@]}" || die
}
_KERNEL_BUILD_ECLASS=1
fi
EXPORT_FUNCTIONS src_configure src_compile src_test src_install pkg_postinst