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 <alon.barlev@gmail.com>
This commit is contained in:
Alon Bar-Lev 2017-04-08 16:34:32 +03:00 committed by Justus Winter
parent df8433bffa
commit 7309ce6f5f
No known key found for this signature in database
GPG Key ID: DD1A52F9DA8C9020

View File

@ -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:
errors_i_content = ''
for line in gpg_error_content.splitlines():
if not filter_re.search(line):
continue
sink.write(rewrite_re.sub(r'%constant long \1 = \1;'+'\n', line.strip()))
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