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
|