Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Try to switch pkg-config (works on OpenSUSE) #1315

Closed
wants to merge 2 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 53 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,12 @@ def __init__(self, build_ext):
self.pg_config_exe = self.build_ext.pg_config
if not self.pg_config_exe:
self.pg_config_exe = self.autodetect_pg_config_path()
if self.pg_config_exe is None:
self.pkg_config_exe = self.build_ext.pkg_config
self.using_pkg_config = self.pkg_config_exe is not None
if not self.pg_config_exe and not self.pkg_config_exe:
self.pkg_config_exe = self.autodetect_pkg_config_path()
self.using_pkg_config = self.pkg_config_exe is not None
if not self.pg_config_exe and not self.pkg_config_exe:
sys.stderr.write("""
Error: pg_config executable not found.

Expand All @@ -102,10 +107,48 @@ def __init__(self, build_ext):

""")
sys.exit(1)

def query_pkgconfig(self, attr_name):
"""Spawn the pkg-config executable, querying for the given config
name, and return the printed value, sanitized. """

# Compability patch for pg_config
process = None
if attr_name == "libdir":
ldconfig = self.find_on_path('ldconfig')
process = "{} -p | grep -m1 libpq.so | cut -f4 -d' ' | sed 's|/[^/]*$||'".format(ldconfig)
elif attr_name == "includedir":
process = "{} --cflags libpq | sed 's/^-I//'".format(self.pkg_config_exe)
elif attr_name == "includedir-server":
process = "{0} --cflags libpq | sed -e 's/^-I//' -e 's/\s$/\/'$({0} --modversion libpq | cut -f1 -d\".\")'\/server/'".format(self.pkg_config_exe)
elif attr_name == "version":
process = "{} --modversion libpq | sed 's/^/PostgreSQL /'".format(self.pkg_config_exe)
elif attr_name == "ldflags":
process = "{} --libs-only-L libpq".format(self.pkg_config_exe)
elif attr_name == "cppflags":
process = "{} --cflags libpq".format(self.pkg_config_exe)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry but this is really not something that I wish to accept. Depending on so many external tool is nothing I wish to maintain. The pg_config exists exactly to avoid this.

If you provide a patch so that, calling pg_config --what it looks for an env var PG_CONFIG_WHAT and uses it in preference then we might consider it. Then Suse or whatever else think it's a good idea could create an external wrapper using cut, sed, awk, perl, or whatever bashism to call setup.py.

else:
raise Exception("Unsupported attr '{}'".format(attr_name))

try:
pkg_config_process = subprocess.getoutput(process)
except OSError:
raise Warning(
f"Unable to find 'pkgconfig' file in '{self.pkg_config_exe}'")
result = pkg_config_process
if not result:
print("Command error at {}".format(process))
if not isinstance(result, str):
result = result.decode('ascii')
return result

def query(self, attr_name):
"""Spawn the pg_config executable, querying for the given config
name, and return the printed value, sanitized. """

if self.using_pkg_config:
return self.query_pkgconfig(attr_name)

try:
pg_config_process = subprocess.Popen(
[self.pg_config_exe, "--" + attr_name],
Expand Down Expand Up @@ -197,6 +240,13 @@ def _get_pg_config_from_registry(self):
return None

return pg_config_path

def autodetect_pkg_config_path(self):
if PLATFORM_IS_WINDOWS:
sys.stderr.write("pkg-config is not supported on Windows.")
return None
else:
return self.find_on_path("pkg-config")


class psycopg_build_ext(build_ext):
Expand Down Expand Up @@ -233,6 +283,8 @@ def initialize_options(self):
self.have_ssl = have_ssl
self.static_libpq = static_libpq
self.pg_config = None
self.pkg_config = None
self.using_pkg_config = False

def compiler_is_msvc(self):
return self.get_compiler_name().lower().startswith('msvc')
Expand Down