在pip安装上运行Makefile [英] Run Makefile on pip install

查看:91
本文介绍了在pip安装上运行Makefile的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些协议缓冲区定义,它们是pip install流程的一部分,需要在Python源代码中构建.我在setup.py中将setuptools.command.install命令子类化,但是我认为它在安装软件包后试图运行Makefile,因此无法识别源.

I have some protocol buffer definitions which need to be built to Python source as part of the pip install process. I've subclassed the setuptools.command.install command in setup.py but I think it's trying to run the Makefile after the package is installed so the sources aren't recognised.

我找不到有关在安装pip期间会发生什么的信息.任何人都可以照亮吗?

I can't find information about what happens during a pip installation. Can anyone shed any light?

setup.py:

import subprocess
import sys

from setuptools import setup
from setuptools.command.install import install

class Install(install):
    """Customized setuptools install command - builds protos on install."""
    def run(self):
        protoc_command = ["make", "python"]
        if subprocess.call(protoc_command) != 0:
            sys.exit(-1)
        install.run(self)


setup(
    name='myprotos',
    version='0.0.1',
    description='Protocol Buffers.',
    install_requires=[],
    cmdclass={
        'install': Install,
    }
)

$ pip install -vvv .的输出:

Processing /path/to/myprotos
  Running setup.py (path:/private/var/folders/3t/4qwkfyr903d0b7db7by2kj6r0000gn/T/pip-jpgCby-build/setup.py) egg_info for package from file:///path/to/myprotos
    Running command python setup.py egg_info
    running egg_info
    creating pip-egg-info/myprotos.egg-info
    writing pip-egg-info/myprotos.egg-info/PKG-INFO
    writing top-level names to pip-egg-info/myprotos.egg-info/top_level.txt
    writing dependency_links to pip-egg-info/myprotos.egg-info/dependency_links.txt
    writing manifest file 'pip-egg-info/myprotos.egg-info/SOURCES.txt'
    reading manifest file 'pip-egg-info/myprotos.egg-info/SOURCES.txt'
    writing manifest file 'pip-egg-info/myprotos.egg-info/SOURCES.txt'
  Source in /private/var/folders/3t/4qwkfyr903d0b7db7by2kj6r0000gn/T/pip-jpgCby-build has version 0.0.1, which satisfies requirement myprotos==0.0.1 from file:///path/to/myprotos
Building wheels for collected packages: myprotos
  Running setup.py bdist_wheel for myprotos: started
  Destination directory: /var/folders/3t/4qwkfyr903d0b7db7by2kj6r0000gn/T/tmpD7dfGKpip-wheel-
  Running command /usr/local/opt/python/bin/python2.7 -u -c "import setuptools, tokenize;__file__='/private/var/folders/3t/4qwkfyr903d0b7db7by2kj6r0000gn/T/pip-jpgCby-build/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" bdist_wheel -d /var/folders/3t/4qwkfyr903d0b7db7by2kj6r0000gn/T/tmpD7dfGKpip-wheel- --python-tag cp27
  running bdist_wheel
  running build
  installing to build/bdist.macosx-10.12-x86_64/wheel
  running install

  # THIS IS MY MAKEFILE RUNNING
  Grabbing github.com/google/protobuf...
  Building Python protos...
  # MAKEFILE COMPLETE

  running install_egg_info
  running egg_info
  creating myprotos.egg-info
  writing myprotos.egg-info/PKG-INFO
  writing top-level names to myprotos.egg-info/top_level.txt
  writing dependency_links to myprotos.egg-info/dependency_links.txt
  writing manifest file 'myprotos.egg-info/SOURCES.txt'
  reading manifest file 'myprotos.egg-info/SOURCES.txt'
  writing manifest file 'myprotos.egg-info/SOURCES.txt'
  Copying myprotos.egg-info to build/bdist.macosx-10.12-x86_64/wheel/myprotos-0.0.1-py2.7.egg-info
  running install_scripts
  creating build/bdist.macosx-10.12-x86_64/wheel/myprotos-0.0.1.dist-info/WHEEL
  Running setup.py bdist_wheel for myprotos: finished with status 'done'
  Stored in directory: /Users/jds/Library/Caches/pip/wheels/92/0b/37/b5a50146994bc0b6774407139f01d648ba3a9b4853d2719c51
  Removing source in /private/var/folders/3t/4qwkfyr903d0b7db7by2kj6r0000gn/T/pip-jpgCby-build
