pax_global_header00006660000000000000000000000064132365764020014522gustar00rootroot0000000000000052 comment=365cbee888b3794739fdd938d885e3f45337a732 pkgconfig-1.3.1/000077500000000000000000000000001323657640200134735ustar00rootroot00000000000000pkgconfig-1.3.1/.gitignore000066400000000000000000000000631323657640200154620ustar00rootroot00000000000000build/ dist/ .tox/ .eggs/ *.egg/* *.egg-info *.pyc pkgconfig-1.3.1/.travis.yml000066400000000000000000000002261323657640200156040ustar00rootroot00000000000000language: python python: - "2.6" - "2.7" - "3.3" - "3.4" - "3.5" - "3.6" install: - pip install nose script: nosetests pkgconfig-1.3.1/LICENSE000066400000000000000000000021111323657640200144730ustar00rootroot00000000000000Copyright (c) 2013 Matthias Vogelgesang Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. pkgconfig-1.3.1/MANIFEST.in000066400000000000000000000001021323657640200152220ustar00rootroot00000000000000include LICENSE include README.rst include test.py include data/* pkgconfig-1.3.1/README.rst000066400000000000000000000043221323657640200151630ustar00rootroot00000000000000pkgconfig ========= .. image:: https://travis-ci.org/matze/pkgconfig.png?branch=master :target: https://travis-ci.org/matze/pkgconfig ``pkgconfig`` is a Python module to interface with the ``pkg-config`` command line tool and supports Python 2.6+. It can be used to - find all pkg-config packages :: >>> packages = pkgconfig.list_all() - check if a package exists :: >>> pkgconfig.exists('glib-2.0') True - check if a package meets certain version requirements :: >>> pkgconfig.installed('glib-2.0', '< 2.26') False - query CFLAGS and LDFLAGS :: >>> pkgconfig.cflags('glib-2.0') '-I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include' >>> pkgconfig.libs('glib-2.0') '-lglib-2.0' - get all variables defined for a package:: >>> pkgconfig.variables('glib-2.0') {u'exec_prefix': u'/usr'} - parse the output to build extensions with setup.py :: >>> d = pkgconfig.parse('glib-2.0 gtk+-2.0') >>> d['libraries'] [u'gtk+-2.0', u'glib-2.0'] The ``pkgconfig.parse`` function return a dictonary of list. The lists returned are an accurate representations of the equivalent ``pkg-config`` call, both in content and order. If ``pkg-config`` is not on the path, raises ``EnvironmentError``. The ``pkgconfig`` module is licensed under the MIT license. Changelog --------- Version 1.3.1 ~~~~~~~~~~~~~ - Fix compatibility problems with Python 2.6 Version 1.3.0 ~~~~~~~~~~~~~ - Add variables() API to query defined variables - Disable Python 3.2 and enable Python 3.5 and 3.6 tests - Fix #16: handle spaces of values in .pc files correctly Version 1.2.1 and 1.2.2 ~~~~~~~~~~~~~~~~~~~~~~~ Bug fix releases released on December 1st and 2nd 2016. - Include the ``data`` folder in the distribution in order to run tests - Improve the tests Version 1.2.0 ~~~~~~~~~~~~~ Released on November 30th 2016. - Potential break: switch from result set to list - Expose --list-all query - Added support for PKG_CONFIG environment variable Version 1.1.0 ~~~~~~~~~~~~~ Released on November 6th 2013. - Multiple packages can now be parsed with a single call to ``.parse``. Version 1.0.0 ~~~~~~~~~~~~~ First release on September 8th 2013. pkgconfig-1.3.1/data/000077500000000000000000000000001323657640200144045ustar00rootroot00000000000000pkgconfig-1.3.1/data/fake-gtk+-3.0.pc000066400000000000000000000004501323657640200167710ustar00rootroot00000000000000prefix=/usr exec_prefix=/usr libdir=/usr/lib_gtk_foo includedir=/usr/include targets=x11 broadway gtk_binary_version=3.0.0 gtk_host=x86_64-suse-linux-gnu Name: GTK+ Description: GTK+ Graphical UI Library Version: 3.2.1 Libs: -L${libdir} -lgtk-3 Cflags: -I${includedir}/gtk-3.0 -DGSEAL_ENABLE pkgconfig-1.3.1/data/fake-python.pc000066400000000000000000000004151323657640200171550ustar00rootroot00000000000000prefix=/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib_python_foo includedir=${prefix}/include Name: Python Description: Python library Requires: Version: 2.7 Libs.private: -lpthread -ldl -lutil Libs: -L${libdir} -lpython2.7 Cflags: -I${includedir}/python2.7 pkgconfig-1.3.1/pkgconfig/000077500000000000000000000000001323657640200154425ustar00rootroot00000000000000pkgconfig-1.3.1/pkgconfig/__init__.py000066400000000000000000000000311323657640200175450ustar00rootroot00000000000000from .pkgconfig import * pkgconfig-1.3.1/pkgconfig/pkgconfig.py000066400000000000000000000152231323657640200177660ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Copyright (c) 2013 Matthias Vogelgesang # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. """pkgconfig is a Python module to interface with the pkg-config command line tool.""" import os import shlex import re import collections from functools import wraps from subprocess import call, PIPE, Popen def _compare_versions(v1, v2): """ Compare two version strings and return -1, 0 or 1 depending on the equality of the subset of matching version numbers. The implementation is taken from the top answer at http://stackoverflow.com/a/1714190/997768. """ def normalize(v): return [int(x) for x in re.sub(r'(\.0+)*$', '', v).split(".")] n1 = normalize(v1) n2 = normalize(v2) return (n1 > n2) - (n1 < n2) def _split_version_specifier(spec): """Splits version specifiers in the form ">= 0.1.2" into ('0.1.2', '>=')""" m = re.search(r'([<>=]?=?)?\s*((\d*\.)*\d*)', spec) return m.group(2), m.group(1) def _convert_error(func): @wraps(func) def _wrapper(*args, **kwargs): try: return func(*args, **kwargs) except OSError: raise EnvironmentError("pkg-config is not installed") return _wrapper @_convert_error def _query(package, option): pkg_config_exe = os.environ.get('PKG_CONFIG', None) or 'pkg-config' cmd = '{0} {1} {2}'.format(pkg_config_exe, option, package) proc = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE) out, err = proc.communicate() return out.rstrip().decode('utf-8') @_convert_error def exists(package): """ Return True if package information is available. If ``pkg-config`` not on path, raises ``EnvironmentError``. """ pkg_config_exe = os.environ.get('PKG_CONFIG', None) or 'pkg-config' cmd = '{0} --exists {1}'.format(pkg_config_exe, package).split() return call(cmd) == 0 @_convert_error def requires(package): """ Return a list of package names that is required by the package. If ``pkg-config`` not on path, raises ``EnvironmentError``. """ return _query(package, '--print-requires').split('\n') def cflags(package): """ Return the CFLAGS string returned by pkg-config. If ``pkg-config`` not on path, raises ``EnvironmentError``. """ return _query(package, '--cflags') def libs(package): """Return the LDFLAGS string returned by pkg-config.""" return _query(package, '--libs') def variables(package): """ Return a dictionary of all the variables defined in the .pc pkg-config file of 'package'. """ if not exists(package): msg = "Package `{0}' does not exist in PKG_CONFIG_PATH".format(package) raise ValueError(msg) result = _query(package, '--print-variables') names = (x for x in result.split('\n') if x != '') return dict(((x, _query(package, '--variable={0}'.format(x)).strip()) for x in names)) def installed(package, version): """ Check if the package meets the required version. The version specifier consists of an optional comparator (one of =, ==, >, <, >=, <=) and an arbitrarily long version number separated by dots. The should be as you would expect, e.g. for an installed version '0.1.2' of package 'foo': >>> installed('foo', '==0.1.2') True >>> installed('foo', '<0.1') False >>> installed('foo', '>= 0.0.4') True If ``pkg-config`` not on path, raises ``EnvironmentError``. """ if not exists(package): return False number, comparator = _split_version_specifier(version) modversion = _query(package, '--modversion') try: result = _compare_versions(modversion, number) except ValueError: msg = "{0} is not a correct version specifier".format(version) raise ValueError(msg) if comparator in ('', '=', '=='): return result == 0 if comparator == '>': return result > 0 if comparator == '>=': return result >= 0 if comparator == '<': return result < 0 if comparator == '<=': return result <= 0 _PARSE_MAP = { '-D': 'define_macros', '-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries' } def parse(packages): """ Parse the output from pkg-config about the passed package or packages. Builds a dictionary containing the 'libraries', the 'library_dirs', the 'include_dirs', and the 'define_macros' that are presented by pkg-config. *package* is a string with space-delimited package names. If ``pkg-config`` not on path, raises ``EnvironmentError``. """ def parse_package(package): result = collections.defaultdict(list) # Execute the query to pkg-config and clean the result. out = _query(package, '--cflags --libs') out = out.replace('\\"', '') # Iterate through each token in the output. for token in re.split(r'(?=1.0'], python_requires='>=2.6, !=3.0.*, !=3.1.*, !=3.2.*', test_suite='test', ) pkgconfig-1.3.1/test.py000066400000000000000000000037161323657640200150330ustar00rootroot00000000000000import os import pkgconfig import nose.tools as nt os.environ['PKG_CONFIG_PATH'] = os.path.abspath('./data') PACKAGE_NAME = 'fake-gtk+-3.0' def test_exists(): nt.assert_true(pkgconfig.exists(PACKAGE_NAME)) def test_version(): assertions = { '3.2.1': True, '==3.2.1': True, '==3.2.2': False, '> 2.2': True, '> 3.4': False, '<= 3.3.5': True, '< 2.3': False } for version, val in assertions.items(): nt.assert_true(pkgconfig.installed(PACKAGE_NAME, version) == val) def test_cflags(): flags = pkgconfig.cflags(PACKAGE_NAME) for flag in flags.split(' '): nt.assert_true(flag in ('-DGSEAL_ENABLE', '-I/usr/include/gtk-3.0')) def test_libs(): flags = pkgconfig.libs(PACKAGE_NAME) for flag in flags.split(' '): nt.assert_true(flag in ('-L/usr/lib_gtk_foo', '-lgtk-3')) def test_parse(): config = pkgconfig.parse("fake-gtk+-3.0 fake-python") nt.assert_true(('GSEAL_ENABLE', None) in config['define_macros']) nt.assert_true('/usr/include/gtk-3.0' in config['include_dirs']) nt.assert_true('/usr/lib_gtk_foo' in config['library_dirs']) nt.assert_true('/usr/lib_python_foo' in config['library_dirs']) nt.assert_true('gtk-3' in config['libraries']) nt.assert_true('/usr/include/python2.7' in config['include_dirs']) def test_listall(): packages = pkgconfig.list_all() nt.assert_true('fake-gtk+-3.0' in packages) nt.assert_true('fake-python' in packages) def test_variables(): variables = pkgconfig.variables('fake-python') nt.assert_true('prefix' in variables) nt.assert_true('exec_prefix' in variables) nt.assert_true('libdir' in variables) nt.assert_true('includedir' in variables) nt.assert_true(variables['prefix'] == '/usr') nt.assert_true(variables['exec_prefix'] == '/usr') nt.assert_true(variables['libdir'] == '/usr/lib_python_foo') nt.assert_true(variables['includedir'] == '/usr/include') pkgconfig-1.3.1/tox.ini000066400000000000000000000001361323657640200150060ustar00rootroot00000000000000[tox] envlist = py26, py27, py33, py34, py35, py36 [testenv] deps = nose commands= nosetests