bake-toolkit 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+
@@ -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