xref: /dpdk/devtools/linux-uapi.sh (revision cf97dfd12eaf3617cf7243226efa4940729c9a9a)
1*cf97dfd1SMaxime Coquelin#!/bin/sh -e
2*cf97dfd1SMaxime Coquelin# SPDX-License-Identifier: BSD-3-Clause
3*cf97dfd1SMaxime Coquelin# Copyright (c) 2024 Red Hat, Inc.
4*cf97dfd1SMaxime Coquelin
5*cf97dfd1SMaxime Coquelin#
6*cf97dfd1SMaxime Coquelin# Import and check Linux Kernel uAPI headers
7*cf97dfd1SMaxime Coquelin#
8*cf97dfd1SMaxime Coquelin
9*cf97dfd1SMaxime Coquelinbase_url="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/"
10*cf97dfd1SMaxime Coquelinbase_path="kernel/linux/uapi/"
11*cf97dfd1SMaxime Coquelinversion=""
12*cf97dfd1SMaxime Coquelinfile=""
13*cf97dfd1SMaxime Coquelincheck_headers=0
14*cf97dfd1SMaxime Coquelinerrors=0
15*cf97dfd1SMaxime Coquelin
16*cf97dfd1SMaxime Coquelinprint_usage()
17*cf97dfd1SMaxime Coquelin{
18*cf97dfd1SMaxime Coquelin	echo "Usage: $(basename $0) [-h] [-i FILE] [-u VERSION] [-c]"
19*cf97dfd1SMaxime Coquelin	echo "-i FILE      import Linux header file. E.g. linux/vfio.h"
20*cf97dfd1SMaxime Coquelin	echo "-u VERSION   update imported list of Linux headers to a given version. E.g. v6.10"
21*cf97dfd1SMaxime Coquelin	echo "-c           check headers are valid"
22*cf97dfd1SMaxime Coquelin}
23*cf97dfd1SMaxime Coquelin
24*cf97dfd1SMaxime Coquelinversion_older_than() {
25*cf97dfd1SMaxime Coquelin    printf '%s\n%s' "$1" "$2" | sort -C -V
26*cf97dfd1SMaxime Coquelin}
27*cf97dfd1SMaxime Coquelin
28*cf97dfd1SMaxime Coquelindownload_header()
29*cf97dfd1SMaxime Coquelin{
30*cf97dfd1SMaxime Coquelin	local header=$1
31*cf97dfd1SMaxime Coquelin	local path=$2
32*cf97dfd1SMaxime Coquelin
33*cf97dfd1SMaxime Coquelin	local url="${base_url}${header}?h=${version}"
34*cf97dfd1SMaxime Coquelin
35*cf97dfd1SMaxime Coquelin	if ! curl -s -f --create-dirs -o $path $url; then
36*cf97dfd1SMaxime Coquelin		echo "Failed to download $url"
37*cf97dfd1SMaxime Coquelin		return 1
38*cf97dfd1SMaxime Coquelin	fi
39*cf97dfd1SMaxime Coquelin
40*cf97dfd1SMaxime Coquelin	return 0
41*cf97dfd1SMaxime Coquelin}
42*cf97dfd1SMaxime Coquelin
43*cf97dfd1SMaxime Coquelinupdate_headers()
44*cf97dfd1SMaxime Coquelin{
45*cf97dfd1SMaxime Coquelin	local header
46*cf97dfd1SMaxime Coquelin	local url
47*cf97dfd1SMaxime Coquelin	local path
48*cf97dfd1SMaxime Coquelin
49*cf97dfd1SMaxime Coquelin	echo "Updating to $version"
50*cf97dfd1SMaxime Coquelin	for filename in $(find $base_path -name "*.h" -type f); do
51*cf97dfd1SMaxime Coquelin		header=${filename#$base_path}
52*cf97dfd1SMaxime Coquelin		download_header $header $filename || return 1
53*cf97dfd1SMaxime Coquelin	done
54*cf97dfd1SMaxime Coquelin
55*cf97dfd1SMaxime Coquelin	return 0
56*cf97dfd1SMaxime Coquelin}
57*cf97dfd1SMaxime Coquelin
58*cf97dfd1SMaxime Coquelinimport_header()
59*cf97dfd1SMaxime Coquelin{
60*cf97dfd1SMaxime Coquelin	local include
61*cf97dfd1SMaxime Coquelin	local import
62*cf97dfd1SMaxime Coquelin	local header=$1
63*cf97dfd1SMaxime Coquelin
64*cf97dfd1SMaxime Coquelin	local path="${base_path}${header}"
65*cf97dfd1SMaxime Coquelin
66*cf97dfd1SMaxime Coquelin	download_header $header $path || return 1
67*cf97dfd1SMaxime Coquelin
68*cf97dfd1SMaxime Coquelin	for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
69*cf97dfd1SMaxime Coquelin		if [ ! -f "${base_path}${include}" ]; then
70*cf97dfd1SMaxime Coquelin			read -p "Import $include (y/n): " import && [ "$import" = 'y' ] || continue
71*cf97dfd1SMaxime Coquelin			echo "Importing $include for $path"
72*cf97dfd1SMaxime Coquelin			import_header "$include" || return 1
73*cf97dfd1SMaxime Coquelin		fi
74*cf97dfd1SMaxime Coquelin	done
75*cf97dfd1SMaxime Coquelin
76*cf97dfd1SMaxime Coquelin	return 0
77*cf97dfd1SMaxime Coquelin}
78*cf97dfd1SMaxime Coquelin
79*cf97dfd1SMaxime Coquelinfixup_includes()
80*cf97dfd1SMaxime Coquelin{
81*cf97dfd1SMaxime Coquelin	local path=$1
82*cf97dfd1SMaxime Coquelin
83*cf97dfd1SMaxime Coquelin	sed -i "s|^#include <linux/compiler.h>||g" $path
84*cf97dfd1SMaxime Coquelin	sed -i "s|\<__user[[:space:]]||" $path
85*cf97dfd1SMaxime Coquelin
86*cf97dfd1SMaxime Coquelin	# Prepend include path with "uapi/" if the header is imported
87*cf97dfd1SMaxime Coquelin	for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
88*cf97dfd1SMaxime Coquelin		if [ -f "${base_path}${include}" ]; then
89*cf97dfd1SMaxime Coquelin			sed -i "s|${include}|uapi/${include}|g" $path
90*cf97dfd1SMaxime Coquelin		fi
91*cf97dfd1SMaxime Coquelin	done
92*cf97dfd1SMaxime Coquelin}
93*cf97dfd1SMaxime Coquelin
94*cf97dfd1SMaxime Coquelincheck_header() {
95*cf97dfd1SMaxime Coquelin	echo -n "Checking $1... "
96*cf97dfd1SMaxime Coquelin
97*cf97dfd1SMaxime Coquelin	if ! diff -q $1 $2 >/dev/null; then
98*cf97dfd1SMaxime Coquelin		echo "KO"
99*cf97dfd1SMaxime Coquelin		diff -u $1 $2
100*cf97dfd1SMaxime Coquelin		return 1
101*cf97dfd1SMaxime Coquelin	else
102*cf97dfd1SMaxime Coquelin		echo "OK"
103*cf97dfd1SMaxime Coquelin	fi
104*cf97dfd1SMaxime Coquelin
105*cf97dfd1SMaxime Coquelin	return 0
106*cf97dfd1SMaxime Coquelin}
107*cf97dfd1SMaxime Coquelin
108*cf97dfd1SMaxime Coquelinwhile getopts i:u:ch opt ; do
109*cf97dfd1SMaxime Coquelin	case ${opt} in
110*cf97dfd1SMaxime Coquelin		i ) file=$OPTARG ;;
111*cf97dfd1SMaxime Coquelin		u ) version=$OPTARG ;;
112*cf97dfd1SMaxime Coquelin		c ) check_headers=1 ;;
113*cf97dfd1SMaxime Coquelin		h ) print_usage ; exit 0 ;;
114*cf97dfd1SMaxime Coquelin		? ) print_usage ; exit 1 ;;
115*cf97dfd1SMaxime Coquelin	esac
116*cf97dfd1SMaxime Coquelindone
117*cf97dfd1SMaxime Coquelin
118*cf97dfd1SMaxime Coquelinshift $(($OPTIND - 1))
119*cf97dfd1SMaxime Coquelinif [ $# -ne 0 ]; then
120*cf97dfd1SMaxime Coquelin	print_usage
121*cf97dfd1SMaxime Coquelin	exit 1
122*cf97dfd1SMaxime Coquelinfi
123*cf97dfd1SMaxime Coquelin
124*cf97dfd1SMaxime Coquelincd $(dirname $0)/..
125*cf97dfd1SMaxime Coquelin
126*cf97dfd1SMaxime Coquelincurrent_version=$(< ${base_path}/version)
127*cf97dfd1SMaxime Coquelin
128*cf97dfd1SMaxime Coquelinif [ -n "${version}" ]; then
129*cf97dfd1SMaxime Coquelin	if version_older_than "$version" "$current_version"; then
130*cf97dfd1SMaxime Coquelin		echo "Headers already up to date ($current_version >= $version)"
131*cf97dfd1SMaxime Coquelin		version=$current_version
132*cf97dfd1SMaxime Coquelin	else
133*cf97dfd1SMaxime Coquelin		update_headers || exit 1
134*cf97dfd1SMaxime Coquelin	fi
135*cf97dfd1SMaxime Coquelinelse
136*cf97dfd1SMaxime Coquelin	echo "Version not specified, using current version ($current_version)"
137*cf97dfd1SMaxime Coquelin	version=$current_version
138*cf97dfd1SMaxime Coquelinfi
139*cf97dfd1SMaxime Coquelin
140*cf97dfd1SMaxime Coquelinif [ -n "${file}" ]; then
141*cf97dfd1SMaxime Coquelin	import_header $file || exit 1
142*cf97dfd1SMaxime Coquelinfi
143*cf97dfd1SMaxime Coquelin
144*cf97dfd1SMaxime Coquelinfor filename in $(find $base_path -name "*.h" -type f); do
145*cf97dfd1SMaxime Coquelin	fixup_includes $filename || exit 1
146*cf97dfd1SMaxime Coquelindone
147*cf97dfd1SMaxime Coquelin
148*cf97dfd1SMaxime Coquelinecho $version > ${base_path}/version
149*cf97dfd1SMaxime Coquelin
150*cf97dfd1SMaxime Coquelinif [ $check_headers -eq 0 ]; then
151*cf97dfd1SMaxime Coquelin	exit 0
152*cf97dfd1SMaxime Coquelinfi
153*cf97dfd1SMaxime Coquelin
154*cf97dfd1SMaxime Coquelintmpheader="$(mktemp -t dpdk.checkuapi.XXXXXX)"
155*cf97dfd1SMaxime Coquelintrap "rm -f '$tmpheader'" INT
156*cf97dfd1SMaxime Coquelin
157*cf97dfd1SMaxime Coquelinecho "Checking imported headers for version ${version}"
158*cf97dfd1SMaxime Coquelin
159*cf97dfd1SMaxime Coquelinfor filename in $(find $base_path -name "*.h" -type f); do
160*cf97dfd1SMaxime Coquelin	header=${filename#$base_path}
161*cf97dfd1SMaxime Coquelin	download_header $header $tmpheader || exit 1
162*cf97dfd1SMaxime Coquelin	fixup_includes $tmpheader || exit 1
163*cf97dfd1SMaxime Coquelin	check_header $filename $tmpheader || errors=$((errors+1))
164*cf97dfd1SMaxime Coquelindone
165*cf97dfd1SMaxime Coquelin
166*cf97dfd1SMaxime Coquelinecho "$errors error(s) found"
167*cf97dfd1SMaxime Coquelin
168*cf97dfd1SMaxime Coquelinrm -f $tmpheader
169*cf97dfd1SMaxime Coquelintrap - INT
170*cf97dfd1SMaxime Coquelin
171*cf97dfd1SMaxime Coquelinexit $errors
172