ActiveState Code

Recipe 502261: Python distutils + pkg-config


This is a short and sweet recipe for using pkg-config with your distutils extension modules.

Python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#!/usr/bin/env python
from distutils.core import setup
from distutils.extension import Extension
import commands

def pkgconfig(*packages, **kw):
    flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries'}
    for token in commands.getoutput("pkg-config --libs --cflags %s" % ' '.join(packages)).split():
        kw.setdefault(flag_map.get(token[:2]), []).append(token[2:])
    return kw

setup(
    name = "myPackage",
    ext_modules=[
        Extension("extension", ["extension_main.c"], **pkgconfig('glib-2.0')),
    ],
)

Discussion

Pkg-config is a very common system for obtaining path information about system libraries in a portable way. Makefiles typically invoke "pkg-config --cflags" to generate compiler flags, and "pkg-config --libs" to generate library flags for the linker.

This recipe makes it easy to use pkg-config's output with distutils. Now you can use system libraries without hard-coding paths, as long as those libraries are distributed with pkg-config data files.

The example builds a module "extension.so" that requires the GLib library.

Comments

  1. 1. At 11:25 a.m. on 1 jun 2007, Thomas Pönitz said:

    Problems with additional arguments. So I made some changes:

    def pkgconfig(packages, *kw):

    flag_map = {'-I': 'include_dirs', '-L': 'library_dirs', '-l': 'libraries'}
    
    for token in commands.getoutput("pkg-config --libs --cflags %s" % ' '.join(packages)).split():
    
        if flag_map.has_key(token[:2]):
    
            kw.setdefault(flag_map.get(token[:2]), []).append(token[2:])
    
        else: # throw others to extra_link_args
    
            kw.setdefault('extra_link_args', []).append(token)
    
    
    for k, v in kw.iteritems(): # remove duplicated
    
        kw[k] = list(set(v))
    
    return kw
    

Sign in to comment