bake-toolkit 1.8.0.1 → 2.0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/bin/bake +14 -53
  3. data/bin/bakery +50 -43
  4. data/bin/createVSProjects +3 -3
  5. data/doc/cmd/install.html +1 -5
  6. data/doc/cmd/usecmd.html +29 -5
  7. data/doc/dyk/lint.html +21 -4
  8. data/doc/dyk/tipps.html +0 -6
  9. data/doc/eclipse/import.html +3 -1
  10. data/doc/eclipse/import/Import.png +0 -0
  11. data/doc/eclipse/use.html +8 -5
  12. data/doc/further/change.html +134 -1
  13. data/doc/further/issues.html +1 -0
  14. data/doc/further/wish.html +24 -21
  15. data/doc/index.html +1 -1
  16. data/doc/syntax/subst.html +8 -1
  17. data/doc/syntax/syntax.html +42 -14
  18. data/lib/bake/cache.rb +51 -59
  19. data/lib/bake/config/loader.rb +289 -0
  20. data/lib/bake/libElement.rb +134 -0
  21. data/lib/bake/mergeConfig.rb +1 -1
  22. data/lib/bake/model/language.rb +1 -1
  23. data/lib/bake/model/loader.rb +88 -0
  24. data/lib/bake/model/metamodel.rb +24 -16
  25. data/lib/bake/model/metamodel_ext.rb +9 -4
  26. data/lib/bake/options/options.rb +222 -0
  27. data/lib/bake/options/showConfigNames.rb +44 -0
  28. data/lib/bake/options/showDoc.rb +19 -0
  29. data/lib/bake/options/showLicense.rb +9 -0
  30. data/lib/bake/options/showToolchains.rb +39 -0
  31. data/lib/bake/options/usage.rb +54 -0
  32. data/lib/bake/process_output.rb +10 -0
  33. data/lib/bake/subst.rb +105 -40
  34. data/lib/bake/toolchain/clang.rb +44 -0
  35. data/lib/bake/toolchain/colorizing_formatter.rb +125 -0
  36. data/lib/bake/toolchain/diab.rb +53 -0
  37. data/lib/bake/toolchain/errorparser/diab_compiler_error_parser.rb +40 -0
  38. data/lib/bake/toolchain/errorparser/diab_linker_error_parser.rb +41 -0
  39. data/lib/bake/toolchain/errorparser/error_parser.rb +71 -0
  40. data/lib/bake/toolchain/errorparser/gcc_compiler_error_parser.rb +35 -0
  41. data/lib/bake/toolchain/errorparser/gcc_linker_error_parser.rb +35 -0
  42. data/lib/bake/toolchain/errorparser/greenhills_compiler_error_parser.rb +32 -0
  43. data/lib/bake/toolchain/errorparser/greenhills_linker_error_parser.rb +44 -0
  44. data/lib/bake/toolchain/errorparser/keil_compiler_error_parser.rb +40 -0
  45. data/lib/bake/toolchain/errorparser/keil_linker_error_parser.rb +30 -0
  46. data/lib/bake/toolchain/errorparser/lint_error_parser.rb +34 -0
  47. data/lib/bake/toolchain/errorparser/process_output.rb +3 -0
  48. data/lib/bake/toolchain/errorparser/ti_compiler_error_parser.rb +30 -0
  49. data/lib/bake/toolchain/errorparser/ti_linker_error_parser.rb +30 -0
  50. data/lib/bake/toolchain/gcc.rb +49 -0
  51. data/lib/bake/toolchain/gcc_param.rb +7 -0
  52. data/lib/bake/toolchain/greenhills.rb +52 -0
  53. data/lib/bake/toolchain/keil.rb +55 -0
  54. data/lib/bake/toolchain/lint.rb +20 -0
  55. data/lib/bake/toolchain/provider.rb +136 -0
  56. data/lib/bake/toolchain/ti.rb +47 -0
  57. data/lib/bake/util.rb +27 -15
  58. data/lib/bakery/buildPattern.rb +1 -1
  59. data/lib/bakery/model/language.rb +1 -1
  60. data/lib/bakery/model/loader.rb +56 -0
  61. data/lib/bakery/model/metamodel.rb +1 -1
  62. data/lib/bakery/options/options.rb +87 -0
  63. data/lib/bakery/toBake.rb +10 -6
  64. data/lib/blocks/block.rb +225 -0
  65. data/lib/blocks/blockBase.rb +155 -0
  66. data/lib/blocks/commandLine.rb +25 -0
  67. data/lib/blocks/compile.rb +382 -0
  68. data/lib/blocks/docu.rb +28 -0
  69. data/lib/blocks/executable.rb +143 -0
  70. data/lib/blocks/has_execute_command.rb +31 -0
  71. data/lib/blocks/library.rb +78 -0
  72. data/lib/blocks/lint.rb +53 -0
  73. data/lib/blocks/makefile.rb +87 -0
  74. data/lib/blocks/showIncludes.rb +114 -0
  75. data/lib/common/abortException.rb +4 -0
  76. data/lib/common/cleanup.rb +9 -0
  77. data/lib/common/exit_helper.rb +28 -0
  78. data/lib/common/ext/file.rb +88 -0
  79. data/lib/common/ext/stdout.rb +45 -0
  80. data/lib/common/ide_interface.rb +194 -0
  81. data/lib/common/options/option.rb +13 -0
  82. data/lib/common/options/parser.rb +59 -0
  83. data/lib/common/process.rb +64 -0
  84. data/lib/common/utils.rb +52 -0
  85. data/lib/{bake → common}/version.rb +3 -10
  86. data/lib/multithread/job.rb +44 -0
  87. data/lib/tocxx.rb +201 -932
  88. data/lib/vs/options.rb +3 -2
  89. data/license.txt +47 -22
  90. metadata +90 -30
  91. data/bin/bake-doc +0 -12
  92. data/lib/alias/loader.rb +0 -56
  93. data/lib/alias/model/language.rb +0 -22
  94. data/lib/alias/model/metamodel.rb +0 -29
  95. data/lib/bake/loader.rb +0 -92
  96. data/lib/bake/options.rb +0 -421
  97. data/lib/bakery/loader.rb +0 -57
  98. data/lib/bakery/options.rb +0 -105
  99. data/lib/option/parser.rb +0 -73
