[ovs-dev] [PATCH 6/9] tests: Convert sodepends build tool from Perl to Python.

Aaron Conole aconole at redhat.com
Thu Nov 16 14:42:20 UTC 2017


Ben Pfaff <blp at ovn.org> writes:

> Perl is unfashionable and Python is more widely available and understood,
> so this commit converts one of the OVS uses of Perl into Python.
>
> Signed-off-by: Ben Pfaff <blp at ovn.org>
> ---
>  Makefile.am            |   6 +--
>  build-aux/automake.mk  |   1 +
>  build-aux/sodepends.pl |  70 ---------------------------------
>  build-aux/sodepends.py | 105 +++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 109 insertions(+), 73 deletions(-)
>  delete mode 100644 build-aux/sodepends.pl
>  create mode 100755 build-aux/sodepends.py
>
> diff --git a/Makefile.am b/Makefile.am
> index 11e2e6d21005..5bcd2919c1b4 100644
> --- a/Makefile.am
> +++ b/Makefile.am
> @@ -87,7 +87,7 @@ EXTRA_DIST = \
>  	build-aux/calculate-schema-cksum \
>  	build-aux/dist-docs \
>  	build-aux/dpdkstrip.py \
> -	build-aux/sodepends.pl \
> +	build-aux/sodepends.py \
>  	build-aux/soexpand.py \
>  	build-aux/xml2nroff \
>  	$(MAN_FRAGMENTS) \
> @@ -394,8 +394,8 @@ endif
>  CLEANFILES += flake8-check
>  
>  include $(srcdir)/manpages.mk
> -$(srcdir)/manpages.mk: $(MAN_ROOTS) build-aux/sodepends.pl
> -	@$(PERL) $(srcdir)/build-aux/sodepends.pl -I. -I$(srcdir) $(MAN_ROOTS) >$(@F).tmp
> +$(srcdir)/manpages.mk: $(MAN_ROOTS) build-aux/sodepends.py
> +	@$(PYTHON) $(srcdir)/build-aux/sodepends.py -I. -I$(srcdir) $(MAN_ROOTS) >$(@F).tmp
>  	@if cmp -s $(@F).tmp $@; then \
>  	  touch $@; \
>  	  rm -f $(@F).tmp; \
> diff --git a/build-aux/automake.mk b/build-aux/automake.mk
> index 1003144fd664..6baafab0e867 100644
> --- a/build-aux/automake.mk
> +++ b/build-aux/automake.mk
> @@ -2,4 +2,5 @@
>  FLAKE8_PYFILES += \
>      $(srcdir)/build-aux/xml2nroff \
>      build-aux/dpdkstrip.py \
> +    build-aux/sodepends.py \
>      build-aux/soexpand.py
> diff --git a/build-aux/sodepends.pl b/build-aux/sodepends.pl
> deleted file mode 100644
> index 333d037f2dcf..000000000000
> --- a/build-aux/sodepends.pl
> +++ /dev/null
> @@ -1,70 +0,0 @@
> -# Copyright (c) 2008, 2011 Nicira, Inc.
> -#
> -# 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.
> -
> -use strict;
> -use warnings;
> -use Getopt::Long;
> -
> -our ($exit_code) = 0;
> -
> -our (@include_dirs);
> -Getopt::Long::Configure ("bundling");
> -GetOptions("I|include=s" => \@include_dirs) or exit(1);
> - at include_dirs = ('.') if !@include_dirs;
> -
> -sub find_file {
> -    my ($name) = @_;
> -    foreach my $dir (@include_dirs, '.') {
> -        my $file = "$dir/$name";
> -        if (stat($file)) {
> -            return $file;
> -        }
> -    }
> -    print STDERR "$name not found in: ", join(' ', @include_dirs), "\n";
> -    $exit_code = 1;
> -    return;
> -}
> -
> -print "# Generated automatically -- do not modify!    -*- buffer-read-only: t -*-\n";
> -for my $toplevel (sort(@ARGV)) {
> -    # Skip names that don't end in .in.
> -    next if $toplevel !~ /\.in$/;
> -
> -    # Open file.
> -    my ($fn) = find_file($toplevel);
> -    next if !defined($fn);
> -    if (!open(OUTER, '<', $fn)) {
> -        print "$fn: open: $!\n";
> -        $exit_code = 1;
> -        next;
> -    }
> -
> -    my (@dependencies);
> -  OUTER:
> -    while (<OUTER>) {
> -        if (my ($name) = /^\.so (\S+)$/) {
> -            push(@dependencies, $name) if find_file($name);
> -        }
> -    }
> -    close(OUTER);
> -
> -    my ($output) = $toplevel;
> -    $output =~ s/\.in//;
> -
> -    print "\n$output:";
> -    print " \\\n\t$_" foreach $toplevel, sort(@dependencies);
> -    print "\n";
> -    print "$_:\n" foreach $toplevel, sort(@dependencies);
> -}
> -exit $exit_code;
> diff --git a/build-aux/sodepends.py b/build-aux/sodepends.py
> new file mode 100755
> index 000000000000..fafe900b9965
> --- /dev/null
> +++ b/build-aux/sodepends.py
> @@ -0,0 +1,105 @@
> +#! /usr/bin/env python
> +
> +# Copyright (c) 2008, 2011, 2017 Nicira, Inc.
> +#
> +# 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.
> +
> +import os
> +import re
> +import sys
> +import getopt
> +
> +
> +def parse_include_dirs():
> +    include_dirs = []
> +    options, args = getopt.gnu_getopt(sys.argv[1:], 'I:', ['include='])
> +    for key, value in options:
> +        if key in ['-I', '--include']:
> +            include_dirs.append(value)
> +        else:
> +            assert False
> +
> +    include_dirs.append('.')
> +    return include_dirs, args
> +
> +
> +def find_file(include_dirs, name):
> +    for dir in include_dirs:
> +        file = "%s/%s" % (dir, name)
> +        try:
> +            os.stat(file)
> +            return file
> +        except OSError as e:

