SCons入門(1)
SConsとは?
Python製のMake代替ツール。
中でPythonコードを書けるので、複雑なMake処理を簡単に書ける。
C言語の依存関係などを自動に調べる機能などがあるらしいが、使った事はないので詳しい事はわからない。
自分の場合はプログラムのビルドではなく、ゲームデータのビルドに使用した。
(プログラムのビルドならVisualCやEclipseなどの専用ツールに任せた方が楽だったりする)
C言語などのビルドでは依存関係を調べる関係上、大規模開発では速度が出ないという意見もある。
しかし、自分が使っている限りでは、ゲームデータなどのコンバートであればかなりの数のデータを処をしているが、実用十分な速度が出ていると思う。
■SCons公式
http://www.scons.org/
使い方
ビルドしたいプロジェクトディレクトリに「SConstruct」というファイルを作成する。
SConstructにビルドコマンドを記述していくが、もちろんPythonコードをそのまま書ける。
以下、簡単なSConstructの例。
#!/usr/bin/env python # -*- coding: utf-8 -*- import os print "hello scons: %s" % os.getcwd()
コマンドライン上で「scons」と打つと、ビルドが始まる。
> scons scons: Reading SConscript files ... hello scons /home/xxxx scons: done reading SConscript files. scons: Building targets ... scons: `.' is up to date. scons: done building targets.
-cコマンドを付けると、クリーンアップされる。
> scons -c
独自のコマンドを実行する「Command」
自前で作ったコンバートプログラムを実行するには「Command」を使用する。
以下、自前のコンバートプログラム「my_convert.py」で、ルートディレクトリ配下のtxtファイルをコンバートする例。
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import glob #環境設定 システムパスの設定など env = Environment(ENV = os.environ) for input_name in glob.glob("*.txt"): output_name = os.path.splitext(input_name)[0]+".out" env.Command( output_name, input_name, "python my_convert.py $SOURCE $TARGET" )
「Command」は、出力したファイル名を返す。
env = Environment(ENV = os.environ) print env.Command("a.out", "a.in", "python my_convert.py $SOURCE $TARGET") # -> "a.out"
第2引数の出力ファイルをNoneにすると、出力ファイルがないタスクを作ることができる。
ファイルの更新チェックは行われずに、毎回必ず実行されるタスクとなる。
env = Environment(ENV = os.environ) #出力ファイルがない場合、毎回実行されるタスクとなる env.Command(None, "a.in", "python my_convert.py $SOURCE")
また、第3引数のactionにはPython関数も指定する事が可能。
def my_action(target, source, env): print target[0], len(target) print source[0], len(source) return None env.Command("a.out", "a.in", my_action)
独自のビルダーを定義する「Builder」もあるが、「Command」で十分な場合が多い。
独自のビルダーを実行する「Builder」
独自のビルダーを登録する事も可能、こちらは拡張子などを自動で変換してくれる。
#!/usr/bin/env python # -*- coding: utf-8 -*- import os import glob #独自ビルダー bld = Builder( action = "python my_convert.py $SOURCE $TARGET", suffix = '.out', src_suffix = '.txt', ) #独自ビルダーを登録 env = Environment(ENV = os.environ, BUILDERS = {'MyBuilder' : bld}) for input_name in glob.glob("*.txt"): env.MyBuilder(input_name)
引数の解析
sconsに引数を設定する事ができる。
以下、引数「project_dir」を渡すコマンドライン。
> scons project_dir=/home/prj
「arg=value」の形で書かないと、ターゲットオブジェクトの認識されてしまうので注意。
SConstructでは、「ARGUMENTS」という辞書に引数が格納される。
#引数 project_pathを取得 project_path = ARGUMENTS.get("project_path", "./") # -> project_path = /home/prj