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.
- data/Rakefile.rb +55 -33
- data/bin/cxx +10 -0
- data/lib/cxxproject/buildingblocks/binary_library.rb +16 -0
- data/lib/cxxproject/buildingblocks/building_block.rb +93 -0
- data/lib/cxxproject/buildingblocks/command_line.rb +30 -0
- data/lib/cxxproject/buildingblocks/custom_building_block.rb +17 -0
- data/lib/cxxproject/buildingblocks/executable.rb +49 -0
- data/lib/cxxproject/buildingblocks/has_dependencies_mixin.rb +57 -0
- data/lib/cxxproject/buildingblocks/has_libraries_mixin.rb +35 -0
- data/lib/cxxproject/buildingblocks/has_sources_mixin.rb +85 -0
- data/lib/cxxproject/buildingblocks/makefile.rb +35 -0
- data/lib/cxxproject/buildingblocks/module.rb +14 -0
- data/lib/cxxproject/buildingblocks/single_source.rb +11 -0
- data/lib/cxxproject/buildingblocks/source_library.rb +31 -0
- data/lib/cxxproject/extensions/file_ext.rb +47 -0
- data/lib/cxxproject/extensions/rake_dirty_ext.rb +30 -0
- data/lib/cxxproject/extensions/rake_ext.rb +158 -0
- data/lib/cxxproject/extensions/rake_listener_ext.rb +53 -0
- data/lib/cxxproject/extensions/stdout_ext.rb +35 -0
- data/lib/cxxproject/extensions/string_ext.rb +9 -0
- data/lib/cxxproject/task_maker.rb +418 -0
- data/lib/cxxproject/testinstanceeval.rb +65 -0
- data/lib/cxxproject/toolchain/base.rb +98 -0
- data/lib/cxxproject/toolchain/diab.rb +47 -0
- data/lib/cxxproject/toolchain/gcc.rb +39 -0
- data/lib/cxxproject/toolchain/provider.rb +18 -0
- data/lib/cxxproject/torake/compiler.rb +10 -0
- data/lib/cxxproject/torake.rb +152 -0
- data/lib/cxxproject/utils/dot/building_block_graph_writer.rb +19 -0
- data/lib/cxxproject/utils/dot/graph_writer.rb +53 -0
- data/lib/cxxproject/utils/dot/task_graph_writer.rb +34 -0
- data/lib/cxxproject/utils/ubigraph.rb +237 -0
- data/lib/cxxproject/{utils.rb → utils/utils.rb} +19 -1
- data/lib/cxxproject.rb +13 -223
- data/lib/tools/Rakefile.rb.template +10 -0
- data/lib/tools/project.rb.template +6 -0
- data/lib/tools/projectWizard.rb +44 -0
- data/spec/build_dependencies_spec.rb +169 -0
- data/spec/building_block_spec.rb +12 -0
- data/spec/dir_spec.rb +13 -0
- data/spec/project_path_spec.rb +73 -0
- data/spec/rake_listener_ext_spec.rb +25 -0
- data/spec/string_spec.rb +11 -0
- data/spec/testdata/basic/exe12/project.rb +5 -0
- data/spec/testdata/basic/lib1/project.rb +5 -0
- data/spec/testdata/basic/lib2/project.rb +8 -0
- data/spec/testdata/multiple_levels/libs/lib1/project.rb +5 -0
- data/spec/testdata/multiple_levels/libs/lib2/project.rb +19 -0
- data/spec/testdata/multiple_levels/mainproject/basic/project.rb +8 -0
- data/spec/testdata/onlyOneHeader/Rakefile.rb +4 -0
- data/spec/testdata/onlyOneHeader/project.rb +4 -0
- metadata +83 -19
- data/lib/cxxproject/compiler.rb +0 -80
- data/lib/cxxproject/dependencies.rb +0 -41
- data/spec/dependencies_spec.rb +0 -19
- /data/lib/cxxproject/{gcccompiler.rb → torake/gcccompiler.rb} +0 -0
- /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,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
|