This should just be 'except OSError'.

There looks to be a bit of overlap between this and sodepends and
dpdkstrip.  Maybe it's worthwhile to introduce a build-aux.py that these
tools import?

> +            pass
> +    sys.stderr.write("%s not found in: %s\n" % (name, ' '.join(include_dirs)))
> +    return None
> +
> +
> +so_re = re.compile(r'^\.so (\S+)$')
> +
> +
> +def extract_include_directive(line):
> +    m = so_re.match(line)
> +    if m:
> +        return m.group(1)
> +    else:
> +        return None
> +
> +
> +def sodepends(include_dirs, filenames, dst):
> +    ok = True
> +    print("# Generated automatically -- do not modify!    "
> +          "-*- buffer-read-only: t -*-")
> +    for toplevel in sorted(filenames):
> +        # Skip names that don't end in .in.
> +        if not toplevel.endswith('.in'):
> +            continue
> +
> +        # Open file.
> +        fn = find_file(include_dirs, toplevel)
> +        if not fn:
> +            ok = False
> +            continue
> +        try:
> +            outer = open(fn)
> +        except IOError as e:
> +            sys.stderr.write("%s: open: %s\n" % (fn, e.strerror))
> +            ok = False
> +            continue
> +
> +        dependencies = []
> +        while True:
> +            line = outer.readline()
> +            if not line:
> +                break
> +
> +            name = extract_include_directive(line)
> +            if name:
> +                if find_file(include_dirs, name):
> +                    dependencies.append(name)
> +                else:
> +                    ok = False
> +
> +        dst.write("\n%s:" % toplevel[:-3])
> +        for s in [toplevel] + sorted(dependencies):
> +            dst.write(' \\\n\t%s' % s)
> +        dst.write('\n')
> +        for s in [toplevel] + sorted(dependencies):
> +            dst.write('%s:\n' % s)
> +    return ok
> +
> +
> +if __name__ == '__main__':
> +    include_dirs, args = parse_include_dirs()
> +    error = not sodepends(include_dirs, args, sys.stdout)
> +    sys.exit(1 if error else 0)


More information about the dev mailing list