pax_global_header00006660000000000000000000000064122364473550014525gustar00rootroot0000000000000052 comment=b4f285462e4304e99062bdc8e1b4d87b68d742ba pkgconfig-1.1.0/000077500000000000000000000000001223644735500134735ustar00rootroot00000000000000pkgconfig-1.1.0/.gitignore000066400000000000000000000000541223644735500154620ustar00rootroot00000000000000build/ dist/ .tox/ *.egg/* *.egg-info *.pyc pkgconfig-1.1.0/.travis.yml000066400000000000000000000002141223644735500156010ustar00rootroot00000000000000language: python python: - "2.6" - "2.7" - "3.2" - "3.3" install: - pip install nose --use-mirrors script: nosetests pkgconfig-1.1.0/LICENSE000066400000000000000000000021111223644735500144730ustar00rootroot00000000000000Copyright (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.1.0/MANIFEST.in000066400000000000000000000000431223644735500152260ustar00rootroot00000000000000include LICENSE include README.rst pkgconfig-1.1.0/README.rst000066400000000000000000000016251223644735500151660ustar00rootroot00000000000000pkgconfig ========= .. 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 - 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' - parse the output to build extensions with setup.py :: >>> d = pkgconfig.parse('glib-2.0 gtk+-2.0') >>> d['libraries'] set([u'glib-2.0', u'gtk+-2.0']) The ``pkgconfig`` module is licensed under the MIT license. pkgconfig-1.1.0/data/000077500000000000000000000000001223644735500144045ustar00rootroot00000000000000pkgconfig-1.1.0/data/fake-gtk+-3.0.pc000066400000000000000000000004421223644735500167720ustar00rootroot00000000000000prefix=/usr exec_prefix=/usr libdir=/usr/lib64 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.1.0/data/fake-python.pc000066400000000000000000000004021223644735500171510ustar00rootroot00000000000000prefix=/usr exec_prefix=${prefix} libdir=${exec_prefix}/lib 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.1.0/pkgconfig/000077500000000000000000000000001223644735500154425ustar00rootroot00000000000000pkgconfig-1.1.0/pkgconfig/__init__.py000066400000000000000000000000311223644735500175450ustar00rootroot00000000000000from .pkgconfig import * pkgconfig-1.1.0/pkgconfig/pkgconfig.py000066400000000000000000000131111223644735500177600ustar00rootroot00000000000000# -*- 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 subprocess import re import collections 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): 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): cmd = 'pkg-config {0} {1}'.format(option, package).split() proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = proc.communicate() return out.rstrip().decode('utf-8') @_convert_error def exists(package): """Return True if package information is available.""" cmd = 'pkg-config --exists {0}'.format(package).split() return subprocess.call(cmd) == 0 @_convert_error def requires(package): """Return a list of package names that is required by the package""" return _query(package, '--print-requires').split('\n') def cflags(package): """Return the CFLAGS string returned by pkg-config.""" return _query(package, '--cflags') def libs(package): """Return the LDFLAGS string returned by pkg-config.""" return _query(package, '--libs') 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 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. """ def parse_package(package): result = collections.defaultdict(set) # 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 out.split(): key = _PARSE_MAP.get(token[:2]) if key: result[key].add(token[2:].strip()) # Iterate and clean define macros. macros = set() for declaration in result['define_macros']: macro = tuple(declaration.split('=')) if len(macro) == 1: macro += '', macros.add(macro) result['define_macros'] = macros # Return parsed configuration. return result # Go through all package names and update the result dict accordingly. result = collections.defaultdict(set) for package in packages.split(): for k, v in parse_package(package).items(): result[k].update(v) return result pkgconfig-1.1.0/setup.py000066400000000000000000000006641223644735500152130ustar00rootroot00000000000000from setuptools import setup VERSION = '1.1.0' setup( name='pkgconfig', version=VERSION, author='Matthias Vogelgesang', author_email='matthias.vogelgesang@gmail.com', url='http://github.com/matze/pkgconfig', license='MIT', packages=['pkgconfig'], description="Interface Python with pkg-config", long_description=open('README.rst').read(), setup_requires=['nose>=1.0'], test_suite='test', ) pkgconfig-1.1.0/test.py000066400000000000000000000024341223644735500150270ustar00rootroot00000000000000import 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/lib64', '-lgtk-3')) def test_parse(): config = pkgconfig.parse("fake-gtk+-3.0 fake-python") nt.assert_true(('GSEAL_ENABLE', '') in config['define_macros']) nt.assert_true('/usr/include/gtk-3.0' in config['include_dirs']) nt.assert_true('/usr/lib64' in config['library_dirs'] or not config['library_dirs']) nt.assert_true('gtk-3' in config['libraries']) nt.assert_true('/usr/include/python2.7' in config['include_dirs']) pkgconfig-1.1.0/tox.ini000066400000000000000000000001061223644735500150030ustar00rootroot00000000000000[tox] envlist = py26, py27 [testenv] deps = nose commands= nosetests