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