• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3# Copyright (c) 2025 Huawei Device Co., Ltd.
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8#     http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16import os
17import subprocess
18import argparse
19import shutil
20
21
22def check_uapi_dir_exists(uapi_dir):
23    """Check if the UAPI directory exists"""
24    return os.path.isdir(uapi_dir)
25
26
27def make_uapi_headers(kernel_dir, target_cpu, output_dir):
28    """Generate UAPI header file"""
29    uapi_dir = os.path.join(output_dir, "usr/include")
30
31    try:
32        # Clean up and generate header files
33        subprocess.run(['rm', '-rf', str(uapi_dir)], check=True)
34        cmd = [ 'make',
35                '-C',
36                str(kernel_dir),
37                '-sj',
38                'headers',
39                'O=%s' % output_dir,
40                'ARCH=%s' % target_cpu ]
41        subprocess.run(cmd, check=True)
42
43        # Special handling of individual files
44        ashmem_src = os.path.join(kernel_dir, "drivers/staging/android/uapi/ashmem.h")
45        ashmem_dst = os.path.join(uapi_dir, "linux/ashmem.h")
46        if os.path.exists(ashmem_src):
47            subprocess.run(['cp', '-f', str(ashmem_src), str(ashmem_dst)], check=True)
48
49        input_h = os.path.join(uapi_dir, "linux/input.h")
50        if os.path.exists(input_h):
51            input_cmd = [ 'sed',
52                           '-i',
53                           r'/#define _INPUT_H/i#define _UAPI_INPUT_H',
54                           str(input_h) ]
55            subprocess.run(input_cmd, check=True)
56
57        socket_h = os.path.join(uapi_dir, "linux/socket.h")
58        if os.path.exists(socket_h):
59            sockaddr_cmd = [ 'sed',
60                             '-i',
61                             r'/struct __kernel_sockaddr_storage/i#define sockaddr_storage __kernel_sockaddr_storage',
62                             str(socket_h) ]
63            subprocess.run(sockaddr_cmd, check=True)
64
65        return True
66    except subprocess.CalledProcessError as e:
67        print("Failed to make UAPI headers: {e}")
68        return False
69
70
71def list_uapi_files(uapi_dir, exclude_pattern):
72    """List UAPI files and filter them"""
73    try:
74        list_files = subprocess.run(['ls', str(uapi_dir)], capture_output=True, text=True, check=True)
75        result = subprocess.run(['grep', '-vE', str(exclude_pattern)],
76            input=list_files.stdout, capture_output=True, text=True, check=True)
77        return result.stdout.strip().split('\n')
78    except subprocess.CalledProcessError as e:
79        print(f"Failed to list UAPI files: {e}")
80        return []
81
82
83def copy_filtered_uapi_dirs(uapi_dir, final_uapi_dir, output_uapi):
84    copied_files = []
85    try:
86        os.makedirs(output_uapi, exist_ok=True)
87
88        for item in uapi_dir:
89            src_path = os.path.join(final_uapi_dir, item)
90            dst_path = os.path.join(output_uapi, item)
91
92            if os.path.isdir(src_path):
93                for root, dirs, files in os.walk(src_path):
94                    for file in files:
95                        src_file = os.path.join(root, file)
96                        rel_path = os.path.relpath(src_file, final_uapi_dir)
97                        dst_file = os.path.join(output_uapi, rel_path)
98
99                        os.makedirs(os.path.dirname(dst_file), exist_ok=True)
100                        shutil.copy2(src_file, dst_file)
101                        copied_files.append(dst_file)
102                        print(f"Copied: {rel_path} -> {dst_file}")
103            else:
104                # Processing individual files
105                os.makedirs(os.path.dirname(dst_path), exist_ok=True)
106                shutil.copy2(src_path, dst_path)
107                copied_files.append(dst_path)
108                print("Copied: {item} -> {dst_path}")
109    except Exception as e:
110        print(f"Error copying: {e}")
111
112    return copied_files
113
114
115def main():
116    parser = argparse.ArgumentParser()
117    parser.add_argument("--musl-uapi-dir", required=True)
118    parser.add_argument("--musl-linux-kernel-dir", required=True)
119    parser.add_argument("--target-cpu", required=True)
120    parser.add_argument("--uapi-file-list", required=True)
121    parser.add_argument("--output-uapi", required=True)
122    args = parser.parse_args()
123
124    # Determine the source of UAPI
125    if not check_uapi_dir_exists(args.musl_uapi_dir):
126        print("UAPI directory not found, generating from kernel...")
127        kernel_out_dir = os.path.join(args.musl_linux_kernel_dir, "make_output")
128        success = make_uapi_headers(
129            args.musl_linux_kernel_dir,
130            args.target_cpu,
131            kernel_out_dir
132        )
133        if not success:
134            exit(1)
135        uapi_from = "make"
136        final_uapi_dir = os.path.join(kernel_out_dir, "usr/include")
137    else:
138        print("Using existing UAPI directory")
139        uapi_from = "local"
140        final_uapi_dir = args.musl_uapi_dir
141
142    exclude_pattern = "^asm$|^scsi$" if uapi_from == "make" else "^asm-arm$|^asm-arm64$|^scsi$"
143
144    # List UAPI
145    uapi_files = list_uapi_files(final_uapi_dir, exclude_pattern)
146
147    copied_files = copy_filtered_uapi_dirs(uapi_files, final_uapi_dir, args.output_uapi)
148
149    # Write output file
150    with os.fdopen(os.open(args.uapi_file_list, os.O_WRONLY | os.O_CREAT, mode=0o640), 'w') as f:
151        f.write(f"UAPI_FROM:{uapi_from}\n")
152        f.write(f"UAPI_DIR:{final_uapi_dir}\n")
153        f.write("UAPI_FILES:\n")
154        f.write("\n".join(copied_files) + "\n")
155
156
157if __name__ == "__main__":
158    main()