0
0

More than 1 year has passed since last update.

SConsからpythonなど外部のコマンドを呼び出す方法

Last updated at Posted at 2022-11-02

はじめに

GitHubに具体例のリポジトリを上げてあります:ishioka0222/scons-execute-python-example

背景

SConsにはCommandという機能があり、ビルド時にコマンドを呼び出すことができます。
例えば、SConstructファイルに以下のように記述してsconsコマンドを実行すると、echo hello, world! > output.txtが実行されます:

SConstruct
Command(
    target="output.txt",
    source=None,
    action="echo hello, world! > $TARGET"
)

しかし、デフォルトの設定では、actionの中でどのコマンドでも呼び出せるわけではないようです。
例えば、Pythonがインストール済みでPATHを通していても、以下のようにactionの中でpythonコマンドを実行しようとするとエラーが出ます:

SConstruct
Command(
    target="output.txt",
    source=None,
    action="python script.py --out $TARGET"
)
script.py
import argparse

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--out')
    args = parser.parse_args()

    with open(args.out, 'w') as f:
        f.write('hello, world!')

if __name__ == "__main__":
    main()
実行結果(日本語環境の場合)
> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
python script.py --out output.txt
'python' は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
scons: *** [output.txt] Error 1
scons: building terminated because of errors.
実行結果(英語環境の場合)
> scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
python script.py --out output.txt
'python' is not recognized as an internal or external command,
operable program or batch file
scons: *** [output.txt] Error 1
scons: building terminated because of errors.

このようなエラーが出る理由ですが、デフォルトではSConsはシステム環境変数の値(PATHなど)を読み込まず、pythonコマンドを見つけることができないためのようです。
なぜこうなっているかという理由については、公式ドキュメント内のENVの項目に詳しく書かれています。
要約すると、SConsの実行時に設定されている環境変数と関係なく、ビルドの再現性が保証されるようにするためだそうです。

SConsからpythonなど外部のコマンドを呼び出す方法

pythonコマンドはシステム環境変数のPATHに定義されているので、SConstructファイルの中で、以下のようにしてPATHの値を明示的にSConsに読み込ませる必要があります。

SConstruct
import os
env = Environment(ENV={'PATH': os.environ['PATH']})

env.Command(
    ...
)

公式ドキュメントには "it is usually not recommended" と前置きしたうえで、以下のように、PATH以外の環境変数もすべて読み込ませる方法も紹介されています:

SConstruct
import os
env = Environment(ENV=os.environ.copy())

env.Command(
    ...
)
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0