cxxproject 0.2 → 0.4.6

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.
Files changed (57) hide show
  1. data/Rakefile.rb +55 -33
  2. data/bin/cxx +10 -0
  3. data/lib/cxxproject/buildingblocks/binary_library.rb +16 -0
  4. data/lib/cxxproject/buildingblocks/building_block.rb +93 -0
  5. data/lib/cxxproject/buildingblocks/command_line.rb +30 -0
  6. data/lib/cxxproject/buildingblocks/custom_building_block.rb +17 -0
  7. data/lib/cxxproject/buildingblocks/executable.rb +49 -0
  8. data/lib/cxxproject/buildingblocks/has_dependencies_mixin.rb +57 -0
  9. data/lib/cxxproject/buildingblocks/has_libraries_mixin.rb +35 -0
  10. data/lib/cxxproject/buildingblocks/has_sources_mixin.rb +85 -0
  11. data/lib/cxxproject/buildingblocks/makefile.rb +35 -0
  12. data/lib/cxxproject/buildingblocks/module.rb +14 -0
  13. data/lib/cxxproject/buildingblocks/single_source.rb +11 -0
  14. data/lib/cxxproject/buildingblocks/source_library.rb +31 -0
  15. data/lib/cxxproject/extensions/file_ext.rb +47 -0
  16. data/lib/cxxproject/extensions/rake_dirty_ext.rb +30 -0
  17. data/lib/cxxproject/extensions/rake_ext.rb +158 -0
  18. data/lib/cxxproject/extensions/rake_listener_ext.rb +53 -0
  19. data/lib/cxxproject/extensions/stdout_ext.rb +35 -0
  20. data/lib/cxxproject/extensions/string_ext.rb +9 -0
  21. data/lib/cxxproject/task_maker.rb +418 -0
  22. data/lib/cxxproject/testinstanceeval.rb +65 -0
  23. data/lib/cxxproject/toolchain/base.rb +98 -0
  24. data/lib/cxxproject/toolchain/diab.rb +47 -0
  25. data/lib/cxxproject/toolchain/gcc.rb +39 -0
  26. data/lib/cxxproject/toolchain/provider.rb +18 -0
  27. data/lib/cxxproject/torake/compiler.rb +10 -0
  28. data/lib/cxxproject/torake.rb +152 -0
  29. data/lib/cxxproject/utils/dot/building_block_graph_writer.rb +19 -0
  30. data/lib/cxxproject/utils/dot/graph_writer.rb +53 -0
  31. data/lib/cxxproject/utils/dot/task_graph_writer.rb +34 -0
  32. data/lib/cxxproject/utils/ubigraph.rb +237 -0
  33. data/lib/cxxproject/{utils.rb → utils/utils.rb} +19 -1
  34. data/lib/cxxproject.rb +13 -223
  35. data/lib/tools/Rakefile.rb.template +10 -0
  36. data/lib/tools/project.rb.template +6 -0
  37. data/lib/tools/projectWizard.rb +44 -0
  38. data/spec/build_dependencies_spec.rb +169 -0
  39. data/spec/building_block_spec.rb +12 -0
  40. data/spec/dir_spec.rb +13 -0
  41. data/spec/project_path_spec.rb +73 -0
  42. data/spec/rake_listener_ext_spec.rb +25 -0
  43. data/spec/string_spec.rb +11 -0
  44. data/spec/testdata/basic/exe12/project.rb +5 -0
  45. data/spec/testdata/basic/lib1/project.rb +5 -0
  46. data/spec/testdata/basic/lib2/project.rb +8 -0
  47. data/spec/testdata/multiple_levels/libs/lib1/project.rb +5 -0
  48. data/spec/testdata/multiple_levels/libs/lib2/project.rb +19 -0
  49. data/spec/testdata/multiple_levels/mainproject/basic/project.rb +8 -0
  50. data/spec/testdata/onlyOneHeader/Rakefile.rb +4 -0
  51. data/spec/testdata/onlyOneHeader/project.rb +4 -0
  52. metadata +83 -19
  53. data/lib/cxxproject/compiler.rb +0 -80
  54. data/lib/cxxproject/dependencies.rb +0 -41
  55. data/spec/dependencies_spec.rb +0 -19
  56. /data/lib/cxxproject/{gcccompiler.rb → torake/gcccompiler.rb} +0 -0
  57. /data/lib/cxxproject/{osxcompiler.rb → torake/osxcompiler.rb} +0 -0
