我的想法是,每次我想编译cython模块或包时,我都不必自己编写一个setup.py文件,而是创建一个函数。该函数还应该自己运行创建的setup.py。
所以问题也在于“你如何编写代码编写代码?”。
答案 0 :(得分:0)
我找到了一个有效的解决方案。 使用以下代码创建compile_cython.py文件:
import os
from subprocess import Popen
temp_dir = os.environ['TEMP']
def package(directory, packages, logfile=False, byproducts=None, annotate=False, language='C'):
"""Compile cython .pyx files to a .pyd file inplace
:param directory: the directory where the main package lies.
:param packages: List of packages to compile. A package is described in a
:type tuple that consists of package name, relative path from main package, list of include files,
list of include directories and the language (default is C).
:param logfile: Path or :type bool. If true, a log will be created in :param directory:.
:param byproducts: The directory in which the by-products will be stored.
If None, by-products will be saved in "%TEMP%\cython_byproducts".
:param annotate: The Cython annotate option.
:param language: Default language
Example:
package('C:\\projects', [('graphics', 'game\\graphics', ['OpenGL32'], [r'C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\x64']])
"""
if not byproducts: byproducts = os.path.join(temp_dir, "cython_byproducts")
if logfile is True: logfile = os.path.join(directory, "log.txt")
elif not logfile: logfile = os.path.join(byproducts, "log.txt")
if isinstance(packages, str):
dir, package = os.path.split(packages)
packages = [(package, package)]
setup_file = os.path.join(byproducts, "setup.py")
#Write a setup file
with open(setup_file, 'w') as file:
file.write("""
from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy as np
import sys
print(sys.argv) #print for logging
packages = {packages}
extensions = []
for package in packages:
default = ['name', 'path', [], [], '{default_language}']
default[:len(package)]=package
extensions.append(Extension("%s.*" %default[0], ["%s\\\\*.pyx" %default[1]], libraries=default[2],
library_dirs=default[3], language=default[4].lower()))
setup(include_dirs = np.get_include(),ext_modules = cythonize(extensions, annotate={annotate})) # accepts a glob pattern
""".format(packages=packages, annotate=annotate, default_language=language)
)
p = Popen(r'python "{setup}" build_ext --inplace --build-temp "{byproducts}"'.format(setup=setup_file,
byproducts=byproducts,) ,
cwd=directory)
with open(logfile, 'w') as log:
stdout, stderr = p.communicate()
log.write(stdout or 'NO OUTPUT\n')
log.write(stderr or 'NO ERRORS\n')
def module(directory, modules, logfile=False, byproducts=None, annotate=False, language='C'):
"""Compile cython .pyx files to a .pyd file inplace
:param directory: the directory where the module lies
:param modules: The Path relative from :param directory or a List of modules to compile. A module is described in a
:type tuple that consists of module name, relative path from :param directory, list of include files,
list of include directories and the language (default is C).
:param logfile: Path or :type bool. If true, a log will be created in :param directory:.
:param byproducts: The directory in which the by-products will be stored.
If None, by-products will be saved in "%TEMP%\cython_byproducts".
:param annotate: The Cython annotate option.
:param language: Default language
Example:
module('C:\\projects', [('effects', 'game\\graphics\\effects.pyx'])
"""
if not byproducts: byproducts = os.path.join(temp_dir, "cython_byproducts")
if logfile is True: logfile = os.path.join(directory, "log.txt")
elif not logfile: logfile = os.path.join(byproducts, "log.txt")
if isinstance(modules, str):
dir, name_ext = os.path.split(modules)
name, ext = os.path.splitext(name_ext)
modules = [(name, name_ext)]
setup_file = os.path.join(byproducts, "setup.py")
#Write a setup file
with open(setup_file, 'w') as file:
file.write("""
from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy as np
import sys
print(sys.argv) #print for logging
modules = {modules}
extensions = []
for module in modules:
default = ['name', 'path', [], [], '{default_language}']
default[:len(module)]=module
extensions.append(Extension("%s" %default[0], ["%s" %default[1]], libraries=default[2],
library_dirs=default[3], language=default[4].lower()))
setup(include_dirs = np.get_include(),ext_modules = cythonize(extensions, annotate={annotate})) # accepts a glob pattern
""".format(modules=modules, annotate=annotate, default_language=language)
)
p = Popen(r'python "{setup}" build_ext --inplace --build-temp "{byproducts}"'.format(setup=setup_file,
byproducts=byproducts,) ,
cwd=directory)
with open(logfile, 'w') as log:
stdout, stderr = p.communicate()
log.write(stdout or 'NO OUTPUT\n')
log.write(stderr or 'NO ERRORS\n')
还需要进行一些修改才能编译纯C或C ++文件,但它适用于Cython文件。
在此设置中,自动包含Numpy。但我想这没有问题,因为除非你使用numpy函数,否则它不会包含任何东西,或者它是什么?