将命令行参数传递给pip安装 [英] Passing command line arguments to pip install
问题描述
我目前正在处理一个正在导入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 .
根据是否传递setup1
或setup2
还是不传递它们,我想包含不同的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屋!