Successfully built myprotos
Installing collected packages: myprotos
  Found existing installation: myprotos 0.0.1
    Uninstalling myprotos-0.0.1:
      Removing file or directory /usr/local/lib/python2.7/site-packages/myprotos-0.0.1.dist-info/DESCRIPTION.rst
      Removing file or directory /usr/local/lib/python2.7/site-packages/myprotos-0.0.1.dist-info/INSTALLER
      Removing file or directory /usr/local/lib/python2.7/site-packages/myprotos-0.0.1.dist-info/METADATA
      Removing file or directory /usr/local/lib/python2.7/site-packages/myprotos-0.0.1.dist-info/RECORD
      Removing file or directory /usr/local/lib/python2.7/site-packages/myprotos-0.0.1.dist-info/WHEEL
      Removing file or directory /usr/local/lib/python2.7/site-packages/myprotos-0.0.1.dist-info/metadata.json
      Removing file or directory /usr/local/lib/python2.7/site-packages/myprotos-0.0.1.dist-info/top_level.txt
      Successfully uninstalled myprotos-0.0.1

Successfully installed myprotos-0.0.1
Cleaning up...

我的Makefile是否应在生成源文件的过程的早期运行?例如,在运行egg_info之前文件是否需要存在?

Should my Makefile be running early in the process to generate the source files? Do the files need to be there before egg_info runs for example?

如果我手动运行Makefile,然后安装该软件包,那么它将起作用.

If I manually run the Makefile and then install the package then it works.

这是我的项目的结构:

myprotos
├── Makefile
├── README.md
├── document.proto
├── myprotos         # Generated by Makefile
│   ├── __init__.py  # Generated by Makefile
│   └── proto_pb2.py # Generated by Makefile
└── setup.py 

这是Makefile的一部分,该部分根据Potocol缓冲区定义生成Python源:

Here is the section of the Makefile which generates the Python source from Potocol Buffer definitions:

python: protoc deps
    # the protoc and deps command above just downloads
    # the `protoc` binary to a local bin directory 
    @echo "Building Python protos..."
    @mkdir -p "${PYTHON_OUT}"
    @touch "${PYTHON_OUT}"/__init__.py
    @printf "__all__ = ['proto_pb2']" > "${PYTHON_OUT}"/__init__.py
    @PATH="${LOCAL_BINARY_PATH}:$$PATH" protoc \
        --proto_path="${BASE}" \
        --proto_path="${GOPATH}/src/github.com/google/protobuf/src" \
        --python_out="${PYTHON_OUT}/" \
        ${PROTOS}

推荐答案

好的,您需要在此处进行三项更改:

OK, there are three things you need to change here:

  1. Makefiledocument.proto添加到新文件MANIFEST.in.

Makefile
document.proto

如果这样做,python setup.py sdist创建的.zip文件(也上传到PyPI)将包含这些文件.

If you do that, the .zip file created by python setup.py sdist (which is also uploaded to PyPI) will contain those files.

您需要在python setup.py build期间而不是install期间运行make命令:

You need to run your make command during python setup.py build, not during install:

import sys

from setuptools import setup
from setuptools.command.build import build

class Build(build):
    """Customized setuptools build command - builds protos on build."""
    def run(self):
        protoc_command = ["make", "python"]
        if subprocess.call(protoc_command) != 0:
            sys.exit(-1)
        build.run(self)


setup(
    ...
    cmdclass={
        'build': Build,
    }
)

  • 最后,您需要通过在setup()中定义属性packages来告诉setuptools将生成的软件包安装在install上:

  • Lastly, you need to tell setuptools to install the resulting package on install by defining an attribute packages in setup():

    setup(
        ...
        packages=['myprotos']
    )
    

  • 这篇关于在pip安装上运行Makefile的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