blob: cc2aa82a5e6d89ab66e8e8fbf9eb4a2e9161dfee [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
49# Override compiler to be used. (e.g. CC=clang)
50#
51# LD
52# Override linker (flags) to be used.
53#
54# Environment variables to influence the stages of the kernel build.
55#
56# SKIP_MRPROPER
57# if defined, skip `make mrproper`
58#
59# SKIP_DEFCONFIG
60# if defined, skip `make defconfig`
61#
62# POST_DEFCONFIG_CMDS
63# Command evaluated after `make defconfig` and before `make`.
64#
65# IN_KERNEL_MODULES
66# if defined, install kernel modules
67#
68# SKIP_EXT_MODULES
69# if defined, skip building and installing of external modules
70#
71# EXTRA_CMDS
72# Command evaluated after building and installing kernel and modules.
73#
74# SKIP_CP_KERNEL_HDR
75# if defined, skip installing kernel headers.
76#
77# Note: For historic reasons, internally, OUT_DIR will be copied into
78# COMMON_OUT_DIR, and OUT_DIR will be then set to
79# ${COMMON_OUT_DIR}/${KERNEL_DIR}. This has been done to accommodate existing
80# build.config files that expect ${OUT_DIR} to point to the output directory of
81# the kernel build.
82#
83# The kernel is built in ${COMMON_OUT_DIR}/${KERNEL_DIR}.
84# Out-of-tree modules are built in ${COMMON_OUT_DIR}/${EXT_MOD} where
85# ${EXT_MOD} is the path to the module source code.
86
87set -e
88
89# rel_path <to> <from>
90# Generate relative directory path to reach directory <to> from <from>
91function rel_path() {
92 local to=$1
93 local from=$2
94 local path=
95 local stem=
96 local prevstem=
97 [ -n "$to" ] || return 1
98 [ -n "$from" ] || return 1
99 to=$(readlink -e "$to")
100 from=$(readlink -e "$from")
101 [ -n "$to" ] || return 1
102 [ -n "$from" ] || return 1
103 stem=${from}/
104 while [ "${to#$stem}" == "${to}" -a "${stem}" != "${prevstem}" ]; do
105 prevstem=$stem
106 stem=$(readlink -e "${stem}/..")
107 [ "${stem%/}" == "${stem}" ] && stem=${stem}/
108 path=${path}../
109 done
110 echo ${path}${to#$stem}
111}
112
113export ROOT_DIR=$(readlink -f $(dirname $0)/..)
114
115# For module file Signing with the kernel (if needed)
116FILE_SIGN_BIN=scripts/sign-file
117SIGN_SEC=certs/signing_key.pem
118SIGN_CERT=certs/signing_key.x509
119SIGN_ALGO=sha512
120
121source "${ROOT_DIR}/build/envsetup.sh"
122
123export MAKE_ARGS=$@
124export COMMON_OUT_DIR=$(readlink -m ${OUT_DIR:-${ROOT_DIR}/out/${BRANCH}})
125export OUT_DIR=$(readlink -m ${COMMON_OUT_DIR}/${KERNEL_DIR})
126export MODULES_STAGING_DIR=$(readlink -m ${COMMON_OUT_DIR}/staging)
127export MODULES_PRIVATE_DIR=$(readlink -m ${COMMON_OUT_DIR}/private)
128export DIST_DIR=$(readlink -m ${DIST_DIR:-${COMMON_OUT_DIR}/dist})
129export UNSTRIPPED_DIR=${DIST_DIR}/unstripped
130export KERNEL_UAPI_HEADERS_DIR=$(readlink -m ${COMMON_OUT_DIR}/kernel_uapi_headers)
131
132cd ${ROOT_DIR}
133
134export CLANG_TRIPLE CROSS_COMPILE CROSS_COMPILE_ARM32 ARCH SUBARCH
135
136mkdir -p ${OUT_DIR}
137echo "========================================================"
138echo " Setting up for build"
139if [ -z "${SKIP_MRPROPER}" ] ; then
140 set -x
141 (cd ${KERNEL_DIR} && make O=${OUT_DIR} mrproper)
142 set +x
143fi
144
145if [ -z "${SKIP_DEFCONFIG}" ] ; then
146set -x
147(cd ${KERNEL_DIR} && make O=${OUT_DIR} ${DEFCONFIG})
148set +x
149
150if [ "${POST_DEFCONFIG_CMDS}" != "" ]; then
151 echo "========================================================"
152 echo " Running pre-make command(s):"
153 set -x
154 eval ${POST_DEFCONFIG_CMDS}
155 set +x
156fi
157fi
158
159echo "========================================================"
160echo " Building kernel"
161
162if [ -n "${CC}" ]; then
163 CC_ARG="CC=${CC}"
164fi
165
166if [ -n "${LD}" ]; then
167 LD_ARG="LD=${LD}"
168fi
169
170set -x
171(cd ${OUT_DIR} && \
172 make O=${OUT_DIR} ${CC_ARG} ${LD_ARG} -j$(nproc) $@)
173set +x
174
175rm -rf ${MODULES_STAGING_DIR}
176mkdir -p ${MODULES_STAGING_DIR}
177
178if [ -n "${IN_KERNEL_MODULES}" ]; then
179 echo "========================================================"
180 echo " Installing kernel modules into staging directory"
181
182 (cd ${OUT_DIR} && \
183 make O=${OUT_DIR} ${CC_ARG} ${LD_ARG} INSTALL_MOD_STRIP=1 \
184 INSTALL_MOD_PATH=${MODULES_STAGING_DIR} modules_install)
185fi
186
187if [[ -z "${SKIP_EXT_MODULES}" ]] && [[ "${EXT_MODULES}" != "" ]]; then
188 echo "========================================================"
189 echo " Building external modules and installing them into staging directory"
190
191 for EXT_MOD in ${EXT_MODULES}; do
192 # The path that we pass in via the variable M needs to be a relative path
193 # relative to the kernel source directory. The source files will then be
194 # looked for in ${KERNEL_DIR}/${EXT_MOD_REL} and the object files (i.e. .o
195 # and .ko) files will be stored in ${OUT_DIR}/${EXT_MOD_REL}. If we
196 # instead set M to an absolute path, then object (i.e. .o and .ko) files
197 # are stored in the module source directory which is not what we want.
198 EXT_MOD_REL=$(rel_path ${ROOT_DIR}/${EXT_MOD} ${KERNEL_DIR})
199 # The output directory must exist before we invoke make. Otherwise, the
200 # build system behaves horribly wrong.
201 mkdir -p ${OUT_DIR}/${EXT_MOD_REL}
202 set -x
203 make -C ${EXT_MOD} M=${EXT_MOD_REL} KERNEL_SRC=${ROOT_DIR}/${KERNEL_DIR} \
204 O=${OUT_DIR} ${CC_ARG} ${LD_ARG} -j$(nproc) "$@"
205 make -C ${EXT_MOD} M=${EXT_MOD_REL} KERNEL_SRC=${ROOT_DIR}/${KERNEL_DIR} \
206 O=${OUT_DIR} ${CC_ARG} ${LD_ARG} INSTALL_MOD_STRIP=1 \
207 INSTALL_MOD_PATH=${MODULES_STAGING_DIR} modules_install
208 set +x
209 done
210
211fi
212
213if [ "${EXTRA_CMDS}" != "" ]; then
214 echo "========================================================"
215 echo " Running extra build command(s):"
216 set -x
217 eval ${EXTRA_CMDS}
218 set +x
219fi
220
221OVERLAYS_OUT=""
222for ODM_DIR in ${ODM_DIRS}; do
223 OVERLAY_DIR=${ROOT_DIR}/device/${ODM_DIR}/overlays
224
225 if [ -d ${OVERLAY_DIR} ]; then
226 OVERLAY_OUT_DIR=${OUT_DIR}/overlays/${ODM_DIR}
227 mkdir -p ${OVERLAY_OUT_DIR}
228 make -C ${OVERLAY_DIR} DTC=${OUT_DIR}/scripts/dtc/dtc OUT_DIR=${OVERLAY_OUT_DIR}
229 OVERLAYS=$(find ${OVERLAY_OUT_DIR} -name "*.dtbo")
230 OVERLAYS_OUT="$OVERLAYS_OUT $OVERLAYS"
231 fi
232done
233
234mkdir -p ${DIST_DIR}
235echo "========================================================"
236echo " Copying files"
237for FILE in ${FILES}; do
238 if [ -f ${OUT_DIR}/${FILE} ]; then
239 echo " $FILE"
240 cp -p ${OUT_DIR}/${FILE} ${DIST_DIR}/
241 else
242 echo " $FILE does not exist, skipping"
243 fi
244done
245
246for FILE in ${OVERLAYS_OUT}; do
247 OVERLAY_DIST_DIR=${DIST_DIR}/$(dirname ${FILE#${OUT_DIR}/overlays/})
248 echo " ${FILE#${OUT_DIR}/}"
249 mkdir -p ${OVERLAY_DIST_DIR}
250 cp ${FILE} ${OVERLAY_DIST_DIR}/
251done
252
253MODULES=$(find ${MODULES_STAGING_DIR} -type f -name "*.ko")
254if [ -n "${MODULES}" ]; then
255 echo "========================================================"
256 echo " Copying modules files"
257 if [ -n "${IN_KERNEL_MODULES}" -o "${EXT_MODULES}" != "" ]; then
258 for FILE in ${MODULES}; do
259 echo " ${FILE#${MODULES_STAGING_DIR}/}"
260 cp -p ${FILE} ${DIST_DIR}
261 done
262 fi
263fi
264
265if [ "${UNSTRIPPED_MODULES}" != "" ]; then
266 echo "========================================================"
267 echo " Copying unstripped module files for debugging purposes (not loaded on device)"
268 mkdir -p ${UNSTRIPPED_DIR}
269 for MODULE in ${UNSTRIPPED_MODULES}; do
270 find ${MODULES_PRIVATE_DIR} -name ${MODULE} -exec cp {} ${UNSTRIPPED_DIR} \;
271 done
272fi
273
274if [ -z "${SKIP_CP_KERNEL_HDR}" ]; then
275 echo "========================================================"
276 echo " Installing UAPI kernel headers:"
277 mkdir -p "${KERNEL_UAPI_HEADERS_DIR}/usr"
278 make -C ${OUT_DIR} O=${OUT_DIR} ${CC_ARG} INSTALL_HDR_PATH="${KERNEL_UAPI_HEADERS_DIR}/usr" -j$(nproc) headers_install
279 # The kernel makefiles create files named ..install.cmd and .install which
280 # are only side products. We don't want those. Let's delete them.
281 find ${KERNEL_UAPI_HEADERS_DIR} \( -name ..install.cmd -o -name .install \) -exec rm '{}' +
282 KERNEL_UAPI_HEADERS_TAR=${DIST_DIR}/kernel-uapi-headers.tar.gz
283 echo " Copying kernel UAPI headers to ${KERNEL_UAPI_HEADERS_TAR}"
284 tar -czf ${KERNEL_UAPI_HEADERS_TAR} --directory=${KERNEL_UAPI_HEADERS_DIR} usr/
285fi
286
287if [ -z "${SKIP_CP_KERNEL_HDR}" ] ; then
288 echo "========================================================"
289 KERNEL_HEADERS_TAR=${DIST_DIR}/kernel-headers.tar.gz
290 echo " Copying kernel headers to ${KERNEL_HEADERS_TAR}"
291 TMP_DIR="/tmp"
292 TMP_KERNEL_HEADERS_CHILD="kernel-headers"
293 TMP_KERNEL_HEADERS_DIR=$TMP_DIR/$TMP_KERNEL_HEADERS_CHILD
294 CURDIR=$(pwd)
295 mkdir -p $TMP_KERNEL_HEADERS_DIR
296 cd $ROOT_DIR/$KERNEL_DIR; find arch -name *.h -exec cp --parents {} $TMP_KERNEL_HEADERS_DIR \;
297 cd $ROOT_DIR/$KERNEL_DIR; find include -name *.h -exec cp --parents {} $TMP_KERNEL_HEADERS_DIR \;
298 cd $OUT_DIR; find -name *.h -exec cp --parents {} $TMP_KERNEL_HEADERS_DIR \;
299 tar -czvf $KERNEL_HEADERS_TAR --directory=$TMP_DIR $TMP_KERNEL_HEADERS_CHILD > /dev/null 2>&1
300 rm -rf $TMP_KERNEL_HEADERS_DIR
301 cd $CURDIR
302fi
303
304echo "========================================================"
305echo " Files copied to ${DIST_DIR}"
306
307# No trace_printk use on build server build
308if readelf -a ${DIST_DIR}/vmlinux 2>&1 | grep -q trace_printk_fmt; then
309 echo "========================================================"
310 echo "WARN: Found trace_printk usage in vmlinux."
311 echo ""
312 echo "trace_printk will cause trace_printk_init_buffers executed in kernel"
313 echo "start, which will increase memory and lead warning shown during boot."
314 echo "We should not carry trace_printk in production kernel."
315 echo ""
316 if [ ! -z "${STOP_SHIP_TRACEPRINTK}" ]; then
317 echo "ERROR: stop ship on trace_printk usage." 1>&2
318 exit 1
319 fi
320fi