将命令行参数传递给pip安装 [英] Passing command line arguments to pip install

查看:156
本文介绍了将命令行参数传递给pip安装的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在处理一个正在导入Fortran模块的Python项目. setup.py看起来类似于

I'm currently working on a Python project that is importing a Fortran module. The setup.py looks similar to that

from numpy.distutils.core import Extension
from numpy.distutils.core import setup

ext = Extension(
    name = "fortran_module",
    sources = ["fortran_module.f90"],
    extra_f90_compile_args = ["-some -compile -arguments"]
)

setup(
    ...,
    ...,
    ...,
    ext_modules = [ext],
    ...,
    ...,
    ...
)

我当前正在使用pip install -e .安装它,效果很好. 但是有时我需要更改extra_f90_compile_args,并且我想在使用pip进行安装的过程中将其作为命令行参数,而不是更改setup.py文件.例如:

I'm currently installing it with pip install -e ., which works fine. But sometimes I need to change the extra_f90_compile_args and I would like to do give them as command line argument during installation with pip rather than changing the setup.py file. Something like this for example:

pip install -e --compile_args="-O3 -fbacktrace -fbounds-check -fopenmp" .

是否可以通过pip将命令行参数传递到setup.py文件中?

Is it possible to pass command line arguments via pip into the setup.py file?

与此相关,我也想将不同的设置选项传递到setup.py中.例如

Related to that, I would also like to pass different setup options into setup.py. For example

pip install -e --setup=setup1 .

pip install -e --setup=setup2 .

根据是否传递setup1setup2还是不传递它们,我想包含不同的Fortran源文件并使用不同的extra_f90_compile_args进行编译.

And depending on whether setup1 or setup2 or none of them is passed, I would like to include different Fortran source files and compile them with different extra_f90_compile_args.

这可能吗?

编辑:让我们考虑以下示例:Fortran模块与OpenMP并行化.现在,我希望用户决定是否进行并行编译.也许OpenMP库不可用,用户需要编译串行版本.

Let's consider the following example: The Fortran module is parallelized with OpenMP. Now I want the user to decide, whether to compile parallel or not. Maybe the OpenMP libraries are not available and the user needs to compile the serial version.

我的setup.py现在看起来如下

from numpy.distutils.core import Extension
from numpy.distutils.core import setup
import os
from setuptools.command.install import install as _install

extra_f90_compile_args = ""
extra_link_args = ""

class install(_install):
    user_options = _install.user_options + [('build=', None, None)]

    def initialize_options(self):
        _install.initialize_options(self)
        self.build = None

    def finalize_options(self):
        _install.finalize_options(self)

    def run(self):
        global extra_f90_compile_args
        global extra_link_args
        if(self.build == "parallel"):
            extra_f90_compile_args += "-fopenmp"
            extra_link_args += "-lgomp"
            os.makedirs("~/test/")
        _install.run(self)

ext = Extension(
    name="test_module.fortran_module",
    sources=["test_module/fortran_module.f90"],
    extra_f90_compile_args=[extra_f90_compile_args],
    extra_link_args=[extra_link_args]
)

setup(
    name="test_module",
    packages=["test_module"],
    ext_modules=[ext],
    cmdclass={'install': install}
)

如果我通过以下方式安装

If I install this with

pip install . --install-option="--build=parallel"

它正在if块中执行代码.我创建了test/目录只是为了检查它.如果未指定build或与parallel不同,则不会创建test/目录.

it is executing code in the if-block. I created the test/ directory just to check this. If build is not given or different from parallel, the test/ directory is not created.

但是,该代码不是使用OpenMP编译的.我认为是这样,因为Extension对象是在调用setup()之前创建的,其中要对参数进行求值.我想先评估参数,然后根据参数创建Extension对象,然后调用setup().

However, the code is not compiled with OpenMP. I think this is, because the Extension object is created before the call of setup(), where the arguments get evaluated. I would like to first evaluate the arguments, then create the Extension object depending on the arguments, and then call setup().

我该怎么做?

推荐答案

在仔细阅读源代码之后,我现在可以回答这个问题.

After digging through the source code, I can answer this now.

setup.py文件:

from numpy.distutils.command.install import install as _install
from numpy.distutils.core import Extension
from numpy.distutils.core import setup

extF = Extension(name="test_module.fortran_module",
                 sources=["test_module/fortran_module.f90"])
compile_args_parallel = "-fopenmp"
link_args_parallel = "-lgomp"

class install(_install):
    user_options = _install.user_options + [('build=', None, None)]

    def initialize_options(self):
        _install.initialize_options(self)
        self.build = None

    def finalize_options(self):
        _install.finalize_options(self)
        if(self.build == "parallel"):
            for ext in self.distribution.ext_modules:
                if(ext.name == "test_module.fortran_module"):
                    ext.extra_f90_compile_args = compile_args_parallel
                    ext.extra_link_args = link_args_parallel

    def run(self):
        _install.run(self)

setup(
    name="test_module",
    packages=["test_module"],
    ext_modules=[extF],
    cmdclass={"install": install}
)

通过以下方式安装

pip install .

安装串行版本,然后

pip install . --install-option="--build=parallel"

安装并行版本的Fortran模块.

installs the parallel version of the Fortran module.

这篇关于将命令行参数传递给pip安装的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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