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 |
Matthias Maennich | 0646c8d | 2019-03-20 11:03:51 +0000 | [diff] [blame] | 49 | # 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 Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 53 | # |
| 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 Maennich | e4edd6f | 2019-02-13 12:36:27 +0000 | [diff] [blame] | 65 | # PRE_DEFCONFIG_CMDS |
| 66 | # Command evaluated before `make defconfig` |
| 67 | # |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 68 | # POST_DEFCONFIG_CMDS |
| 69 | # Command evaluated after `make defconfig` and before `make`. |
| 70 | # |
Matthias Maennich | e4edd6f | 2019-02-13 12:36:27 +0000 | [diff] [blame] | 71 | # POST_KERNEL_BUILD_CMDS |
| 72 | # Command evaluated after `make`. |
| 73 | # |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 74 | # 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 | |
| 96 | set -e |
| 97 | |
| 98 | # rel_path <to> <from> |
| 99 | # Generate relative directory path to reach directory <to> from <from> |
| 100 | function 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 | |
| 122 | export ROOT_DIR=$(readlink -f $(dirname $0)/..) |
| 123 | |
| 124 | # For module file Signing with the kernel (if needed) |
| 125 | FILE_SIGN_BIN=scripts/sign-file |
| 126 | SIGN_SEC=certs/signing_key.pem |
| 127 | SIGN_CERT=certs/signing_key.x509 |
| 128 | SIGN_ALGO=sha512 |
| 129 | |
| 130 | source "${ROOT_DIR}/build/envsetup.sh" |
| 131 | |
| 132 | export MAKE_ARGS=$@ |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 133 | export MODULES_STAGING_DIR=$(readlink -m ${COMMON_OUT_DIR}/staging) |
| 134 | export MODULES_PRIVATE_DIR=$(readlink -m ${COMMON_OUT_DIR}/private) |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 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 | 0646c8d | 2019-03-20 11:03:51 +0000 | [diff] [blame] | 142 | # CC=gcc is effectively a fallback to the default gcc including any target |
| 143 | # triplets. If the user wants to use a custom compiler, they are still able to |
| 144 | # pass an absolute path, e.g. CC=/usr/bin/gcc. |
| 145 | [ "${CC}" == "gcc" ] && unset CC |
| 146 | |
Matthias Maennich | 151047e | 2019-03-18 15:01:03 +0000 | [diff] [blame] | 147 | if [ -n "${CC}" ]; then |
| 148 | CC_ARG="CC=${CC}" |
| 149 | fi |
| 150 | |
| 151 | if [ -n "${LD}" ]; then |
| 152 | LD_ARG="LD=${LD}" |
| 153 | fi |
| 154 | |
| 155 | CC_LD_ARG="${CC_ARG} ${LD_ARG}" |
| 156 | |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 157 | mkdir -p ${OUT_DIR} |
| 158 | echo "========================================================" |
| 159 | echo " Setting up for build" |
| 160 | if [ -z "${SKIP_MRPROPER}" ] ; then |
| 161 | set -x |
Matthias Maennich | 151047e | 2019-03-18 15:01:03 +0000 | [diff] [blame] | 162 | (cd ${KERNEL_DIR} && make ${CC_LD_ARG} O=${OUT_DIR} mrproper) |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 163 | set +x |
| 164 | fi |
| 165 | |
Petri Gynther | 0172f35 | 2019-02-12 11:52:50 -0800 | [diff] [blame] | 166 | if [ "${PRE_DEFCONFIG_CMDS}" != "" ]; then |
| 167 | echo "========================================================" |
| 168 | echo " Running pre-defconfig command(s):" |
| 169 | set -x |
| 170 | eval ${PRE_DEFCONFIG_CMDS} |
| 171 | set +x |
| 172 | fi |
| 173 | |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 174 | if [ -z "${SKIP_DEFCONFIG}" ] ; then |
| 175 | set -x |
Matthias Maennich | 151047e | 2019-03-18 15:01:03 +0000 | [diff] [blame] | 176 | (cd ${KERNEL_DIR} && make ${CC_LD_ARG} O=${OUT_DIR} ${DEFCONFIG}) |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 177 | set +x |
| 178 | |
| 179 | if [ "${POST_DEFCONFIG_CMDS}" != "" ]; then |
| 180 | echo "========================================================" |
| 181 | echo " Running pre-make command(s):" |
| 182 | set -x |
| 183 | eval ${POST_DEFCONFIG_CMDS} |
| 184 | set +x |
| 185 | fi |
| 186 | fi |
| 187 | |
| 188 | echo "========================================================" |
| 189 | echo " Building kernel" |
| 190 | |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 191 | set -x |
| 192 | (cd ${OUT_DIR} && \ |
Matthias Maennich | 151047e | 2019-03-18 15:01:03 +0000 | [diff] [blame] | 193 | make O=${OUT_DIR} ${CC_LD_ARG} -j$(nproc) $@) |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 194 | set +x |
| 195 | |
Petri Gynther | 0172f35 | 2019-02-12 11:52:50 -0800 | [diff] [blame] | 196 | if [ "${POST_KERNEL_BUILD_CMDS}" != "" ]; then |
| 197 | echo "========================================================" |
| 198 | echo " Running post-kernel-build command(s):" |
| 199 | set -x |
| 200 | eval ${POST_KERNEL_BUILD_CMDS} |
| 201 | set +x |
| 202 | fi |
| 203 | |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 204 | rm -rf ${MODULES_STAGING_DIR} |
| 205 | mkdir -p ${MODULES_STAGING_DIR} |
| 206 | |
| 207 | if [ -n "${IN_KERNEL_MODULES}" ]; then |
| 208 | echo "========================================================" |
| 209 | echo " Installing kernel modules into staging directory" |
| 210 | |
| 211 | (cd ${OUT_DIR} && \ |
Matthias Maennich | 151047e | 2019-03-18 15:01:03 +0000 | [diff] [blame] | 212 | make O=${OUT_DIR} ${CC_LD_ARG} INSTALL_MOD_STRIP=1 \ |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 213 | INSTALL_MOD_PATH=${MODULES_STAGING_DIR} modules_install) |
| 214 | fi |
| 215 | |
| 216 | if [[ -z "${SKIP_EXT_MODULES}" ]] && [[ "${EXT_MODULES}" != "" ]]; then |
| 217 | echo "========================================================" |
| 218 | echo " Building external modules and installing them into staging directory" |
| 219 | |
| 220 | for EXT_MOD in ${EXT_MODULES}; do |
| 221 | # The path that we pass in via the variable M needs to be a relative path |
| 222 | # relative to the kernel source directory. The source files will then be |
| 223 | # looked for in ${KERNEL_DIR}/${EXT_MOD_REL} and the object files (i.e. .o |
| 224 | # and .ko) files will be stored in ${OUT_DIR}/${EXT_MOD_REL}. If we |
| 225 | # instead set M to an absolute path, then object (i.e. .o and .ko) files |
| 226 | # are stored in the module source directory which is not what we want. |
| 227 | EXT_MOD_REL=$(rel_path ${ROOT_DIR}/${EXT_MOD} ${KERNEL_DIR}) |
| 228 | # The output directory must exist before we invoke make. Otherwise, the |
| 229 | # build system behaves horribly wrong. |
| 230 | mkdir -p ${OUT_DIR}/${EXT_MOD_REL} |
| 231 | set -x |
| 232 | 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] | 233 | O=${OUT_DIR} ${CC_LD_ARG} -j$(nproc) "$@" |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 234 | 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] | 235 | O=${OUT_DIR} ${CC_LD_ARG} INSTALL_MOD_STRIP=1 \ |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 236 | INSTALL_MOD_PATH=${MODULES_STAGING_DIR} modules_install |
| 237 | set +x |
| 238 | done |
| 239 | |
| 240 | fi |
| 241 | |
| 242 | if [ "${EXTRA_CMDS}" != "" ]; then |
| 243 | echo "========================================================" |
| 244 | echo " Running extra build command(s):" |
| 245 | set -x |
| 246 | eval ${EXTRA_CMDS} |
| 247 | set +x |
| 248 | fi |
| 249 | |
| 250 | OVERLAYS_OUT="" |
| 251 | for ODM_DIR in ${ODM_DIRS}; do |
| 252 | OVERLAY_DIR=${ROOT_DIR}/device/${ODM_DIR}/overlays |
| 253 | |
| 254 | if [ -d ${OVERLAY_DIR} ]; then |
| 255 | OVERLAY_OUT_DIR=${OUT_DIR}/overlays/${ODM_DIR} |
| 256 | mkdir -p ${OVERLAY_OUT_DIR} |
| 257 | make -C ${OVERLAY_DIR} DTC=${OUT_DIR}/scripts/dtc/dtc OUT_DIR=${OVERLAY_OUT_DIR} |
| 258 | OVERLAYS=$(find ${OVERLAY_OUT_DIR} -name "*.dtbo") |
| 259 | OVERLAYS_OUT="$OVERLAYS_OUT $OVERLAYS" |
| 260 | fi |
| 261 | done |
| 262 | |
| 263 | mkdir -p ${DIST_DIR} |
| 264 | echo "========================================================" |
| 265 | echo " Copying files" |
| 266 | for FILE in ${FILES}; do |
| 267 | if [ -f ${OUT_DIR}/${FILE} ]; then |
| 268 | echo " $FILE" |
| 269 | cp -p ${OUT_DIR}/${FILE} ${DIST_DIR}/ |
| 270 | else |
| 271 | echo " $FILE does not exist, skipping" |
| 272 | fi |
| 273 | done |
| 274 | |
| 275 | for FILE in ${OVERLAYS_OUT}; do |
| 276 | OVERLAY_DIST_DIR=${DIST_DIR}/$(dirname ${FILE#${OUT_DIR}/overlays/}) |
| 277 | echo " ${FILE#${OUT_DIR}/}" |
| 278 | mkdir -p ${OVERLAY_DIST_DIR} |
| 279 | cp ${FILE} ${OVERLAY_DIST_DIR}/ |
| 280 | done |
| 281 | |
| 282 | MODULES=$(find ${MODULES_STAGING_DIR} -type f -name "*.ko") |
| 283 | if [ -n "${MODULES}" ]; then |
| 284 | echo "========================================================" |
| 285 | echo " Copying modules files" |
| 286 | if [ -n "${IN_KERNEL_MODULES}" -o "${EXT_MODULES}" != "" ]; then |
| 287 | for FILE in ${MODULES}; do |
| 288 | echo " ${FILE#${MODULES_STAGING_DIR}/}" |
| 289 | cp -p ${FILE} ${DIST_DIR} |
| 290 | done |
| 291 | fi |
| 292 | fi |
| 293 | |
| 294 | if [ "${UNSTRIPPED_MODULES}" != "" ]; then |
| 295 | echo "========================================================" |
| 296 | echo " Copying unstripped module files for debugging purposes (not loaded on device)" |
| 297 | mkdir -p ${UNSTRIPPED_DIR} |
| 298 | for MODULE in ${UNSTRIPPED_MODULES}; do |
| 299 | find ${MODULES_PRIVATE_DIR} -name ${MODULE} -exec cp {} ${UNSTRIPPED_DIR} \; |
| 300 | done |
| 301 | fi |
| 302 | |
| 303 | if [ -z "${SKIP_CP_KERNEL_HDR}" ]; then |
| 304 | echo "========================================================" |
| 305 | echo " Installing UAPI kernel headers:" |
| 306 | mkdir -p "${KERNEL_UAPI_HEADERS_DIR}/usr" |
Matthias Maennich | 151047e | 2019-03-18 15:01:03 +0000 | [diff] [blame] | 307 | 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] | 308 | # The kernel makefiles create files named ..install.cmd and .install which |
| 309 | # are only side products. We don't want those. Let's delete them. |
| 310 | find ${KERNEL_UAPI_HEADERS_DIR} \( -name ..install.cmd -o -name .install \) -exec rm '{}' + |
| 311 | KERNEL_UAPI_HEADERS_TAR=${DIST_DIR}/kernel-uapi-headers.tar.gz |
| 312 | echo " Copying kernel UAPI headers to ${KERNEL_UAPI_HEADERS_TAR}" |
| 313 | tar -czf ${KERNEL_UAPI_HEADERS_TAR} --directory=${KERNEL_UAPI_HEADERS_DIR} usr/ |
| 314 | fi |
| 315 | |
| 316 | if [ -z "${SKIP_CP_KERNEL_HDR}" ] ; then |
Matthias Maennich | bec886a | 2019-04-15 07:23:47 +0100 | [diff] [blame^] | 317 | echo "========================================================" |
| 318 | KERNEL_HEADERS_TAR=${DIST_DIR}/kernel-headers.tar.gz |
| 319 | echo " Copying kernel headers to ${KERNEL_HEADERS_TAR}" |
| 320 | pushd $ROOT_DIR/$KERNEL_DIR |
| 321 | find arch include $OUT_DIR -name *.h -print0 \ |
| 322 | | tar -czf $KERNEL_HEADERS_TAR \ |
| 323 | --absolute-names \ |
| 324 | --dereference \ |
| 325 | --transform "s,.*$OUT_DIR,," \ |
| 326 | --transform "s,^,kernel-headers/," \ |
| 327 | --null -T - |
| 328 | popd |
Matthias Maennich | 6652d74 | 2019-02-01 22:20:44 +0000 | [diff] [blame] | 329 | fi |
| 330 | |
| 331 | echo "========================================================" |
| 332 | echo " Files copied to ${DIST_DIR}" |
| 333 | |
| 334 | # No trace_printk use on build server build |
| 335 | if readelf -a ${DIST_DIR}/vmlinux 2>&1 | grep -q trace_printk_fmt; then |
| 336 | echo "========================================================" |
| 337 | echo "WARN: Found trace_printk usage in vmlinux." |
| 338 | echo "" |
| 339 | echo "trace_printk will cause trace_printk_init_buffers executed in kernel" |
| 340 | echo "start, which will increase memory and lead warning shown during boot." |
| 341 | echo "We should not carry trace_printk in production kernel." |
| 342 | echo "" |
| 343 | if [ ! -z "${STOP_SHIP_TRACEPRINTK}" ]; then |
| 344 | echo "ERROR: stop ship on trace_printk usage." 1>&2 |
| 345 | exit 1 |
| 346 | fi |
| 347 | fi |