| #!/bin/bash | |
| # | |
| # Copyright (C) 2013 The Android Open Source Project | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| ### Usage: generate_uapi_headers.sh [<options>] | |
| ### | |
| ### This script is used to get a copy of the uapi kernel headers | |
| ### from an android kernel tree and copies them into an android source | |
| ### tree without any processing. The script also creates all of the | |
| ### generated headers and copies them into the android source tree. | |
| ### | |
| ### Options: | |
| ### --skip-generation | |
| ### Skip the step that generates all of the include files. | |
| ### --download-kernel | |
| ### Automatically create a temporary git repository and check out the | |
| ### linux kernel source code at TOT. | |
| ### --use-kernel-dir <DIR> | |
| ### Do not check out the kernel source, use the kernel directory | |
| ### pointed to by <DIR>. | |
| ### --verify-modified-headers-only <DIR> | |
| ### Do not build anything, simply verify that the set of modified | |
| ### kernel headers have not changed. | |
| # Terminate the script if any command fails. | |
| set -eE | |
| TMPDIR="" | |
| ANDROID_DIR="" | |
| ANDROID_KERNEL_REPO="https://android.googlesource.com/kernel/common/" | |
| ANDROID_KERNEL_BRANCH="android-mainline" | |
| KERNEL_DIR="" | |
| KERNEL_DOWNLOAD=0 | |
| ARCH_LIST=("arm" "arm64" "riscv" "x86") | |
| ANDROID_KERNEL_DIR="external/kernel-headers/original" | |
| SKIP_GENERATION=0 | |
| VERIFY_HEADERS_ONLY=0 | |
| function cleanup () { | |
| if [[ "${TMPDIR}" =~ /tmp ]] && [[ -d "${TMPDIR}" ]]; then | |
| echo "Removing temporary directory ${TMPDIR}" | |
| rm -rf "${TMPDIR}" | |
| TMPDIR="" | |
| fi | |
| } | |
| function usage () { | |
| grep '^###' $0 | sed -e 's/^###//' | |
| } | |
| function copy_hdrs () { | |
| local src_dir=$1 | |
| local tgt_dir=$2 | |
| local dont_copy_dirs=$3 | |
| mkdir -p ${tgt_dir} | |
| local search_dirs=() | |
| # This only works if none of the filenames have spaces. | |
| for file in $(ls -d ${src_dir}/* 2> /dev/null); do | |
| if [[ -d "${file}" ]]; then | |
| search_dirs+=("${file}") | |
| elif [[ -f "${file}" ]] && [[ "${file}" =~ .h$ ]]; then | |
| cp ${file} ${tgt_dir} | |
| fi | |
| done | |
| if [[ "${dont_copy_dirs}" == "" ]]; then | |
| for dir in "${search_dirs[@]}"; do | |
| copy_hdrs "${dir}" ${tgt_dir}/$(basename ${dir}) | |
| done | |
| fi | |
| } | |
| function copy_if_exists () { | |
| local check_dir=$1 | |
| local src_dir=$2 | |
| local tgt_dir=$3 | |
| mkdir -p ${tgt_dir} | |
| # This only works if none of the filenames have spaces. | |
| for file in $(ls -d ${src_dir}/* 2> /dev/null); do | |
| if [[ -f "${file}" ]] && [[ "${file}" =~ .h$ ]]; then | |
| # Check that this file exists in check_dir. | |
| header=$(basename ${file}) | |
| if [[ -f "${check_dir}/${header}" ]]; then | |
| cp ${file} ${tgt_dir} | |
| fi | |
| fi | |
| done | |
| } | |
| function verify_modified_hdrs () { | |
| local src_dir=$1 | |
| local tgt_dir=$2 | |
| local kernel_dir=$3 | |
| local search_dirs=() | |
| # This only works if none of the filenames have spaces. | |
| for file in $(ls -d ${src_dir}/* 2> /dev/null); do | |
| if [[ -d "${file}" ]]; then | |
| search_dirs+=("${file}") | |
| elif [[ -f "${file}" ]] && [[ "${file}" =~ .h$ ]]; then | |
| tgt_file=${tgt_dir}/$(basename ${file}) | |
| if [[ -e ${tgt_file} ]] && ! diff "${file}" "${tgt_file}" > /dev/null; then | |
| if [[ ${file} =~ ${kernel_dir}/*(.+) ]]; then | |
| echo "New version of ${BASH_REMATCH[1]} found in kernel headers." | |
| else | |
| echo "New version of ${file} found in kernel headers." | |
| fi | |
| echo "This file needs to be updated manually." | |
| fi | |
| fi | |
| done | |
| for dir in "${search_dirs[@]}"; do | |
| verify_modified_hdrs "${dir}" ${tgt_dir}/$(basename ${dir}) "${kernel_dir}" | |
| done | |
| } | |
| trap cleanup EXIT | |
| # This automatically triggers a call to cleanup. | |
| trap "exit 1" HUP INT TERM TSTP | |
| while [ $# -gt 0 ]; do | |
| case "$1" in | |
| "--skip-generation") | |
| SKIP_GENERATION=1 | |
| ;; | |
| "--download-kernel") | |
| KERNEL_DOWNLOAD=1 | |
| ;; | |
| "--use-kernel-dir") | |
| if [[ $# -lt 2 ]]; then | |
| echo "--use-kernel-dir requires an argument." | |
| exit 1 | |
| fi | |
| shift | |
| KERNEL_DIR="$1" | |
| KERNEL_DOWNLOAD=0 | |
| ;; | |
| "--verify-modified-headers-only") | |
| if [[ $# -lt 2 ]]; then | |
| echo "--verify-modified-headers-only requires an argument." | |
| exit 1 | |
| fi | |
| shift | |
| KERNEL_DIR="$1" | |
| KERNEL_DOWNLOAD=0 | |
| VERIFY_HEADERS_ONLY=1 | |
| ;; | |
| "-h" | "--help") | |
| usage | |
| exit 1 | |
| ;; | |
| "-"*) | |
| echo "Error: Unrecognized option $1" | |
| usage | |
| exit 1 | |
| ;; | |
| *) | |
| echo "Error: Extra arguments on the command-line." | |
| usage | |
| exit 1 | |
| ;; | |
| esac | |
| shift | |
| done | |
| ANDROID_KERNEL_DIR="${ANDROID_BUILD_TOP}/${ANDROID_KERNEL_DIR}" | |
| if [[ "${ANDROID_BUILD_TOP}" == "" ]]; then | |
| echo "ANDROID_BUILD_TOP is not set, did you run lunch?" | |
| exit 1 | |
| elif [[ ! -d "${ANDROID_KERNEL_DIR}" ]]; then | |
| echo "${ANDROID_BUILD_TOP} doesn't appear to be the root of an android tree." | |
| echo " ${ANDROID_KERNEL_DIR} is not a directory." | |
| exit 1 | |
| fi | |
| if [[ ${KERNEL_DOWNLOAD} -eq 1 ]]; then | |
| TMPDIR=$(mktemp -d /tmp/android_kernelXXXXXXXX) | |
| cd "${TMPDIR}" | |
| echo "Fetching android linux kernel source..." | |
| git clone ${ANDROID_KERNEL_REPO} -b ${ANDROID_KERNEL_BRANCH} --depth=1 | |
| cd common | |
| KERNEL_DIR="${TMPDIR}/common" | |
| elif [[ "${KERNEL_DIR}" == "" ]]; then | |
| echo "Must specify one of --use-kernel-dir or --download-kernel." | |
| exit 1 | |
| elif [[ ! -d "${KERNEL_DIR}" ]] || [[ ! -d "${KERNEL_DIR}/kernel" ]]; then | |
| echo "The kernel directory $KERNEL_DIR or $KERNEL_DIR/kernel does not exist." | |
| exit 1 | |
| else | |
| cd "${KERNEL_DIR}" | |
| fi | |
| if [[ ${VERIFY_HEADERS_ONLY} -eq 1 ]]; then | |
| # Verify if modified headers have changed. | |
| verify_modified_hdrs "${KERNEL_DIR}/include/scsi" \ | |
| "${ANDROID_KERNEL_DIR}/scsi" \ | |
| "${KERNEL_DIR}" | |
| exit 0 | |
| fi | |
| if [[ ${SKIP_GENERATION} -eq 0 ]]; then | |
| # Build all of the generated headers. | |
| for arch in "${ARCH_LIST[@]}"; do | |
| echo "Generating headers for arch ${arch}" | |
| # Clean up any leftover headers. | |
| make ARCH=${arch} distclean | |
| make ARCH=${arch} headers_install | |
| done | |
| fi | |
| # Completely delete the old original headers so that any deleted/moved | |
| # headers are also removed. | |
| rm -rf "${ANDROID_KERNEL_DIR}/uapi" | |
| mkdir -p "${ANDROID_KERNEL_DIR}/uapi" | |
| cd ${ANDROID_BUILD_TOP} | |
| # Copy all of the include/uapi files to the kernel headers uapi directory. | |
| copy_hdrs "${KERNEL_DIR}/include/uapi" "${ANDROID_KERNEL_DIR}/uapi" | |
| # Copy the staging files to uapi/linux. | |
| copy_hdrs "${KERNEL_DIR}/drivers/staging/android/uapi" \ | |
| "${ANDROID_KERNEL_DIR}/uapi/linux" "no-copy-dirs" | |
| # Remove ion.h, it's not fully supported by the upstream kernel (see b/77976082). | |
| rm -f "${ANDROID_KERNEL_DIR}/uapi/linux/ion.h" | |
| # Copy the generated headers. | |
| copy_hdrs "${KERNEL_DIR}/include/generated/uapi" \ | |
| "${ANDROID_KERNEL_DIR}/uapi" | |
| for arch in "${ARCH_LIST[@]}"; do | |
| # Copy arch headers. | |
| copy_hdrs "${KERNEL_DIR}/arch/${arch}/include/uapi" \ | |
| "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}" | |
| # Copy the generated arch headers. | |
| copy_hdrs "${KERNEL_DIR}/arch/${arch}/include/generated/uapi" \ | |
| "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}" | |
| # Special copy of generated header files from arch/<ARCH>/generated/asm that | |
| # also exist in uapi/asm-generic. | |
| copy_if_exists "${KERNEL_DIR}/include/uapi/asm-generic" \ | |
| "${KERNEL_DIR}/arch/${arch}/include/generated/asm" \ | |
| "${ANDROID_KERNEL_DIR}/uapi/asm-${arch}/asm" | |
| done | |
| # Verify if modified headers have changed. | |
| verify_modified_hdrs "${KERNEL_DIR}/include/scsi" \ | |
| "${ANDROID_KERNEL_DIR}/scsi" \ | |
| "${KERNEL_DIR}" | |
| echo "Headers updated." | |
| if [[ ${SKIP_GENERATION} -eq 0 ]]; then | |
| cd "${KERNEL_DIR}" | |
| # Clean all of the generated headers. | |
| for arch in "${ARCH_LIST[@]}"; do | |
| echo "Cleaning kernel files for arch ${arch}" | |
| make ARCH=${arch} distclean | |
| done | |
| fi |