这个想法是,每次我想编译cython模块或包时,我不必自己编写setup.py文件,而是让一个函数来创建它。该函数还应该自己运行创建的setup.py。
因此,问题还在于"如何编写编写代码?"。
我找到了一个有效的解决方案。使用以下代码创建一个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 FilesMicrosoft SDKsWindowsv7.1Libx64']])
"""
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 OUTPUTn')
log.write(stderr or 'NO ERRORSn')
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 OUTPUTn')
log.write(stderr or 'NO ERRORSn')
它仍然需要一些修改才能编译纯C或C++文件,但它适用于Cython文件。
在此设置中,Numpy会自动包含在内。但我想这没问题,因为除非你使用numpy函数,否则它实际上不包括任何东西,或者是这样吗?