diff options
| -rw-r--r-- | lang/python/MANIFEST.in | 2 | ||||
| -rw-r--r-- | lang/python/Makefile.am | 31 | ||||
| -rwxr-xr-x | lang/python/gpgme-h-clean.py | 53 | ||||
| -rwxr-xr-x | lang/python/setup.py.in | 81 | 
4 files changed, 92 insertions, 75 deletions
| diff --git a/lang/python/MANIFEST.in b/lang/python/MANIFEST.in index 8f63640a..ff38172d 100644 --- a/lang/python/MANIFEST.in +++ b/lang/python/MANIFEST.in @@ -1,4 +1,4 @@  recursive-include examples *.py -include gpgme-h-clean.py gpgme.i +include gpgme.i  include helpers.c helpers.h private.h  recursive-include gpg *.py diff --git a/lang/python/Makefile.am b/lang/python/Makefile.am index b9145f5b..42beeee2 100644 --- a/lang/python/Makefile.am +++ b/lang/python/Makefile.am @@ -21,12 +21,20 @@ EXTRA_DIST = \  	MANIFEST.in \  	gpgme.i \  	helpers.c helpers.h private.h \ -	gpgme-h-clean.py \  	examples \  	gpg  SUBDIRS = . tests +COPY_FILES_GPG = \ +	$(srcdir)/gpg/callbacks.py \ +	$(srcdir)/gpg/constants \ +	$(srcdir)/gpg/core.py \ +	$(srcdir)/gpg/errors.py \ +	$(srcdir)/gpg/__init__.py \ +	$(srcdir)/gpg/results.py \ +	$(srcdir)/gpg/util.py +  .PHONY: prepare  prepare: copystamp @@ -35,12 +43,14 @@ prepare: copystamp  copystamp:  	ln -sf "$(abs_top_srcdir)/src/data.h" .  	ln -sf "$(abs_top_builddir)/config.h" . +	if test $(srcdir) != . ; then cp -R $(COPY_FILES_GPG) gpg ; fi  	touch $@  all-local: copystamp  	set -e ; set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \  	  PYTHON="$$1" ; shift ; \  	  CFLAGS="$(CFLAGS)" \ +	  srcdir="$(srcdir)" \  	  abs_top_builddir="$(abs_top_builddir)" \  	    $$PYTHON setup.py build --verbose --build-base=python$${VERSION}-gpg ; \  	done @@ -48,6 +58,7 @@ all-local: copystamp  python$(PYTHON_VERSION)-gpg/dist/gpg-$(VERSION).tar.gz.asc: copystamp  	$(MKDIR_P) python$(PYTHON_VERSION)-gpg-dist  	CFLAGS="$(CFLAGS)" \ +	srcdir="$(srcdir)" \  	abs_top_builddir="$(abs_top_builddir)" \  	  $(PYTHON) setup.py sdist --verbose --dist-dir=python$(PYTHON_VERSION)-gpg-dist \  		--manifest=python$(PYTHON_VERSION)-gpg-dist/MANIFEST @@ -73,6 +84,12 @@ CLEANFILES = copystamp \  # permissions.  clean-local:  	rm -rf -- build +	if test $(srcdir) != . ; then \ +	  find gpg -type d ! -perm -200 -exec chmod u+w {} ';' ; \ +	  for FILE in $(COPY_FILES_GPG); do \ +	    rm -rf -- gpg/$$(basename $$FILE) ; \ +	  done \ +	fi  	for VERSION in $(PYTHON_VERSIONS); do \  	  find python$${VERSION}-gpg -type d ! -perm -200 -exec chmod u+w {} ';' ; \  	  rm -rf -- python$${VERSION}-gpg ; \ @@ -81,20 +98,18 @@ clean-local:  install-exec-local:  	set -e ; set $(PYTHONS); for VERSION in $(PYTHON_VERSIONS); do \  	  PYTHON="$$1" ; shift ; \ +	  srcdir="$(srcdir)" \  	  abs_top_builddir="$(abs_top_builddir)" \  	  $$PYTHON setup.py \  	  build \  	  --build-base=python$${VERSION}-gpg \  	  install \  	  --prefix "$(DESTDIR)$(prefix)" \ -	  --record files.txt \  	  --verbose ; \ -	  cat files.txt >> install_files.txt ; \ -	  rm files.txt ; \  	done -	$(MKDIR_P) "$(DESTDIR)$(pythondir)/gpg" -	mv install_files.txt "$(DESTDIR)$(pythondir)/gpg"  uninstall-local: -	xargs < "$(DESTDIR)$(pythondir)/gpg/install_files.txt" -- rm -rf -- -	rm -rf -- "$(DESTDIR)$(pythondir)/gpg" +	GV=$$(echo $(VERSION) | tr - _); for PV in $(PYTHON_VERSIONS); do \ +	  rm -rf -- "$(DESTDIR)$(prefix)/lib/python$$PV/site-packages/gpg" \ +"$(DESTDIR)$(prefix)/lib/python$$PV/site-packages/gpg-$$GV-py$$PV.egg-info" ; \ +	done diff --git a/lang/python/gpgme-h-clean.py b/lang/python/gpgme-h-clean.py deleted file mode 100755 index 52f86764..00000000 --- a/lang/python/gpgme-h-clean.py +++ /dev/null @@ -1,53 +0,0 @@ -#!/usr/bin/env python - -# Copyright (C) 2016 g10 Code GmbH -# Copyright (C) 2004,2008 Igor Belyi <[email protected]> -# -#    This library is free software; you can redistribute it and/or -#    modify it under the terms of the GNU Lesser General Public -#    License as published by the Free Software Foundation; either -#    version 2.1 of the License, or (at your option) any later version. -# -#    This library is distributed in the hope that it will be useful, -#    but WITHOUT ANY WARRANTY; without even the implied warranty of -#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU -#    Lesser General Public License for more details. -# -#    You should have received a copy of the GNU Lesser General Public -#    License along with this library; if not, write to the Free Software -#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA - -from __future__ import absolute_import, print_function, unicode_literals -del absolute_import, print_function, unicode_literals - -import sys, re - -if len(sys.argv) != 2: -    sys.stderr.write("Usage: %s path/to/[gpgme|gpg-error].h\n" % sys.argv[0]) -    sys.exit(1) - -deprec_func = re.compile(r'^(.*typedef.*|.*\(.*\)|[^#]+\s+.+)' -                         + r'\s*_GPGME_DEPRECATED(_OUTSIDE_GPGME)?\(.*\);\s*', -                         re.S) -line_break = re.compile(';|\\$|\\x0c|^\s*#|{'); - -if 'gpgme.h' in sys.argv[1]: -    gpgme = open(sys.argv[1]) -    tmp = gpgme.readline() -    text = '' -    while tmp: -        text += re.sub(' class ', ' _py_obsolete_class ', tmp) -        if line_break.search(tmp): -            if not deprec_func.search(text): -                sys.stdout.write(text) -            text = '' -        tmp = gpgme.readline() -    sys.stdout.write(text) -    gpgme.close() -else: -    filter_re = re.compile(r'GPG_ERR_[^ ]* =') -    rewrite_re = re.compile(r' *(.*) = .*') -    for line in open(sys.argv[1]): -        if not filter_re.search(line): -            continue -        print(rewrite_re.sub(r'%constant long \1 = \1;', line.strip())) diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in index 6692de6f..2114aafe 100755 --- a/lang/python/setup.py.in +++ b/lang/python/setup.py.in @@ -1,7 +1,7 @@  #!/usr/bin/env python -# Copyright (C) 2016 g10 Code GmbH -# Copyright (C) 2004 Igor Belyi <[email protected]> +# Copyright (C) 2016-2017 g10 Code GmbH +# Copyright (C) 2004,2008 Igor Belyi <[email protected]>  # Copyright (C) 2002 John Goerzen <[email protected]>  #  #    This library is free software; you can redistribute it and/or @@ -19,11 +19,18 @@  #    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA  from distutils.core import setup, Extension +import argparse  import os, os.path, sys  import glob +import re  import shutil  import subprocess +# We parse a subset of the arguments. +parser = argparse.ArgumentParser(add_help=False) +parser.add_argument('--build-base', default='') +options, _ = parser.parse_known_args() +  # Out-of-tree build of the gpg bindings.  gpg_error_config = ["gpg-error-config"]  gpgme_config_flags = ["--thread=pthread"] @@ -31,6 +38,7 @@ gpgme_config = ["gpgme-config"] + gpgme_config_flags  gpgme_h = ""  include_dirs = [os.getcwd()]  library_dirs = [] +vpath_build = os.environ.get('srcdir', '.') != '.'  in_tree = False  extra_swig_opts = []  extra_macros = dict() @@ -133,6 +141,14 @@ if uname_s.startswith("MINGW32"):                 library_dirs.append(os.path.join(tgt, item))                 break +def in_srcdir(name): +    return os.path.join(os.environ.get("srcdir", ""), name) +def in_build_base(name): +    return os.path.join(options.build_base, name) +def up_to_date(source, target): +    return (os.path.exists(target) +            and os.path.getmtime(source) <= os.path.getmtime(target)) +  # We build an Extension using SWIG, which generates a Python module.  # By default, the 'build_py' step is run before 'build_ext', and  # therefore the generated Python module is not copied into the build @@ -143,25 +159,60 @@ if uname_s.startswith("MINGW32"):  from distutils.command.build import build  class BuildExtFirstHack(build): +    def _generate_gpgme_h(self, source_name, sink_name): +        if up_to_date(source_name, sink_name): +            return + +        deprec_func = re.compile(r'^(.*typedef.*|.*\(.*\)|[^#]+\s+.+)' +                                 + r'\s*_GPGME_DEPRECATED(_OUTSIDE_GPGME)?\(.*\);\s*', +                                 re.S) +        line_break = re.compile(';|\\$|\\x0c|^\s*#|{') + +        with open(sink_name, "w") as sink, open(source_name) as source: +            text = '' +            for line in source: +                text += re.sub(' class ', ' _py_obsolete_class ', line) +                if line_break.search(line): +                    if not deprec_func.search(text): +                        sink.write(text) +                    text = '' +            sink.write(text) + +    def _generate_errors_i(self, source_name, sink_name): +        if up_to_date(source_name, sink_name): +            return + +        filter_re = re.compile(r'GPG_ERR_[^ ]* =') +        rewrite_re = re.compile(r' *(.*) = .*') + +        with open(sink_name, "w") as sink, open(source_name) as source: +            for line in source: +                if not filter_re.search(line): +                    continue +                sink.write(rewrite_re.sub(r'%constant long \1 = \1;'+'\n', line.strip())) +      def _generate(self):          print("Building python gpg module using {} and {}.".format(gpgme_h, gpg_error_h))          # Cleanup gpgme.h from deprecated functions and typedefs. -        # Keep timestamp to avoid rebuild          if not os.path.exists(self.build_base):              os.makedirs(self.build_base) -        for src, dst in ( -            (gpgme_h, os.path.join(self.build_base, "gpgme.h")), -            (gpg_error_h, os.path.join(self.build_base, "errors.i")) -        ): -            subprocess.check_call([sys.executable, "gpgme-h-clean.py", src], -                                  stdout=open(dst, "w")) -            shutil.copystat(src, dst) +        self._generate_gpgme_h(gpgme_h, in_build_base("gpgme.h")) +        self._generate_errors_i(gpg_error_h, in_build_base("errors.i")) + +        # Keep timestamp to avoid rebuild +        for source, target in ((gpgme_h, in_build_base("gpgme.h")), +                               (gpg_error_h, in_build_base("errors.i"))): +            if not up_to_date(source, target): +                shutil.copystat(source, target)          # Copy due to http://bugs.python.org/issue2624          # Avoid creating in srcdir -        shutil.copy2("gpgme.i", self.build_base) +        for source, target in ((in_srcdir(n), in_build_base(n)) +                               for n in ('gpgme.i', 'helpers.c')): +            if not up_to_date(source, target): +                shutil.copy2(source, target)      def run(self):          self._generate() @@ -171,14 +222,18 @@ class BuildExtFirstHack(build):              os.makedirs(os.path.join(self.build_lib, "gpg"))          swig_sources.append(os.path.join(self.build_base, 'gpgme.i')) -        swig_opts.extend(['-I' + self.build_base, '-outdir', os.path.join(self.build_lib, 'gpg')]) +        swig_opts.extend(['-I' + self.build_base, +                          '-I' + in_srcdir('.'), +                          '-outdir', os.path.join(self.build_lib, 'gpg')]) +        if vpath_build: +            include_dirs.append(in_srcdir('.'))          include_dirs.append(self.build_base)          self.run_command('build_ext')          build.run(self)  py3 = [] if sys.version_info.major < 3 else ['-py3'] -swig_sources = ['helpers.c'] +swig_sources = [in_build_base('helpers.c')]  swig_opts = ['-threads'] + py3 + extra_swig_opts  swige = Extension("gpg._gpgme",                    sources = swig_sources, | 
