Skip to content

Instantly share code, notes, and snippets.

@hisui
Created April 25, 2016 18:11
Show Gist options
  • Save hisui/ecb18b2db0d455757523fc514c752587 to your computer and use it in GitHub Desktop.
Save hisui/ecb18b2db0d455757523fc514c752587 to your computer and use it in GitHub Desktop.
# coding: utf-8
require "ostruct"
require "fileutils"
require "pp"
require "pathname"
require "rake/loaders/makefile"
### Variables ###
# Project Strcuture
OBJ_ROOT = "build/obj"
SRC_ROOT = {
"main" => "./src"
}
# Commands of Tools
CXX = "clang++"
LINK = "clang++ -dynamiclib"
# Flags for Compiler
CXXFLAGS = %w{
-std=c++1y
}
# Libraries
LIBS = %w{ stdc++ }
# Header Search Paths
INCLUDES = SRC_ROOT.values
INCLUDES.concat(%w(
))
# Final Outputs
ENTRYPOINTS = {
"build/test.dylib" => ["main/test.cpp"]
}
### Source Files ###
# Collecting all the ".cpp" files in the project.
CXXFILES = {}
SRC_ROOT.each do |name, root|
base = Pathname.new(root)
Dir["#{root}/**/*.{cpp,cxx,c}"].map {|e| Pathname.new(e) }.each do |src|
key = src.relative_path_from(base)
CXXFILES["#{name}/#{key}"] = OpenStruct.new({
src: src.to_path,
obj: "#{OBJ_ROOT}/#{name}/#{key}.o",
dep: "#{OBJ_ROOT}/#{name}/#{key}.depends.mf",
})
end
end
# Copies the directory structure of `SRC_ROOT` into `OBJ_ROOT`.
CXXFILES.values.each do |e|
FileUtils.mkpath(File.dirname(e.obj))
end
### Top-level Tasks ###
ep_files = ENTRYPOINTS.keys
task :default => ENTRYPOINTS.keys
task :release => ENTRYPOINTS.keys do |t|
CXXFLAGS.push("-O3")
end
task :debug => ENTRYPOINTS.keys do |t|
CXXFLAGS.push("-g")
end
task :clean do
FileUtils.rm_r("build")
exit
end
### Dependencies among Source Files and Final Outputs ###
cc_opts = []
cc_opts << CXXFLAGS.join(" ")
cc_opts << INCLUDES.map {|e| "-I#{e}" }.join(" ")
cxxflags = cc_opts.join(" ")
CXXFILES.each do |key, sub|
file sub.dep => sub.obj
file sub.obj => sub.src do |t|
sh %Q{#{CXX} #{cxxflags} -c -MD -MF #{sub.dep} -o #{sub.obj} #{sub.src}}
end
import sub.dep
end
obj_files_0 = CXXFILES.reject {|key, e| ENTRYPOINTS.values.flatten.include?(key) }.values.map(&:obj)
ENTRYPOINTS.each do |out, keys|
file out => (CXXFILES.values_at(*keys).map(&:obj) + obj_files_0) do |t|
sh %Q{#{LINK} -o #{t.name} #{t.prerequisites.join " "} #{LIBS.map {|e| "-l" + e }.join " "}}
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment