xref: /spdk/scripts/env_dpdk/check_dpdk_pci_api.sh (revision f8abbede89d30584d2a4f8427b13896f8591b873)
1#!/usr/bin/env bash
2#  SPDX-License-Identifier: BSD-3-Clause
3#  Copyright (C) 2022 Intel Corporation
4#  All rights reserved.
5#
6
7scriptdir=$(readlink -f "$(dirname "$0")")
8rootdir=$(readlink -f "$scriptdir/../..")
9source "$rootdir/scripts/common.sh"
10
11set -e
12shopt -s extglob
13shopt -s nullglob
14
15mode=${1:-check} # check or fix
16
17# By default verify headers matching the DPDK submodule
18dpdk_dir=${2:-"$rootdir/dpdk"}
19dpdk_ver=$(< "$dpdk_dir/VERSION")
20
21env_path="$rootdir/lib/env_dpdk"
22tracked_versions=("$env_path/"+([0-9]).+([0-9])/*.h)
23tracked_versions=("${tracked_versions[@]#"$env_path/"}")
24tracked_versions=("${tracked_versions[@]%/*}")
25
26# The DPDK PCI API tracking started with DPDK 22.11, all prior versions will use DPDK 22.07 headers
27target_ver="22.07"
28while read -r ver; do
29	ge "$dpdk_ver" "$ver" && target_ver=$ver && break
30done < <(printf "%s\n" "${tracked_versions[@]}" | sort -Vru)
31
32echo "Checking DPDK PCI API from $dpdk_ver against $target_ver ..."
33
34target_headers=("$env_path/$target_ver/"*.h)
35target_headers=("${target_headers[@]##*/}")
36
37# The includes should point to headers in SPDK tree rather than system ones.
38use_local_includes="-e "
39for header in "${target_headers[@]}"; do
40	use_local_includes+="s/#include <$header>/#include \"$header\"/g;"
41done
42
43for header in "${target_headers[@]}"; do
44	dpdk_file="$dpdk_dir/$(git -C "$dpdk_dir" ls-files "*/$header")"
45	patch_dir="$scriptdir/$target_ver"
46	patch_versions=("$patch_dir/"+([0-9]).+([0-9])-$header.patch)
47	patch_versions=("${patch_versions[@]#"$patch_dir/"}")
48	patch_versions=("${patch_versions[@]%-$header.patch*}")
49
50	# Patch file version matches to versions equal or greater than
51	# their creation.
52	while read -r ver; do
53		ge "$dpdk_ver" "$ver" && patch_version=$ver && break
54	done < <(printf "%s\n" "${patch_versions[@]}" | sort -Vru)
55
56	# Patch DPDK header with any workarounds necessary
57	patch_file="$patch_dir/$patch_version-$header.patch"
58	if [[ -s $patch_file ]]; then
59		dpdk_header=$(patch -s "$dpdk_file" "$patch_file" -o - | sed "$use_local_includes")
60	else
61		dpdk_header=$(sed "$use_local_includes" "$dpdk_file")
62	fi
63
64	spdk_file="$env_path/$target_ver/$header"
65	if ! single_diff=$(diff -u "$spdk_file" <(echo "$dpdk_header")); then
66		header_diff+="$single_diff\n"
67	fi
68done
69
70if [[ -z "$header_diff" ]]; then
71	echo "No differences in headers found."
72	exit 0
73fi
74
75if [[ "$mode" == "check" ]]; then
76	cat <<- CHECK
77		$(echo -e "$header_diff")
78
79		Differences in DPDK and internal SPDK headers found.
80		For changes that do not affect the API, please use 'fix' as \$1 to this script.
81		If API was changed, please create "$env_path/${dpdk_ver%.*}/" with appropriate headers.
82
83	CHECK
84	exit 1
85elif [[ "$mode" == "fix" ]]; then
86	echo -e "$header_diff" | patch -d "$env_path/$target_ver/"
87	echo "Fixed differences between DPDK and internal SPDK headers."
88else
89	echo "Incorrect \$1 passed, please use 'check' or 'fix'."
90	exit 1
91fi
92