From: David Marchand Date: Thu, 28 Nov 2019 13:46:29 +0000 (+0100) Subject: devtools: move ABI scripts from buildtools X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=b09afc2ad82647ab4f0edc121e9632cc1906c5bb;p=dpdk.git devtools: move ABI scripts from buildtools Those scripts are only used by developers and not part of the build process. Move them to devtools so they are not installed. Signed-off-by: David Marchand Acked-by: Thomas Monjalon --- diff --git a/MAINTAINERS b/MAINTAINERS index b51059bc28..4395d8df14 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -143,13 +143,13 @@ M: Neil Horman F: lib/librte_eal/common/include/rte_compat.h F: lib/librte_eal/common/include/rte_function_versioning.h F: doc/guides/rel_notes/deprecation.rst -F: devtools/validate-abi.sh +F: devtools/check-abi-version.sh F: devtools/check-symbol-change.sh -F: buildtools/check-abi-version.sh +F: devtools/update-abi.sh +F: devtools/update_version_map_abi.py +F: devtools/validate-abi.sh F: buildtools/check-experimental-syms.sh F: buildtools/map-list-symbol.sh -F: buildtools/update-abi.sh -F: buildtools/update_version_map_abi.py Driver information M: Neil Horman diff --git a/buildtools/check-abi-version.sh b/buildtools/check-abi-version.sh deleted file mode 100755 index 9a3d135463..0000000000 --- a/buildtools/check-abi-version.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2019 Intel Corporation - -# Check whether library symbols have correct -# version (provided ABI number or provided ABI -# number + 1 or EXPERIMENTAL). -# Args: -# $1: path of the library .so file -# $2: ABI major version number to check -# (defaults to ABI_VERSION file value) - -if [ -z "$1" ]; then - echo "Script checks whether library symbols have" - echo "correct version (ABI_VER/ABI_VER+1/EXPERIMENTAL)" - echo "Usage:" - echo " $0 SO_FILE_PATH [ABI_VER]" - exit 1 -fi - -LIB="$1" -DEFAULT_ABI=$(cat "$(dirname \ - $(readlink -f $0))/../ABI_VERSION" | \ - cut -d'.' -f 1) -ABIVER="DPDK_${2-$DEFAULT_ABI}" -NEXT_ABIVER="DPDK_$((${2-$DEFAULT_ABI}+1))" - -ret=0 - -# get output of objdump -OBJ_DUMP_OUTPUT=`objdump -TC --section=.text ${LIB} 2>&1 | grep ".text"` - -# there may not be any .text sections in the .so file, in which case exit early -echo "${OBJ_DUMP_OUTPUT}" | grep "not found in any input file" -q -if [ "$?" -eq 0 ]; then - exit 0 -fi - -# we have symbols, so let's see if the versions are correct -for SYM in $(echo "${OBJ_DUMP_OUTPUT}" | awk '{print $(NF-1) "-" $NF}') -do - version=$(echo $SYM | cut -d'-' -f 1) - symbol=$(echo $SYM | cut -d'-' -f 2) - case $version in (*"$ABIVER"*|*"$NEXT_ABIVER"*|"EXPERIMENTAL") - ;; - (*) - echo "Warning: symbol $symbol ($version) should be annotated " \ - "as ABI version $ABIVER / $NEXT_ABIVER, or EXPERIMENTAL." - ret=1 - ;; - esac -done - -exit $ret diff --git a/buildtools/update-abi.sh b/buildtools/update-abi.sh deleted file mode 100755 index 15bc6feab1..0000000000 --- a/buildtools/update-abi.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -e -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2019 Intel Corporation - -abi_version=$1 -abi_version_file="./ABI_VERSION" -update_path="lib drivers" - -# check ABI version format string -check_abi_version() { - echo $1 | grep -q -e "^[[:digit:]]\{1,2\}\.[[:digit:]]\{1,2\}$" -} - -if [ -z "$1" ]; then - # output to stderr - >&2 echo "Please provide ABI version" - exit 1 -fi - -# check version string format -if ! check_abi_version $abi_version ; then - # output to stderr - >&2 echo "ABI version must be formatted as MAJOR.MINOR version" - exit 1 -fi - -if [ -n "$2" ]; then - abi_version_file=$2 -fi - -if [ -n "$3" ]; then - # drop $1 and $2 - shift 2 - # assign all other arguments as update paths - update_path=$@ -fi - -echo "New ABI version:" $abi_version -echo "ABI_VERSION path:" $abi_version_file -echo "Path to update:" $update_path - -echo $abi_version > $abi_version_file - -find $update_path -name \*version.map -exec \ - ./buildtools/update_version_map_abi.py {} \ - $abi_version \; -print diff --git a/buildtools/update_version_map_abi.py b/buildtools/update_version_map_abi.py deleted file mode 100755 index 6b9aff7a43..0000000000 --- a/buildtools/update_version_map_abi.py +++ /dev/null @@ -1,175 +0,0 @@ -#!/usr/bin/env python -# SPDX-License-Identifier: BSD-3-Clause -# Copyright(c) 2019 Intel Corporation - -""" -A Python program that updates and merges all available stable ABI versions into -one ABI version, while leaving experimental ABI exactly as it is. The intended -ABI version is supplied via command-line parameter. This script is to be called -from the buildtools/update-abi.sh utility. -""" - -from __future__ import print_function -import argparse -import sys -import re - - -def __parse_map_file(f_in): - # match function name, followed by semicolon, followed by EOL, optionally - # with whitespace in between each item - func_line_regex = re.compile(r"\s*" - r"(?P[a-zA-Z_0-9]+)" - r"\s*" - r";" - r"\s*" - r"$") - # match section name, followed by opening bracked, followed by EOL, - # optionally with whitespace in between each item - section_begin_regex = re.compile(r"\s*" - r"(?P[a-zA-Z0-9_\.]+)" - r"\s*" - r"{" - r"\s*" - r"$") - # match closing bracket, optionally followed by section name (for when we - # inherit from another ABI version), followed by semicolon, followed by - # EOL, optionally with whitespace in between each item - section_end_regex = re.compile(r"\s*" - r"}" - r"\s*" - r"(?P[a-zA-Z0-9_\.]+)?" - r"\s*" - r";" - r"\s*" - r"$") - - # for stable ABI, we don't care about which version introduced which - # function, we just flatten the list. there are dupes in certain files, so - # use a set instead of a list - stable_lines = set() - # copy experimental section as is - experimental_lines = [] - in_experimental = False - has_stable = False - - # gather all functions - for line in f_in: - # clean up the line - line = line.strip('\n').strip() - - # is this an end of section? - match = section_end_regex.match(line) - if match: - # whatever section this was, it's not active any more - in_experimental = False - continue - - # if we're in the middle of experimental section, we need to copy - # the section verbatim, so just add the line - if in_experimental: - experimental_lines += [line] - continue - - # skip empty lines - if not line: - continue - - # is this a beginning of a new section? - match = section_begin_regex.match(line) - if match: - cur_section = match.group("version") - # is it experimental? - in_experimental = cur_section == "EXPERIMENTAL" - if not in_experimental: - has_stable = True - continue - - # is this a function? - match = func_line_regex.match(line) - if match: - stable_lines.add(match.group("func")) - - return has_stable, stable_lines, experimental_lines - - -def __generate_stable_abi(f_out, abi_version, lines): - # print ABI version header - print("DPDK_{} {{".format(abi_version), file=f_out) - - # print global section if it exists - if lines: - print("\tglobal:", file=f_out) - # blank line - print(file=f_out) - - # print all stable lines, alphabetically sorted - for line in sorted(lines): - print("\t{};".format(line), file=f_out) - - # another blank line - print(file=f_out) - - # print local section - print("\tlocal: *;", file=f_out) - - # end stable version - print("};", file=f_out) - - -def __generate_experimental_abi(f_out, lines): - # start experimental section - print("EXPERIMENTAL {", file=f_out) - - # print all experimental lines as they were - for line in lines: - # don't print empty whitespace - if not line: - print("", file=f_out) - else: - print("\t{}".format(line), file=f_out) - - # end section - print("};", file=f_out) - - -def __main(): - arg_parser = argparse.ArgumentParser( - description='Merge versions in linker version script.') - - arg_parser.add_argument("map_file", type=str, - help='path to linker version script file ' - '(pattern: *version.map)') - arg_parser.add_argument("abi_version", type=str, - help='target ABI version (pattern: MAJOR.MINOR)') - - parsed = arg_parser.parse_args() - - if not parsed.map_file.endswith('version.map'): - print("Invalid input file: {}".format(parsed.map_file), - file=sys.stderr) - arg_parser.print_help() - sys.exit(1) - - if not re.match(r"\d{1,2}\.\d{1,2}", parsed.abi_version): - print("Invalid ABI version: {}".format(parsed.abi_version), - file=sys.stderr) - arg_parser.print_help() - sys.exit(1) - - with open(parsed.map_file) as f_in: - has_stable, stable_lines, experimental_lines = __parse_map_file(f_in) - - with open(parsed.map_file, 'w') as f_out: - need_newline = has_stable and experimental_lines - if has_stable: - __generate_stable_abi(f_out, parsed.abi_version, stable_lines) - if need_newline: - # separate sections with a newline - print(file=f_out) - if experimental_lines: - __generate_experimental_abi(f_out, experimental_lines) - - -if __name__ == "__main__": - __main() diff --git a/devtools/check-abi-version.sh b/devtools/check-abi-version.sh new file mode 100755 index 0000000000..9a3d135463 --- /dev/null +++ b/devtools/check-abi-version.sh @@ -0,0 +1,54 @@ +#!/bin/sh +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2019 Intel Corporation + +# Check whether library symbols have correct +# version (provided ABI number or provided ABI +# number + 1 or EXPERIMENTAL). +# Args: +# $1: path of the library .so file +# $2: ABI major version number to check +# (defaults to ABI_VERSION file value) + +if [ -z "$1" ]; then + echo "Script checks whether library symbols have" + echo "correct version (ABI_VER/ABI_VER+1/EXPERIMENTAL)" + echo "Usage:" + echo " $0 SO_FILE_PATH [ABI_VER]" + exit 1 +fi + +LIB="$1" +DEFAULT_ABI=$(cat "$(dirname \ + $(readlink -f $0))/../ABI_VERSION" | \ + cut -d'.' -f 1) +ABIVER="DPDK_${2-$DEFAULT_ABI}" +NEXT_ABIVER="DPDK_$((${2-$DEFAULT_ABI}+1))" + +ret=0 + +# get output of objdump +OBJ_DUMP_OUTPUT=`objdump -TC --section=.text ${LIB} 2>&1 | grep ".text"` + +# there may not be any .text sections in the .so file, in which case exit early +echo "${OBJ_DUMP_OUTPUT}" | grep "not found in any input file" -q +if [ "$?" -eq 0 ]; then + exit 0 +fi + +# we have symbols, so let's see if the versions are correct +for SYM in $(echo "${OBJ_DUMP_OUTPUT}" | awk '{print $(NF-1) "-" $NF}') +do + version=$(echo $SYM | cut -d'-' -f 1) + symbol=$(echo $SYM | cut -d'-' -f 2) + case $version in (*"$ABIVER"*|*"$NEXT_ABIVER"*|"EXPERIMENTAL") + ;; + (*) + echo "Warning: symbol $symbol ($version) should be annotated " \ + "as ABI version $ABIVER / $NEXT_ABIVER, or EXPERIMENTAL." + ret=1 + ;; + esac +done + +exit $ret diff --git a/devtools/update-abi.sh b/devtools/update-abi.sh new file mode 100755 index 0000000000..b9b859a3e9 --- /dev/null +++ b/devtools/update-abi.sh @@ -0,0 +1,46 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2019 Intel Corporation + +abi_version=$1 +abi_version_file="./ABI_VERSION" +update_path="lib drivers" + +# check ABI version format string +check_abi_version() { + echo $1 | grep -q -e "^[[:digit:]]\{1,2\}\.[[:digit:]]\{1,2\}$" +} + +if [ -z "$1" ]; then + # output to stderr + >&2 echo "Please provide ABI version" + exit 1 +fi + +# check version string format +if ! check_abi_version $abi_version ; then + # output to stderr + >&2 echo "ABI version must be formatted as MAJOR.MINOR version" + exit 1 +fi + +if [ -n "$2" ]; then + abi_version_file=$2 +fi + +if [ -n "$3" ]; then + # drop $1 and $2 + shift 2 + # assign all other arguments as update paths + update_path=$@ +fi + +echo "New ABI version:" $abi_version +echo "ABI_VERSION path:" $abi_version_file +echo "Path to update:" $update_path + +echo $abi_version > $abi_version_file + +find $update_path -name \*version.map -exec \ + devtools/update_version_map_abi.py {} \ + $abi_version \; -print diff --git a/devtools/update_version_map_abi.py b/devtools/update_version_map_abi.py new file mode 100755 index 0000000000..616412a1c4 --- /dev/null +++ b/devtools/update_version_map_abi.py @@ -0,0 +1,175 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(c) 2019 Intel Corporation + +""" +A Python program that updates and merges all available stable ABI versions into +one ABI version, while leaving experimental ABI exactly as it is. The intended +ABI version is supplied via command-line parameter. This script is to be called +from the devtools/update-abi.sh utility. +""" + +from __future__ import print_function +import argparse +import sys +import re + + +def __parse_map_file(f_in): + # match function name, followed by semicolon, followed by EOL, optionally + # with whitespace in between each item + func_line_regex = re.compile(r"\s*" + r"(?P[a-zA-Z_0-9]+)" + r"\s*" + r";" + r"\s*" + r"$") + # match section name, followed by opening bracked, followed by EOL, + # optionally with whitespace in between each item + section_begin_regex = re.compile(r"\s*" + r"(?P[a-zA-Z0-9_\.]+)" + r"\s*" + r"{" + r"\s*" + r"$") + # match closing bracket, optionally followed by section name (for when we + # inherit from another ABI version), followed by semicolon, followed by + # EOL, optionally with whitespace in between each item + section_end_regex = re.compile(r"\s*" + r"}" + r"\s*" + r"(?P[a-zA-Z0-9_\.]+)?" + r"\s*" + r";" + r"\s*" + r"$") + + # for stable ABI, we don't care about which version introduced which + # function, we just flatten the list. there are dupes in certain files, so + # use a set instead of a list + stable_lines = set() + # copy experimental section as is + experimental_lines = [] + in_experimental = False + has_stable = False + + # gather all functions + for line in f_in: + # clean up the line + line = line.strip('\n').strip() + + # is this an end of section? + match = section_end_regex.match(line) + if match: + # whatever section this was, it's not active any more + in_experimental = False + continue + + # if we're in the middle of experimental section, we need to copy + # the section verbatim, so just add the line + if in_experimental: + experimental_lines += [line] + continue + + # skip empty lines + if not line: + continue + + # is this a beginning of a new section? + match = section_begin_regex.match(line) + if match: + cur_section = match.group("version") + # is it experimental? + in_experimental = cur_section == "EXPERIMENTAL" + if not in_experimental: + has_stable = True + continue + + # is this a function? + match = func_line_regex.match(line) + if match: + stable_lines.add(match.group("func")) + + return has_stable, stable_lines, experimental_lines + + +def __generate_stable_abi(f_out, abi_version, lines): + # print ABI version header + print("DPDK_{} {{".format(abi_version), file=f_out) + + # print global section if it exists + if lines: + print("\tglobal:", file=f_out) + # blank line + print(file=f_out) + + # print all stable lines, alphabetically sorted + for line in sorted(lines): + print("\t{};".format(line), file=f_out) + + # another blank line + print(file=f_out) + + # print local section + print("\tlocal: *;", file=f_out) + + # end stable version + print("};", file=f_out) + + +def __generate_experimental_abi(f_out, lines): + # start experimental section + print("EXPERIMENTAL {", file=f_out) + + # print all experimental lines as they were + for line in lines: + # don't print empty whitespace + if not line: + print("", file=f_out) + else: + print("\t{}".format(line), file=f_out) + + # end section + print("};", file=f_out) + + +def __main(): + arg_parser = argparse.ArgumentParser( + description='Merge versions in linker version script.') + + arg_parser.add_argument("map_file", type=str, + help='path to linker version script file ' + '(pattern: *version.map)') + arg_parser.add_argument("abi_version", type=str, + help='target ABI version (pattern: MAJOR.MINOR)') + + parsed = arg_parser.parse_args() + + if not parsed.map_file.endswith('version.map'): + print("Invalid input file: {}".format(parsed.map_file), + file=sys.stderr) + arg_parser.print_help() + sys.exit(1) + + if not re.match(r"\d{1,2}\.\d{1,2}", parsed.abi_version): + print("Invalid ABI version: {}".format(parsed.abi_version), + file=sys.stderr) + arg_parser.print_help() + sys.exit(1) + + with open(parsed.map_file) as f_in: + has_stable, stable_lines, experimental_lines = __parse_map_file(f_in) + + with open(parsed.map_file, 'w') as f_out: + need_newline = has_stable and experimental_lines + if has_stable: + __generate_stable_abi(f_out, parsed.abi_version, stable_lines) + if need_newline: + # separate sections with a newline + print(file=f_out) + if experimental_lines: + __generate_experimental_abi(f_out, experimental_lines) + + +if __name__ == "__main__": + __main()