bake-toolkit 1.0.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.
- data/Rakefile.rb +3 -0
- data/bin/bake +86 -0
- data/bin/bakery +234 -0
- data/lib/alias/loader.rb +56 -0
- data/lib/alias/model/language.rb +22 -0
- data/lib/alias/model/metamodel.rb +29 -0
- data/lib/bake/cache.rb +142 -0
- data/lib/bake/loader.rb +92 -0
- data/lib/bake/model/language.rb +46 -0
- data/lib/bake/model/metamodel.rb +226 -0
- data/lib/bake/model/metamodel_ext.rb +15 -0
- data/lib/bake/options.rb +288 -0
- data/lib/bake/subst.rb +90 -0
- data/lib/bake/util.rb +98 -0
- data/lib/bake/version.rb +30 -0
- data/lib/bakery/loader.rb +57 -0
- data/lib/bakery/model/language.rb +22 -0
- data/lib/bakery/model/metamodel.rb +44 -0
- data/lib/bakery/options.rb +98 -0
- data/lib/option/parser.rb +66 -0
- data/lib/tocxx.rb +883 -0
- data/license.txt +64 -0
- metadata +109 -0
data/lib/bake/subst.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
module Cxxproject
|
2
|
+
|
3
|
+
class Subst
|
4
|
+
|
5
|
+
def self.itute(config, projName, options)
|
6
|
+
|
7
|
+
@@configName = config.name
|
8
|
+
@@projName = projName
|
9
|
+
@@options = options
|
10
|
+
@@mainProjectName = File::basename(options.main_dir)
|
11
|
+
|
12
|
+
@@artifactName = ""
|
13
|
+
if Metamodel::ExecutableConfig === config
|
14
|
+
if not config.artifactName.nil?
|
15
|
+
@@artifactName = config.artifactName.name
|
16
|
+
elsif config.defaultToolchain != nil
|
17
|
+
basedOnToolchain = Cxxproject::Toolchain::Provider[config.defaultToolchain.basedOn]
|
18
|
+
if basedOnToolchain != nil
|
19
|
+
@@artifactName = projName+basedOnToolchain[:LINKER][:OUTPUT_ENDING]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
subst(config)
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.subst(elem)
|
28
|
+
elem.class.ecore.eAllAttributes_derived.each do |a|
|
29
|
+
next if a.name == "file_name" or a.name == "line_number"
|
30
|
+
next if a.eType.name != "EString"
|
31
|
+
str = elem.getGeneric(a.name)
|
32
|
+
|
33
|
+
posSubst = 0
|
34
|
+
substStr = ""
|
35
|
+
while (true)
|
36
|
+
posStart = str.index("$(", posSubst)
|
37
|
+
break if posStart.nil?
|
38
|
+
posEnd = str.index(")", posStart)
|
39
|
+
break if posEnd.nil?
|
40
|
+
substStr << str[posSubst..posStart-1] if posStart>0
|
41
|
+
|
42
|
+
var = str[posStart+2..posEnd-1]
|
43
|
+
|
44
|
+
if var == "MainConfigName"
|
45
|
+
substStr << @@options.build_config
|
46
|
+
elsif var == "MainProjectName"
|
47
|
+
substStr << @@mainProjectName
|
48
|
+
elsif var == "ConfigName"
|
49
|
+
substStr << @@configName
|
50
|
+
elsif var == "ProjectName"
|
51
|
+
substStr << @@projName
|
52
|
+
elsif var == "OutputDir"
|
53
|
+
if @@projName == @@mainProjectName
|
54
|
+
substStr << @@options.build_config
|
55
|
+
else
|
56
|
+
substStr << (@@options.build_config + "_" + @@mainProjectName)
|
57
|
+
end
|
58
|
+
elsif var == "Time"
|
59
|
+
substStr << Time.now.to_s
|
60
|
+
elsif var == "Hostname"
|
61
|
+
substStr << Socket.gethostname
|
62
|
+
elsif var == "ArtifactName"
|
63
|
+
substStr << @@artifactName
|
64
|
+
elsif var == "ArtifactNameBase"
|
65
|
+
substStr << @@artifactName.chomp(File.extname(@@artifactName))
|
66
|
+
elsif ENV[var]
|
67
|
+
substStr << ENV[var]
|
68
|
+
elsif var == "PATH_TO_CYGWIN" # allowed to be not set
|
69
|
+
substStr << ""
|
70
|
+
else
|
71
|
+
Printer.printError "Error: #{elem.file_name}(#{elem.line_number}): unknown substitution variable '$(#{var})'"
|
72
|
+
ExitHelper.exit(1)
|
73
|
+
end
|
74
|
+
|
75
|
+
posSubst = posEnd + 1
|
76
|
+
end
|
77
|
+
substStr << str[posSubst..-1]
|
78
|
+
|
79
|
+
elem.setGeneric(a.name, substStr)
|
80
|
+
end
|
81
|
+
|
82
|
+
childsRefs = elem.class.ecore.eAllReferences.select{|r| r.containment}
|
83
|
+
childsRefs.each do |c|
|
84
|
+
elem.getGenericAsArray(c.name).each { |child| subst(child) }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
data/lib/bake/util.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'bake/model/metamodel_ext'
|
2
|
+
require 'bake/model/metamodel'
|
3
|
+
require 'set'
|
4
|
+
require 'cxxproject/utils/printer'
|
5
|
+
require 'cxxproject/utils/exit_helper'
|
6
|
+
require 'cxxproject/utils/utils'
|
7
|
+
|
8
|
+
def adjustFlags(orgStr, flags)
|
9
|
+
orgSplitted = Cxxproject::Utils::flagSplit(orgStr)
|
10
|
+
|
11
|
+
flags.each do |f|
|
12
|
+
if f.overwrite != ""
|
13
|
+
orgSplitted = Cxxproject::Utils::flagSplit(f.overwrite)
|
14
|
+
end
|
15
|
+
|
16
|
+
if f.remove != ""
|
17
|
+
rmSplitted = Cxxproject::Utils::flagSplit(f.remove)
|
18
|
+
orgSplitted.delete_if {|o| rmSplitted.any? { |r|
|
19
|
+
begin
|
20
|
+
o.match("\\A"+r+"\\Z")
|
21
|
+
rescue Exception => e
|
22
|
+
Cxxproject::Printer.printError "Error: #{f.file_name}(#{f.line_number}): " + e.message
|
23
|
+
Cxxproject::ExitHelper.exit(1)
|
24
|
+
end
|
25
|
+
}}
|
26
|
+
end
|
27
|
+
|
28
|
+
if f.add != ""
|
29
|
+
Cxxproject::Utils::flagSplit(f.add).each do |a|
|
30
|
+
orgSplitted << a unless orgSplitted.any? { |o| o==a }
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
orgSplitted.join(" ")
|
37
|
+
end
|
38
|
+
|
39
|
+
def integrateToolchain(tcs, toolchain)
|
40
|
+
return tcs unless toolchain
|
41
|
+
|
42
|
+
integrateLinker(tcs, toolchain.linker) if toolchain.respond_to?"linker"
|
43
|
+
integrateArchiver(tcs, toolchain.archiver)
|
44
|
+
toolchain.compiler.each do |c|
|
45
|
+
integrateCompiler(tcs, c, c.ctype)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def integrateLinker(tcs, linker)
|
51
|
+
return tcs unless linker
|
52
|
+
tcs[:LINKER][:COMMAND] = linker.command if linker.command != ""
|
53
|
+
tcs[:LINKER][:FLAGS] = adjustFlags(tcs[:LINKER][:FLAGS], linker.flags)
|
54
|
+
tcs[:LINKER][:LIB_PREFIX_FLAGS] = adjustFlags(tcs[:LINKER][:LIB_PREFIX_FLAGS], linker.libprefixflags)
|
55
|
+
tcs[:LINKER][:LIB_POSTFIX_FLAGS] = adjustFlags(tcs[:LINKER][:LIB_POSTFIX_FLAGS], linker.libpostfixflags)
|
56
|
+
end
|
57
|
+
|
58
|
+
def integrateArchiver(tcs, archiver)
|
59
|
+
return tcs unless archiver
|
60
|
+
tcs[:ARCHIVER][:COMMAND] = archiver.command if archiver.command != ""
|
61
|
+
tcs[:ARCHIVER][:FLAGS] = adjustFlags(tcs[:ARCHIVER][:FLAGS], archiver.flags)
|
62
|
+
end
|
63
|
+
|
64
|
+
def integrateCompiler(tcs, compiler, type)
|
65
|
+
return tcs unless compiler
|
66
|
+
if compiler.respond_to?"command"
|
67
|
+
tcs[:COMPILER][type][:COMMAND] = compiler.command if compiler.command != ""
|
68
|
+
end
|
69
|
+
tcs[:COMPILER][type][:FLAGS] = adjustFlags(tcs[:COMPILER][type][:FLAGS], compiler.flags)
|
70
|
+
compiler.define.each do |d|
|
71
|
+
tcs[:COMPILER][type][:DEFINES] << d.str
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def integrateCompilerFile(tcs, compiler)
|
76
|
+
[:CPP, :C, :ASM].each do |t|
|
77
|
+
integrateCompiler(tcs, compiler, t)
|
78
|
+
end
|
79
|
+
return tcs
|
80
|
+
end
|
81
|
+
|
82
|
+
|
83
|
+
def sanitize_filename(filename)
|
84
|
+
filename.strip do |name|
|
85
|
+
# NOTE: File.basename doesn't work right with Windows paths on Unix
|
86
|
+
# get only the filename, not the whole path
|
87
|
+
name.gsub! /^.*(\\|\/)/, ''
|
88
|
+
|
89
|
+
# Finally, replace all non alphanumeric, underscore
|
90
|
+
# or periods with underscore
|
91
|
+
# name.gsub! /[^\w\.\-]/, '_'
|
92
|
+
# Basically strip out the non-ascii alphabets too
|
93
|
+
# and replace with x.
|
94
|
+
# You don't want all _ :)
|
95
|
+
name.gsub!(/[^0-9A-Za-z.\-]/, 'x')
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
data/lib/bake/version.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Cxxproject
|
2
|
+
class Version
|
3
|
+
def self.bake
|
4
|
+
"1.0.1"
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
expectedCxx = "0.5.59"
|
9
|
+
expectedRGen = "0.6.0"
|
10
|
+
expectedRText = "0.2.0"
|
11
|
+
|
12
|
+
begin
|
13
|
+
gem "cxxproject", "=#{expectedCxx}"
|
14
|
+
rescue Exception => e
|
15
|
+
puts "Warning: Failed to load cxxproject #{expectedCxx}, using latest version"
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
gem "rgen", "=#{expectedRGen}"
|
20
|
+
rescue Exception => e
|
21
|
+
puts "Warning: Failed to load rgen #{expectedRGen}, using latest version"
|
22
|
+
end
|
23
|
+
|
24
|
+
begin
|
25
|
+
gem "rtext", "=#{expectedRText}"
|
26
|
+
rescue Exception => e
|
27
|
+
puts "Warning: Failed to load rtext #{expectedRText}, using latest version"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'bakery/model/metamodel'
|
2
|
+
require 'bakery/model/language'
|
3
|
+
require 'bake/version'
|
4
|
+
|
5
|
+
require 'rgen/environment'
|
6
|
+
require 'rgen/fragment/fragmented_model'
|
7
|
+
|
8
|
+
require 'rtext/default_loader'
|
9
|
+
|
10
|
+
require 'cxxproject/utils/exit_helper'
|
11
|
+
require 'cxxproject/utils/printer'
|
12
|
+
|
13
|
+
module Cxxproject
|
14
|
+
|
15
|
+
class BakeryLoader
|
16
|
+
|
17
|
+
attr_reader :model
|
18
|
+
|
19
|
+
def initialize(options)
|
20
|
+
@env = RGen::Environment.new
|
21
|
+
@options = options
|
22
|
+
@model = RGen::Fragment::FragmentedModel.new(:env => @env)
|
23
|
+
end
|
24
|
+
|
25
|
+
def load(filename)
|
26
|
+
|
27
|
+
sumErrors = 0
|
28
|
+
|
29
|
+
if not File.exists?filename
|
30
|
+
Printer.printError "Error: #{filename} does not exist"
|
31
|
+
ExitHelper.exit(1)
|
32
|
+
end
|
33
|
+
|
34
|
+
loader = RText::DefaultLoader.new(
|
35
|
+
Cxxproject::BakeryLanguage,
|
36
|
+
@model,
|
37
|
+
:file_provider => proc { [filename] },
|
38
|
+
:cache => @DumpFileCache)
|
39
|
+
loader.load()
|
40
|
+
|
41
|
+
f = @model.fragments[0]
|
42
|
+
|
43
|
+
f.data[:problems].each do |p|
|
44
|
+
Printer.printError "Error: "+p.file+"("+p.line.to_s+"): "+p.message
|
45
|
+
end
|
46
|
+
|
47
|
+
if f.data[:problems].length > 0
|
48
|
+
ExitHelper.exit(1)
|
49
|
+
end
|
50
|
+
|
51
|
+
return @env
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'bake/model/metamodel'
|
2
|
+
require 'rtext/language'
|
3
|
+
|
4
|
+
module Cxxproject
|
5
|
+
|
6
|
+
BakeryLanguage =
|
7
|
+
RText::Language.new(BakeryModel.ecore,
|
8
|
+
:feature_provider => proc {|c|
|
9
|
+
RGen::Serializer::OppositeReferenceFilter.call(c.eAllStructuralFeatures).reject {|f|
|
10
|
+
f.eAnnotations.any? {|a|
|
11
|
+
a.details.any? {|d| d.key == 'internal' && d.value == 'true'}
|
12
|
+
}
|
13
|
+
}
|
14
|
+
},
|
15
|
+
:unlabled_arguments => proc {|c|
|
16
|
+
["name"]
|
17
|
+
},
|
18
|
+
:line_number_attribute => "line_number",
|
19
|
+
:file_name_attribute => "file_name"
|
20
|
+
)
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'rgen/metamodel_builder'
|
2
|
+
require 'rgen/metamodel_builder/data_types'
|
3
|
+
|
4
|
+
module Cxxproject
|
5
|
+
|
6
|
+
module BakeryModel
|
7
|
+
extend RGen::MetamodelBuilder::ModuleExtension
|
8
|
+
|
9
|
+
class ModelElement < RGen::MetamodelBuilder::MMBase
|
10
|
+
abstract
|
11
|
+
has_attr 'line_number', Integer do
|
12
|
+
annotation :details => {'internal' => 'true'}
|
13
|
+
end
|
14
|
+
has_attr 'file_name', String do
|
15
|
+
annotation :details => {'internal' => 'true'}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Project < ModelElement
|
20
|
+
has_attr 'name', String, :defaultValueLiteral => ""
|
21
|
+
has_attr 'config', String, :defaultValueLiteral => ""
|
22
|
+
end
|
23
|
+
class Exclude < ModelElement
|
24
|
+
has_attr 'name', String, :defaultValueLiteral => ""
|
25
|
+
has_attr 'config', String, :defaultValueLiteral => ""
|
26
|
+
end
|
27
|
+
class Collection < ModelElement
|
28
|
+
has_attr 'name', String, :defaultValueLiteral => ""
|
29
|
+
contains_many 'project', Project, 'collection'
|
30
|
+
contains_many 'exclude', Exclude, 'collection'
|
31
|
+
end
|
32
|
+
|
33
|
+
module Project::ClassModule
|
34
|
+
def isFound
|
35
|
+
@isFound ||= false
|
36
|
+
end
|
37
|
+
def found
|
38
|
+
@isFound = true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'cxxproject/utils/printer'
|
2
|
+
require "cxxproject/toolchain/colorizing_formatter"
|
3
|
+
require "option/parser"
|
4
|
+
|
5
|
+
module Cxxproject
|
6
|
+
|
7
|
+
class BakeryOptions < Parser
|
8
|
+
attr_reader :collection_name, :collection_dir # String
|
9
|
+
attr_reader :roots # String List
|
10
|
+
attr_reader :color, :error # Boolean
|
11
|
+
attr_reader :socket # Fixnum
|
12
|
+
|
13
|
+
def initialize(argv)
|
14
|
+
super(argv)
|
15
|
+
|
16
|
+
@collection_name = nil
|
17
|
+
@collection_dir = nil
|
18
|
+
@color = nil
|
19
|
+
@error = false
|
20
|
+
@roots = []
|
21
|
+
@socket = 0
|
22
|
+
@def_root = nil
|
23
|
+
|
24
|
+
add_option(Option.new("-b",true) { |x| set_collection_name(x) })
|
25
|
+
add_option(Option.new("-m",true) { |x| set_collection_dir(x) })
|
26
|
+
add_option(Option.new("-r",false) { set_error })
|
27
|
+
add_option(Option.new("-a",true) { |x| set_color(x) })
|
28
|
+
add_option(Option.new("-w",true) { |x| set_root(x) })
|
29
|
+
add_option(Option.new("--socket",true) { |x| set_socket(x) })
|
30
|
+
add_option(Option.new("-h",false) { usage; ExitHelper.exit(0) })
|
31
|
+
end
|
32
|
+
|
33
|
+
def usage
|
34
|
+
puts "\nUsage: bake [options]"
|
35
|
+
puts " -b <name> Name of the collection to build."
|
36
|
+
puts " -m <dir> Directory containing the collection file (default is current directory)."
|
37
|
+
puts " -r Stop on first error."
|
38
|
+
puts " -a <scheme> Use ansi color sequences (console must support it). Possible values are 'white' and 'black'."
|
39
|
+
puts " -h Print this help."
|
40
|
+
puts " -w <root> Add a workspace root (can be used multiple times)."
|
41
|
+
puts " If no root is specified, the parent directory of Collection.meta is added automatically."
|
42
|
+
puts " --socket <num> Set socket for sending errors, receiving commands, etc. - used by e.g. Eclipse."
|
43
|
+
puts "Note: all parameters except -b, -p and -h will be passed to bake - see bake help for more options."
|
44
|
+
end
|
45
|
+
|
46
|
+
def parse_options()
|
47
|
+
parse_internal(true)
|
48
|
+
set_collection_dir(Dir.pwd) if @collection_dir.nil?
|
49
|
+
@roots << @def_root if @roots.length == 0
|
50
|
+
end
|
51
|
+
|
52
|
+
def check_valid_dir(dir)
|
53
|
+
if not File.exists?(dir)
|
54
|
+
Printer.printError "Error: Directory #{dir} does not exist"
|
55
|
+
ExitHelper.exit(1)
|
56
|
+
end
|
57
|
+
if not File.directory?(dir)
|
58
|
+
Printer.printError "Error: #{dir} is not a directory"
|
59
|
+
ExitHelper.exit(1)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def set_collection_name(collection_name)
|
64
|
+
@collection_name = collection_name
|
65
|
+
end
|
66
|
+
|
67
|
+
def set_collection_dir(dir)
|
68
|
+
check_valid_dir(dir)
|
69
|
+
@collection_dir = File.expand_path(dir.gsub(/[\\]/,'/'))
|
70
|
+
@def_root = File.dirname(@collection_dir)
|
71
|
+
end
|
72
|
+
|
73
|
+
def set_color(x)
|
74
|
+
if (x != "black" and x != "white")
|
75
|
+
Printer.printError "Error: color scheme must be 'black' or 'white'"
|
76
|
+
ExitHelper.exit(1)
|
77
|
+
end
|
78
|
+
@color = x
|
79
|
+
ColorizingFormatter.enabled = true
|
80
|
+
ColorizingFormatter::setColorScheme(x.to_sym)
|
81
|
+
end
|
82
|
+
def set_error()
|
83
|
+
@error = true
|
84
|
+
end
|
85
|
+
|
86
|
+
def set_root(dir)
|
87
|
+
check_valid_dir(dir)
|
88
|
+
r = File.expand_path(dir.gsub(/[\\]/,'/'))
|
89
|
+
@roots << r if not @roots.include?r
|
90
|
+
end
|
91
|
+
|
92
|
+
def set_socket(num)
|
93
|
+
@socket = String === num ? num.to_i : num
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|