From 7309ce6f5f7c86570953a141965d4f54cd9ad9a0 Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Sat, 8 Apr 2017 16:34:32 +0300 Subject: [PATCH] python: Read gpg-error.h using the pre-processor * lang/python/setup.py.in: Read gpg-error.h using the pre-processor. -- The libgpg-error may be installed in multilib configuration in which there is a wrapper header at /usr/include that includes the actual header at /usr/include/*. This causes invalid errors.i generation. Let the pre-processor extract the header content instead reading it explicitly. Signed-off-by: Alon Bar-Lev --- lang/python/setup.py.in | 60 ++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 25 deletions(-) diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in index f4ce64ff..a1279f80 100755 --- a/lang/python/setup.py.in +++ b/lang/python/setup.py.in @@ -54,13 +54,6 @@ if hasattr(subprocess, "DEVNULL"): else: devnull = open(os.devnull, "w") -try: - subprocess.check_call(gpg_error_config + ['--version'], - stdout=devnull) -except: - sys.exit("Could not find gpg-error-config. " + - "Please install the libgpg-error development package.") - try: subprocess.check_call(gpgme_config + ['--version'], stdout=devnull) @@ -84,13 +77,6 @@ if not (major > 1 or (major == 1 and minor >= 7)): if not gpgme_h: gpgme_h = os.path.join(getconfig("prefix")[0], "include", "gpgme.h") -gpg_error_prefix = getconfig("prefix", config=gpg_error_config)[0] -gpg_error_h = os.path.join(gpg_error_prefix, "include", "gpg-error.h") -if not os.path.exists(gpg_error_h): - gpg_error_h = \ - glob.glob(os.path.join(gpg_error_prefix, "include", - "*", "gpg-error.h"))[0] - define_macros = [] libs = getconfig('libs') @@ -150,10 +136,27 @@ def up_to_date(source, target): from distutils.command.build import build class BuildExtFirstHack(build): + def _read_header(self, header, cflags): + tmp_include = self._in_build_base("include1.h") + with open(tmp_include, 'w') as f: + f.write("#include <%s>" % header) + return subprocess.check_output(os.environ.get('CPP', 'cc -E').split() + cflags + [tmp_include]).decode('utf-8') + + def _write_if_unchanged(self, target, content): + if os.path.exists(target): + with open(target) as f: + if f.read() == content: + return + + with open(target, "w") as sink: + sink.write(content) + def _generate_gpgme_h(self, source_name, sink_name): if up_to_date(source_name, sink_name): return + print("Using gpgme.h from {}".format(source_name)) + deprec_func = re.compile(r'^(.*typedef.*|.*\(.*\)|[^#]+\s+.+)' + r'\s*_GPGME_DEPRECATED(_OUTSIDE_GPGME)?\(.*\);\s*', re.S) @@ -169,31 +172,38 @@ class BuildExtFirstHack(build): text = '' sink.write(text) - def _generate_errors_i(self, source_name, sink_name): - if up_to_date(source_name, sink_name): - return + def _generate_errors_i(self): + + try: + subprocess.check_call(gpg_error_config + ['--version'], + stdout=devnull) + except: + sys.exit("Could not find gpg-error-config. " + + "Please install the libgpg-error development package.") + + gpg_error_content = self._read_header("gpg-error.h", getconfig("cflags", config=gpg_error_config)) 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())) + errors_i_content = '' + for line in gpg_error_content.splitlines(): + if not filter_re.search(line): + continue + errors_i_content += rewrite_re.sub(r'%constant long \1 = \1;'+'\n', line.strip()) + + self._write_if_unchanged(self._in_build_base("errors.i"), errors_i_content) def _in_build_base(self, name): return os.path.join(self.build_base, name) def _generate(self): - print("Building python gpg module using {} and {}.".format(gpgme_h, gpg_error_h)) - # Cleanup gpgme.h from deprecated functions and typedefs. if not os.path.exists(self.build_base): os.makedirs(self.build_base) self._generate_gpgme_h(gpgme_h, self._in_build_base("gpgme.h")) - self._generate_errors_i(gpg_error_h, self._in_build_base("errors.i")) + self._generate_errors_i() # Copy due to http://bugs.python.org/issue2624 # Avoid creating in srcdir