canoe 0.2.3 → 0.3.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 +4 -4
- data/bin/canoe +1 -0
- data/lib/canoe.rb +14 -12
- data/lib/cmd.rb +34 -21
- data/lib/coloring.rb +23 -0
- data/lib/compiler.rb +31 -12
- data/lib/config_reader.rb +4 -1
- data/lib/default_files.rb +89 -61
- data/lib/dependence.rb +56 -17
- data/lib/err.rb +5 -3
- data/lib/source_files.rb +7 -4
- data/lib/workspace/add.rb +27 -0
- data/lib/workspace/build.rb +131 -0
- data/lib/workspace/clean.rb +27 -0
- data/lib/workspace/dep.rb +12 -0
- data/lib/workspace/generate.rb +5 -0
- data/lib/workspace/help.rb +76 -0
- data/lib/workspace/make.rb +232 -0
- data/lib/workspace/new.rb +28 -0
- data/lib/workspace/run.rb +9 -0
- data/lib/workspace/test.rb +41 -0
- data/lib/workspace/update.rb +5 -0
- data/lib/workspace/workspace.rb +52 -0
- metadata +24 -7
- data/lib/workspace.rb +0 -272
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: af31768c0b36d635c13ff31e41dc772dd9834ccd2d52e791f399053ebb3b9782
|
|
4
|
+
data.tar.gz: 135f95f9631bcc43c4817833ee9a6075b1d336239b9131c8f5f26d3f0006cd3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 9c82734822d59c1cd1a119dcc55f954f3d6b971457f44df22c8e9f6eceaa638c503816a1f05dc54019ea8ded2c70f1431e26cab0c057db3cd4ee2775dc12583c
|
|
7
|
+
data.tar.gz: 9b23406264a260e2b715018f5ad275c6a8b9293d712fd4d7623b03709fa5d93ee03cbc916472d9b24e9e6e1d4e2dd83e6781903ca7987febc4ec28a3e92e0ce5
|
data/bin/canoe
CHANGED
data/lib/canoe.rb
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
|
-
require_relative "workspace"
|
|
1
|
+
require_relative "workspace/workspace.rb"
|
|
2
2
|
require_relative "cmd"
|
|
3
3
|
require_relative "source_files"
|
|
4
4
|
|
|
5
5
|
class Canoe
|
|
6
6
|
def initialize
|
|
7
|
-
options = [
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
options = ["new",
|
|
8
|
+
"add",
|
|
9
|
+
"build",
|
|
10
|
+
"generate",
|
|
11
|
+
"make",
|
|
12
|
+
"run",
|
|
13
|
+
"dep",
|
|
14
|
+
"clean",
|
|
15
|
+
"version",
|
|
16
|
+
"help",
|
|
17
|
+
"update",
|
|
18
|
+
"test"]
|
|
17
19
|
@cmd = CmdParser.new options
|
|
18
20
|
end
|
|
19
21
|
|
|
20
22
|
def parse(args)
|
|
21
|
-
|
|
23
|
+
@cmd.parse args
|
|
22
24
|
end
|
|
23
25
|
end
|
data/lib/cmd.rb
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
require_relative "workspace"
|
|
1
|
+
require_relative "workspace/workspace"
|
|
2
2
|
require_relative "err"
|
|
3
3
|
require_relative "config_reader"
|
|
4
4
|
|
|
5
|
+
##
|
|
6
|
+
# class CmdParser
|
|
7
|
+
# Parsing command arguments passed to canoe
|
|
5
8
|
class CmdParser
|
|
6
9
|
include Err
|
|
10
|
+
|
|
7
11
|
def initialize(options)
|
|
8
|
-
@options = options
|
|
12
|
+
@options = options
|
|
9
13
|
end
|
|
10
14
|
|
|
11
15
|
def parse(args)
|
|
12
|
-
if args.size < 1
|
|
13
|
-
abort_on_err "please give one command among #{@options.join(
|
|
16
|
+
if args.size < 1
|
|
17
|
+
abort_on_err "please give one command among #{@options.join(", ")}"
|
|
14
18
|
end
|
|
15
19
|
|
|
16
20
|
unless @options.include?(args[0])
|
|
@@ -21,6 +25,7 @@ class CmdParser
|
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
private
|
|
28
|
+
|
|
24
29
|
def get_current_workspace
|
|
25
30
|
abort_on_err "not in a canoe workspace" unless File.exists? ".canoe"
|
|
26
31
|
config = ConfigReader.extract_flags("config.json")
|
|
@@ -31,7 +36,7 @@ class CmdParser
|
|
|
31
36
|
name = Dir.pwd.split("/")[-1]
|
|
32
37
|
mode = File.exists?("src/main.#{src_sfx}") ? :bin : :lib
|
|
33
38
|
|
|
34
|
-
Dir.chdir(
|
|
39
|
+
Dir.chdir("..") do
|
|
35
40
|
return WorkSpace.new(name, mode, src_sfx, hdr_sfx)
|
|
36
41
|
end
|
|
37
42
|
end
|
|
@@ -41,10 +46,10 @@ class CmdParser
|
|
|
41
46
|
|
|
42
47
|
name, mode = nil, "bin"
|
|
43
48
|
suffixes = ["cpp", "hpp"]
|
|
44
|
-
|
|
49
|
+
|
|
45
50
|
args.each do |arg|
|
|
46
51
|
case arg
|
|
47
|
-
when
|
|
52
|
+
when "--bin", "--lib"
|
|
48
53
|
mode = arg[2..]
|
|
49
54
|
when /--suffix=(\w+)\:(\w+)/
|
|
50
55
|
suffixes[0], suffixes[1] = $1, $2
|
|
@@ -52,7 +57,7 @@ class CmdParser
|
|
|
52
57
|
name = arg unless name
|
|
53
58
|
end
|
|
54
59
|
end
|
|
55
|
-
|
|
60
|
+
|
|
56
61
|
abort_on_err("please give a name to this project") unless name
|
|
57
62
|
WorkSpace.new(name, mode.to_sym, suffixes[0], suffixes[1]).new
|
|
58
63
|
end
|
|
@@ -64,7 +69,7 @@ class CmdParser
|
|
|
64
69
|
|
|
65
70
|
get_current_workspace.add args
|
|
66
71
|
end
|
|
67
|
-
|
|
72
|
+
|
|
68
73
|
def parse_build(args)
|
|
69
74
|
get_current_workspace.build args
|
|
70
75
|
end
|
|
@@ -72,31 +77,35 @@ class CmdParser
|
|
|
72
77
|
def parse_generate(args)
|
|
73
78
|
get_current_workspace.generate
|
|
74
79
|
end
|
|
75
|
-
|
|
80
|
+
|
|
76
81
|
def parse_run(args)
|
|
77
82
|
get_current_workspace.run args
|
|
78
83
|
end
|
|
79
84
|
|
|
80
85
|
def parse_dep(args)
|
|
81
|
-
get_current_workspace.dep
|
|
86
|
+
get_current_workspace.dep
|
|
82
87
|
end
|
|
83
|
-
|
|
88
|
+
|
|
84
89
|
def parse_clean(args)
|
|
85
90
|
get_current_workspace.clean
|
|
86
91
|
end
|
|
87
92
|
|
|
93
|
+
def parse_test(args)
|
|
94
|
+
get_current_workspace.test args
|
|
95
|
+
end
|
|
96
|
+
|
|
88
97
|
def parse_version(args)
|
|
89
98
|
puts <<~VER
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
canoe v0.3.1
|
|
100
|
+
For features in this version, please visit https://github.com/Dicridon/canoe
|
|
101
|
+
Currently, canoe can do below:
|
|
102
|
+
- project creation
|
|
103
|
+
- project auto build and run (works like Cargo for Rust)
|
|
104
|
+
- project structure management
|
|
105
|
+
by XIONG Ziwei
|
|
106
|
+
VER
|
|
98
107
|
end
|
|
99
|
-
|
|
108
|
+
|
|
100
109
|
def parse_help(args)
|
|
101
110
|
WorkSpace.help
|
|
102
111
|
end
|
|
@@ -104,4 +113,8 @@ class CmdParser
|
|
|
104
113
|
def parse_update(args)
|
|
105
114
|
get_current_workspace.update
|
|
106
115
|
end
|
|
116
|
+
|
|
117
|
+
def parse_make(args)
|
|
118
|
+
get_current_workspace.make
|
|
119
|
+
end
|
|
107
120
|
end
|
data/lib/coloring.rb
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
##
|
|
2
|
+
# gem Colorize is a great tool, but I don't want add dependencies to Canoe
|
|
3
|
+
class String
|
|
4
|
+
def self.define_coloring_methods
|
|
5
|
+
colors = {
|
|
6
|
+
30 => :black,
|
|
7
|
+
31 => :red,
|
|
8
|
+
32 => :green,
|
|
9
|
+
33 => :yellow,
|
|
10
|
+
34 => :blue,
|
|
11
|
+
35 => :magenta,
|
|
12
|
+
36 => :cyan,
|
|
13
|
+
37 => :white,
|
|
14
|
+
}
|
|
15
|
+
colors.each do |k, v|
|
|
16
|
+
define_method v do
|
|
17
|
+
"\033[#{k}m#{self}\033[0m"
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
define_coloring_methods
|
|
23
|
+
end
|
data/lib/compiler.rb
CHANGED
|
@@ -1,27 +1,46 @@
|
|
|
1
|
+
##
|
|
2
|
+
# class Compiler
|
|
3
|
+
# Storing compiler name in String and flags as an array
|
|
1
4
|
class Compiler
|
|
2
5
|
attr_reader :name, :flags
|
|
3
|
-
|
|
6
|
+
##
|
|
7
|
+
# @name: String
|
|
8
|
+
# @flgs: Array of String
|
|
9
|
+
def initialize(name, compiling_flags, linking_flags)
|
|
4
10
|
@name = name
|
|
5
|
-
@
|
|
11
|
+
@linking_flags = linking_flags
|
|
12
|
+
@compiling_flags = compiling_flags
|
|
6
13
|
end
|
|
7
14
|
|
|
8
|
-
def
|
|
9
|
-
|
|
15
|
+
def compiling_flags_as_str
|
|
16
|
+
@compiling_flags.join " "
|
|
10
17
|
end
|
|
11
18
|
|
|
12
|
-
def
|
|
13
|
-
@
|
|
19
|
+
def linking_flags_as_str
|
|
20
|
+
@linking_flags.join " "
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def append_compiling_flag(flag)
|
|
24
|
+
@compiling_flags << flag
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def append_linking_flag(flag)
|
|
28
|
+
@linking_flags << flag
|
|
14
29
|
end
|
|
15
30
|
|
|
16
31
|
def compile(src, out)
|
|
17
|
-
puts "#{name} -o #{out} #{
|
|
18
|
-
system "#{name} -o #{out} #{
|
|
32
|
+
puts "#{name} -o #{out} #{compiling_flags_as_str} -c #{src}"
|
|
33
|
+
system "#{name} -o #{out} #{compiling_flags_as_str} -c #{src}"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def link_executable(out, objs)
|
|
37
|
+
puts "#{name} -o #{out} #{objs.join(" ")} #{linking_flags_as_str}"
|
|
38
|
+
system "#{name} -o #{out} #{objs.join(" ")} #{linking_flags_as_str}"
|
|
19
39
|
end
|
|
20
40
|
|
|
21
|
-
def
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
system "#{name} -o #{out} #{objs.join(" ")} #{libs.join(" ")}"
|
|
41
|
+
def link_shared(out, objs)
|
|
42
|
+
puts "#{name} -shared -o #{out}.so #{objs.join(" ")} #{linking_flags_as_str}"
|
|
43
|
+
system "#{name} -shared -o #{out}.so #{objs.join(" ")} #{linking_flags_as_str}"
|
|
25
44
|
end
|
|
26
45
|
|
|
27
46
|
def inspect
|
data/lib/config_reader.rb
CHANGED
data/lib/default_files.rb
CHANGED
|
@@ -1,70 +1,98 @@
|
|
|
1
|
+
##
|
|
2
|
+
# class DefaultFiles
|
|
3
|
+
# A singleton class to generate header and souce files.
|
|
4
|
+
# TODO: consider using class source_file.rb in Pareater
|
|
1
5
|
class DefaultFiles
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
6
|
+
class << self
|
|
7
|
+
def open_file_and_write(filename, content)
|
|
8
|
+
File.open(filename, "w") do |f|
|
|
9
|
+
f.write(content)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
7
12
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
13
|
+
def create_config(path, src_sfx = "cpp", hdr_sfx = "hpp")
|
|
14
|
+
open_file_and_write(
|
|
15
|
+
"#{path}/config.json",
|
|
16
|
+
<<~CONFIG
|
|
17
|
+
{
|
|
18
|
+
"compiler": "clang++",
|
|
19
|
+
"header-suffix": "#{hdr_sfx}",
|
|
20
|
+
"source-suffix": "#{src_sfx}",
|
|
21
|
+
"flags": {
|
|
22
|
+
"compile": {
|
|
23
|
+
"opt": "-O2",
|
|
24
|
+
"debug": "-g",
|
|
25
|
+
"std": "-std=c++17"
|
|
26
|
+
},
|
|
27
|
+
"link": {
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
CONFIG
|
|
33
|
+
|
|
34
|
+
)
|
|
35
|
+
end
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
+
def create_main(path, suffix = "cpp")
|
|
38
|
+
open_file_and_write(
|
|
39
|
+
"#{path}/main.#{suffix}",
|
|
40
|
+
<<~DOC
|
|
41
|
+
#include <iostream>
|
|
42
|
+
int main(int argc, char *argv[]) {
|
|
43
|
+
std::cout << "hello world!" << std::endl;
|
|
44
|
+
}
|
|
45
|
+
DOC
|
|
46
|
+
|
|
47
|
+
)
|
|
48
|
+
end
|
|
37
49
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
def create_lib_header(path, lib_name, suffix = "hpp")
|
|
51
|
+
open_file_and_write(
|
|
52
|
+
"#{path}/#{lib_name}.#{suffix}",
|
|
53
|
+
<<~DOC
|
|
54
|
+
#ifndef __#{lib_name.upcase}__
|
|
55
|
+
#define __#{lib_name.upcase}__
|
|
56
|
+
|
|
57
|
+
#endif
|
|
58
|
+
DOC
|
|
59
|
+
|
|
60
|
+
)
|
|
61
|
+
end
|
|
49
62
|
|
|
50
|
-
|
|
51
|
-
open_file_and_write(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
# def create_emacs_dir_local(path)
|
|
64
|
+
# open_file_and_write(
|
|
65
|
+
# "#{path}/.dir-locals.el",
|
|
66
|
+
# <<~DOC
|
|
67
|
+
# ((nil . ((company-clang-arguments . ("-I./src/components/"
|
|
68
|
+
# "-I./components/"))))
|
|
69
|
+
# (nil . ((company-c-headers-path-user . ("./src/components/"
|
|
70
|
+
# "./components/")))))
|
|
71
|
+
# DOC
|
|
72
|
+
# )
|
|
73
|
+
# end
|
|
58
74
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
75
|
+
def create_cpp(filename, src_sfx = "cpp", hdr_sfx = "hpp")
|
|
76
|
+
open_file_and_write(
|
|
77
|
+
"#{filename}.#{src_sfx}",
|
|
78
|
+
<<~DOC
|
|
79
|
+
#include "#{filename}.#{hdr_sfx}"
|
|
80
|
+
DOC
|
|
81
|
+
|
|
82
|
+
)
|
|
83
|
+
end
|
|
65
84
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
85
|
+
def create_hpp(workspace, prefix, filename, hdr_sfx = "hpp")
|
|
86
|
+
open_file_and_write(
|
|
87
|
+
"#{filename}.#{hdr_sfx}",
|
|
88
|
+
<<~DOC
|
|
89
|
+
#ifndef __#{workspace.upcase}__#{prefix.upcase}__#{filename.upcase}__
|
|
90
|
+
#define __#{workspace.upcase}__#{prefix.upcase}__#{filename.upcase}__
|
|
91
|
+
|
|
92
|
+
#endif
|
|
93
|
+
DOC
|
|
94
|
+
|
|
95
|
+
)
|
|
96
|
+
end
|
|
69
97
|
end
|
|
70
98
|
end
|
data/lib/dependence.rb
CHANGED
|
@@ -1,31 +1,54 @@
|
|
|
1
|
-
require_relative
|
|
2
|
-
require_relative
|
|
1
|
+
require_relative "source_files"
|
|
2
|
+
require_relative "err"
|
|
3
3
|
|
|
4
|
+
##
|
|
5
|
+
# class DepAnalyzer
|
|
6
|
+
# This class is the key component of canoe, which offers file dependency analysis functionality.
|
|
7
|
+
# A DepAnalyzer takes a directory as input, sources files and corresponding header files in this
|
|
8
|
+
# directory should have same name, e.g. test.cpp and test.hpp.
|
|
9
|
+
# DepAnalyzer would read every source file and recursively process user header files included in this source file to
|
|
10
|
+
# find out all user header files this source file depends on.
|
|
11
|
+
# Based on dependencies built in previous stage, DepAnalyzer determines which files should be recompiled and return
|
|
12
|
+
# these files to caller.
|
|
13
|
+
#
|
|
14
|
+
# Dependencies could be written to a file to avoid wasting time parsing all files, Depanalyzer would read from
|
|
15
|
+
# this file to construct dependencies. But if sources files included new headers or included headers are revmoed,
|
|
16
|
+
# Depanalyzer should rebuild the whole dependencies.
|
|
4
17
|
class DepAnalyzer
|
|
5
18
|
include Err
|
|
6
19
|
def self.read_from(filename)
|
|
7
20
|
File.open(filename, "r") do |f|
|
|
8
21
|
ret = Hash.new []
|
|
9
22
|
f.each_with_index do |line, i|
|
|
10
|
-
entry = line.split(
|
|
11
|
-
Err.abort_on_err("Bad .canoe.deps format, line #{i+1}") unless entry.length == 2
|
|
23
|
+
entry = line.split(": ")
|
|
24
|
+
Err.abort_on_err("Bad .canoe.deps format, line #{i + 1}") unless entry.length == 2
|
|
12
25
|
ret[entry[0]] = entry[1].split
|
|
13
|
-
end
|
|
26
|
+
end
|
|
14
27
|
ret
|
|
15
28
|
end
|
|
16
29
|
end
|
|
17
30
|
|
|
18
|
-
def self.compiling_filter(deps, build_time, src_sfx=
|
|
19
|
-
files = []
|
|
31
|
+
def self.compiling_filter(deps, build_time, src_sfx = "cpp", hdr_sfx = "hpp")
|
|
32
|
+
files = []
|
|
33
|
+
@processed = {}
|
|
34
|
+
@recompiles = {}
|
|
35
|
+
deps.keys.each do |k|
|
|
36
|
+
@processed[k] = false
|
|
37
|
+
@recompiles[k] = false
|
|
38
|
+
end
|
|
20
39
|
deps.each do |k, v|
|
|
21
40
|
next if k.end_with? ".#{hdr_sfx}"
|
|
22
41
|
if should_recompile?(k, build_time)
|
|
23
42
|
files << k
|
|
43
|
+
@processed[k] = true
|
|
44
|
+
@recompiles[k] = true
|
|
24
45
|
next
|
|
25
46
|
end
|
|
26
47
|
v.each do |f|
|
|
27
48
|
if mark(f, build_time, deps) || mark(f.sub(".#{hdr_sfx}", ".#{src_sfx}"), build_time, deps)
|
|
28
49
|
files << k
|
|
50
|
+
@processed[k] = true
|
|
51
|
+
@recompiles[k] = true
|
|
29
52
|
break
|
|
30
53
|
end
|
|
31
54
|
end
|
|
@@ -34,22 +57,36 @@ class DepAnalyzer
|
|
|
34
57
|
end
|
|
35
58
|
|
|
36
59
|
private
|
|
60
|
+
|
|
37
61
|
def self.mark(file, build_time, deps)
|
|
62
|
+
ret = false
|
|
38
63
|
return false unless File.exists? file
|
|
39
64
|
if should_recompile?(file, build_time)
|
|
40
65
|
return true
|
|
41
66
|
else
|
|
42
67
|
deps[file].each do |f|
|
|
43
|
-
|
|
68
|
+
if @processed[f]
|
|
69
|
+
ret |= @recompiles[f]
|
|
70
|
+
next
|
|
71
|
+
end
|
|
72
|
+
@processed[f] = true
|
|
73
|
+
if mark(f, build_time, deps)
|
|
74
|
+
@recompiles[f] = true
|
|
75
|
+
return true
|
|
76
|
+
end
|
|
44
77
|
end
|
|
45
78
|
end
|
|
46
|
-
|
|
79
|
+
ret
|
|
47
80
|
end
|
|
48
81
|
|
|
49
|
-
def self.should_recompile?(file, build_time)
|
|
82
|
+
def self.should_recompile?(file, build_time)
|
|
50
83
|
judge = build_time
|
|
51
84
|
if build_time == Time.new(0)
|
|
52
|
-
objfile =
|
|
85
|
+
objfile = if file.start_with?("./src/components")
|
|
86
|
+
"./obj/" + file.delete_suffix(File.extname(file))["./src/components/".length..].gsub("/", "_") + ".o"
|
|
87
|
+
else
|
|
88
|
+
"./obj/#{File.basename(file, ".*")}.o"
|
|
89
|
+
end
|
|
53
90
|
return true unless File.exists? objfile
|
|
54
91
|
judge = File.mtime(objfile)
|
|
55
92
|
end
|
|
@@ -57,7 +94,8 @@ class DepAnalyzer
|
|
|
57
94
|
end
|
|
58
95
|
|
|
59
96
|
public
|
|
60
|
-
|
|
97
|
+
|
|
98
|
+
def initialize(dir, src_sfx = "cpp", hdr_sfx = "hpp")
|
|
61
99
|
@dir = dir
|
|
62
100
|
@deps = Hash.new []
|
|
63
101
|
@source_suffix = src_sfx
|
|
@@ -79,25 +117,26 @@ class DepAnalyzer
|
|
|
79
117
|
|
|
80
118
|
def build_to_file(include_path, filename)
|
|
81
119
|
build_dependence include_path
|
|
82
|
-
|
|
120
|
+
|
|
83
121
|
File.open(filename, "w") do |f|
|
|
84
122
|
@deps.each do |k, v|
|
|
85
123
|
f.write "#{k}: #{v.join(" ")}\n"
|
|
86
124
|
end
|
|
87
125
|
end
|
|
88
|
-
|
|
126
|
+
|
|
89
127
|
@deps
|
|
90
128
|
end
|
|
91
129
|
|
|
92
130
|
private
|
|
93
|
-
|
|
131
|
+
|
|
132
|
+
def get_all_headers(include_path, file, suffix = "hpp")
|
|
94
133
|
File.open(file, "r") do |f|
|
|
95
134
|
ret = []
|
|
96
135
|
if file.end_with?(".#{@source_suffix}")
|
|
97
136
|
header = file.sub(".#{@source_suffix}", ".#{@header_suffix}")
|
|
98
137
|
ret += [header] if File.exists?(header)
|
|
99
138
|
end
|
|
100
|
-
|
|
139
|
+
|
|
101
140
|
f.each_line do |line|
|
|
102
141
|
if mat = line.match(/include "(.+\.#{suffix})"/)
|
|
103
142
|
include_path.each do |path|
|
|
@@ -106,7 +145,7 @@ class DepAnalyzer
|
|
|
106
145
|
end
|
|
107
146
|
end
|
|
108
147
|
end
|
|
109
|
-
|
|
148
|
+
|
|
110
149
|
ret.uniq
|
|
111
150
|
end
|
|
112
151
|
end
|