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