invoke コマンドによる簡易代替makefile

概要

  • Python タスクランナ invoke で、簡易に makefileの代替 が作成可能.

  • ビルド・実行・ポスト処理・クリーンアップ などを簡易にコマンド化.

invoke のインストール

pip install invoke

使用方法

  • カレントディレクトリに tasks.py ファイルを用意.

  • 各種コマンドを実行. ( e.g. $ invoke build , etc. )


代表構成コマンド

  1. ビルド(build)

    • 指定されたファイル(または任意のソース)をコンパイル.

    invoke build --file=input.src
    
    • Makefileとは異なり、依存関係は見れない.

  2. 実行(run)

    • コンパイル済みのバイナリを実行します。

    invoke run
    
    • 何を実行するかは tasks.py に記載.

  3. ポスト処理(post)

    実行結果に対して、ポスト処理スクリプトを実行.

    invoke post
    
    • 実行内容は、 tasks.py に記載する.

  4. クリーン(clean)

    ビルドで生成した中間ファイルやバイナリ等を削除.

    invoke clean
    

サンプル tasks.py

import os, sys, subprocess
import invoke

# ========================================================= #
# ===  build command                                    === #
# ========================================================= #
@invoke.task( help={ 'file': 'input file == input file.'} )
def build( c, file="input.src" ):
    """ build command -- invoke build --file=input.src etc. """
    # ------------------------------------------------- #
    # --- [1] file check                            --- #
    # ------------------------------------------------- #
    if not( os.path.exists(file) ):
        sys.exit(" cannot find input file :: {}".format( file ))
    else:
        print( f"\n --- input : {file} --- \n" )
    # ------------------------------------------------- #
    # --- [2] build command                       --- #
    # ------------------------------------------------- #
    build__cmd = "gfortran {}".format( file )
    try:
        subprocess.run( build__cmd, shell=True, check=True )
        print(  "\n ---      End       --- \n" )
    except Exception as e:
        print( f"Error :: {e}" )
    return()
        

# ========================================================= #
# ===  run command                                      === #
# ========================================================= #
@invoke.task
def run(c):
    """ run command -- invoke run """
    # ------------------------------------------------- #
    # --- [1] execute command                       --- #
    # ------------------------------------------------- #
    cmd = "./a.out"
    try:
        subprocess.run( cmd, shell=True, check=True )
    except Exception as e:
        print( f"Error :: {e}" )
    return()
        

# ========================================================= #
# ===  post command                                     === #
# ========================================================= #
@invoke.task
def post(c):
    """ post command -- invoke post """
    # ------------------------------------------------- #
    # --- [1] execute command                       --- #
    # ------------------------------------------------- #
    cmd = "python post.py"
    try:
        subprocess.run( cmd, shell=True, check=True )
    except Exception as e:
        print( f"Error :: {e}" )
    return()


# ========================================================= #
# ===  clean command                                    === #
# ========================================================= #
@invoke.task
def clean(c):
    """ clean command -- invoke clean """
    extensions = [ ".o", "a.out" ]
    deleted    = 0
    for file in os.listdir("."):
        if any( file.endswith( ext ) for ext in extensions ):
            os.remove(file)
            deleted += 1
    print(f" --- delete : {deleted} files --- " )
    return()



ファイル構成例

project/
├── tasks.py         # invoke タスク定義
├── input.f90        # コンパイル対象ソース(例: Fortran)
└── post.py          # ポスト処理用スクリプト(任意)

補足

  • コマンド一覧確認.

    invoke --list