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.
35set -eE
36
37TMPDIR=""
38ANDROID_DIR=""
39KERNEL_VERSION="android-3.10"
40KERNEL_DIR=""
41KERNEL_DOWNLOAD=0
42ARCH_LIST=("arm" "arm64" "mips" "x86")
43ANDROID_KERNEL_DIR="external/kernel-headers/original"
44SKIP_GENERATION=0
45
46function cleanup () {
47  if [[ "${TMPDIR}" =~ /tmp ]] && [[ -d "${TMPDIR}" ]]; then
48    echo "Removing temporary directory ${TMPDIR}"
49    rm -rf "${TMPDIR}"
50    TMPDIR=""
51  fi
52}
53
54function usage () {
55  grep '^###' $0 | sed -e 's/^###//'
56}
57
58function 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
83function 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
102trap cleanup EXIT
103# This automatically triggers a call to cleanup.
104trap "exit 1" HUP INT TERM TSTP
105
106while [ $# -gt 0 ]; do
107  case "$1" in
108    "--skip-generation")
109      SKIP_GENERATION=1
110      ;;
111    "--download-kernel")
112      KERNEL_DOWNLOAD=1
113      ;;
114    "--use-kernel-dir")
115      if [[ $# -lt 2 ]]; then
116        echo "--use-kernel-dir requires an argument."
117        exit 1
118      fi
119      shift
120      KERNEL_DIR="$1"
121      KERNEL_DOWNLOAD=0
122      ;;
123    "-h" | "--help")
124      usage
125      exit 1
126      ;;
127    "-"*)
128      echo "Error: Unrecognized option $1"
129      usage
130      exit 1
131      ;;
132    *)
133      echo "Error: Extra arguments on the command-line."
134      usage
135      exit 1
136      ;;
137  esac
138  shift
139done
140
141ANDROID_KERNEL_DIR="${ANDROID_BUILD_TOP}/${ANDROID_KERNEL_DIR}"
142if [[ "${ANDROID_BUILD_TOP}" == "" ]]; then
143  echo "ANDROID_BUILD_TOP is not set, did you run lunch?"
144  exit 1
145elif [[ ! -d "${ANDROID_KERNEL_DIR}" ]]; then
146  echo "${ANDROID_BUILD_TOP} doesn't appear to be the root of an android tree."
147  echo "  ${ANDROID_KERNEL_DIR} is not a directory."
148  exit 1
149fi
150
151if [[ -d "${KERNEL_DIR}/linux-stable" ]]; then
152  src_dir="linux-stable"
153else
154  src_dir="common"
155fi
156
157if [[ ${KERNEL_DOWNLOAD} -eq 1 ]]; then
158  TMPDIR=$(mktemp -d /tmp/android_kernelXXXXXXXX)
159  cd "${TMPDIR}"
160  echo "Fetching android kernel source ${KERNEL_VERSION}"
161  git clone https://android.googlesource.com/kernel/common.git
162  cd "${src_dir}"
163  git checkout "${KERNEL_VERSION}"
164  KERNEL_DIR="${TMPDIR}"
165elif [[ "${KERNEL_DIR}" == "" ]]; then
166  echo "Must specify one of --use-kernel-dir or --download-kernel."
167  exit 1
168elif [[ ! -d "${KERNEL_DIR}" ]] || [[ ! -d "${KERNEL_DIR}/${src_dir}" ]]; then
169  echo "The kernel directory $KERNEL_DIR or $KERNEL_DIR/${src_dir} does not exist."
170  exit 1
171else
172  cd "${KERNEL_DIR}/${src_dir}"
173fi
174
175if [[ ${SKIP_GENERATION} -eq 0 ]]; then
176  # Build all of the generated headers.
177  for arch in "${ARCH_LIST[@]}"; do
178    echo "Generating headers for arch ${arch}"
179    make ARCH=${arch} headers_install
180  done
181fi
182
183cd ${ANDROID_BUILD_TOP}
184
185# Copy all of the include/uapi files to the kernel headers uapi directory.
186copy_hdrs "${KERNEL_DIR}/${src_dir}/include/uapi" "${ANDROID_KERNEL_DIR}/uapi"
187
188# Copy the staging files to uapi/linux.
189copy_hdrs "${KERNEL_DIR}/${src_dir}/drivers/staging/android/uapi" \
190          "${ANDROID_KERNEL_DIR}/uapi/linux" "no-copy-dirs"
191
192# Copy the generated headers.
193copy_hdrs "${KERNEL_DIR}/${src_dir}/include/generated/uapi" \
194          "${ANDROID_KERNEL_DIR}/uapi"
195
196for arch in "${ARCH_LIST[@]}"; do
197  # Copy arch headers.
198  copy_hdrs "${KERNEL_DIR}/${src_dir}/arch/${arch}/include/uapi" \
199            "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}"
200  # Copy the generated arch headers.
201  copy_hdrs "${KERNEL_DIR}/${src_dir}/arch/${arch}/include/generated/uapi" \
202            "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}"
203
204  # Special copy of generated header files from arch/<ARCH>/generated/asm that
205  # also exist in uapi/asm-generic.
206  copy_if_exists "${KERNEL_DIR}/${src_dir}/include/uapi/asm-generic" \
207                 "${KERNEL_DIR}/${src_dir}/arch/${arch}/include/generated/asm" \
208                 "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}/asm"
209done
210