@@ -0,0 +1,25 @@
1
+ require 'blocks/has_execute_command'
2
+
3
+ module Bake
4
+ module Blocks
5
+
6
+ class CommandLine
7
+ include HasExecuteCommand
8
+
9
+ def initialize(config, referencedConfigs)
10
+ @config = config # Bake::Metamodel::CommandLine
11
+ @commandLine = config.name
12
+ @projectDir = config.get_project_dir
13
+ end
14
+
15
+ def execute
16
+ executeCommand(@commandLine)
17
+ end
18
+ def clean
19
+ # nothing to do here
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,382 @@
1
+ require 'blocks/blockBase'
2
+ require 'multithread/job'
3
+ require 'common/process'
4
+ require 'common/utils'
5
+ require 'bake/toolchain/colorizing_formatter'
6
+ require 'bake/config/loader'
7
+
8
+ module Bake
9
+
10
+ module Blocks
11
+
12
+ class Compile < BlockBase
13
+
14
+ attr_reader :objects, :include_list
15
+
16
+ def initialize(block, config, referencedConfigs, tcs)
17
+ super(block, config, referencedConfigs, tcs)
18
+ @objects = []
19
+
20
+ calcFileTcs
21
+ calcIncludes
22
+ calcDefines # not for files with changed tcs
23
+ calcFlags # not for files with changed tcs
24
+ end
25
+
26
+ def get_object_file(source)
27
+ adaptedSource = source.chomp(File.extname(source)).gsub(/\.\./, "##") + (Bake.options.prepro ? ".i" : ".o")
28
+ return adaptedSource if File.is_absolute?source
29
+ File.join([@output_dir, adaptedSource])
30
+ end
31
+
32
+ def needed?(source, object, type, dep_filename_conv)
33
+ return false if Bake.options.linkOnly
34
+
35
+ return "because prepro was specified" if Bake.options.prepro
36
+
37
+ return "because object does not exist" if not File.exist?(object)
38
+ oTime = File.mtime(object)
39
+
40
+ return "because config file has been changed" if oTime < File.mtime(@config.file_name)
41
+ return "Compiling #{source} because DefaultToolchain has been changed" if oTime < Bake::Config.defaultToolchainTime
42
+
43
+ return "because source is newer than object" if oTime < File.mtime(source)
44
+
45
+ if type != :ASM
46
+ return "because dependency file does not exist" if not File.exist?(dep_filename_conv)
47
+
48
+ begin
49
+ File.readlines(dep_filename_conv).map{|line| line.strip}.each do |dep|
50
+ return "because dependent header #{dep} does not exist" if not File.exist?(dep)
51
+ return "because dependent header #{dep} is newer than object" if oTime < File.mtime(dep)
52
+ end
53
+ rescue Exception => ex
54
+ if Bake.options.debug
55
+ puts "While reading #{dep_filename_conv}:"
56
+ puts ex.message
57
+ puts ex.backtrace
58
+ end
59
+ return "because dependency file could not be loaded"
60
+ end
61
+ end
62
+
63
+ false
64
+ end
65
+
66
+ def calcDepFile(object, type)
67
+ dep_filename = nil
68
+ if type != :ASM
69
+ dep_filename = object[0..-3] + ".d"
70
+ end
71
+ dep_filename
72
+ end
73
+
74
+ def calcDepFileConv(dep_filename)
75
+ dep_filename + ".bake"
76
+ end
77
+
78
+ def get_source_type(source)
79
+ ex = File.extname(source)
80
+ [:CPP, :C, :ASM].each do |t|
81
+ return t if @tcs[:COMPILER][t][:SOURCE_FILE_ENDINGS].include?(ex)
82
+ end
83
+ nil
84
+ end
85
+
86
+ def compileFile(source)
87
+ type = get_source_type(source)
88
+ return true if type.nil?
89
+
90
+ object = get_object_file(source)
91
+ @objects << object
92
+
93
+ dep_filename = calcDepFile(object, type)
94
+ dep_filename_conv = calcDepFileConv(dep_filename) if type != :ASM
95
+
96
+ reason = needed?(source, object, type, dep_filename_conv)
97
+ return true unless reason
98
+
99
+ if @fileTcs.include?(source)
100
+ compiler = @fileTcs[source][:COMPILER][type]
101
+ defines = getDefines(compiler)
102
+ flags = getFlags(compiler)
103
+ else
104
+ compiler = @tcs[:COMPILER][type]
105
+ defines = @define_array[type]
106
+ flags = @flag_array[type]
107
+ end
108
+ includes = @include_array[type]
109
+
110
+ if Bake.options.prepro and compiler[:PREPRO_FLAGS] == ""
111
+ Bake.formatter.printError("Error: No preprocessor option available for " + source)
112
+ raise SystemCommandFailed.new
113
+ end
114
+
115
+ prepareOutput(object)
116
+
117
+ cmd = Utils.flagSplit(compiler[:COMMAND], false)
118
+ cmd += compiler[:COMPILE_FLAGS].split(" ")
119
+
120
+ if dep_filename
121
+ cmd += @tcs[:COMPILER][type][:DEP_FLAGS].split(" ")
122
+ if @tcs[:COMPILER][type][:DEP_FLAGS_FILENAME]
123
+ if @tcs[:COMPILER][type][:DEP_FLAGS_SPACE]
124
+ cmd << dep_filename
125
+ else
126
+ if dep_filename.include?" "
127
+ cmd[cmd.length-1] << "\"" + dep_filename + "\""
128
+ else
129
+ cmd[cmd.length-1] << dep_filename
130
+ end
131
+
132
+ end
133
+ end
134
+ end
135
+
136
+ cmd += compiler[:PREPRO_FLAGS].split(" ") if Bake.options.prepro
137
+ cmd += flags
138
+ cmd += includes
139
+ cmd += defines
140
+
141
+ if compiler[:OBJ_FLAG_SPACE]
142
+ cmd << compiler[:OBJECT_FILE_FLAG]
143
+ cmd << object
144
+ else
145
+ if object.include?" "
146
+ cmd << compiler[:OBJECT_FILE_FLAG] + "\"" + object + "\""
147
+ else
148
+ cmd << compiler[:OBJECT_FILE_FLAG] + object
149
+ end
150
+ end
151
+ cmd << source
152
+
153
+ success, consoleOutput = ProcessHelper.run(cmd, false, false)
154
+ outputType = Bake.options.prepro ? "Preprocessing" : "Compiling"
155
+ process_result(cmd, consoleOutput, compiler[:ERROR_PARSER], "#{outputType} #{source}", reason, success)
156
+
157
+ Compile.convert_depfile(dep_filename, dep_filename_conv, @projectDir, @tcs[:COMPILER][:DEP_FILE_SINGLE_LINE]) if type != :ASM
158
+ check_config_file
159
+ end
160
+
161
+ def self.read_depfile(dep_filename, projDir, singeLine)
162
+ deps = []
163
+ begin
164
+ if singeLine
165
+ File.readlines(dep_filename).each do |line|
166
+ splitted = line.split(": ")
167
+ deps << splitted[1].gsub(/[\\]/,'/') if splitted.length > 1
168
+ end
169
+ else
170
+ deps_string = File.read(dep_filename)
171
+ deps_string = deps_string.gsub(/\\\n/,'')
172
+ dep_splitted = deps_string.split(/([^\\]) /).each_slice(2).map(&:join)[2..-1]
173
+ deps = dep_splitted.map { |d| d.gsub(/[\\] /,' ').gsub(/[\\]/,'/').strip }.delete_if {|d| d == "" }
174
+ end
175
+ rescue Exception
176
+ Bake.formatter.printWarning("Could not read '#{dep_filename}'", projDir)
177
+ return nil
178
+ end
179
+ deps
180
+ end
181
+
182
+ # todo: move to toolchain util file
183
+ def self.convert_depfile(dep_filename, dep_filename_conv, projDir, singleLine)
184
+ deps = read_depfile(dep_filename, projDir, singleLine)
185
+ if deps
186
+ begin
187
+ File.open(dep_filename_conv, 'wb') do |f|
188
+ deps.each do |dep|
189
+ f.puts(dep)
190
+ end
191
+ end
192
+ rescue Exception
193
+ Bake.formatter.printWarning("Could not write '#{dep_filename_conv}'", projDir)
194
+ return nil
195
+ end
196
+ end
197
+ end
198
+
199
+ def mutex
200
+ @mutex ||= Mutex.new
201
+ end
202
+
203
+ def execute
204
+ Dir.chdir(@projectDir) do
205
+
206
+ calcSources
207
+
208
+ @error_strings = {}
209
+
210
+ compileJobs = Multithread::Jobs.new(@source_files) do |jobs|
211
+ while source = jobs.get_next_or_nil do
212
+
213
+ if (jobs.failed and Bake.options.stopOnFirstError) or Bake::IDEInterface.instance.get_abort
214
+ break
215
+ end
216
+
217
+ s = StringIO.new
218
+ tmp = Thread.current[:stdout]
219
+ Thread.current[:stdout] = s unless tmp
220
+
221
+ result = false
222
+ begin
223
+ compileFile(source)
224
+ result = true
225
+ rescue Bake::SystemCommandFailed => scf # normal compilation error
226
+ rescue SystemExit => exSys
227
+ rescue Exception => ex1
228
+ if not Bake::IDEInterface.instance.get_abort
229
+ Bake.formatter.printError("Error: #{ex1.message}")
230
+ puts ex1.backtrace if Bake.options.debug
231
+ end
232
+ end
233
+
234
+ jobs.set_failed if not result
235
+
236
+ Thread.current[:stdout] = tmp
237
+
238
+ mutex.synchronize do
239
+ if s.string.length > 0
240
+ if Bake.options.stopOnFirstError and not result
241
+ @error_strings[source] = s.string
242
+ else
243
+ puts s.string
244
+ end
245
+ end
246
+ end
247
+
248
+ end
249
+ end
250
+ compileJobs.join
251
+
252
+ # can only happen in case of bail_on_first_error.
253
+ # if not sorted, it may be confusing when builing more than once and the order of the error appearances changes from build to build
254
+ # (it is not deterministic which file compilation finishes first)
255
+ @error_strings.sort.each {|es| puts es[1]}
256
+
257
+ raise SystemCommandFailed.new if compileJobs.failed
258
+
259
+ end
260
+ end
261
+
262
+ def clean
263
+ if Bake.options.filename
264
+ Dir.chdir(@projectDir) do
265
+ calcSources(true)
266
+ @source_files.each do |source|
267
+
268
+ type = get_source_type(source)
269
+ next if type.nil?
270
+ object = get_object_file(source)
271
+ dep_filename = calcDepFile(object, type)
272
+ if File.exist?object
273
+ puts "Deleting file #{object}" if Bake.options.verboseHigh
274
+ FileUtils.rm_rf(object)
275
+ end
276
+ if File.exist?dep_filename
277
+ puts "Deleting file #{dep_filename}" if Bake.options.verboseHigh
278
+ FileUtils.rm_rf(dep_filename)
279
+ end
280
+ end
281
+ end
282
+ end
283
+ end
284
+
285
+ def calcSources(cleaning = false)
286
+ @source_files = []
287
+
288
+ exclude_files = Set.new
289
+ @config.excludeFiles.each do |p|
290
+ Dir.glob(p.name).each {|f| exclude_files << f}
291
+ end
292
+
293
+ source_files = Set.new
294
+ @config.files.each do |sources|
295
+ p = sources.name
296
+ res = Dir.glob(p)
297
+ if res.length == 0 and cleaning == false
298
+ if not p.include?"*" and not p.include?"?"
299
+ Bake.formatter.printError("Source file '#{p}' not found", sources)
300
+ raise SystemCommandFailed.new
301
+ elsif not Bake.options.verboseLow
302
+ Bake.formatter.printInfo("Source file pattern '#{p}' does not match to any file", sources)
303
+ end
304
+ end
305
+ res.each do |f|
306
+ next if exclude_files.include?(f)
307
+ source_files << f
308
+ end
309
+ end
310
+
311
+ if Bake.options.filename
312
+ source_files.keep_if do |source|
313
+ source.include?Bake.options.filename
314
+ end
315
+ if source_files.length == 0 and cleaning == false
316
+ Bake.formatter.printInfo("#{Bake.options.filename} does not match to any source", @config)
317
+ end
318
+ end
319
+
320
+ @source_files = source_files.sort.to_a
321
+ end
322
+
323
+ def calcIncludes
324
+ @include_list = @config.includeDir.map do |dir|
325
+ (dir.name == "___ROOTS___") ? (Bake.options.roots.map { |r| File.rel_from_to_project(@projectDir,r,false) }) : @block.convPath(dir)
326
+ end.flatten
327
+
328
+ @include_array = {}
329
+ [:CPP, :C, :ASM].each do |type|
330
+ @include_array[type] = @include_list.map {|k| "#{@tcs[:COMPILER][type][:INCLUDE_PATH_FLAG]}#{k}"}
331
+ end
332
+ end
333
+
334
+ def getDefines(compiler)
335
+ compiler[:DEFINES].map {|k| "#{compiler[:DEFINE_FLAG]}#{k}"}
336
+ end
337
+
338
+ def getFlags(compiler)
339
+ Bake::Utils::flagSplit(compiler[:FLAGS],true)
340
+ end
341
+
342
+ def calcDefines
343
+ @define_array = {}
344
+ [:CPP, :C, :ASM].each do |type|
345
+ @define_array[type] = getDefines(@tcs[:COMPILER][type])
346
+ end
347
+ end
348
+ def calcFlags
349
+ @flag_array = {}
350
+ [:CPP, :C, :ASM].each do |type|
351
+ @flag_array[type] = getFlags(@tcs[:COMPILER][type])
352
+ end
353
+ end
354
+
355
+ def calcFileTcs
356
+ @fileTcs = {}
357
+ @config.files.each do |f|
358
+ if (f.define.length > 0 or f.flags.length > 0)
359
+ if f.name.include?"*"
360
+ Bake.formatter.printWarning("Toolchain settings not allowed for file pattern #{f.name}", f)
361
+ err_res = ErrorDesc.new
362
+ err_res.file_name = @config.file_name
363
+ err_res.line_number = f.line_number
364
+ err_res.severity = ErrorParser::SEVERITY_WARNING
365
+ err_res.message = "Toolchain settings not allowed for file patterns"
366
+ Bake::IDEInterface.instance.set_errors([err_res])
367
+ else
368
+ @fileTcs[f.name] = integrateCompilerFile(Utils.deep_copy(@tcs),f)
369
+ end
370
+ end
371
+ end
372
+ end
373
+
374
+ def tcs4source(source)
375
+ @fileTcs[source] || @tcs
376
+ end
377
+
378
+
379
+ end
380
+
381
+ end
382
+ end
@@ -0,0 +1,28 @@
1
+ require 'blocks/compile'
2
+
3
+ module Bake
4
+ module Blocks
5
+ class Docu
6
+ include HasExecuteCommand
7
+
8
+ def initialize(config, tcs)
9
+ @config = config # Bake::Metamodel::CommandLine
10
+ @commandLine = tcs[:DOCU]
11
+ @projectDir = config.get_project_dir
12
+ end
13
+
14
+ def execute
15
+ if @commandLine.empty?
16
+ Bake.formatter.printInfo("No documentation command specified", @config)
17
+ else
18
+ executeCommand(@commandLine)
19
+ end
20
+ end
21
+
22
+ def clean
23
+ # nothing to do here
24
+ end
25
+
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,143 @@
1
+ require 'blocks/blockBase'
2
+
3
+ module Bake
4
+
5
+ module Blocks
6
+
7
+ class Executable < BlockBase
8
+
9
+ def initialize(block, config, referencedConfigs, tcs, compileBlock)
10
+ super(block, config, referencedConfigs, tcs)
11
+ @compileBlock = compileBlock
12
+
13
+ calcArtifactName
14
+ calcMapFile
15
+ calcLinkerScript
16
+
17
+ end
18
+
19
+ def calcLinkerScript
20
+ @linker_script = @config.linkerScript.nil? ? nil : @block.convPath(@config.linkerScript)
21
+ end
22
+
23
+ def calcArtifactName
24
+ if not @config.artifactName.nil? and @config.artifactName.name != ""
25
+ baseFilename = @config.artifactName.name
26
+ else
27
+ baseFilename = "#{@projectName}#{@tcs[:LINKER][:OUTPUT_ENDING]}"
28
+ end
29
+ @exe_name ||= File.join([@output_dir, baseFilename])
30
+ end
31
+
32
+ def calcMapFile
33
+ @mapfile = nil
34
+ if (not Bake.options.docu) and (not Bake.options.lint) and (not @config.mapFile.nil?)
35
+ if @config.mapFile.name == ""
36
+ @mapfile = @exe_name.chomp(File.extname(@exe_name)) + ".map"
37
+ else
38
+ @mapfile = @config.mapFile.name
39
+ end
40
+ end
41
+ end
42
+
43
+ def depHasError(block)
44
+ block.dependencies.each do |dep|
45
+ subBlock = Blocks::ALL_BLOCKS[dep]
46
+ return true unless subBlock.result
47
+ return depHasError(subBlock)
48
+ end
49
+ return false
50
+ end
51
+
52
+ def needed?(libs)
53
+ return false if depHasError(@block)
54
+ return false if Bake.options.prepro
55
+ return "because linkOnly was specified" if Bake.options.linkOnly
56
+
57
+ # exe
58
+ return "because executable does not exist" if not File.exists?(@exe_name)
59
+
60
+ eTime = File.mtime(@exe_name)
61
+
62
+ # config
63
+ return "because config file has been changed" if eTime < File.mtime(@config.file_name)
64
+ return "because DefaultToolchain has been changed" if eTime < Bake::Config.defaultToolchainTime
65
+
66
+ # linkerscript
67
+ if @linker_script
68
+ return "because linker script does not exist - will most probably result in an error" if not File.exists?(@linker_script)
69
+ return "because linker script is newer than executable" if eTime < File.mtime(@linker_script)
70
+ end
71
+
72
+ # sources
73
+ @compileBlock.objects.each do |obj|
74
+ return "because object #{obj} does not exist" if not File.exists?(obj)
75
+ return "because object #{obj} is newer than executable" if eTime < File.mtime(obj)
76
+ end
77
+
78
+ # libs
79
+ libs.each do |lib|
80
+ return "because library #{lib} does not exist" if not File.exists?(lib)
81
+ return "because library #{lib} is newer than executable" if eTime < File.mtime(lib)
82
+ end
83
+ false
84
+ end
85
+
86
+ def execute
87
+
88
+ Dir.chdir(@projectDir) do
89
+
90
+ libs, linker_libs_array = LibElements.calc_linker_lib_string(@block, @tcs)
91
+
92
+ reason = needed?(libs)
93
+ return unless reason
94
+
95
+ prepareOutput(@exe_name)
96
+
97
+ linker = @tcs[:LINKER]
98
+
99
+ cmd = Utils.flagSplit(linker[:COMMAND], false) # g++
100
+ cmd += linker[:MUST_FLAGS].split(" ")
101
+ cmd += Bake::Utils::flagSplit(linker[:FLAGS],true)
102
+ cmd << linker[:EXE_FLAG]
103
+ cmd << @exe_name # -o debug/x.exe
104
+ cmd += @compileBlock.objects
105
+ cmd << linker[:SCRIPT] if @linker_script # -T
106
+ cmd << @linker_script if @linker_script # xy/xy.dld
107
+ cmd += linker[:MAP_FILE_FLAG].split(" ") if @mapfile # -Wl,-m6
108
+ if not linker[:MAP_FILE_PIPE] and @mapfile
109
+ cmd[cmd.length-1] << @mapfile
110
+ end
111
+ cmd += Bake::Utils::flagSplit(linker[:LIB_PREFIX_FLAGS],true) # "-Wl,--whole-archive "
112
+ cmd += linker_libs_array
113
+ cmd += Bake::Utils::flagSplit(linker[:LIB_POSTFIX_FLAGS],true) # "-Wl,--no-whole-archive "
114
+
115
+ mapfileStr = (@mapfile and linker[:MAP_FILE_PIPE]) ? " >#{@mapfile}" : ""
116
+
117
+ # pre print because linking can take much time
118
+ cmdLinePrint = cmd.dup
119
+ outPipe = (@mapfile and linker[:MAP_FILE_PIPE]) ? "#{@mapfile}" : nil
120
+ cmdLinePrint << "> #{outPipe}" if outPipe
121
+
122
+ printCmd(cmdLinePrint, "Linking #{@exe_name}", reason, false)
123
+ success, consoleOutput = ProcessHelper.run(cmd, false, false, outPipe)
124
+ process_result(cmdLinePrint, consoleOutput, linker[:ERROR_PARSER], nil, reason, success)
125
+
126
+ check_config_file()
127
+ end
128
+
129
+ end
130
+
131
+ def clean
132
+ Dir.chdir(@projectDir) do
133
+ if File.exist?@output_dir
134
+ puts "Deleting folder #{@output_dir}" if Bake.options.verboseHigh
135
+ FileUtils.rm_rf(@output_dir)
136
+ end
137
+ end unless Bake.options.filename
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+ end