[pypy-commit] cffi default: Passing of proper CFLAGS/CXXFLAGS/LDFLAGS is hard and error prone
vyskocilm
pypy.commits at gmail.com
Thu Jan 31 04:26:40 EST 2019
Author: Michal Vyskocil <michal.vyskocil at gmail.com>
Branch:
Changeset: r3189:4e8e9cab26fd
Date: 2017-05-22 23:49 +0200
http://bitbucket.org/cffi/cffi/changeset/4e8e9cab26fd/
Log: Passing of proper CFLAGS/CXXFLAGS/LDFLAGS is hard and error prone
Add pkg-config wrapper, which is the cross-platform tool telling
exactly this.
diff --git a/cffi/api.py b/cffi/api.py
--- a/cffi/api.py
+++ b/cffi/api.py
@@ -2,6 +2,7 @@
from .lock import allocate_lock
from .error import CDefError
from . import model
+from .pkgconfig import pkgconfig_installed, merge_dicts, pkgconfig_kwargs
try:
callable
@@ -611,6 +612,18 @@
if os.sep in module_name or (os.altsep and os.altsep in module_name):
raise ValueError("'module_name' must not contain '/': use a dotted "
"name to make a 'package.module' location")
+ if "pkgconfig" in kwds:
+ if pkgconfig_installed ():
+ try:
+ del kwds ["libraries"]
+ except KeyError:
+ pass
+ merge_dicts (kwds, pkgconfig_kwargs (kwds ["pkgconfig"]))
+ try:
+ del kwds ["pkgconfig"]
+ except KeyError:
+ pass
+ print (kwds)
self._assigned_source = (str(module_name), source,
source_extension, kwds)
diff --git a/cffi/pkgconfig.py b/cffi/pkgconfig.py
new file mode 100644
--- /dev/null
+++ b/cffi/pkgconfig.py
@@ -0,0 +1,65 @@
+# pkg-config, https://www.freedesktop.org/wiki/Software/pkg-config/ integration for cffi
+import subprocess
+
+def pkgconfig_installed ():
+ try:
+ subprocess.check_output (["pkg-config", "--version"])
+ return True
+ except subprocess.CalledProcessError:
+ return False
+
+def merge_dicts (d1, d2):
+ for key, value in d2.items ():
+ if not key in d1:
+ d1 [key] = value
+ else:
+ d1 [key].extend (value)
+ return d1
+
+def pkgconfig_kwargs (libs):
+ """If pkg-config is available, then return kwargs for set_source based on pkg-config output
+
+ It setup include_dirs, library_dirs, libraries and define_macros
+ """
+
+ # make API great again!
+ if isinstance (libs, (str, bytes)):
+ libs = (libs, )
+
+ # drop starting -I -L -l from cflags
+ def dropILl (string):
+ def _dropILl (string):
+ if string.startswith ("-I") or string.startswith ("-L") or string.startswith ("-l"):
+ return string [2:]
+ return [_dropILl (x) for x in string.split ()]
+
+ # convert -Dfoo=bar to list of tuples [("foo", "bar")] expected by cffi
+ def macros (string):
+ def _macros (string):
+ return tuple (string [2:].split ('=', 2))
+ return [_macros (x) for x in string.split () if x.startswith ("-D")]
+
+ # pkg-config call
+ def pc (libname, *args):
+ a = ["pkg-config", "--print-errors"]
+ a.extend (args)
+ a.append (libname)
+ return subprocess.check_output (a)
+
+ # return kwargs for given libname
+ def kwargs (libname):
+ return {
+ "include_dirs" : dropILl (pc (libname, "--cflags-only-I")),
+ "library_dirs" : dropILl (pc (libname, "--libs-only-L")),
+ "libraries" : dropILl (pc (libname, "--libs-only-l")),
+ "define_macros" : macros (pc (libname, "--cflags")),
+ }
+
+ # merge all arguments together
+ ret = {}
+ for libname in libs:
+ foo = kwargs (libname)
+ merge_dicts (ret, foo)
+
+ return ret
+
More information about the pypy-commit
mailing list