Created
December 30, 2013 19:18
-
-
Save hisui/8186640 to your computer and use it in GitHub Desktop.
Rakefile for building C/C++ project.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
require "ostruct" | |
require "fileutils" | |
require "pp" | |
require "rake/loaders/makefile" | |
extend FileUtils | |
Rake.application.options.instance_eval { | |
#trace = false | |
#trace_rules = nil | |
} | |
### 定数定義 ### | |
# 各種パスの設定 | |
DEP_ROOT = "build/makedepend" # 依存関係リスト(.mf)を入れる | |
OBJ_ROOT = "build/obj" # CXXのオブジェクトファイルの出力先 | |
SRC_ROOT = "src" # ソースフォルダー | |
# 各種ツールのコマンド | |
CXX = "g++" # C++ コンパイラー | |
LINK = "g++ -g" # リンカー | |
MAKEDEPEND = "g++ -MM -std=c++0x" # 依存関係リストを作るコマンド | |
# コンパイラーのオプション | |
CXXFLAGS = %w{ -Wall -g -lpthread -std=c++11 -stdlib=stdc++ } | |
# インポートするライブラリ | |
LIB = %w{} | |
# ヘッダー検索パス | |
INCLUDES = %w{} | |
# オブジェクトファイルは単一のディレクトリに出力されるので、パスのスラッシュの代わりに使う文字列 | |
PATH_SEPARATOR = "___" | |
### 依存関係 ### | |
# すべてのcppファイルを集める | |
CXXFILES = {} | |
Dir[SRC_ROOT + "/**/*.cpp"].each {|filename| | |
if filename.index(PATH_SEPARATOR) | |
raise "ファイル名にPATH_SEPARATOR(#{PATH_SEPARATOR})が含まれています:#{filename}" | |
end | |
name = filename[SRC_ROOT.size+1..-1].gsub(/[\\\/]/, PATH_SEPARATOR).sub(/\.cpp$/, "") | |
raise "bug?? (x_x)" if CXXFILES.key? name | |
raise "bug?? (x_x)" if filename.index(SRC_ROOT+"/") != 0 | |
CXXFILES[name] = OpenStruct.new({ | |
obj: "#{OBJ_ROOT}/#{name}.o", | |
src: filename, | |
exe: nil | |
}) | |
} | |
# エントリーポイントを含むobjファイルを実行ファイルとして出力する | |
EXECUTABLES = %w{ main } | |
EXECUTABLES.each {|name| | |
CXXFILES[name].exe = name +".exe" | |
} | |
### タスク ### | |
# デフォルトのタスク: 全ての実行ファイルを作成 | |
exe_files = CXXFILES.values.select(&:exe).map(&:exe) | |
task :default => exe_files | |
# デバッグ用にビルド | |
task :debug => exe_files do |t| | |
CXXFLAGS.push("-g") | |
end | |
# リリース用にビルド | |
task :release => exe_files do |t| | |
CXXFLAGS.push("-O2") | |
end | |
# rakeした結果出てきたファイルを全て削除 | |
task :clean do | |
$stderr.print "OK? [y/n]:" | |
$stderr.flush | |
if $stdin.gets =~/y/ | |
rm Dir[DEP_ROOT + "/*.mf" ] | |
rm Dir[OBJ_ROOT + "/*.o" ] | |
rm Dir["." + "/*.exe"] | |
end | |
exit | |
end | |
### 依存関係 ### | |
# cpp, hファイルを処理 | |
CXXFILES.each {|name, sub| | |
# cppファイルのコンパイル | |
file sub.obj => sub.src do |t| | |
options = [] | |
options << CXXFLAGS.join(" ") | |
options << INCLUDES.map {|e| "-I#{e}" }.join(" ") | |
sh %Q{#{CXX} #{options.join " "} -c -o #{sub.obj} #{sub.src}} | |
end | |
# .obj -> .h の依存関係を作成 | |
file( ( mf = "#{DEP_ROOT}/#{name}.depends.mf" ) => sub.src )do |t| | |
sh %Q{#{MAKEDEPEND} -MT "#{sub.obj}" "#{sub.src}" > #{mf}} | |
# | |
# rakeは "./foo/../bar" と "./bar" が同一のパスであると認識出来ないっぽいので | |
# ここで **makedepend によって出力された** このようなパスを修正する | |
# | |
# ※注意: パスは空白で区切られていると仮定するので、パス自体に空白が入ってる場合はNG | |
# | |
content = File.read mf | |
content.gsub!(/\S+(?!:)/) {|path| | |
1 while path.sub!( %r{[^/]+/\.\./}, "" ) | |
path | |
} | |
open(mf, "w") {|io| io.print content } | |
end | |
import mf | |
} | |
# 実行ファイルの作成 | |
obj_files = CXXFILES.values.reject(&:exe).map(&:obj) | |
CXXFILES.values.select(&:exe).each {|sub| | |
file sub.exe => obj_files + [sub.obj] do |t| | |
sh %Q{#{LINK} -o #{sub.exe} #{t.prerequisites.join " "} #{LIB.join " "}} | |
end | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment