2015-01-29 16 views
7

pip ile yüklenen python uygulamaları için, C uzantısı gereksinimlerini otomatik olarak nasıl yönetebilirsiniz?Pipolu python uygulamaları için C uzantıları nasıl kullanılır?

Örneğin, mysqlclient modül sistemde yüklü MySQL gelişimi kütüphanelerini gerektirir. Başlangıçta bu modülü gerektiren bir uygulama yüklediğinizde, MySQL geliştirme kütüphaneleri sistemde değilse başarısız olur. Yani soru şu ki bunu nasıl çözebilirim?

  1. ben bilmem zaten setup.py ile bu çözmenin bir yolu var mı?
  2. Saf bir python modülü uygulaması kullanmamalı mıyım?

Not; Ben "sadece py2exe kullanın" gibi yanıtları arıyorum değil değilim.

+0

Özellikle 'pip' ile sınırlı mısınız? Aksi takdirde, ikili (ve Python olmayan) bağımlılıkları ele almak için icat edilen [conda] (http://conda.pydata.org/) 'a bir göz atın. –

cevap

8

yok. extension yazmıyorsanız, oluşturma işleminizin bir parçası olarak tamamen ayrı C kitaplığı eklemenin bir yolu yoktur. Bu durumda bile, ext_modules dosyalarındaki tüm .c dosyalarını belirtmeniz gerekir, böylece bunların tümü sizin oluşturma işleminizin bir parçası olarak derlenebilir; Yapabileceğiniz

tek şey basitçe inşa sürecini durdurmak ve mysql-devel (veya libmysqlclient-dev) henüz yüklenmemiş ise kullanıcıya makul hatayı vermektir. MySQL-dev mysql.h ithal ve başarıyla derlenmiş olup olmadığını kontrol basit bir C işlevi yazıyor yüklüyse

bir yolu bilmek.

Not:mysql.h ve my_global.h libmysqlclient-dev paketinin bir parçasıdır.


test/test_mysqlclient.c


// Taken from: http://zetcode.com/db/mysqlc 

#include <my_global.h> 
#include <mysql.h> 

int main(int argc, char **argv) 
{ 
    printf("MySQL client version: %s\n", mysql_get_client_info()); 
    exit(0); 
} 
İkinci olarak, inşa sürecinin bir parçası olarak dahil edilecektir ki en bizim setup.py dosyasını güncellemek edelim.

kurulumu.py

#!/usr/bin/env python 

import os 
import subprocess 

from setuptools import setup, Extension 

def mysql_test_extension(): 
    process = subprocess.Popen(['which', 'mysql_config'], 
           stdout=subprocess.PIPE, 
           stderr=subprocess.PIPE, 
           close_fds=True) 

    result, error = process.communicate() 
    if process.returncode > 0: 
     raise RuntimeError(error) 

    config_command = result.strip() 

    cflags = subprocess.check_output([config_command, '--cflags'], close_fds=True).strip() 

    include_dirs = [] 
    extra_compile_args = [] 
    for arg in cflags.split(' '): 
     if not arg.strip(): 
      continue 
     elif arg.startswith('-I'): 
      include_dirs.append(arg[2:]) 
     elif arg.startswith('-'): 
      extra_compile_args.append(arg) 
     else: 
      extra_compile_args[-1] = extra_compile_args[-1] + ' ' + arg 

    libs = subprocess.check_output([config_command, '--libs'], close_fds=True).strip() 

    libraries = [] 
    linkers = [] 
    for arg in libs.split(' '): 
     if not arg.strip(): 
      continue 
     elif arg.startswith('-L'): 
      libraries.append(arg[2:]) 
     elif arg.startswith('-'): 
      linkers.append(arg) 
     else: 
      linkers[-1] = extra_compile_args[-1] + ' ' + arg 

    return Extension('test_mysqlclient', ['test/test_mysqlclient.c'], 
        include_dirs=include_dirs, 
        library_dirs=libraries, 
        extra_link_args=linkers, 
        extra_compile_args=extra_compile_args) 



setup(name='python-project', 
     version='1.0', 
     description='Python Project', 
     classifiers=[ 
      'Development Status :: 5 - Production/Stable', 
      'Environment :: Console', 
      'Intended Audience :: Developers', 
      'License :: OSI Approved :: MIT License', 
      'Operating System :: OS Independent', 
      'Programming Language :: Python :: 2.7', 
      'Natural Language :: English', 
     ], 
     keywords='mysql python project', 
     author='Ozgur Vatansever', 
     url='http://github.com/ozgur/python-project/', 
     license='MIT', 
     packages=['some_project'], 
     ext_modules = [mysql_test_extension()] 
) 

Sen test_mysqlclient dosyası ile birlikte paketinizi oluşturmaya başlayabilirsiniz: mysql-devel sisteminizde yüklü değilse

$ python setup.py build 

varsa, alırsınız Buna benzer bir yapı hatası:

test/test_mysqlclient.c:3:10: fatal error: 'my_global.h' file not found 
#include <my_global.h> 
    ^
1 error generated. 
-2

Yani soru bu çözerim nasıl?

Nasıl olsa bu sorunu çözmek değil. Setup.py'deki python ekosisteminin dışındaki harici bağımlılıkları tanımlamak için herhangi bir yöntem yoktur. Sadece bir README içinde sağlayın.

İlgili konular