将命令行参数传递给 pip install
Passing command line arguments to pip install
我目前正在处理一个导入 Fortran 模块的 Python 项目。 setup.py
看起来与
相似
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
文件。例如:
pip install -e --compile_args="-O3 -fbacktrace -fbounds-check -fopenmp" .
是否可以通过 pip
将命令行参数传递到 setup.py
文件中?
与此相关,我还想将不同的设置选项传递给 setup.py
。例如
pip install -e --setup=setup1 .
或
pip install -e --setup=setup2 .
并且根据它们中的 setup1
或 setup2
或 none 是否通过,我想包含不同的 Fortran 源文件并用不同的 extra_f90_compile_args
编译它们.
这可能吗?
编辑: 让我们考虑以下示例:Fortran 模块与 OpenMP 并行化。现在我希望用户决定是否并行编译。可能OpenMP库不可用,用户需要编译串口版。
我的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}
)
如果我用
安装它
pip install . --install-option="--build=parallel"
它正在执行 if
块中的代码。我创建 test/
目录只是为了检查这个。如果 build
未给出或与 parallel
不同,则不会创建 test/
目录。
但是,代码不是用 OpenMP 编译的。我认为这是因为 Extension
对象是在调用 setup()
之前创建的,其中参数被评估。我想先评估参数,然后根据参数创建 Extension
对象,然后调用 setup()
.
我该怎么做?
在深入了解源代码后,我现在可以回答这个问题了。
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 模块的并行版本。
如果在我看来有不止一种选择,那么同时处理 --install-option
和 --global-option
似乎非常混乱。我想添加 this real life solution
取而代之的是环境变量,并在安装时设置它们。
在setup.py中:
import os
config_var = os.environ.get("MY_PARAM", None)
if config_var:
do_something()
setup()
然后像这样调用 pip:
MY_PARAM="Some_value" pip install my_module
我目前正在处理一个导入 Fortran 模块的 Python 项目。 setup.py
看起来与
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
文件。例如:
pip install -e --compile_args="-O3 -fbacktrace -fbounds-check -fopenmp" .
是否可以通过 pip
将命令行参数传递到 setup.py
文件中?
与此相关,我还想将不同的设置选项传递给 setup.py
。例如
pip install -e --setup=setup1 .
或
pip install -e --setup=setup2 .
并且根据它们中的 setup1
或 setup2
或 none 是否通过,我想包含不同的 Fortran 源文件并用不同的 extra_f90_compile_args
编译它们.
这可能吗?
编辑: 让我们考虑以下示例:Fortran 模块与 OpenMP 并行化。现在我希望用户决定是否并行编译。可能OpenMP库不可用,用户需要编译串口版。
我的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}
)
如果我用
安装它pip install . --install-option="--build=parallel"
它正在执行 if
块中的代码。我创建 test/
目录只是为了检查这个。如果 build
未给出或与 parallel
不同,则不会创建 test/
目录。
但是,代码不是用 OpenMP 编译的。我认为这是因为 Extension
对象是在调用 setup()
之前创建的,其中参数被评估。我想先评估参数,然后根据参数创建 Extension
对象,然后调用 setup()
.
我该怎么做?
在深入了解源代码后,我现在可以回答这个问题了。
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 模块的并行版本。
如果在我看来有不止一种选择,那么同时处理 --install-option
和 --global-option
似乎非常混乱。我想添加 this real life solution
取而代之的是环境变量,并在安装时设置它们。
在setup.py中:
import os
config_var = os.environ.get("MY_PARAM", None)
if config_var:
do_something()
setup()
然后像这样调用 pip:
MY_PARAM="Some_value" pip install my_module