@@ -0,0 +1,65 @@
1
+ require 'rake'
2
+
3
+ project_string = 'cxx_configuration "debug" do
4
+ exe "basic",
5
+ :sources => FileList.new("**/*.cpp"),
6
+ :dependencies => ["2"]
7
+ exe "debug",
8
+ :sources => FileList.new("**/*.cpp"),
9
+ :dependencies => ["abc"]
10
+ end'
11
+ # project_string = 'cxx_configuration "debug" do
12
+ # [exe ("basic", :sources => FileList.new("**/*.cpp")),
13
+ # exe ("next",{})]
14
+ # end'
15
+ class EvalContext
16
+
17
+ attr_accessor :name, :myblock
18
+
19
+ def cxx_configuration(name, &block)
20
+ puts "calling cxx_configuration with name: #{name}"
21
+ @myblock = block
22
+ @name = name
23
+ end
24
+
25
+ def eval_project(project_text)
26
+ instance_eval(project_text)
27
+ puts "instance_eval with #{project_text}"
28
+ end
29
+
30
+ def configuration(*args, &block)
31
+ name = args[0]
32
+ raise "no name given" unless name.is_a?(String) && !name.strip.empty?
33
+ instance_eval(&block)
34
+ end
35
+
36
+ def check_hash(hash,allowed)
37
+ puts "hash" + hash.inspect
38
+ hash.keys.map {|k| raise "#{k} is not a valid specifier!" unless allowed.include?(k) }
39
+ end
40
+
41
+ def exe(name, hash)
42
+ puts "inside exe"
43
+ raise "not a hash" unless hash.is_a?(Hash)
44
+ check_hash hash,[:sources,:includes,:dependencies]
45
+ puts "sources are: #{hash[:sources]}"
46
+ end
47
+
48
+ def source_lib(name, hash)
49
+ raise "not a hash" unless hash.is_a?(Hash)
50
+ check_hash hash,[:sources,:includes,:dependencies]
51
+ raise ":sources need to be defined" unless hash.has_key?(:sources)
52
+ puts "sources are: #{hash[:sources]}"
53
+ end
54
+
55
+ def compile(name, hash)
56
+ raise "not a hash" unless hash.is_a?(Hash)
57
+ check_hash hash,[:sources,:includes]
58
+ end
59
+
60
+ end
61
+
62
+ loadContext = EvalContext.new
63
+ loadContext.eval_project(project_string)
64
+ loadContext.myblock.call()
65
+
@@ -0,0 +1,98 @@
1
+ module Cxxproject
2
+ module Toolchain
3
+
4
+ class Provider
5
+ @@settings = {}
6
+ @@default = {
7
+ :COMPILER =>
8
+ {
9
+ :CPP => {
10
+ :COMMAND => "",
11
+ :DEFINE_FLAG => "",
12
+ :OBJECT_FILE_FLAG => "",
13
+ :INCLUDE_PATH_FLAG => "",
14
+ :COMPILE_FLAGS => "",
15
+ :DEFINES => [],
16
+ :FLAGS => "",
17
+ :SOURCE_FILE_ENDINGS => [".cxx", ".cpp", ".c++", ".cc", ".C"],
18
+ :DEP_FLAGS => ""
19
+ },
20
+ :C => {
21
+ :COMMAND => "",
22
+ :DEFINE_FLAG => "",
23
+ :OBJECT_FILE_FLAG => "",
24
+ :INCLUDE_PATH_FLAG => "",
25
+ :COMPILE_FLAGS => "",
26
+ :DEFINES => [],
27
+ :FLAGS => "",
28
+ :SOURCE_FILE_ENDINGS => [".c"],
29
+ :DEP_FLAGS => ""
30
+ },
31
+ :ASM => {
32
+ :COMMAND => "",
33
+ :DEFINE_FLAG => "",
34
+ :OBJECT_FILE_FLAG => "",
35
+ :INCLUDE_PATH_FLAG => "",
36
+ :COMPILE_FLAGS => "",
37
+ :DEFINES => [],
38
+ :FLAGS => "",
39
+ :SOURCE_FILE_ENDINGS => [".asm", ".s", ".S"],
40
+ :DEP_FLAGS => ""
41
+ }
42
+ },
43
+
44
+ :ARCHIVER =>
45
+ {
46
+ :COMMAND => "",
47
+ :ARCHIVE_FLAGS => "",
48
+ :FLAGS => ""
49
+ },
50
+
51
+ :LINKER =>
52
+ {
53
+ :COMMAND => "",
54
+ :MUST_FLAGS => "",
55
+ :SCRIPT => "",
56
+ :USER_LIB_FLAG => "",
57
+ :EXE_FLAG => "",
58
+ :LIB_FLAG => "",
59
+ :LIB_PATH_FLAG => "",
60
+ :LIB_PREFIX_FLAGS => "", # "-Wl,--whole-archive",
61
+ :LIB_POSTFIX_FLAGS => "", # "-Wl,--no-whole-archive",
62
+ :FLAGS => "",
63
+ :MAP_FILE_FLAG => "",
64
+ :OUTPUT_ENDING => ".exe", # or .elf
65
+ },
66
+
67
+ :MAKE =>
68
+ {
69
+ :COMMAND => "make",
70
+ :MAKE_FLAGS => "",
71
+ :FLAGS => "-j",
72
+ :FILE_FLAG => "-f",
73
+ :DIR_FLAG => "-C",
74
+ :CLEAN => "clean"
75
+ },
76
+
77
+ }
78
+
79
+ def self.add(name, basedOn = nil)
80
+ chain = Marshal.load(Marshal.dump(basedOn.nil? ? @@default : @@settings[basedOn]))
81
+ @@settings[name] = chain
82
+ chain
83
+ end
84
+
85
+ def self.default
86
+ @@default
87
+ end
88
+
89
+ def self.modify_cpp_compiler(based_on, h)
90
+ chain = Marshal.load(Marshal.dump(@@settings[based_on]))
91
+ chain[:COMPILER][:CPP].update(h)
92
+ chain
93
+ end
94
+
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,47 @@
1
+ require 'cxxproject/toolchain/base'
2
+ require 'cxxproject/utils/utils'
3
+
4
+ module Cxxproject
5
+ module Toolchain
6
+
7
+ DiabChainDebug = Provider.add("Diab_Debug")
8
+
9
+ DiabChainDebug[:COMPILER][:C].update({
10
+ :COMMAND => "dcc",
11
+ :FLAGS => "-tPPCE200Z6VEN:simple -O -XO -Xsize-opt -Xsmall-const=0 -Xenum-is-best -Xexceptions-off -g",
12
+ :DEFINE_FLAG => "-D",
13
+ :OBJECT_FILE_FLAG => "-o",
14
+ :INCLUDE_PATH_FLAG => "-I",
15
+ :COMPILE_FLAGS => "-c",
16
+ :DEP_FLAGS => "-Xmake-dependency=6 -Xmake-dependency-savefile="
17
+ })
18
+
19
+ DiabChainDebug[:COMPILER][:CPP] = Utils.deep_copy(DiabChainDebug[:COMPILER][:C])
20
+ DiabChainDebug[:COMPILER][:CPP][:FLAGS] = DiabChainDebug[:COMPILER][:CPP][:FLAGS] + " -Xrtti-off"
21
+ DiabChainDebug[:COMPILER][:CPP][:SOURCE_FILE_ENDINGS] = Provider.default[:COMPILER][:CPP][:SOURCE_FILE_ENDINGS]
22
+
23
+ DiabChainDebug[:COMPILER][:ASM] = Utils.deep_copy(DiabChainDebug[:COMPILER][:C])
24
+ DiabChainDebug[:COMPILER][:ASM][:COMMAND] = "das"
25
+ DiabChainDebug[:COMPILER][:ASM][:FLAGS] = "-tPPCE200Z6VEN:simple -Xisa-vle -g -Xasm-debug-on"
26
+ DiabChainDebug[:COMPILER][:ASM][:COMPILE_FLAGS] = ""
27
+ DiabChainDebug[:COMPILER][:ASM][:SOURCE_FILE_ENDINGS] = Provider.default[:COMPILER][:ASM][:SOURCE_FILE_ENDINGS]
28
+
29
+ DiabChainDebug[:ARCHIVER][:COMMAND] = "dar"
30
+ DiabChainDebug[:ARCHIVER][:ARCHIVE_FLAGS] = "-r"
31
+
32
+ DiabChainDebug[:LINKER][:COMMAND] = "dcc"
33
+ DiabChainDebug[:LINKER][:SCRIPT] = "-Wm"
34
+ DiabChainDebug[:LINKER][:USER_LIB_FLAG] = "-l:"
35
+ DiabChainDebug[:LINKER][:EXE_FLAG] = "-o"
36
+ DiabChainDebug[:LINKER][:LIB_FLAG] = "-l"
37
+ DiabChainDebug[:LINKER][:LIB_PATH_FLAG] = "-L"
38
+ DiabChainDebug[:LINKER][:MAP_FILE_FLAG] = "-Wl,-m6" # no map file if this string is empty, otherwise -Wl,-m6>abc.map
39
+ DiabChainDebug[:LINKER][:FLAGS] = "-ulink_date_time -uResetConfigurationHalfWord -Wl,-Xstop-on-redeclaration -Wl,-Xstop-on-warning -tPPCE200Z6VEN:simple -Wl,-Xremove-unused-sections -Wl,-Xunused-sections-list"
40
+ DiabChainDebug[:LINKER][:OUTPUT_ENDING] = ".elf"
41
+
42
+ DiabChainRelease = Provider.add("Diab_Release", "Diab_Debug")
43
+ DiabChainRelease[:COMPILER][:C][:FLAGS] = "-tPPCE200Z6VEN:simple -XO -Xsize-opt -Xsmall-const=0 -Xenum-is-best -Xsection-split -Xforce-declarations"
44
+ DiabChainRelease[:COMPILER][:CPP][:FLAGS] = "-tPPCE200Z6VEN:simple -XO -Xsize-opt -Xsmall-const=0 -Xenum-is-best -Xrtti-off -Xexceptions-off -Xsection-split"
45
+
46
+ end
47
+ end
@@ -0,0 +1,39 @@
1
+ require 'cxxproject/toolchain/base'
2
+ require 'cxxproject/utils/utils'
3
+
4
+ module Cxxproject
5
+ module Toolchain
6
+
7
+ GCCChain = Provider.add("GCC")
8
+
9
+ GCCChain[:COMPILER][:CPP].update({
10
+ :COMMAND => "g++",
11
+ :DEFINE_FLAG => "-D",
12
+ :OBJECT_FILE_FLAG => "-o",
13
+ :INCLUDE_PATH_FLAG => "-I",
14
+ :COMPILE_FLAGS => "-c ",
15
+ :DEP_FLAGS => "-MMD -MF " # empty space at the end is important!
16
+ })
17
+
18
+ GCCChain[:COMPILER][:C] = Utils.deep_copy(GCCChain[:COMPILER][:CPP])
19
+ GCCChain[:COMPILER][:C][:SOURCE_FILE_ENDINGS] = Provider.default[:COMPILER][:C][:SOURCE_FILE_ENDINGS]
20
+ GCCChain[:COMPILER][:C][:COMMAND] = "gcc"
21
+
22
+ GCCChain[:COMPILER][:ASM] = Utils.deep_copy(GCCChain[:COMPILER][:C])
23
+ GCCChain[:COMPILER][:ASM][:SOURCE_FILE_ENDINGS] = Provider.default[:COMPILER][:ASM][:SOURCE_FILE_ENDINGS]
24
+
25
+ GCCChain[:ARCHIVER][:COMMAND] = "ar"
26
+ GCCChain[:ARCHIVER][:ARCHIVE_FLAGS] = "-r"
27
+
28
+ GCCChain[:LINKER][:COMMAND] = "g++"
29
+ GCCChain[:LINKER][:SCRIPT] = "-T"
30
+ GCCChain[:LINKER][:USER_LIB_FLAG] = "-l:"
31
+ GCCChain[:LINKER][:EXE_FLAG] = "-o"
32
+ GCCChain[:LINKER][:LIB_FLAG] = "-l"
33
+ GCCChain[:LINKER][:LIB_PATH_FLAG] = "-L"
34
+ GCCChain[:LINKER][:FLAGS] = "-all_load"
35
+ GCCChain[:LINKER][:LIB_PREFIX_FLAGS] = "-Wl,--whole-archive"
36
+ GCCChain[:LINKER][:LIB_POSTFIX_FLAGS] = "-Wl,--no-whole-archive"
37
+
38
+ end
39
+ end
@@ -0,0 +1,18 @@
1
+ require 'cxxproject/toolchain/diab'
2
+ require 'cxxproject/toolchain/gcc'
3
+
4
+ module Cxxproject
5
+ module Toolchain
6
+
7
+ class Provider
8
+
9
+ def self.[](name)
10
+ return @@settings[name] if @@settings.include? name
11
+ nil
12
+ end
13
+
14
+
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,10 @@
1
+
2
+ class Compiler
3
+ attr_reader :output_path
4
+
5
+ def initialize(output_path)
6
+ @output_path = output_path
7
+ CLOBBER.include(output_path)
8
+ end
9
+
10
+ end
@@ -0,0 +1,152 @@
1
+ require 'logger'
2
+ require 'pp'
3
+ require 'pathname'
4
+ require 'cxxproject/extensions/rake_ext'
5
+ require 'cxxproject/toolchain/gcc'
6
+ require 'cxxproject/task_maker'
7
+
8
+ class CxxProject2Rake
9
+
10
+ attr_accessor :base, :all_tasks
11
+
12
+ def initialize(projects, build_dir, toolchain, base='.', logLevel=Logger::ERROR)
13
+ pwd = `pwd`
14
+ @log = Logger.new(STDOUT)
15
+ @log.formatter = proc { |severity, datetime, progname, msg|
16
+ "#{severity}: #{msg}\n"
17
+ }
18
+
19
+ @log.level = logLevel
20
+ @log.debug "starting..."
21
+ @base = base
22
+ @all_tasks = instantiate_tasks(projects, build_dir, toolchain, base)
23
+ end
24
+
25
+ def instantiate_tasks(project_configs, build_dir, toolchain, base='.')
26
+ cd base do
27
+ project_configs.each do |p|
28
+ abort "project config #{p} cannot be found!" unless File.exists?(p)
29
+ end
30
+ end
31
+ @log.debug "project_configs: #{project_configs}"
32
+ register_projects(project_configs)
33
+ define_project_info_task()
34
+ @gcc = toolchain
35
+ task_maker = TaskMaker.new(@log)
36
+ task_maker.set_loglevel(@log.level);
37
+ tasks = []
38
+
39
+ #todo: sort ALL_BUILDING_BLOCKS (circular deps)
40
+
41
+ ALL_BUILDING_BLOCKS.each do |name,block|
42
+ block.set_tcs(@gcc) unless block.has_tcs?
43
+ block.set_output_dir(Dir.pwd + "/" + build_dir)
44
+ rel_projects = project_configs.collect { |p| File.join(base,p) }
45
+ block.set_config_files(rel_projects)
46
+ block.complete_init()
47
+ end
48
+
49
+ ALL_BUILDING_BLOCKS.each do |name,block|
50
+ @log.debug "creating task for block: #{block.name}/taskname: #{block.get_task_name} (#{block})"
51
+ t = task_maker.create_tasks_for_building_block(block)
52
+ if (t != nil)
53
+ tasks << { :task => t, :name => name }
54
+ end
55
+ end
56
+ tasks
57
+ end
58
+
59
+ def register_projects(projects)
60
+ cd(@base,:verbose => false) do |b|
61
+ projects.each do |project_file|
62
+ @log.debug "register project #{project_file}"
63
+ dirname = File.dirname(project_file)
64
+ @log.debug "dirname for project was: #{dirname}"
65
+ cd(dirname,:verbose => false) do | base_dir |
66
+ @log.debug "current dir: #{`pwd`}, #{base_dir}"
67
+ loadContext = EvalContext.new
68
+ loadContext.eval_project(File.read(File.basename(project_file)))
69
+ loadContext.myblock.call()
70
+ loadContext.all_blocks.each do |p|
71
+ p.set_project_dir(Dir.pwd)
72
+ if p.sources.instance_of?(Rake::FileList)
73
+ p.set_sources(p.sources.to_a)
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+ def define_project_info_task
81
+ desc "shows your defined projects"
82
+ task :project_info do
83
+ p "ProjectBase: #{@base}"
84
+ ALL_BUILDING_BLOCKS.each_value do |bb|
85
+ pp bb
86
+ end
87
+ end
88
+ end
89
+
90
+ end
91
+
92
+ class EvalContext
93
+
94
+ attr_accessor :myblock, :all_blocks
95
+
96
+ def cxx_configuration(&block)
97
+ @myblock = block
98
+ @all_blocks = []
99
+ end
100
+
101
+ def eval_project(project_text)
102
+ instance_eval(project_text)
103
+ end
104
+
105
+ def configuration(*args, &block)
106
+ name = args[0]
107
+ raise "no name given" unless name.is_a?(String) && !name.strip.empty?
108
+ instance_eval(&block)
109
+ end
110
+
111
+ def check_hash(hash,allowed)
112
+ hash.keys.map {|k| raise "#{k} is not a valid specifier!" unless allowed.include?(k) }
113
+ end
114
+
115
+ def exe(name, hash)
116
+ raise "not a hash" unless hash.is_a?(Hash)
117
+ check_hash hash,[:sources,:includes,:dependencies]
118
+ bblock = Executable.new(name)
119
+ bblock.set_sources(hash[:sources]) if hash.has_key?(:sources)
120
+ bblock.set_includes(hash[:includes]) if hash.has_key?(:includes)
121
+ bblock.set_dependencies(hash[:dependencies]) if hash.has_key?(:dependencies)
122
+
123
+ if OS.linux?
124
+ bblock.set_lib_searchpaths(["/usr/local/lib","/usr/lib"])
125
+ else
126
+ bblock.set_lib_searchpaths(["C:/tool/cygwin/lib"])
127
+ end
128
+ all_blocks << bblock
129
+ end
130
+
131
+ def source_lib(name, hash)
132
+ raise "not a hash" unless hash.is_a?(Hash)
133
+ check_hash hash,[:sources,:includes,:dependencies,:toolchain]
134
+ raise ":sources need to be defined" unless hash.has_key?(:sources)
135
+ bblock = SourceLibrary.new(name)
136
+ bblock.set_sources(hash[:sources])
137
+ bblock.set_includes(hash[:includes]) if hash.has_key?(:includes)
138
+ bblock.set_tcs(hash[:toolchain]) if hash.has_key?(:toolchain)
139
+ bblock.set_dependencies(hash[:dependencies]) if hash.has_key?(:dependencies)
140
+ all_blocks << bblock
141
+ end
142
+
143
+ def compile(name, hash)
144
+ raise "not a hash" unless hash.is_a?(Hash)
145
+ check_hash hash,[:sources,:includes]
146
+ bblock = SingleSource.new(name)
147
+ bblock.set_sources(hash[:sources]) if hash.has_key?(:sources)
148
+ bblock.set_includes(hash[:includes]) if hash.has_key?(:includes)
149
+ all_blocks << bblock
150
+ end
151
+
152
+ end
@@ -0,0 +1,19 @@
1
+ require 'cxxproject/utils/dot/graph_writer'
2
+
3
+ class BuildingBlockGraphWriter < GraphWriter
4
+
5
+ private
6
+
7
+ def write_node(node)
8
+ @dotFile.write(" \"#{node.graph_name}\"\n")
9
+ end
10
+
11
+ def write_transition(node, dep)
12
+ @dotFile.write(" \"#{node.graph_name}\" -> \"#{dep.graph_name}\"\n")
13
+ end
14
+
15
+ def get_deps(node)
16
+ return node.dependencies.map { |depName| ALL_BUILDING_BLOCKS[depName] }
17
+ end
18
+
19
+ end
@@ -0,0 +1,53 @@
1
+ class GraphWriter
2
+
3
+ NO = 0
4
+ DETAIL = 1
5
+ YES = 2
6
+
7
+ def write_graph(filename,startNodes)
8
+ @filename = filename
9
+ start_graph
10
+ @writtenNodes = []
11
+ startNodes.each { |n| write_step(n) }
12
+ end_graph
13
+ end
14
+
15
+ private
16
+
17
+ def write_step(node)
18
+ return if @writtenNodes.include? node
19
+ @writtenNodes << node
20
+
21
+ write_node(node)
22
+
23
+ get_deps(node).each do |dep|
24
+ write_transition(node, dep)
25
+ write_step(dep)
26
+ end
27
+ end
28
+
29
+ def start_graph
30
+ puts "\nWriting dot-file #{@filename}...\n"
31
+ @dotFile = File.new(@filename, "w")
32
+ @dotFile.write("digraph TaskGraph\n");
33
+ @dotFile.write("{\n");
34
+ end
35
+
36
+ def end_graph
37
+ @dotFile.write("}\n");
38
+ @dotFile.close()
39
+ end
40
+
41
+ def write_node(node)
42
+ raise "Must be implemented by descendants"
43
+ end
44
+
45
+ def write_transition(node, dep)
46
+ raise "Must be implemented by descendants"
47
+ end
48
+
49
+ def get_deps(node)
50
+ raise "Must be implemented by descendants"
51
+ end
52
+
53
+ end
@@ -0,0 +1,34 @@
1
+ require 'cxxproject/utils/dot/graph_writer'
2
+
3
+ class TaskGraphWriter < GraphWriter
4
+
5
+ def write_graph(filename,startNodes,detailTasks = false)
6
+ @detailTasks = detailTasks ? GraphWriter::DETAIL : GraphWriter::YES
7
+ super(filename,startNodes)
8
+ end
9
+
10
+ private
11
+
12
+ def get_deps(node)
13
+ deps = []
14
+ if node.showInGraph == GraphWriter::YES
15
+ node.prerequisites.each do |p|
16
+ task = Rake.application.lookup(p)
17
+ if (task)
18
+ next if task.showInGraph < @detailTasks
19
+ deps << task
20
+ end
21
+ end
22
+ end
23
+ deps
24
+ end
25
+
26
+ def write_node(node)
27
+ @dotFile.write(" \"#{node.name}\"\n")
28
+ end
29
+
30
+ def write_transition(node, dep)
31
+ @dotFile.write(" \"#{node.name}\" -> \"#{dep.name}\"\n")
32
+ end
33
+
34
+ end