首页 > 编程语言 >SciTech-Python-编译Python的C/C++扩展的setup.py

SciTech-Python-编译Python的C/C++扩展的setup.py

时间:2023-12-24 17:22:49浏览次数:36  
标签:Python setup py tree build path os self dir

https://github.com/google-deepmind/tree/setup.py

"""Setup for pip package."""

import os, platform, sys, sysconfig, shutil, subprocess, setuptools
from setuptools.command import build_ext

here = os.path.dirname(os.path.abspath(file))

def _get_tree_version():
  """Parse the version string from tree/__init__.py."""
  with open(os.path.join(here, 'tree', '__init__.py')) as f:
    try:
      version_line = next(line for line in f if line.startswith('__version__'))
    except StopIteration:
      raise ValueError('__version__ not defined in tree/__init__.py')
    else:
      ns = {}
      exec(version_line, ns)  # pylint: disable=exec-used
      return ns['__version__']

def _parse_requirements(path):
  with open(os.path.join(here, path)) as f:
    return [
        line.rstrip() for line in f
        if not (line.isspace() or line.startswith('#'))
    ]

class CMakeExtension(setuptools.Extension):
  """An extension with no sources.

  We do not want distutils to handle any of the compilation (instead we rely
  on CMake), so we always pass an empty list to the constructor.
  """

  def __init__(self, name, source_dir=''):
    super().__init__(name, sources=[])
    self.source_dir = os.path.abspath(source_dir)

class BuildCMakeExtension(build_ext.build_ext):
  """Our custom build_ext command.

  Uses CMake to build extensions instead of a bare compiler (e.g. gcc, clang).
  """

  def run(self):
    self._check_build_environment()
    for ext in self.extensions:
      self.build_extension(ext)

  def _check_build_environment(self):
    """Check for required build tools: CMake, C++ compiler, and python dev."""
    try:
      subprocess.check_call(['cmake', '--version'])
    except OSError as e:
      ext_names = ', '.join(e.name for e in self.extensions)
      raise RuntimeError(
          f'CMake must be installed to build the following extensions: {ext_names}'
      ) from e
    print('Found CMake')

  def build_extension(self, ext):
    extension_dir = os.path.abspath(
        os.path.dirname(self.get_ext_fullpath(ext.name)))
    build_cfg = 'Debug' if self.debug else 'Release'
    cmake_args = [
        f'-DPython3_ROOT_DIR={sys.prefix}',
        f'-DPython3_EXECUTABLE={sys.executable}',
        f'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extension_dir}',
        f'-DCMAKE_BUILD_TYPE={build_cfg}'
    ]
    if platform.system() != 'Windows':
      cmake_args.extend([
          f'-DPython3_LIBRARY={sysconfig.get_paths()["stdlib"]}',
          f'-DPython3_INCLUDE_DIR={sysconfig.get_paths()["include"]}',
      ])
    if platform.system() == 'Darwin' and os.environ.get('ARCHFLAGS'):
      osx_archs = []
      if '-arch x86_64' in os.environ['ARCHFLAGS']:
        osx_archs.append('x86_64')
      if '-arch arm64' in os.environ['ARCHFLAGS']:
        osx_archs.append('arm64')
      cmake_args.append(f'-DCMAKE_OSX_ARCHITECTURES={";".join(osx_archs)}')
    os.makedirs(self.build_temp, exist_ok=True)
    subprocess.check_call(
        ['cmake', ext.source_dir] + cmake_args, cwd=self.build_temp)
    subprocess.check_call(
        ['cmake', '--build', '.', f'-j{os.cpu_count()}', '--config', build_cfg],
        cwd=self.build_temp)

    # Force output to <extension_dir>/. Amends CMake multigenerator output paths
    # on Windows and avoids Debug/ and Release/ subdirs, which is CMake default.
    tree_dir = os.path.join(extension_dir, 'tree')  # pylint:disable=unreachable
    for cfg in ('Release', 'Debug'):
      cfg_dir = os.path.join(extension_dir, cfg)
      if os.path.isdir(cfg_dir):
        for f in os.listdir(cfg_dir):
          shutil.move(os.path.join(cfg_dir, f), tree_dir)

