Boostの依存ヘッダファイルを自動コピー…できなかった
最近Boostを使い始めたところです。インクルードするだけで使えるライブラリって導入らくちんですね。とはいっても、Boostはかなり規模が大きいので、全部コピーしてきてリポジトリにつっこむのはちょっと嫌です。Boostの中でどのライブラリを使っているかは把握しておきたいというのもありますし。
Boost全体のうちで使うのはほんの一部なので、実際に必要なファイルだけ持ってきたい、という問題が持ち上がりました。
というわけで、指定したファイルとそいつがインクルードしているヘッダファイルを再帰的にコピーしてくるスクリプトをRubyで書いてみたんですが、動作確認してみるとどうも上手く動かない。
なんとBoostのヘッダファイルの中には、#includeディレクティブのファイル名がマクロで書かれているところがあって、マクロを展開してやらないとインクルードすべきファイル名がわからない、ということになってました。
例:config.hpp
// if we don't have a user config, then use the default location: #if !defined(BOOST_USER_CONFIG) && !defined(BOOST_NO_USER_CONFIG) # define BOOST_USER_CONFIG <boost/config/user.hpp> #endif // include it first: #ifdef BOOST_USER_CONFIG # include BOOST_USER_CONFIG #endif
これは同じツールを誰かが作ってるのを探しても見あたらないはずだ。さすがにマクロのプリプロセッサまで作る気はしません。
結局ファイルコピーは手作業でやらないといけないのか…。とりあえず作った物を以下に貼っておきます。
# 指定したヘッダファイルと、それが#includeしているファイルを再帰的にコピーする # usage: ruby copy_include_file.rb targetFile dstDir # 例: ruby copy_include_file.rb boost/shared_ptr.hpp ../workspace/include # ################# # global variable ################# $BOOST_DIR = "D:/dev/cpp/boost_1_39_0/" # boostのソースがあるディレクトリ $visited = Hash.new(nil) ################# # fuction ################# def copy(file, dstDir) return if File.exist?(dstDir + file) return if !File.exist?($BOOST_DIR + file) makeDir(dstDir + file) contents = IO.read($BOOST_DIR + file); contents.scan(/^\s*#include\s*<([^>]+)>/){|match| inc = match[0] if !$visited[inc] $visited[inc] = true copy(inc, dstDir) end } open(dstDir + file, "wb"){|f| f.write(contents) } end def makeDir(target) dir = File.dirname(target) if !File.exist?(dir) parent = File.dirname(dir) if(parent != ".") makeDir(dir) end Dir.mkdir(dir) end end ################# # main routine ################# if ARGV.length != 2 puts "usage: ruby copy_include_file.rb targetFile dstDir" exit end targetFile = ARGV[0].dup; dstDir = ARGV[1].dup; if dstDir[-1] != ?/ dstDir << "/" end copy(targetFile, dstDir)