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