blob: dfde9b11124da3be57f93996ad38678ccfa46f1a [file] [log] [blame]
Matthias Maennich6652d742019-02-01 22:20:44 +00001#!/bin/bash
2
3# Copyright (C) 2019 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17# Usage:
18# build/build.sh <make options>*
19# or:
20# OUT_DIR=<out dir> DIST_DIR=<dist dir> build/build.sh <make options>*
21#
22# Example:
23# OUT_DIR=output DIST_DIR=dist build/build.sh -j24
24#
25#
26# The following environment variables are considered during execution:
27#
28# BUILD_CONFIG
29# Build config file to initialize the build environment from. The location
30# is to be defined relative to the repo root directory.
31# Defaults to 'build.config'.
32#
33# OUT_DIR
34# Base output directory for the kernel build.
35# Defaults to <REPO_ROOT>/out/<BRANCH>.
36#
37# DIST_DIR
38# Base output directory for the kernel distribution.
39# Defaults to <OUT_DIR>/dist
40#
41# EXT_MODULES
42# Space separated list of external kernel modules to be build.
43#
44# UNSTRIPPED_MODULES
45# Space separated list of modules to be copied to <DIST_DIR>/unstripped
46# for debugging purposes.
47#
48# CC
Matthias Maennich0646c8d2019-03-20 11:03:51 +000049# Override compiler to be used. (e.g. CC=clang) Specifying CC=gcc
50# effectively unsets CC to fall back to the default gcc detected by kbuild
51# (including any target triplet). To use a custom 'gcc' from PATH, use an
52# absolute path, e.g. CC=/usr/local/bin/gcc
Matthias Maennich6652d742019-02-01 22:20:44 +000053#
54# LD
55# Override linker (flags) to be used.
56#
57# Environment variables to influence the stages of the kernel build.
58#
59# SKIP_MRPROPER
60# if defined, skip `make mrproper`
61#
62# SKIP_DEFCONFIG
63# if defined, skip `make defconfig`
64#
Matthias Maenniche4edd6f2019-02-13 12:36:27 +000065# PRE_DEFCONFIG_CMDS
66# Command evaluated before `make defconfig`
67#
Matthias Maennich6652d742019-02-01 22:20:44 +000068# POST_DEFCONFIG_CMDS
69# Command evaluated after `make defconfig` and before `make`.
70#
Matthias Maenniche4edd6f2019-02-13 12:36:27 +000071# POST_KERNEL_BUILD_CMDS
72# Command evaluated after `make`.
73#
Matthias Maennich6652d742019-02-01 22:20:44 +000074# IN_KERNEL_MODULES
75# if defined, install kernel modules
76#
77# SKIP_EXT_MODULES
78# if defined, skip building and installing of external modules
79#
80# EXTRA_CMDS
81# Command evaluated after building and installing kernel and modules.
82#
83# SKIP_CP_KERNEL_HDR
84# if defined, skip installing kernel headers.
85#
86# Note: For historic reasons, internally, OUT_DIR will be copied into
87# COMMON_OUT_DIR, and OUT_DIR will be then set to
88# ${COMMON_OUT_DIR}/${KERNEL_DIR}. This has been done to accommodate existing
89# build.config files that expect ${OUT_DIR} to point to the output directory of
90# the kernel build.
91#
92# The kernel is built in ${COMMON_OUT_DIR}/${KERNEL_DIR}.
93# Out-of-tree modules are built in ${COMMON_OUT_DIR}/${EXT_MOD} where
94# ${EXT_MOD} is the path to the module source code.
95
96set -e
97
98# rel_path <to> <from>
99# Generate relative directory path to reach directory <to> from <from>
100function rel_path() {
101 local to=$1
102 local from=$2
103 local path=
104 local stem=
105 local prevstem=
106 [ -n "$to" ] || return 1
107 [ -n "$from" ] || return 1
108 to=$(readlink -e "$to")
109 from=$(readlink -e "$from")
110 [ -n "$to" ] || return 1
111 [ -n "$from" ] || return 1
112 stem=${from}/
113 while [ "${to#$stem}" == "${to}" -a "${stem}" != "${prevstem}" ]; do
114 prevstem=$stem
115 stem=$(readlink -e "${stem}/..")
116 [ "${stem%/}" == "${stem}" ] && stem=${stem}/
117 path=${path}../
118 done
119 echo ${path}${to#$stem}
120}
121
122export ROOT_DIR=$(readlink -f $(dirname $0)/..)
123
124# For module file Signing with the kernel (if needed)
125FILE_SIGN_BIN=scripts/sign-file
126SIGN_SEC=certs/signing_key.pem
127SIGN_CERT=certs/signing_key.x509
128SIGN_ALGO=sha512
129
130source "${ROOT_DIR}/build/envsetup.sh"
131
132export MAKE_ARGS=$@
133export COMMON_OUT_DIR=$(readlink -m ${OUT_DIR:-${ROOT_DIR}/out/${BRANCH}})
134export OUT_DIR=$(readlink -m ${COMMON_OUT_DIR}/${KERNEL_DIR})
135export MODULES_STAGING_DIR=$(readlink -m ${COMMON_OUT_DIR}/staging)
136export MODULES_PRIVATE_DIR=$(readlink -m ${COMMON_OUT_DIR}/private)
137export DIST_DIR=$(readlink -m ${DIST_DIR:-${COMMON_OUT_DIR}/dist})
138export UNSTRIPPED_DIR=${DIST_DIR}/unstripped
139export KERNEL_UAPI_HEADERS_DIR=$(readlink -m ${COMMON_OUT_DIR}/kernel_uapi_headers)
140
141cd ${ROOT_DIR}
142
143export CLANG_TRIPLE CROSS_COMPILE CROSS_COMPILE_ARM32 ARCH SUBARCH
144
Matthias Maennich0646c8d2019-03-20 11:03:51 +0000145# CC=gcc is effectively a fallback to the default gcc including any target
146# triplets. If the user wants to use a custom compiler, they are still able to
147# pass an absolute path, e.g. CC=/usr/bin/gcc.
148[ "${CC}" == "gcc" ] && unset CC
149
Matthias Maennich151047e2019-03-18 15:01:03 +0000150if [ -n "${CC}" ]; then
151 CC_ARG="CC=${CC}"
152fi
153
154if [ -n "${LD}" ]; then
155 LD_ARG="LD=${LD}"
156fi
157
158CC_LD_ARG="${CC_ARG} ${LD_ARG}"
159
Matthias Maennich6652d742019-02-01 22:20:44 +0000160mkdir -p ${OUT_DIR}
161echo "========================================================"
162echo " Setting up for build"
163if [ -z "${SKIP_MRPROPER}" ] ; then
164 set -x
Matthias Maennich151047e2019-03-18 15:01:03 +0000165 (cd ${KERNEL_DIR} && make ${CC_LD_ARG} O=${OUT_DIR} mrproper)
Matthias Maennich6652d742019-02-01 22:20:44 +0000166 set +x
167fi
168
Petri Gynther0172f352019-02-12 11:52:50 -0800169if [ "${PRE_DEFCONFIG_CMDS}" != "" ]; then
170 echo "========================================================"
171 echo " Running pre-defconfig command(s):"
172 set -x
173 eval ${PRE_DEFCONFIG_CMDS}
174 set +x
175fi
176
Matthias Maennich6652d742019-02-01 22:20:44 +0000177if [ -z "${SKIP_DEFCONFIG}" ] ; then
178set -x
Matthias Maennich151047e2019-03-18 15:01:03 +0000179(cd ${KERNEL_DIR} && make ${CC_LD_ARG} O=${OUT_DIR} ${DEFCONFIG})
Matthias Maennich6652d742019-02-01 22:20:44 +0000180set +x
181
182if [ "${POST_DEFCONFIG_CMDS}" != "" ]; then
183 echo "========================================================"
184 echo " Running pre-make command(s):"
185 set -x
186 eval ${POST_DEFCONFIG_CMDS}
187 set +x
188fi
189fi
190
191echo "========================================================"
192echo " Building kernel"
193
Matthias Maennich6652d742019-02-01 22:20:44 +0000194set -x
195(cd ${OUT_DIR} && \
Matthias Maennich151047e2019-03-18 15:01:03 +0000196 make O=${OUT_DIR} ${CC_LD_ARG} -j$(nproc) $@)
Matthias Maennich6652d742019-02-01 22:20:44 +0000197set +x
198
Petri Gynther0172f352019-02-12 11:52:50 -0800199if [ "${POST_KERNEL_BUILD_CMDS}" != "" ]; then
200 echo "========================================================"
201 echo " Running post-kernel-build command(s):"
202 set -x
203 eval ${POST_KERNEL_BUILD_CMDS}
204 set +x
205fi
206
Matthias Maennich6652d742019-02-01 22:20:44 +0000207rm -rf ${MODULES_STAGING_DIR}
208mkdir -p ${MODULES_STAGING_DIR}
209
210if [ -n "${IN_KERNEL_MODULES}" ]; then
211 echo "========================================================"
212 echo " Installing kernel modules into staging directory"
213
214 (cd ${OUT_DIR} && \
Matthias Maennich151047e2019-03-18 15:01:03 +0000215 make O=${OUT_DIR} ${CC_LD_ARG} INSTALL_MOD_STRIP=1 \
Matthias Maennich6652d742019-02-01 22:20:44 +0000216 INSTALL_MOD_PATH=${MODULES_STAGING_DIR} modules_install)
217fi
218
219if [[ -z "${SKIP_EXT_MODULES}" ]] && [[ "${EXT_MODULES}" != "" ]]; then
220 echo "========================================================"
221 echo " Building external modules and installing them into staging directory"
222
223 for EXT_MOD in ${EXT_MODULES}; do
224 # The path that we pass in via the variable M needs to be a relative path
225 # relative to the kernel source directory. The source files will then be
226 # looked for in ${KERNEL_DIR}/${EXT_MOD_REL} and the object files (i.e. .o
227 # and .ko) files will be stored in ${OUT_DIR}/${EXT_MOD_REL}. If we
228 # instead set M to an absolute path, then object (i.e. .o and .ko) files
229 # are stored in the module source directory which is not what we want.
230 EXT_MOD_REL=$(rel_path ${ROOT_DIR}/${EXT_MOD} ${KERNEL_DIR})
231 # The output directory must exist before we invoke make. Otherwise, the
232 # build system behaves horribly wrong.
233 mkdir -p ${OUT_DIR}/${EXT_MOD_REL}
234 set -x
235 make -C ${EXT_MOD} M=${EXT_MOD_REL} KERNEL_SRC=${ROOT_DIR}/${KERNEL_DIR} \
Matthias Maennich151047e2019-03-18 15:01:03 +0000236 O=${OUT_DIR} ${CC_LD_ARG} -j$(nproc) "$@"
Matthias Maennich6652d742019-02-01 22:20:44 +0000237 make -C ${EXT_MOD} M=${EXT_MOD_REL} KERNEL_SRC=${ROOT_DIR}/${KERNEL_DIR} \
Matthias Maennich151047e2019-03-18 15:01:03 +0000238 O=${OUT_DIR} ${CC_LD_ARG} INSTALL_MOD_STRIP=1 \
Matthias Maennich6652d742019-02-01 22:20:44 +0000239 INSTALL_MOD_PATH=${MODULES_STAGING_DIR} modules_install
240 set +x
241 done
242
243fi
244
245if [ "${EXTRA_CMDS}" != "" ]; then
246 echo "========================================================"
247 echo " Running extra build command(s):"
248 set -x
249 eval ${EXTRA_CMDS}
250 set +x
251fi
252
253OVERLAYS_OUT=""
254for ODM_DIR in ${ODM_DIRS}; do
255 OVERLAY_DIR=${ROOT_DIR}/device/${ODM_DIR}/overlays
256
257 if [ -d ${OVERLAY_DIR} ]; then
258 OVERLAY_OUT_DIR=${OUT_DIR}/overlays/${ODM_DIR}
259 mkdir -p ${OVERLAY_OUT_DIR}
260 make -C ${OVERLAY_DIR} DTC=${OUT_DIR}/scripts/dtc/dtc OUT_DIR=${OVERLAY_OUT_DIR}
261 OVERLAYS=$(find ${OVERLAY_OUT_DIR} -name "*.dtbo")
262 OVERLAYS_OUT="$OVERLAYS_OUT $OVERLAYS"
263 fi
264done
265
266mkdir -p ${DIST_DIR}
267echo "========================================================"
268echo " Copying files"
269for FILE in ${FILES}; do
270 if [ -f ${OUT_DIR}/${FILE} ]; then
271 echo " $FILE"
272 cp -p ${OUT_DIR}/${FILE} ${DIST_DIR}/
273 else
274 echo " $FILE does not exist, skipping"
275 fi
276done
277
278for FILE in ${OVERLAYS_OUT}; do
279 OVERLAY_DIST_DIR=${DIST_DIR}/$(dirname ${FILE#${OUT_DIR}/overlays/})
280 echo " ${FILE#${OUT_DIR}/}"
281 mkdir -p ${OVERLAY_DIST_DIR}
282 cp ${FILE} ${OVERLAY_DIST_DIR}/
283done
284
285MODULES=$(find ${MODULES_STAGING_DIR} -type f -name "*.ko")
286if [ -n "${MODULES}" ]; then
287 echo "========================================================"
288 echo " Copying modules files"
289 if [ -n "${IN_KERNEL_MODULES}" -o "${EXT_MODULES}" != "" ]; then
290 for FILE in ${MODULES}; do
291 echo " ${FILE#${MODULES_STAGING_DIR}/}"
292 cp -p ${FILE} ${DIST_DIR}
293 done
294 fi
295fi
296
297if [ "${UNSTRIPPED_MODULES}" != "" ]; then
298 echo "========================================================"
299 echo " Copying unstripped module files for debugging purposes (not loaded on device)"
300 mkdir -p ${UNSTRIPPED_DIR}
301 for MODULE in ${UNSTRIPPED_MODULES}; do
302 find ${MODULES_PRIVATE_DIR} -name ${MODULE} -exec cp {} ${UNSTRIPPED_DIR} \;
303 done
304fi
305
306if [ -z "${SKIP_CP_KERNEL_HDR}" ]; then
307 echo "========================================================"
308 echo " Installing UAPI kernel headers:"
309 mkdir -p "${KERNEL_UAPI_HEADERS_DIR}/usr"
Matthias Maennich151047e2019-03-18 15:01:03 +0000310 make -C ${OUT_DIR} O=${OUT_DIR} ${CC_LD_ARG} INSTALL_HDR_PATH="${KERNEL_UAPI_HEADERS_DIR}/usr" -j$(nproc) headers_install
Matthias Maennich6652d742019-02-01 22:20:44 +0000311 # The kernel makefiles create files named ..install.cmd and .install which
312 # are only side products. We don't want those. Let's delete them.
313 find ${KERNEL_UAPI_HEADERS_DIR} \( -name ..install.cmd -o -name .install \) -exec rm '{}' +
314 KERNEL_UAPI_HEADERS_TAR=${DIST_DIR}/kernel-uapi-headers.tar.gz
315 echo " Copying kernel UAPI headers to ${KERNEL_UAPI_HEADERS_TAR}"
316 tar -czf ${KERNEL_UAPI_HEADERS_TAR} --directory=${KERNEL_UAPI_HEADERS_DIR} usr/
317fi
318
319if [ -z "${SKIP_CP_KERNEL_HDR}" ] ; then
320 echo "========================================================"
321 KERNEL_HEADERS_TAR=${DIST_DIR}/kernel-headers.tar.gz
322 echo " Copying kernel headers to ${KERNEL_HEADERS_TAR}"
Matthias Maennich14f6db72019-03-27 07:46:11 +0000323 TMP_DIR="${OUT_DIR}/tmp"
Matthias Maennich6652d742019-02-01 22:20:44 +0000324 TMP_KERNEL_HEADERS_CHILD="kernel-headers"
325 TMP_KERNEL_HEADERS_DIR=$TMP_DIR/$TMP_KERNEL_HEADERS_CHILD
326 CURDIR=$(pwd)
327 mkdir -p $TMP_KERNEL_HEADERS_DIR
328 cd $ROOT_DIR/$KERNEL_DIR; find arch -name *.h -exec cp --parents {} $TMP_KERNEL_HEADERS_DIR \;
329 cd $ROOT_DIR/$KERNEL_DIR; find include -name *.h -exec cp --parents {} $TMP_KERNEL_HEADERS_DIR \;
330 cd $OUT_DIR; find -name *.h -exec cp --parents {} $TMP_KERNEL_HEADERS_DIR \;
331 tar -czvf $KERNEL_HEADERS_TAR --directory=$TMP_DIR $TMP_KERNEL_HEADERS_CHILD > /dev/null 2>&1
332 rm -rf $TMP_KERNEL_HEADERS_DIR
333 cd $CURDIR
334fi
335
336echo "========================================================"
337echo " Files copied to ${DIST_DIR}"
338
339# No trace_printk use on build server build
340if readelf -a ${DIST_DIR}/vmlinux 2>&1 | grep -q trace_printk_fmt; then
341 echo "========================================================"
342 echo "WARN: Found trace_printk usage in vmlinux."
343 echo ""
344 echo "trace_printk will cause trace_printk_init_buffers executed in kernel"
345 echo "start, which will increase memory and lead warning shown during boot."
346 echo "We should not carry trace_printk in production kernel."
347 echo ""
348 if [ ! -z "${STOP_SHIP_TRACEPRINTK}" ]; then
349 echo "ERROR: stop ship on trace_printk usage." 1>&2
350 exit 1
351 fi
352fi