Modulesを使った環境設定、環境スイッチ

複数環境の併用・スイッチは面倒

複数の作業環境を併用・スイッチしながら作業するのはとても面倒です。おいらの場合、コンパイラを複数バージョン併用なんてのよくあります。人によっては、何かのVMだったりライブラリだったりすると思います。

こういった環境のスイッチをしようと思うと、

  1. それぞれの環境の環境変数を設定するスクリプトを用意しておく
  2. ターミナル毎に目的の環境のスクリプトをロードする

なんてことをすることが多いと思います。
こういった作業は煩雑で、特に環境に依存関係があったり、一時的に設定した環境を元の環境に戻す、なんてことになってくると非常に面倒だし、オペレーションを途中でミスってはじめからやりなおしなんてことも往々にしてあります。
こういった環境のスイッチをエレガントに行えるようにするツールとして、Modulesというのがあります。

Modulesという名前が汎用的すぎるせいか、googleで検索をしても上記の本家サイト以外の情報がなかなかみつかりません。

とりあえず使用イメージを

導入・利用に必要な説明は上記サイトにちゃんと書いてあるので、おいらの環境をベースに使用するコンパイラの環境をスイッチする例を示します。

使用可能な環境のリストを見てみます。

$ module avail 

----------------------------------- /Users/daichi/etc/modulefiles ------------------------------------
gcc/4.6.3 gcc/4.7.2

gccコマンドは、デフォルトでは/usr/binにあるシステム標準のGCCが使われます。

$ gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ which gcc
/usr/bin/gcc

GCC4.6.3の環境をロードすると、gccコマンドは /opt/gcc/4.6.3 にあるGCC4.6.3になります。

$ module load gcc/4.6.3
$ gcc --version
gcc (GCC) 4.6.3
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ which gcc
/opt/gcc/4.6.3/bin/gcc

同様にGCC4.7.2の環境をロード・・・しようとすると、すでにロードしてるGCC4.6.3の環境と衝突してエラーになります。GCC4.6.3の環境をアンロードしたうえで、GCC4.7.2の環境をロードします。

$ module load gcc/4.7.2 
gcc/4.7.2(20):ERROR:150: Module 'gcc/4.7.2' conflicts with the currently loaded module(s) 'gcc/4.6.3'
gcc/4.7.2(20):ERROR:102: Tcl command execution failed: conflict gcc/4.6.3

$ module list
Currently Loaded Modulefiles:
  1) gcc/4.6.3
$ module unload gcc/4.6.3
$ module load gcc/4.7.2 
$ which gcc
/opt/gcc/4.6.3/bin/gcc
$ module load gcc/4.7.2 
$ gcc --version
gcc (GCC) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ which gcc
/opt/gcc/4.7.2/bin/gcc

GCC4.7.2の環境をアンロードして元の環境に戻します。

$ module unload gcc/4.7.2 
$ gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ which gcc
/usr/bin/gcc

Modulesを使うメリット

上記例をみてもらえば環境のスイッチが非常に簡単に行えることが理解できると思います。
おいらもそれほど使い込んでいるわけではないですが、環境をスイッチする操作に関して次のことは問題なくできます。

  • 環境に名前をつけて管理
  • 複数の環境をロード
  • 複数の環境をロードした状態で、特定の環境のみアンロードする
  • 環境間の排他制御・依存関係の設定

Modulesの環境の実装

上記の挙動をするModulesの環境の実装はこんな具合です。

環境設定を記述するファイルを置いておくディレクトリ(ここではmodulefiles)を用意し、環境ごとにファイルを用意しておきます。modulefiles配下のツリー構造が、moduleコマンドで認識する環境名になります。

$ ls -R ~/etc/modulefiles/
/Users/daichi/etc/modulefiles/:
gcc

/Users/daichi/etc/modulefiles/gcc:
4.6.3  4.7.2

各環境の設定はTclで記述します。
環境固有の環境変数を記述しておきます、特にパス関係の環境変数はappend-pathで書いておくとよいです。環境間の依存関係、排他制御もここに記述します。

$ cat ~/etc/modulefiles/gcc/4.6.3
set version 4.6.3
set prefix  /opt/gcc/$version

conflict gcc/4.7.2

prepend-path PATH            ${prefix}/bin
prepend-path LD_LIBRARY_PATH ${prefix}/lib
prepend-path MANPATH         ${prefix}/man

$ cat ~/etc/modulefiles/gcc/4.7.2
set version 4.7.2
set prefix  /opt/gcc/$version

conflict gcc/4.6.3

prepend-path PATH            ${prefix}/bin
prepend-path LD_LIBRARY_PATH ${prefix}/lib
prepend-path MANPATH         ${prefix}/man

最後に、.profileにModulesの環境を記述しておきます。ポイントは

  • 環境変数 MODULEPATH にmodulefilesへのパスを設定しておく
  • 使用するシェルに合わせて、Modulesのパッケージが提供する環境設定スクリプトをsourceする

あたりでしょうか。

MODULE_HOME=/opt/Modules/3.2.9
if [ -d "$MODULE_HOME" ]; then
  export MODULEPATH=$HOME/etc/modulefiles
  source $MODULE_HOME/init/bash
  export MANPATH=$MODULE_HOME/share/man:$MANPATH
fi

まとめ

環境のスイッチをエレガントに行うツールとしてModulesを紹介しました。複数環境を併用しながら作業するときに、煩雑な環境設定のオペレーションから開放されて、快適な作業ができるようになります。