SCons のすすめ

2019年8月16日

はじめに

Make の代替ツール SCons のメモ。

環境

Ubuntu 16.04 LTS/macOS Mojave 10.14.2 (Anaconda3)

インストール

Ubuntu なら apt-get でインストールできる。

$ sudo apt-get install scons

Python を入れているなら pip でもよい。

$ pip install scons

最小のコンパイル

C のソースファイル hello.c を用意する。SConstruct ファイルを作る。

SConstruct

Program("hello.c")

コンパイル。

$ scons

実行ファイル "hello" ができる。実行ファイル名を指定することもできる。

Program("myhello", "hello.c")

コードが C++ なら、単純に次のように書けばよい。

Program("hello.cc")

オプション "-Q" でメッセージを最低限にすることができる。

$ scons -Q

クリーン

作成されたオブジェクトファイルなどを削除するには、オプション "-c" を指定して実行する。

$ scons -c

分割コンパイル

ソースファイルが複数ある場合は、次のようにする。

SConstruct

Program("prog", ["file1.cc", "file2.cc"])

次のようにも書ける。

Program("prog", Split("file1.cc file2.cc"))

また、次のように拡張子で選択してもよい。

Program("prog", Glob("*.cc"))

SConstruct は Python スクリプトなので、変数を渡してもよい。

prog = "prog"
src = [
    "file1.cc",
    "file2.cc",
]
Program(prog, src)

scons は、make のように変更があったものだけをコンパイルする。もし、file2.cc に対応するヘッダーファイル file2.h があって、それを file1.cc がインクルードしているとする。このとき、make では Makefile で file1.cc が file2.h に依存していることを設定しておく必要があるが、scons はそのあたりを勝手にやってくれるようである。

インクルードパスの指定

インクルードファイルのパスを指定する場合は、CPPPATH を使う。

Program(prog, src, CPPPATH=["/usr/local/include"])

ライブラリの指定

ライブラリを指定する場合は、LIBS などの引数で指定する。たとえば、"-L/usr/lib -L/usr/local/lib -lm" を指定するのと同等の設定は以下のようになる。

Program(prog, src, LIBS=["lib1"], LIBPATH=["/usr/local/lib"])

上記だけでは、プログラムがリンクしたライブラリを見失うことがある。別途 RPATH でパスを設定する。

LIBPATH=["/usr/local/lib"]
Program(prog, src, LIBS=["lib1"], LIBPATH=LIBPATH, RPATH=LIBPATH)

コンパイルオプションの指定

コンパイルオプションを指定するには、引数 parse_flags に渡す。

Program(prog, src, parse_flags="-O2 -Wall -lm")

上記のように設定すると、オプションをちゃんと考えて設定してくれるようである。

$ scons -Q
g++ -o file1.o -c -O2 -Wall file1.cc
g++ -o file2.o -c -O2 -Wall file2.cc
g++ -o prog file1.o file2.o -lm

オプションを個別に設定したい場合は、次のように書ける。

Object("file1.cc", CCFLAGS="-O2")
Object("file2.cc", CCFLAGS="-O2")
Program("prog", ["file1.o", "file2.o"])