Seb*_*ian 2 python pip setup.py
我目前正在处理一个导入 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],
...,
...,
...
)
Run Code Online (Sandbox Code Playgroud)
我目前正在安装它pip install -e .,它工作正常。但有时我需要更改extra_f90_compile_args,我想在安装过程中将它们作为命令行参数提供,pip而不是更改setup.py文件。例如这样的事情:
pip install -e --compile_args="-O3 -fbacktrace -fbounds-check -fopenmp" .
Run Code Online (Sandbox Code Playgroud)
是否可以将命令行参数传递pip到setup.py文件中?
与此相关,我还想将不同的设置选项传递到setup.py. 例如
pip install -e --setup=setup1 .
Run Code Online (Sandbox Code Playgroud)
或者
pip install -e --setup=setup2 .
Run Code Online (Sandbox Code Playgroud)
而且取决于是否setup1还是setup2和他们没有通过,我想包括不同的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}
)
Run Code Online (Sandbox Code Playgroud)
如果我安装这个
pip install . --install-option="--build=parallel"
Run Code Online (Sandbox Code Playgroud)
它正在执行if-block 中的代码。我创建test/目录只是为了检查这个。如果build未给出或与 不同parallel,test/则不会创建目录。
但是,代码不是用 OpenMP 编译的。我认为这是因为Extension对象是在调用 之前创建的setup(),在那里评估参数。我想首先评估参数,然后Extension根据参数创建对象,然后调用setup().
我怎样才能做到这一点?
既处理--install-option,并--global-option似乎很混乱,如果有一个在我看来,多一种选择。我想添加这个现实生活中的解决方案
取而代之的是环境变量,并在安装时设置它们。
在 setup.py 中:
import os
config_var = os.environ.get("MY_PARAM", None)
if config_var:
do_something()
setup()
Run Code Online (Sandbox Code Playgroud)
并像这样调用 pip:
MY_PARAM="Some_value" pip install my_module