setuptools.setup(
    name='dm-tree',
    version=_get_tree_version(),
    url='https://github.com/deepmind/tree',
    description='Tree is a library for working with nested data structures.',
    author='DeepMind',
    author_email='[email protected]',
    long_description=open(os.path.join(here, 'README.md')).read(),
    long_description_content_type='text/markdown',
    # Contained modules and scripts.
    packages=setuptools.find_packages(),
    tests_require=_parse_requirements('requirements-test.txt'),
    test_suite='tree',
    cmdclass=dict(build_ext=BuildCMakeExtension),
    ext_modules=[CMakeExtension('_tree', source_dir='tree')],
    zip_safe=False,
    # PyPI package information.
    classifiers=[
        'Development Status :: 4 - Beta',
        'Intended Audience :: Developers',
        'Intended Audience :: Science/Research',
        'License :: OSI Approved :: Apache Software License',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: 3.9',
        'Programming Language :: Python :: 3.10',
        'Programming Language :: Python :: 3.11',
        'Topic :: Scientific/Engineering :: Mathematics',
        'Topic :: Software Development :: Libraries',
    ],
    license='Apache 2.0',
    keywords='tree nest flatten',
)

标签:Python,setup,py,tree,build,path,os,self,dir
From: https://www.cnblogs.com/abaelhe/p/17924622.html

相关文章

  • Python教程(17)——python模块是什么?python模块详解
    Python模块简介模块是一个包含了Python定义和语句的文件,可用于将功能组织成可重用和可维护的代码块。每个Python文件都可以作为一个模块,模块可以包含变量、函数、类或可执行代码。通过使用模块,我们可以将代码分离成逻辑单元,促进模块化编程。所以我们可以简单的理解为,一个py文件就......
  • Python3.12新增内容
    https://medium.com/techtofreedom/5-handy-python-3-12-new-features-that-improve-your-coding-experience-fe2d6e1f05b4类型系统,更方便的类型别名声明方式简便的类型别名声明我们可以直接如下定义类型别名Point=tuple[float,float]classPointTest: def__init__(s......
  • 字符函数和字符串函数:strcmp、strncpy——《初学C语言第37天》
    //////————strcmp(比较两个字符串(的内容,ASCII值))————>头文件#include<string.h>//第一个字符串大于第二个字符串,则返回大于0的数字//第一个字符串等于第二个字符串,则返回0//第一个字符串小于第二个字符串,则返回小于0的数字//那么如何判断两个字符串?//比较方法:下标逐步......
  • Python教程(16)——lambda表达式详解
    lambda函数介绍我们平时经常可以在Python的代码中看到一种lambda开头的这种表达式,如果没有学过Python的相关知识,可能会一脸懵逼,不清楚到底这个关键字是干嘛的,用来表示什么。实际上这个就是lambda函数。lambda函数是Python中一种特殊的匿名函数,但不仅仅只存在Python中,它允许我们......
  • Python教程(16)——lambda表达式详解
    lambda函数介绍我们平时经常可以在Python的代码中看到一种lambda开头的这种表达式,如果没有学过Python的相关知识,可能会一脸懵逼,不清楚到底这个关键字是干嘛的,用来表示什么。实际上这个就是lambda函数。lambda函数是Python中一种特殊的匿名函数,但不仅仅只存在Python中,它允许我们......
  • Python爬虫知识点(bs/find_all/正则表达式)
    格式输出 BeautifulSoup库  信息提取  正则表达式     ......
  • Python面试题汇总
    1、一行代码实现1-100之和利用sum()函数求和sum(range(1,101))2、如何在一个函数内部修改全局变量利用global将函数内的变量指定成全局变量a=5deffn():globalaa=4fn()print(a)结果是4,不加global,则解决是53、列出5个python标准库sys:提供了不少与操作系统相关......
  • Python学生成绩管理系统
    filename='student.txt'importosdefmenu():print('--------------学生管理系统-----------')print('--------------功能菜单--------------')print('1.录入学生信息')print('2.查找学生信息')print(&......
  • Python网络编程:掌握urllib包的妙用
    在Python的世界里,处理网络请求是日常任务之一。不论是爬取网页数据,还是调用网络API,一个好用的HTTP客户端库是必不可少的。Python标准库中的urllib包就是这样一个强大的工具,它提供了一个简单的界面来与网上资源互动。本文将带你深入了解urllib包,包括它的主要模块,以及如何使用它们完......
  • Python 潮流周刊第 32 期(摘要)
    本周刊由Python猫出品,精心筛选国内外的250+信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进Python技术,并增长职业和副业的收入。周刊全文:https://pythoncat.top/posts/2023-12-23-weekly以下是本期摘要:......