• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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