1#!/bin/bash 2# 3# Copyright (C) 2013 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: generate_uapi_headers.sh [<options>] 18### 19### This script is used to get a copy of the uapi kernel headers 20### from an android kernel tree and copies them into an android source 21### tree without any processing. The script also creates all of the 22### generated headers and copies them into the android source tree. 23### 24### Options: 25### --skip-generation 26### Skip the step that generates all of the include files. 27### --download-kernel 28### Automatically create a temporary git repository and check out the 29### linux kernel source code at TOT. 30### --use-kernel-dir <DIR> 31### Do not check out the kernel source, use the kernel directory 32### pointed to by <DIR>. 33### --verify-modified-headers-only <DIR> 34### Do not build anything, simply verify that the set of modified 35### kernel headers have not changed. 36 37# Terminate the script if any command fails. 38set -eE 39 40TMPDIR="" 41ANDROID_DIR="" 42ANDROID_KERNEL_REPO="https://android.googlesource.com/kernel/common/" 43ANDROID_KERNEL_BRANCH="android-mainline" 44KERNEL_DIR="" 45KERNEL_DOWNLOAD=0 46ARCH_LIST=("arm" "arm64" "riscv" "x86") 47ANDROID_KERNEL_DIR="external/kernel-headers/original" 48SKIP_GENERATION=0 49VERIFY_HEADERS_ONLY=0 50 51function cleanup () { 52 if [[ "${TMPDIR}" =~ /tmp ]] && [[ -d "${TMPDIR}" ]]; then 53 echo "Removing temporary directory ${TMPDIR}" 54 rm -rf "${TMPDIR}" 55 TMPDIR="" 56 fi 57} 58 59function usage () { 60 grep '^###' $0 | sed -e 's/^###//' 61} 62 63function copy_hdrs () { 64 local src_dir=$1 65 local tgt_dir=$2 66 local dont_copy_dirs=$3 67 68 mkdir -p ${tgt_dir} 69 70 local search_dirs=() 71 72 # This only works if none of the filenames have spaces. 73 for file in $(ls -d ${src_dir}/* 2> /dev/null); do 74 if [[ -d "${file}" ]]; then 75 search_dirs+=("${file}") 76 elif [[ -f "${file}" ]] && [[ "${file}" =~ .h$ ]]; then 77 cp ${file} ${tgt_dir} 78 fi 79 done 80 81 if [[ "${dont_copy_dirs}" == "" ]]; then 82 for dir in "${search_dirs[@]}"; do 83 copy_hdrs "${dir}" ${tgt_dir}/$(basename ${dir}) 84 done 85 fi 86} 87 88function copy_if_exists () { 89 local check_dir=$1 90 local src_dir=$2 91 local tgt_dir=$3 92 93 mkdir -p ${tgt_dir} 94 95 # This only works if none of the filenames have spaces. 96 for file in $(ls -d ${src_dir}/* 2> /dev/null); do 97 if [[ -f "${file}" ]] && [[ "${file}" =~ .h$ ]]; then 98 # Check that this file exists in check_dir. 99 header=$(basename ${file}) 100 if [[ -f "${check_dir}/${header}" ]]; then 101 cp ${file} ${tgt_dir} 102 fi 103 fi 104 done 105} 106 107function verify_modified_hdrs () { 108 local src_dir=$1 109 local tgt_dir=$2 110 local kernel_dir=$3 111 112 local search_dirs=() 113 114 # This only works if none of the filenames have spaces. 115 for file in $(ls -d ${src_dir}/* 2> /dev/null); do 116 if [[ -d "${file}" ]]; then 117 search_dirs+=("${file}") 118 elif [[ -f "${file}" ]] && [[ "${file}" =~ .h$ ]]; then 119 tgt_file=${tgt_dir}/$(basename ${file}) 120 if [[ -e ${tgt_file} ]] && ! diff "${file}" "${tgt_file}" > /dev/null; then 121 if [[ ${file} =~ ${kernel_dir}/*(.+) ]]; then 122 echo "New version of ${BASH_REMATCH[1]} found in kernel headers." 123 else 124 echo "New version of ${file} found in kernel headers." 125 fi 126 echo "This file needs to be updated manually." 127 fi 128 fi 129 done 130 131 for dir in "${search_dirs[@]}"; do 132 verify_modified_hdrs "${dir}" ${tgt_dir}/$(basename ${dir}) "${kernel_dir}" 133 done 134} 135 136trap cleanup EXIT 137# This automatically triggers a call to cleanup. 138trap "exit 1" HUP INT TERM TSTP 139 140while [ $# -gt 0 ]; do 141 case "$1" in 142 "--skip-generation") 143 SKIP_GENERATION=1 144 ;; 145 "--download-kernel") 146 KERNEL_DOWNLOAD=1 147 ;; 148 "--use-kernel-dir") 149 if [[ $# -lt 2 ]]; then 150 echo "--use-kernel-dir requires an argument." 151 exit 1 152 fi 153 shift 154 KERNEL_DIR="$1" 155 KERNEL_DOWNLOAD=0 156 ;; 157 "--verify-modified-headers-only") 158 if [[ $# -lt 2 ]]; then 159 echo "--verify-modified-headers-only requires an argument." 160 exit 1 161 fi 162 shift 163 KERNEL_DIR="$1" 164 KERNEL_DOWNLOAD=0 165 VERIFY_HEADERS_ONLY=1 166 ;; 167 "-h" | "--help") 168 usage 169 exit 1 170 ;; 171 "-"*) 172 echo "Error: Unrecognized option $1" 173 usage 174 exit 1 175 ;; 176 *) 177 echo "Error: Extra arguments on the command-line." 178 usage 179 exit 1 180 ;; 181 esac 182 shift 183done 184 185ANDROID_KERNEL_DIR="${ANDROID_BUILD_TOP}/${ANDROID_KERNEL_DIR}" 186if [[ "${ANDROID_BUILD_TOP}" == "" ]]; then 187 echo "ANDROID_BUILD_TOP is not set, did you run lunch?" 188 exit 1 189elif [[ ! -d "${ANDROID_KERNEL_DIR}" ]]; then 190 echo "${ANDROID_BUILD_TOP} doesn't appear to be the root of an android tree." 191 echo " ${ANDROID_KERNEL_DIR} is not a directory." 192 exit 1 193fi 194 195if [[ ${KERNEL_DOWNLOAD} -eq 1 ]]; then 196 TMPDIR=$(mktemp -d /tmp/android_kernelXXXXXXXX) 197 cd "${TMPDIR}" 198 echo "Fetching android linux kernel source..." 199 git clone ${ANDROID_KERNEL_REPO} -b ${ANDROID_KERNEL_BRANCH} --depth=1 200 cd common 201 KERNEL_DIR="${TMPDIR}/common" 202elif [[ "${KERNEL_DIR}" == "" ]]; then 203 echo "Must specify one of --use-kernel-dir or --download-kernel." 204 exit 1 205elif [[ ! -d "${KERNEL_DIR}" ]] || [[ ! -d "${KERNEL_DIR}/kernel" ]]; then 206 echo "The kernel directory $KERNEL_DIR or $KERNEL_DIR/kernel does not exist." 207 exit 1 208else 209 cd "${KERNEL_DIR}" 210fi 211 212if [[ ${VERIFY_HEADERS_ONLY} -eq 1 ]]; then 213 # Verify if modified headers have changed. 214 verify_modified_hdrs "${KERNEL_DIR}/include/scsi" \ 215 "${ANDROID_KERNEL_DIR}/scsi" \ 216 "${KERNEL_DIR}" 217 exit 0 218fi 219 220if [[ ${SKIP_GENERATION} -eq 0 ]]; then 221 # Build all of the generated headers. 222 for arch in "${ARCH_LIST[@]}"; do 223 echo "Generating headers for arch ${arch}" 224 # Clean up any leftover headers. 225 make ARCH=${arch} distclean 226 make ARCH=${arch} headers_install 227 done 228fi 229 230# Completely delete the old original headers so that any deleted/moved 231# headers are also removed. 232rm -rf "${ANDROID_KERNEL_DIR}/uapi" 233mkdir -p "${ANDROID_KERNEL_DIR}/uapi" 234 235cd ${ANDROID_BUILD_TOP} 236 237# Copy all of the include/uapi files to the kernel headers uapi directory. 238copy_hdrs "${KERNEL_DIR}/include/uapi" "${ANDROID_KERNEL_DIR}/uapi" 239 240# Copy the staging files to uapi/linux. 241copy_hdrs "${KERNEL_DIR}/drivers/staging/android/uapi" \ 242 "${ANDROID_KERNEL_DIR}/uapi/linux" "no-copy-dirs" 243 244# Remove ion.h, it's not fully supported by the upstream kernel (see b/77976082). 245rm -f "${ANDROID_KERNEL_DIR}/uapi/linux/ion.h" 246 247# Copy the generated headers. 248copy_hdrs "${KERNEL_DIR}/include/generated/uapi" \ 249 "${ANDROID_KERNEL_DIR}/uapi" 250 251for arch in "${ARCH_LIST[@]}"; do 252 # Copy arch headers. 253 copy_hdrs "${KERNEL_DIR}/arch/${arch}/include/uapi" \ 254 "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}" 255 # Copy the generated arch headers. 256 copy_hdrs "${KERNEL_DIR}/arch/${arch}/include/generated/uapi" \ 257 "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}" 258 259 # Special copy of generated header files from arch/<ARCH>/generated/asm that 260 # also exist in uapi/asm-generic. 261 copy_if_exists "${KERNEL_DIR}/include/uapi/asm-generic" \ 262 "${KERNEL_DIR}/arch/${arch}/include/generated/asm" \ 263 "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}/asm" 264done 265 266# Verify if modified headers have changed. 267verify_modified_hdrs "${KERNEL_DIR}/include/scsi" \ 268 "${ANDROID_KERNEL_DIR}/scsi" \ 269 "${KERNEL_DIR}" 270echo "Headers updated." 271 272if [[ ${SKIP_GENERATION} -eq 0 ]]; then 273 cd "${KERNEL_DIR}" 274 # Clean all of the generated headers. 275 for arch in "${ARCH_LIST[@]}"; do 276 echo "Cleaning kernel files for arch ${arch}" 277 make ARCH=${arch} distclean 278 done 279fi 280