2017-11-09 34 views
1

現在、私はFortranモジュールをインポートしているPythonプロジェクトを作成中です。 setup.pyが正常に動作しますpip install -e .と私は現在、それをインストールしていますそのピップインストールにコマンドライン引数を渡す

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], 
    ..., 
    ..., 
    ... 
) 

、のようになります。 しかし、extra_f90_compile_argsを変更する必要がある場合があり、インストール中にpipというコマンドライン引数として、setup.pyファイルを変更するのではなく、コマンドライン引数として指定することがあります。例えば、このような何か:

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

それがsetup.pyファイルにpipを介してコマンドライン引数を渡すことは可能ですか?

これに関連して、別の設定オプションをsetup.pyに渡したいと思います。例えば

pip install -e --setup=setup1 . 

または

pip install -e --setup=setup2 . 

そしてそれらのsetup1またはsetup2または何も渡されないかどうかに応じて、私は別のFortranソースファイルを含めると異なるextra_f90_compile_argsでそれらをコンパイルしたいと思います。

これは可能ですか?


編集:のは、次の例を考えてみましょう:Fortranのモジュールは、OpenMPの並列化とされます。今私は、並列にするかどうかをユーザーが決定してほしい。おそらくOpenMPライブラリが利用できず、ユーザはシリアル・バージョンをコンパイルする必要があるかもしれません。私はそれがif - ブロック内のコードを実行される

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

でこれをインストールする場合

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} 
) 

を次のように

setup.pyは今見えます。これを確認するためにtest/ディレクトリを作成しました。 buildが指定されていないか、またはparallelと異なる場合、test/ディレクトリは作成されません。

ただし、コードはOpenMPでコンパイルされません。これは、オブジェクトがsetup()の呼び出しの前に作成され、引数が評価されるためです。最初に引数を評価してから、引数に応じてExtensionオブジェクトを作成してから、setup()を呼び出してください。

どうすればいいですか?

+0

https://stackoverflow.com/a/33200591/7976758 – phd

+0

私はこれと他のいくつかの質問を承知しています。しかし、私はそれを私の場合に働かせることはできません。編集を参照してください。 – Sebastian

+0

追加されたコードにはインデントの問題があります。メソッドが正しくインデントされません。修正してください。 – phd

答えて

1

ソースコードを掘り下げた後、私は今これに答えることができます。

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モジュールの並列バージョンがインストールされます。

関連する問題