canoe 0.3.0 → 0.3.2
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 +4 -4
- data/bin/canoe +1 -1
- data/lib/canoe.rb +22 -18
- data/lib/cmd.rb +73 -88
- data/lib/coloring.rb +23 -0
- data/lib/compiler.rb +44 -46
- data/lib/config_reader.rb +1 -1
- data/lib/default_files.rb +19 -26
- data/lib/dependence.rb +116 -97
- data/lib/source_files.rb +7 -7
- data/lib/util.rb +81 -0
- data/lib/workspace/add.rb +29 -0
- data/lib/workspace/build.rb +150 -0
- data/lib/workspace/clean.rb +36 -0
- data/lib/workspace/dep.rb +14 -0
- data/lib/workspace/generate.rb +10 -0
- data/lib/workspace/help.rb +84 -0
- data/lib/workspace/make.rb +280 -0
- data/lib/workspace/new.rb +31 -0
- data/lib/workspace/run.rb +12 -0
- data/lib/workspace/test.rb +136 -0
- data/lib/workspace/update.rb +7 -0
- data/lib/workspace/version.rb +15 -0
- data/lib/workspace/workspace.rb +63 -0
- metadata +18 -5
- data/lib/err.rb +0 -19
- data/lib/workspace.rb +0 -328
data/lib/dependence.rb
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
require_relative 'source_files'
|
|
2
|
-
require_relative '
|
|
3
|
-
|
|
2
|
+
require_relative 'util'
|
|
4
3
|
##
|
|
5
4
|
# class DepAnalyzer
|
|
6
|
-
# This class is the key component of canoe, which offers file dependency analysis functionality.
|
|
5
|
+
# This class is the key component of canoe, which offers file dependency analysis functionality.
|
|
7
6
|
# A DepAnalyzer takes a directory as input, sources files and corresponding header files in this
|
|
8
|
-
# directory should have same name,
|
|
7
|
+
# directory should have same name, e.g. test.cpp and test.hpp.
|
|
9
8
|
# DepAnalyzer would read every source file and recursively process user header files included in this source file to
|
|
10
9
|
# find out all user header files this source file depends on.
|
|
11
10
|
# Based on dependencies built in previous stage, DepAnalyzer determines which files should be recompiled and return
|
|
@@ -14,120 +13,140 @@ require_relative 'err'
|
|
|
14
13
|
# Dependencies could be written to a file to avoid wasting time parsing all files, Depanalyzer would read from
|
|
15
14
|
# this file to construct dependencies. But if sources files included new headers or included headers are revmoed,
|
|
16
15
|
# Depanalyzer should rebuild the whole dependencies.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
ret = Hash.new []
|
|
22
|
-
f.each_with_index do |line, i|
|
|
23
|
-
entry = line.split(': ')
|
|
24
|
-
Err.abort_on_err("Bad .canoe.deps format, line #{i+1}") unless entry.length == 2
|
|
25
|
-
ret[entry[0]] = entry[1].split
|
|
26
|
-
end
|
|
27
|
-
ret
|
|
28
|
-
end
|
|
29
|
-
end
|
|
16
|
+
module Canoe
|
|
17
|
+
class DepAnalyzer
|
|
18
|
+
include Err
|
|
19
|
+
include SystemCommand
|
|
30
20
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
21
|
+
class << self
|
|
22
|
+
include WorkSpaceUtil
|
|
23
|
+
def read_from(filename)
|
|
24
|
+
File.open(filename, 'r') do |f|
|
|
25
|
+
ret = Hash.new []
|
|
26
|
+
f.each_with_index do |line, i|
|
|
27
|
+
entry = line.split(': ')
|
|
28
|
+
abort_on_err("Bad .canoe.deps format, line #{i + 1}") unless entry.length == 2
|
|
29
|
+
ret[entry[0]] = entry[1].split
|
|
30
|
+
end
|
|
31
|
+
ret
|
|
32
|
+
end
|
|
43
33
|
end
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
|
|
35
|
+
def compiling_filter(deps, build_time, src_sfx = 'cpp', hdr_sfx = 'hpp')
|
|
36
|
+
files = []
|
|
37
|
+
@processed = {}
|
|
38
|
+
@recompiles = {}
|
|
39
|
+
deps.each_key do |k|
|
|
40
|
+
@processed[k] = false
|
|
41
|
+
@recompiles[k] = false
|
|
48
42
|
end
|
|
43
|
+
deps.each do |k, v|
|
|
44
|
+
next if k.end_with? ".#{hdr_sfx}"
|
|
45
|
+
|
|
46
|
+
if should_recompile?(k, build_time)
|
|
47
|
+
files << k
|
|
48
|
+
@processed[k] = true
|
|
49
|
+
@recompiles[k] = true
|
|
50
|
+
next
|
|
51
|
+
end
|
|
52
|
+
v.each do |f|
|
|
53
|
+
next unless mark(f, build_time, deps) || mark(f.sub(".#{hdr_sfx}", ".#{src_sfx}"), build_time, deps)
|
|
54
|
+
|
|
55
|
+
files << k
|
|
56
|
+
@processed[k] = true
|
|
57
|
+
@recompiles[k] = true
|
|
58
|
+
break
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
files
|
|
49
62
|
end
|
|
50
|
-
end
|
|
51
|
-
files
|
|
52
|
-
end
|
|
53
63
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
+
private
|
|
65
|
+
|
|
66
|
+
def mark(file, build_time, deps)
|
|
67
|
+
ret = false
|
|
68
|
+
return false unless File.exist? file
|
|
69
|
+
return true if should_recompile?(file, build_time)
|
|
70
|
+
|
|
71
|
+
deps[file].each do |f|
|
|
72
|
+
if @processed[f]
|
|
73
|
+
ret |= @recompiles[f]
|
|
74
|
+
next
|
|
75
|
+
end
|
|
76
|
+
@processed[f] = true
|
|
77
|
+
if mark(f, build_time, deps)
|
|
78
|
+
@recompiles[f] = true
|
|
79
|
+
return true
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
ret
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def should_recompile?(file, build_time)
|
|
86
|
+
judge = build_time
|
|
87
|
+
if build_time == Time.new(0)
|
|
88
|
+
objfile = file_to_obj(file)
|
|
89
|
+
return true unless File.exist? objfile
|
|
90
|
+
|
|
91
|
+
judge = File.mtime(objfile)
|
|
92
|
+
end
|
|
93
|
+
File.mtime(file) > judge
|
|
64
94
|
end
|
|
65
95
|
end
|
|
66
|
-
false
|
|
67
|
-
end
|
|
68
96
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
judge = File.mtime(objfile)
|
|
97
|
+
def initialize(dir, src_sfx = 'cpp', hdr_sfx = 'hpp')
|
|
98
|
+
@dir = dir
|
|
99
|
+
@deps = Hash.new []
|
|
100
|
+
@source_suffix = src_sfx
|
|
101
|
+
@header_suffix = hdr_sfx
|
|
75
102
|
end
|
|
76
|
-
File.mtime(file) > judge
|
|
77
|
-
end
|
|
78
103
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
@source_suffix = src_sfx
|
|
84
|
-
@header_suffix = hdr_sfx
|
|
85
|
-
end
|
|
104
|
+
def build_dependence(include_path)
|
|
105
|
+
files = SourceFiles.get_all(@dir) do |f|
|
|
106
|
+
f.end_with?(".#{@source_suffix}") || f.end_with?(".#{@header_suffix}")
|
|
107
|
+
end
|
|
86
108
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
109
|
+
@deps = Hash.new []
|
|
110
|
+
files.each do |fname|
|
|
111
|
+
@deps[fname] = get_all_headers include_path, fname, @header_suffix
|
|
112
|
+
end
|
|
91
113
|
|
|
92
|
-
|
|
93
|
-
files.each do |fname|
|
|
94
|
-
@deps[fname] = get_all_headers include_path, fname, @header_suffix
|
|
114
|
+
@deps
|
|
95
115
|
end
|
|
96
116
|
|
|
97
|
-
|
|
98
|
-
|
|
117
|
+
def build_to_file(include_path, filename)
|
|
118
|
+
build_dependence include_path
|
|
99
119
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
@deps.each do |k, v|
|
|
105
|
-
f.write "#{k}: #{v.join(" ")}\n"
|
|
120
|
+
File.open(filename, 'w') do |f|
|
|
121
|
+
@deps.each do |k, v|
|
|
122
|
+
f.write "#{k}: #{v.join(' ')}\n"
|
|
123
|
+
end
|
|
106
124
|
end
|
|
125
|
+
|
|
126
|
+
@deps
|
|
107
127
|
end
|
|
108
|
-
|
|
109
|
-
@deps
|
|
110
|
-
end
|
|
111
128
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
129
|
+
private
|
|
130
|
+
|
|
131
|
+
def get_all_headers(include_path, file, suffix = 'hpp')
|
|
132
|
+
File.open(file, 'r') do |f|
|
|
133
|
+
ret = []
|
|
134
|
+
if file.end_with?(".#{@source_suffix}")
|
|
135
|
+
header = file.sub(".#{@source_suffix}", ".#{@header_suffix}")
|
|
136
|
+
ret += [header] if File.exist?(header)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
f.each_line do |line|
|
|
140
|
+
if (mat = line.match(/include "(.+\.#{suffix})"/))
|
|
141
|
+
include_path.each do |path|
|
|
142
|
+
dep = "#{path}/#{mat[1]}"
|
|
143
|
+
ret += [dep] if File.exist? dep
|
|
144
|
+
end
|
|
126
145
|
end
|
|
127
146
|
end
|
|
147
|
+
|
|
148
|
+
ret.uniq
|
|
128
149
|
end
|
|
129
|
-
|
|
130
|
-
ret.uniq
|
|
131
150
|
end
|
|
132
151
|
end
|
|
133
152
|
end
|
data/lib/source_files.rb
CHANGED
|
@@ -5,27 +5,28 @@ class SourceFiles
|
|
|
5
5
|
class << self
|
|
6
6
|
def get_all(dir, &block)
|
|
7
7
|
@files = []
|
|
8
|
-
get_all_helper(dir, &block)
|
|
8
|
+
get_all_helper(dir, &block)
|
|
9
9
|
@files
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
def get_in(dir
|
|
12
|
+
def get_in(dir)
|
|
13
13
|
@files = []
|
|
14
14
|
Dir.each_child(dir) do |f|
|
|
15
15
|
file = "#{dir}/#{f}"
|
|
16
16
|
if File.file? file
|
|
17
17
|
if block_given?
|
|
18
|
-
@files <<
|
|
18
|
+
@files << file.to_s if yield(f)
|
|
19
19
|
else
|
|
20
|
-
@files <<
|
|
20
|
+
@files << file.to_s
|
|
21
21
|
end
|
|
22
|
-
end
|
|
22
|
+
end
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
@files
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
private
|
|
29
|
+
|
|
29
30
|
def get_all_helper(dir, &block)
|
|
30
31
|
Dir.each_child(dir) do |f|
|
|
31
32
|
file = "#{dir}/#{f}"
|
|
@@ -42,4 +43,3 @@ class SourceFiles
|
|
|
42
43
|
end
|
|
43
44
|
end
|
|
44
45
|
end
|
|
45
|
-
|
data/lib/util.rb
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
require_relative 'coloring'
|
|
2
|
+
|
|
3
|
+
module Canoe
|
|
4
|
+
class Stepper
|
|
5
|
+
def initialize(total, togo)
|
|
6
|
+
@total = total.to_f
|
|
7
|
+
@togo = togo.to_f
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def progress_as_str
|
|
11
|
+
progress = ((@total - @togo) / @total).round(2) * 100
|
|
12
|
+
"[#{progress.to_i}%%]"
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def step
|
|
16
|
+
@togo -= 1 if @togo.positive?
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# wrapping workspace related functionality to expose to other modules
|
|
22
|
+
module WorkSpaceUtil
|
|
23
|
+
def get_current_workspace
|
|
24
|
+
abort_on_err 'not in a canoe workspace' unless File.exist? '.canoe'
|
|
25
|
+
config = ConfigReader.extract_flags('config.json')
|
|
26
|
+
|
|
27
|
+
src_sfx = config['source-suffix'] || 'cpp'
|
|
28
|
+
hdr_sfx = config['header-suffix'] || 'hpp'
|
|
29
|
+
|
|
30
|
+
name = Dir.pwd.split('/')[-1]
|
|
31
|
+
mode = File.exist?("src/main.#{src_sfx}") ? :bin : :lib
|
|
32
|
+
|
|
33
|
+
WorkSpace.new(name, mode, src_sfx, hdr_sfx)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def src_to_obj(src)
|
|
37
|
+
get_current_workspace.src_to_obj(src)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def comp_to_obj(comp)
|
|
41
|
+
get_current_workspace.comp_to_obj(comp)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def file_to_obj(file)
|
|
45
|
+
get_current_workspace.file_to_obj(file)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def extract_one_file(file, deps)
|
|
49
|
+
get_current_workspace.extract_one_file(file, deps)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def extract_one_file_obj(file, deps)
|
|
53
|
+
get_current_workspace.extract_one_file_obj(file, deps)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
module SystemCommand
|
|
58
|
+
def issue_command(cmd_str)
|
|
59
|
+
puts cmd_str
|
|
60
|
+
system cmd_str
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module Err
|
|
65
|
+
def warn_on_err(err)
|
|
66
|
+
puts <<~ERR
|
|
67
|
+
#{'Waring: '.yellow}
|
|
68
|
+
#{err}
|
|
69
|
+
try 'canoe help' for more information
|
|
70
|
+
ERR
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def abort_on_err(err)
|
|
74
|
+
abort <<~ERR
|
|
75
|
+
#{'Fatal: '.red}
|
|
76
|
+
#{err}
|
|
77
|
+
try 'canoe help' for more information
|
|
78
|
+
ERR
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Canoe
|
|
2
|
+
class WorkSpace
|
|
3
|
+
def add(args)
|
|
4
|
+
args.each do |i|
|
|
5
|
+
dir = @components
|
|
6
|
+
filenames = i.split '/'
|
|
7
|
+
prefix = []
|
|
8
|
+
filenames.each do |filename|
|
|
9
|
+
dir += "/#{filename}"
|
|
10
|
+
prefix << filename
|
|
11
|
+
next if Dir.exist? dir
|
|
12
|
+
|
|
13
|
+
FileUtils.mkdir dir
|
|
14
|
+
Dir.chdir(dir) do
|
|
15
|
+
puts "created + #{Dir.pwd.blue}"
|
|
16
|
+
create_working_files prefix.join('__'), filename
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def create_working_files(prefix, filename)
|
|
25
|
+
DefaultFiles.create_cpp filename, @source_suffix, @header_suffix
|
|
26
|
+
DefaultFiles.create_hpp @name, prefix, filename, @header_suffix
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
module Canoe
|
|
2
|
+
class WorkSpace
|
|
3
|
+
def src_to_obj(src)
|
|
4
|
+
@obj_prefix + File.basename(src, ".*") + ".o"
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def comp_to_obj(comp)
|
|
8
|
+
@obj_prefix + comp.delete_suffix(File.extname(comp))[@components_prefix.length..].gsub("/", "_") + ".o"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# the if else order is important because tests are regarded as sources
|
|
12
|
+
def file_to_obj(file)
|
|
13
|
+
if file.start_with?(@components_prefix)
|
|
14
|
+
comp_to_obj file
|
|
15
|
+
else
|
|
16
|
+
src_to_obj file
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# args are commandline parameters passed to `canoe build`,
|
|
21
|
+
# could be 'all', 'test', 'target' or empty
|
|
22
|
+
def build(args)
|
|
23
|
+
options = {[] => 'target', ['all'] => 'all', ['test'] => 'test'}
|
|
24
|
+
if options.include?(args)
|
|
25
|
+
send "build_#{options[args]}"
|
|
26
|
+
else
|
|
27
|
+
abort_on_err "Unkown subcommand #{args.join(" ").red}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def build_flags(flags, config)
|
|
34
|
+
config.values.each do |v|
|
|
35
|
+
case v
|
|
36
|
+
when String
|
|
37
|
+
flags << v
|
|
38
|
+
when Array
|
|
39
|
+
v.each do |o|
|
|
40
|
+
flags << o
|
|
41
|
+
end
|
|
42
|
+
else
|
|
43
|
+
abort_on_err "unknown options in config.json, #{v}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def build_compiler_from_config
|
|
49
|
+
flags = ConfigReader.extract_flags "config.json"
|
|
50
|
+
compiler_name = flags["compiler"] ? flags["compiler"] : "clang++"
|
|
51
|
+
|
|
52
|
+
abort_on_err "compiler #{compiler_name} not found" unless system "which #{compiler_name} > /dev/null"
|
|
53
|
+
compiler_flags = ["-Isrc/components"]
|
|
54
|
+
linker_flags = []
|
|
55
|
+
|
|
56
|
+
c_flags, l_flags = flags["flags"]["compile"], flags["flags"]["link"]
|
|
57
|
+
build_flags(compiler_flags, c_flags)
|
|
58
|
+
build_flags(linker_flags, l_flags)
|
|
59
|
+
|
|
60
|
+
@compiler = Compiler.new compiler_name, compiler_flags, linker_flags
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def compile(f, o)
|
|
64
|
+
@compiler.compile f, o
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def link_exectutable(odir, objs)
|
|
68
|
+
puts "#{"[100%]".green} linking"
|
|
69
|
+
@compiler.link_executable "#{odir}/#{@name}", objs
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def link_shared(odir, objs)
|
|
73
|
+
puts "#{"[100%]".green} linking"
|
|
74
|
+
@compiler.link_shared "#{odir}/lib#{@name}", objs
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def build_bin(files)
|
|
78
|
+
if build_common(files) &&
|
|
79
|
+
link_exectutable(@target_short, Dir.glob("obj/*.o").reject { |f| f.start_with? 'obj/test_' })
|
|
80
|
+
puts "BUILDING SUCCEEDED".green
|
|
81
|
+
return true
|
|
82
|
+
else
|
|
83
|
+
puts "building target FAILED".red
|
|
84
|
+
return false
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def build_lib(files)
|
|
89
|
+
@compiler.append_compiling_flag "-fPIC"
|
|
90
|
+
if build_common(files) &&
|
|
91
|
+
link_shared(@target_short, Dir.glob("obj/*.o").reject { |f| f.start_with? 'obj/test_'})
|
|
92
|
+
puts "BUILDING SUCCEEDED".green
|
|
93
|
+
else
|
|
94
|
+
puts "building target FAILED".red
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def build_common(files)
|
|
99
|
+
all = SourceFiles.get_all(@src_short) { |f| f.end_with? @source_suffix }
|
|
100
|
+
stepper = Stepper.new all.size, files.size
|
|
101
|
+
flag = true
|
|
102
|
+
|
|
103
|
+
files.each do |f|
|
|
104
|
+
progress = stepper.progress_as_str.green
|
|
105
|
+
printf "#{progress.green} compiling #{f.yellow}: "
|
|
106
|
+
o = file_to_obj(f)
|
|
107
|
+
flag = false unless compile f, o
|
|
108
|
+
stepper.step
|
|
109
|
+
end
|
|
110
|
+
flag
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def build_all
|
|
114
|
+
build_target
|
|
115
|
+
build_test
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def get_deps(dep_file, source_dir, include_dirs)
|
|
119
|
+
File.exist?(dep_file) ? DepAnalyzer.read_from(dep_file) :
|
|
120
|
+
DepAnalyzer.new(source_dir, @source_suffix, @header_suffix).build_to_file(include_dirs, dep_file)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def target_deps
|
|
124
|
+
get_deps @deps, @src_short, [@src_short, @components_short]
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# contain only headers
|
|
128
|
+
# sources in ./src/components are not included
|
|
129
|
+
def tests_deps
|
|
130
|
+
get_deps @test_deps, @tests_short, [@src_short, @components_short]
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def build_target
|
|
134
|
+
puts "#{'[BUILDING TARGET]'.magenta}..."
|
|
135
|
+
deps = get_deps @deps, @src, [@src_short, @components_short]
|
|
136
|
+
target = "#{@target}/#{@name}"
|
|
137
|
+
build_time = File.exist?(target) ? File.mtime(target) : Time.new(0)
|
|
138
|
+
files = DepAnalyzer.compiling_filter deps, build_time, @source_suffix, @header_suffix
|
|
139
|
+
|
|
140
|
+
build_compiler_from_config
|
|
141
|
+
|
|
142
|
+
if files.empty? && File.exist?(target)
|
|
143
|
+
puts "nothing to do, all up to date"
|
|
144
|
+
return
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
self.send "build_#{@mode.to_s}", files
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|