simple-make 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/bin/sm +10 -0
- data/lib/simple-make/dependency.rb +33 -0
- data/lib/simple-make/dir_traverser.rb +28 -0
- data/lib/simple-make/project.rb +119 -0
- data/lib/simple-make/search_path.rb +14 -0
- data/lib/simple-make.rb +1 -0
- data/template/makefile.erb +65 -0
- metadata +52 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b6aa846b3416f493a8e42e59338a63e74970ea3d
|
4
|
+
data.tar.gz: 6cb6ec03baa63adfcfecb0cddd7a1b537cb00767
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: fb13206f2c96d93171666e77d25940b4adc1633bd745384378b89adca9cdee6dc4da445c7592036c1dcb1d36d274eb9bdfd078ac60c84268f0e3e001746d16f6
|
7
|
+
data.tar.gz: 4d58f6d963967b8d6604f74d2b30d0f6ac82b255faa136cb20d5bf8b86d435777b44f72cf16db762bb45a4ccdc6344480d1eb2e0fa2ee7b5e269cb7d37bd86f1
|
data/.gitignore
ADDED
data/bin/sm
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'simple-make'
|
4
|
+
|
5
|
+
raise "Cannot find the build file <build.sm>" if !File.exist?("build.sm")
|
6
|
+
|
7
|
+
configuration = File.open("build.sm").read
|
8
|
+
project = Project.new
|
9
|
+
project.instance_eval(configuration)
|
10
|
+
project.generate_make_file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Dependency
|
2
|
+
attr_reader :include, :scope
|
3
|
+
def initialize map
|
4
|
+
raise wrong_format_msg(map) if !(map.is_a? Hash) or map[:include].nil? or map[:lib].nil?
|
5
|
+
|
6
|
+
@include = File.absolute_path(map[:include])
|
7
|
+
@lib = File.absolute_path(map[:lib])
|
8
|
+
@scope = map[:scope] || :compile
|
9
|
+
end
|
10
|
+
|
11
|
+
def lib_name
|
12
|
+
if @lib_name.nil?
|
13
|
+
matches = @lib.match /.*\/lib([^\/]*)\.a/
|
14
|
+
raise "lib name format is wrong, it should be [libxxx.a]" if matches.nil?
|
15
|
+
@lib_name = matches[1]
|
16
|
+
raise "lib name format is wrong, it should be [libxxx.a], and the xxx should not be empty" if @lib_name.empty?
|
17
|
+
end
|
18
|
+
@lib_name
|
19
|
+
end
|
20
|
+
|
21
|
+
def lib_path
|
22
|
+
if @lib_path.nil?
|
23
|
+
matches = @lib.match /(.*\/)[^\/]*/
|
24
|
+
@lib_path = matches[1]
|
25
|
+
end
|
26
|
+
@lib_path
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
def wrong_format_msg(map)
|
31
|
+
"#{map.inspect} is not a map, please present dependencies in format {include: <include_path>, lib: <lib_file_name>}"
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class DirTraverser
|
2
|
+
def self.all_files_in_absolute_path base, found=[]
|
3
|
+
Dir.foreach(base) do |each|
|
4
|
+
next if(each == "." || each == "..")
|
5
|
+
|
6
|
+
full_name = base + "/" +each
|
7
|
+
if File.directory? full_name
|
8
|
+
all_files_in_absolute_path(full_name, found)
|
9
|
+
else
|
10
|
+
found << full_name
|
11
|
+
end
|
12
|
+
end
|
13
|
+
found
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.all_folders_in_absolute_path base, found=[]
|
17
|
+
Dir.foreach(base) do |each|
|
18
|
+
next if(each == "." || each == "..")
|
19
|
+
|
20
|
+
full_name = base + "/" +each
|
21
|
+
if File.directory? full_name
|
22
|
+
found << full_name
|
23
|
+
all_folders_in_absolute_path(full_name, found)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
found
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require "simple-make/dependency"
|
2
|
+
require "simple-make/search_path"
|
3
|
+
require "simple-make/dir_traverser"
|
4
|
+
require "erb"
|
5
|
+
|
6
|
+
class Project
|
7
|
+
attr_writer :name
|
8
|
+
|
9
|
+
def initialize(name=nil)
|
10
|
+
@name = name || default_name
|
11
|
+
@app_path = "app"
|
12
|
+
@test_path = "test"
|
13
|
+
@prod_path = "prod"
|
14
|
+
@output_path = "build"
|
15
|
+
@source_folder_name = "src"
|
16
|
+
@deps = []
|
17
|
+
@includes = []
|
18
|
+
@cc = "g++ -O0 -g3 -Wall"
|
19
|
+
@link = "g++"
|
20
|
+
end
|
21
|
+
|
22
|
+
def default_name
|
23
|
+
File.absolute_path(".").split("/").last
|
24
|
+
end
|
25
|
+
|
26
|
+
def depend_on(*deps)
|
27
|
+
raise "depend_on only accept array of dependencies, use [] to wrap your dependency if there is only one" if !(deps.is_a? Array)
|
28
|
+
@deps += deps.map{|depHash| Dependency.new(depHash)}
|
29
|
+
end
|
30
|
+
|
31
|
+
def srcs
|
32
|
+
all_sources_in(@app_path)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_srcs
|
36
|
+
all_sources_in(@test_path)
|
37
|
+
end
|
38
|
+
|
39
|
+
def prod_srcs
|
40
|
+
all_sources_in(@prod_path)
|
41
|
+
end
|
42
|
+
|
43
|
+
def sub_folders_in_target_folder
|
44
|
+
(all_output_dirs_related_to(@app_path) + all_output_dirs_related_to(@prod_path) + all_output_dirs_related_to(@test_path)).join(" \\\n")
|
45
|
+
end
|
46
|
+
|
47
|
+
def header_search_path *paths
|
48
|
+
raise "search path only accept array of paths, use [] to wrap your search paths if there is only one" if !(paths.is_a? Array)
|
49
|
+
@includes += paths.map{|path| SearchPath.new(path)}
|
50
|
+
end
|
51
|
+
|
52
|
+
def compile_command_with_flag cc
|
53
|
+
@cc = cc
|
54
|
+
end
|
55
|
+
|
56
|
+
def link_command_with_flag link
|
57
|
+
@link = link
|
58
|
+
end
|
59
|
+
|
60
|
+
def generate_make_file(filename = "Makefile")
|
61
|
+
makefile = ERB.new(File.open(File.expand_path(File.dirname(__FILE__) + "/../../template/makefile.erb")).read)
|
62
|
+
File.open(filename, "w") do |f|
|
63
|
+
f.write makefile.result(binding)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
[:compile, :test, :prod].each do |scope|
|
68
|
+
define_method("#{scope}_time_search_path_flag") do
|
69
|
+
return search_path_flag(:compile) if scope == :compile
|
70
|
+
search_path_flag(:compile, scope)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
[:test, :prod].each do |scope|
|
75
|
+
define_method("#{scope}_time_lib_path_flag") do
|
76
|
+
lib_path_flag(:compile, scope)
|
77
|
+
end
|
78
|
+
|
79
|
+
define_method("#{scope}_time_lib_flag") do
|
80
|
+
lib_name_flag(:compile, scope)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
private
|
84
|
+
def all_output_dirs_related_to(base)
|
85
|
+
(DirTraverser.all_folders_in_absolute_path("#{base}/#{@source_folder_name}") << "#{base}/#{@source_folder_name}").map do |origin|
|
86
|
+
"build/#{origin.sub("/#{@source_folder_name}", "")}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def all_sources_in(base)
|
91
|
+
DirTraverser.all_files_in_absolute_path("#{base}/#{@source_folder_name}").join(" \\\n")
|
92
|
+
end
|
93
|
+
|
94
|
+
def lib_name_flag(*scopes)
|
95
|
+
libs_name = []
|
96
|
+
scopes.each do |scope|
|
97
|
+
@deps.select { |dep| dep.scope == scope}.each{|dep| libs_name << dep.lib_name}
|
98
|
+
end
|
99
|
+
libs_name.map{|p| "-l#{p}"}.join(" ")
|
100
|
+
end
|
101
|
+
|
102
|
+
def lib_path_flag(*scopes)
|
103
|
+
libs_path = []
|
104
|
+
scopes.each do |scope|
|
105
|
+
@deps.select { |dep| dep.scope == scope}.each{|dep| libs_path << dep.lib_path}
|
106
|
+
end
|
107
|
+
libs_path.map{|p| "-L#{p}"}.join(" ")
|
108
|
+
end
|
109
|
+
|
110
|
+
def search_path_flag(*scopes)
|
111
|
+
includes = ["-I#{File.absolute_path(@app_path)}/include"]
|
112
|
+
scopes.each do |scope|
|
113
|
+
ex_includes = @includes.select { |include| include.scope == scope}.map(&:path)
|
114
|
+
ex_includes += @deps.select { |dep| dep.scope == scope}.map(&:include)
|
115
|
+
includes += ex_includes.map { |include| "-I#{include}" }
|
116
|
+
end
|
117
|
+
includes.join(" ")
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class SearchPath
|
2
|
+
attr_reader :path, :scope
|
3
|
+
def initialize map
|
4
|
+
raise wrong_format_msg(map) if !(map.is_a? Hash) or map[:path].nil?
|
5
|
+
|
6
|
+
@path = File.absolute_path(map[:path])
|
7
|
+
@scope = map[:scope] || :compile
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
def wrong_format_msg(map)
|
12
|
+
"#{map.inspect} is not a map, please present dependencies in format {path: <include_path>, type: <compile/test/prod(external is default value)>}"
|
13
|
+
end
|
14
|
+
end
|
data/lib/simple-make.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "simple-make/project"
|
@@ -0,0 +1,65 @@
|
|
1
|
+
#--------------------configurations-----------------
|
2
|
+
APP_PATH = <%= @app_path %>
|
3
|
+
TEST_PATH = <%= @test_path %>
|
4
|
+
PROD_PATH = <%= @prod_path %>
|
5
|
+
PROJECT_NAME = <%= @name %>
|
6
|
+
OUTPUT_PATH = <%= @output_path %>
|
7
|
+
SOURCE_FOLDER_NAME = <%= @source_folder_name %>
|
8
|
+
|
9
|
+
#--------------------flags-----------------
|
10
|
+
DEPS_FLAG = -MMD -MP -MF"$(@:%.o=%.d)"
|
11
|
+
CC = <%= @cc %>
|
12
|
+
LINK = <%= @link %>
|
13
|
+
|
14
|
+
#--------------------source files-----------------
|
15
|
+
SRCS = <%= srcs %>
|
16
|
+
TEST_SRCS = <%= test_srcs %>
|
17
|
+
PROD_SRCS = <%= prod_srcs %>
|
18
|
+
|
19
|
+
#--------------------folders-----------------
|
20
|
+
|
21
|
+
FOLDERS = <%= sub_folders_in_target_folder%>
|
22
|
+
|
23
|
+
#--------------------objs-----------------
|
24
|
+
OBJS += $(patsubst $(APP_PATH)/$(SOURCE_FOLDER_NAME)/%.cc, $(OUTPUT_PATH)/app/%.o, $(SRCS))
|
25
|
+
TEST_OBJS += $(patsubst $(TEST_PATH)/$(SOURCE_FOLDER_NAME)/%.cc, $(OUTPUT_PATH)/test/%.o, $(TEST_SRCS))
|
26
|
+
PROD_OBJS += $(patsubst $(PROD_PATH)/$(SOURCE_FOLDER_NAME)/%.cc, $(OUTPUT_PATH)/prod/%.o, $(PROD_SRCS))
|
27
|
+
|
28
|
+
#--------------------deps-----------------
|
29
|
+
DEPS += $(OBJS:.o=.d)
|
30
|
+
TEST_DEPS += $(TEST_OBJS:.o=.d)
|
31
|
+
PROD_DEPS += $(PROD_OBJS:.o=.d)
|
32
|
+
ALL_DEPS = $(DEPS) $(TEST_DEPS) $(PROD_DEPS)
|
33
|
+
|
34
|
+
#--------------------compile rules-----------------
|
35
|
+
|
36
|
+
$(TEST_OBJS): $(OUTPUT_PATH)/test/%.o: $(TEST_PATH)/$(SOURCE_FOLDER_NAME)/%.cc
|
37
|
+
$(CC) <%= test_time_search_path_flag %> $(DEPS_FLAG) -c -o "$@" "$<"
|
38
|
+
$(OBJS): $(OUTPUT_PATH)/app/%.o: $(APP_PATH)/$(SOURCE_FOLDER_NAME)/%.cc
|
39
|
+
$(CC) <%= compile_time_search_path_flag %> $(DEPS_FLAG) -c -o "$@" "$<"
|
40
|
+
$(PROD_OBJS): $(OUTPUT_PATH)/prod/%.o: $(PROD_PATH)/$(SOURCE_FOLDER_NAME)/%.cc
|
41
|
+
$(CC) <%= prod_time_search_path_flag %> $(DEPS_FLAG) -c -o "$@" "$<"
|
42
|
+
|
43
|
+
#--------------------ut-----------------
|
44
|
+
$(OUTPUT_PATH)/$(PROJECT_NAME)_ut: $(OBJS) $(TEST_OBJS)
|
45
|
+
$(LINK) -o $(OUTPUT_PATH)/$(PROJECT_NAME)_ut <%= test_time_lib_path_flag %> ${TEST_OBJS} $(OBJS) <%= test_time_lib_flag %>
|
46
|
+
test: init $(OUTPUT_PATH)/$(PROJECT_NAME)_ut
|
47
|
+
$(OUTPUT_PATH)/$(PROJECT_NAME)_ut
|
48
|
+
|
49
|
+
#--------------------package-----------------
|
50
|
+
$(OUTPUT_PATH)/$(PROJECT_NAME): $(OBJS) $(PROD_OBJS)
|
51
|
+
$(LINK) -o $(OUTPUT_PATH)/$(PROJECT_NAME) <%= prod_time_lib_path_flag %> ${PROD_OBJS} $(OBJS) <%= prod_time_lib_flag %>
|
52
|
+
run: init $(OUTPUT_PATH)/$(PROJECT_NAME)
|
53
|
+
$(OUTPUT_PATH)/$(PROJECT_NAME)
|
54
|
+
package: $(OUTPUT_PATH)/$(PROJECT_NAME)
|
55
|
+
|
56
|
+
#--------------------misc-----------------
|
57
|
+
$(FOLDERS): %:
|
58
|
+
mkdir -p "$@"
|
59
|
+
init:$(FOLDERS)
|
60
|
+
clean:
|
61
|
+
rm -rf $(OBJS) $(TEST_OBJS) $(PROD_OBJS) $(ALL_DEPS) $(OUTPUT_PATH)/$(PROJECT_NAME) $(OUTPUT_PATH)/$(PROJECT_NAME)_ut $(FOLDERS)
|
62
|
+
|
63
|
+
.PHONY: clean init
|
64
|
+
|
65
|
+
-include $(ALL_DEPS)
|
metadata
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple-make
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Cui Liqiang
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-30 00:00:00.000000000 Z
|
12
|
+
dependencies: []
|
13
|
+
description: A tool to help you create makefile base on a build.sm file.
|
14
|
+
email: cui.liqiang@gmail.com
|
15
|
+
executables:
|
16
|
+
- sm
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- .gitignore
|
21
|
+
- bin/sm
|
22
|
+
- lib/simple-make.rb
|
23
|
+
- lib/simple-make/dependency.rb
|
24
|
+
- lib/simple-make/dir_traverser.rb
|
25
|
+
- lib/simple-make/project.rb
|
26
|
+
- lib/simple-make/search_path.rb
|
27
|
+
- template/makefile.erb
|
28
|
+
homepage: ''
|
29
|
+
licenses:
|
30
|
+
- MIT
|
31
|
+
metadata: {}
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
requirements:
|
43
|
+
- - '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
requirements: []
|
47
|
+
rubyforge_project:
|
48
|
+
rubygems_version: 2.0.3
|
49
|
+
signing_key:
|
50
|
+
specification_version: 4
|
51
|
+
summary: convention over configuration c/c++ file build tool
|
52
|
+
test_files: []
|