cxxproject 0.6.30 → 0.6.31
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/README.md +14 -0
- data/lib/cxxproject.rb +3 -3
- data/lib/cxxproject/buildingblocks/building_block.rb +36 -6
- data/lib/cxxproject/buildingblocks/building_blocks.rb +7 -16
- data/lib/cxxproject/buildingblocks/command_line.rb +2 -2
- data/lib/cxxproject/buildingblocks/has_sources_mixin.rb +81 -63
- data/lib/cxxproject/buildingblocks/linkable.rb +395 -0
- data/lib/cxxproject/buildingblocks/makefile.rb +2 -2
- data/lib/cxxproject/buildingblocks/shared_libs_helper.rb +93 -0
- data/lib/cxxproject/buildingblocks/{source_library.rb → static_library.rb} +35 -22
- data/lib/cxxproject/context.rb +1 -1
- data/lib/cxxproject/ext/rake.rb +51 -29
- data/lib/cxxproject/plugin_context.rb +20 -2
- data/lib/cxxproject/toolchain/provider.rb +38 -13
- data/lib/cxxproject/toolchain/toolchain.rb +3 -0
- data/lib/cxxproject/utils/deprecated.rb +23 -0
- data/lib/cxxproject/utils/utils.rb +10 -4
- data/lib/cxxproject/version.rb +1 -1
- metadata +35 -38
- data/lib/cxxproject/buildingblocks/executable.rb +0 -227
- data/lib/cxxproject/ext/progressbar.rb +0 -20
- data/lib/cxxproject/ext/rake_listener.rb +0 -57
- data/lib/cxxproject/utils/progress.rb +0 -66
- data/lib/cxxproject/utils/progress_helper.rb +0 -77
- data/lib/cxxproject/utils/rbcurse.rb +0 -284
- data/lib/cxxproject/utils/ubigraph.rb +0 -228
data/README.md
CHANGED
@@ -3,6 +3,20 @@
|
|
3
3
|
|
4
4
|
see documentation page: [cxxproject](http://marcmo.github.com/cxxproject)
|
5
5
|
|
6
|
+
# teststrategy for plugins
|
7
|
+
|
8
|
+
each plugin should have unit-tests and acceptance-tests.
|
9
|
+
|
10
|
+
rake-task: spec
|
11
|
+
unit-tests should be able to run from source without preinstalled gems (apart from rspec).
|
12
|
+
|
13
|
+
rake-task: prepare_accept
|
14
|
+
should prepare the current gemset with all gems needed. usually this should build cxxproject, cxx and a toolchain and install those gems.
|
15
|
+
|
16
|
+
rake-task: accept
|
17
|
+
this should run with the gems that are installed by prepare_accept. this can be a whole build.
|
18
|
+
|
19
|
+
|
6
20
|
## Change History:
|
7
21
|
|
8
22
|
0.6.28 => 0.6.29
|
data/lib/cxxproject.rb
CHANGED
@@ -18,9 +18,9 @@ require 'cxxproject/buildingblocks/building_blocks'
|
|
18
18
|
require 'frazzle/frazzle'
|
19
19
|
registry = Frazzle::Registry.new('cxxproject', '_', '')
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
registry.load_plugin(
|
21
|
+
plugins = registry.get_all_plugins
|
22
|
+
plugins.each do |plugin|
|
23
|
+
registry.load_plugin(plugin, Cxxproject::PluginContext.create_no_args_context())
|
24
24
|
end
|
25
25
|
|
26
26
|
include Cxxproject::Toolchain
|
@@ -4,6 +4,7 @@ require 'cxxproject/ext/rake'
|
|
4
4
|
require 'cxxproject/ext/file'
|
5
5
|
require 'cxxproject/ide_interface'
|
6
6
|
require 'cxxproject/utils/printer'
|
7
|
+
require 'rake/clean'
|
7
8
|
|
8
9
|
# no deprecated warning for rake >= 0.9.x
|
9
10
|
include Rake::DSL if defined?(Rake::DSL)
|
@@ -12,6 +13,32 @@ module Cxxproject
|
|
12
13
|
# stores all defined buildingblocks by name (the name should be unique)
|
13
14
|
ALL_BUILDING_BLOCKS = {}
|
14
15
|
|
16
|
+
def self.sorted_building_blocks
|
17
|
+
todo = ALL_BUILDING_BLOCKS.keys.dup
|
18
|
+
res = []
|
19
|
+
while not todo.empty?
|
20
|
+
bb = resolve_by_name(todo.pop)
|
21
|
+
add_unique(res, bb)
|
22
|
+
todo += bb.dependencies
|
23
|
+
end
|
24
|
+
return res.reverse
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.resolve_by_name(name)
|
28
|
+
res = ALL_BUILDING_BLOCKS[name]
|
29
|
+
raise "BuildingBlock #{name} not defined" unless res
|
30
|
+
res
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.add_unique(res, bb)
|
34
|
+
res.delete(bb)
|
35
|
+
res.push(bb)
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.find_by_tag(tag)
|
39
|
+
ALL_BUILDING_BLOCKS.values.find_all{|o|o.tags.include?(tag)}
|
40
|
+
end
|
41
|
+
|
15
42
|
trap("INT") do
|
16
43
|
Rake.application.idei.set_abort(true)
|
17
44
|
end
|
@@ -27,6 +54,7 @@ module Cxxproject
|
|
27
54
|
attr_accessor :output_dir
|
28
55
|
attr_accessor :pre_step
|
29
56
|
attr_reader :output_dir_abs
|
57
|
+
attr_accessor :tags
|
30
58
|
|
31
59
|
def set_name(x)
|
32
60
|
@name = x
|
@@ -164,10 +192,10 @@ module Cxxproject
|
|
164
192
|
|
165
193
|
def printCmd(cmd, alternate, showPath)
|
166
194
|
@lastCommand = cmd
|
167
|
-
if showPath or RakeFileUtils.verbose or (alternate.nil? and not Rake::application.options.silent)
|
195
|
+
if showPath or (RakeFileUtils.verbose == true) or (alternate.nil? and not Rake::application.options.silent)
|
168
196
|
@printedCmdAlternate = false
|
169
197
|
exedIn = ""
|
170
|
-
exedIn = " (executed in '#{@project_dir}')" if (showPath or RakeFileUtils.verbose)
|
198
|
+
exedIn = " (executed in '#{@project_dir}')" if (showPath or (RakeFileUtils.verbose == true))
|
171
199
|
puts "" if Rake::application.addEmptyLine
|
172
200
|
if cmd.is_a?(Array)
|
173
201
|
puts cmd.join(' ') + exedIn
|
@@ -214,12 +242,11 @@ module Cxxproject
|
|
214
242
|
end
|
215
243
|
end
|
216
244
|
|
217
|
-
def typed_file_task(type,
|
218
|
-
t = file
|
245
|
+
def typed_file_task(type, hash, &block)
|
246
|
+
t = file hash do
|
219
247
|
block.call
|
220
248
|
end
|
221
249
|
t.type = type
|
222
|
-
t.progress_count = 1
|
223
250
|
return t
|
224
251
|
end
|
225
252
|
|
@@ -249,6 +276,9 @@ module Cxxproject
|
|
249
276
|
end
|
250
277
|
end
|
251
278
|
|
252
|
-
|
279
|
+
def additional_path_components
|
280
|
+
[]
|
281
|
+
end
|
282
|
+
end # class BuildingBlock
|
253
283
|
|
254
284
|
end
|
@@ -1,19 +1,10 @@
|
|
1
|
-
require 'cxxproject/buildingblocks/binary_library'
|
2
1
|
require 'cxxproject/buildingblocks/building_block'
|
3
|
-
require 'cxxproject/buildingblocks/executable'
|
4
|
-
require 'cxxproject/buildingblocks/source_library'
|
5
2
|
require 'cxxproject/buildingblocks/module'
|
3
|
+
require 'cxxproject/buildingblocks/makefile'
|
4
|
+
require 'cxxproject/buildingblocks/linkable'
|
5
|
+
require 'cxxproject/buildingblocks/static_library'
|
6
|
+
require 'cxxproject/buildingblocks/single_source'
|
7
|
+
require 'cxxproject/buildingblocks/binary_library'
|
6
8
|
require 'cxxproject/buildingblocks/custom_building_block'
|
7
|
-
|
8
|
-
|
9
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 688 Jul 10 15:12 custom_building_block.rb
|
10
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 7241 Jul 18 11:51 executable.rb
|
11
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 2047 Jul 10 15:12 has_dependencies_mixin.rb
|
12
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 297 Jul 10 15:12 has_includes_mixin.rb
|
13
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 792 Jul 10 15:12 has_libraries_mixin.rb
|
14
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 10084 Jul 18 12:24 has_sources_mixin.rb
|
15
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 4034 Jul 10 15:12 makefile.rb
|
16
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 775 Jul 10 15:12 module.rb
|
17
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 811 Jul 10 15:12 single_source.rb
|
18
|
-
-rw-rw-r-- 2 ckoestlin ckoestlin 3582 Jul 18 12:23 source_library.rb
|
19
|
-
=end
|
9
|
+
require 'cxxproject/buildingblocks/command_line'
|
10
|
+
|
@@ -47,7 +47,7 @@ module Cxxproject
|
|
47
47
|
Dir.chdir(@project_dir) do
|
48
48
|
check_config_file
|
49
49
|
cmd = get_command_line
|
50
|
-
puts cmd + (RakeFileUtils.verbose ? " (executed in '#{@project_dir}')" : "")
|
50
|
+
puts cmd + ((RakeFileUtils.verbose == true) ? " (executed in '#{@project_dir}')" : "")
|
51
51
|
cmd_result = false
|
52
52
|
begin
|
53
53
|
cmd_result = ProcessHelper.spawnProcess(cmd + " 2>&1")
|
@@ -62,7 +62,7 @@ module Cxxproject
|
|
62
62
|
err_res.message = "Command \"#{get_command_line}\" failed"
|
63
63
|
Rake.application.idei.set_errors([err_res])
|
64
64
|
end
|
65
|
-
Printer.printError "Error: command \"#{get_command_line}\" failed" + (RakeFileUtils.verbose ? "" : " (executed in '#{@project_dir}')")
|
65
|
+
Printer.printError "Error: command \"#{get_command_line}\" failed" + ((RakeFileUtils.verbose == true) ? "" : " (executed in '#{@project_dir}')")
|
66
66
|
raise SystemCommandFailed.new
|
67
67
|
end
|
68
68
|
end
|
@@ -85,7 +85,7 @@ module Cxxproject
|
|
85
85
|
if BinaryLibrary === d
|
86
86
|
@incArray.concat(d.includes)
|
87
87
|
else
|
88
|
-
prefix = File.rel_from_to_project(@project_dir,d.project_dir)
|
88
|
+
prefix = File.rel_from_to_project(@project_dir, d.project_dir)
|
89
89
|
next if not prefix
|
90
90
|
@incArray.concat(d.includes.map {|inc| File.add_prefix(prefix,inc)})
|
91
91
|
end
|
@@ -189,7 +189,8 @@ module Cxxproject
|
|
189
189
|
end
|
190
190
|
end
|
191
191
|
|
192
|
-
|
192
|
+
# returns a hash from all sources to the toolchain that should be used for a source
|
193
|
+
def collect_sources_and_toolchains
|
193
194
|
sources_to_build = {}
|
194
195
|
|
195
196
|
exclude_files = Set.new
|
@@ -217,26 +218,33 @@ module Cxxproject
|
|
217
218
|
end
|
218
219
|
add_to_sources_to_build(sources_to_build, exclude_files, globRes, tcs4source(p))
|
219
220
|
end
|
221
|
+
return sources_to_build
|
222
|
+
end
|
220
223
|
|
221
|
-
|
222
|
-
|
223
|
-
no_sources_found() if sources_to_build.empty?
|
224
|
-
|
225
|
-
dirs = []
|
224
|
+
# calcs a map from unique directories to array of sources within this dir
|
225
|
+
def calc_dirs_with_files(sources)
|
226
226
|
filemap = {}
|
227
|
-
|
227
|
+
sources.keys.sort.reverse.each do |o|
|
228
228
|
d = File.dirname(o)
|
229
229
|
if filemap.include?(d)
|
230
230
|
filemap[d] << o
|
231
231
|
else
|
232
232
|
filemap[d] = [o]
|
233
|
-
dirs << d
|
234
233
|
end
|
235
234
|
end
|
235
|
+
return filemap
|
236
|
+
end
|
237
|
+
|
238
|
+
def create_object_file_tasks()
|
239
|
+
sources_to_build = collect_sources_and_toolchains()
|
240
|
+
no_sources_found() if sources_to_build.empty?
|
241
|
+
|
242
|
+
dirs_with_files = calc_dirs_with_files(sources_to_build)
|
236
243
|
|
237
244
|
obj_tasks = []
|
238
|
-
|
239
|
-
|
245
|
+
@objects = []
|
246
|
+
dirs_with_files.each do |dir, files|
|
247
|
+
files.reverse.each do |f|
|
240
248
|
obj_task = create_object_file_task(f, sources_to_build[f])
|
241
249
|
obj_tasks << obj_task unless obj_task.nil?
|
242
250
|
end
|
@@ -244,73 +252,83 @@ module Cxxproject
|
|
244
252
|
obj_tasks
|
245
253
|
end
|
246
254
|
|
247
|
-
def
|
248
|
-
if !File.exists?(
|
249
|
-
raise "File '#{
|
255
|
+
def calc_command_line_for_source(source, toolchain)
|
256
|
+
if !File.exists?(source)
|
257
|
+
raise "File '#{source}' not found"
|
250
258
|
end
|
251
|
-
|
252
|
-
|
253
|
-
sourceRel = File.rel_from_to_project(@project_dir, sourceRel, false)
|
259
|
+
if File.is_absolute?(source)
|
260
|
+
source = File.rel_from_to_project(@project_dir, source, false)
|
254
261
|
end
|
255
262
|
|
256
|
-
type = get_source_type(
|
257
|
-
raise "Unknown filetype for #{
|
263
|
+
type = get_source_type(source)
|
264
|
+
raise "Unknown filetype for #{source}" unless type
|
265
|
+
|
266
|
+
object = get_object_file(source)
|
267
|
+
object_path = File.expand_path(object)
|
268
|
+
source_path = File.expand_path(source)
|
258
269
|
|
259
|
-
|
260
|
-
@objects << objectRel
|
261
|
-
object = File.expand_path(objectRel)
|
262
|
-
source = File.expand_path(sourceRel)
|
270
|
+
@objects << object
|
263
271
|
|
264
272
|
depStr = ""
|
265
273
|
dep_file = nil
|
266
274
|
if type != :ASM
|
267
|
-
dep_file = get_dep_file(
|
275
|
+
dep_file = get_dep_file(object)
|
268
276
|
dep_file = "\""+dep_file+"\"" if dep_file.include?(" ")
|
269
|
-
depStr =
|
277
|
+
depStr = toolchain[:COMPILER][type][:DEP_FLAGS]
|
270
278
|
end
|
271
279
|
|
272
|
-
|
273
|
-
|
280
|
+
compiler = toolchain[:COMPILER][type]
|
281
|
+
i_array = toolchain == @tcs ? @include_string[type] : get_include_string(toolchain, type)
|
282
|
+
d_array = toolchain == @tcs ? @define_string[type] : get_define_string(toolchain, type)
|
274
283
|
|
275
|
-
|
276
|
-
|
284
|
+
cmd = [compiler[:COMMAND]].flatten
|
285
|
+
cmd += compiler[:COMPILE_FLAGS].split(" ")
|
286
|
+
if dep_file
|
287
|
+
cmd += depStr.split(" ")
|
288
|
+
if toolchain[:COMPILER][type][:DEP_FLAGS_SPACE]
|
289
|
+
cmd << dep_file
|
277
290
|
else
|
291
|
+
cmd[cmd.length-1] << dep_file
|
292
|
+
end
|
293
|
+
end
|
294
|
+
cmd += compiler[:FLAGS]
|
295
|
+
cmd += additional_object_file_flags
|
296
|
+
cmd += i_array
|
297
|
+
cmd += d_array
|
298
|
+
cmd += (compiler[:OBJECT_FILE_FLAG] + object).split(" ")
|
299
|
+
cmd += compiler[:PREPRO_FLAGS].split(" ") if Rake::application.preproFlags
|
300
|
+
cmd << source
|
301
|
+
return [cmd, source_path, object, object_path, compiler, type]
|
302
|
+
end
|
278
303
|
|
279
|
-
|
280
|
-
|
304
|
+
def additional_object_file_flags
|
305
|
+
[]
|
306
|
+
end
|
281
307
|
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
consoleOutput = ProcessHelper.readOutput(sp, rd, wr)
|
307
|
-
|
308
|
-
process_result(cmd, consoleOutput, compiler[:ERROR_PARSER], "Compiling #{sourceRel}")
|
309
|
-
|
310
|
-
convert_depfile(dep_file) if dep_file
|
311
|
-
|
312
|
-
check_config_file()
|
313
|
-
end
|
308
|
+
def create_object_file_task(sourceRel, the_tcs)
|
309
|
+
cmd, source, object, object_path, compiler, type = calc_command_line_for_source(sourceRel, the_tcs)
|
310
|
+
depStr = ""
|
311
|
+
dep_file = nil
|
312
|
+
if type != :ASM
|
313
|
+
dep_file = get_dep_file(object)
|
314
|
+
dep_file = "\""+dep_file+"\"" if dep_file.include?(" ")
|
315
|
+
depStr = compiler[:DEP_FLAGS]
|
316
|
+
end
|
317
|
+
res = typed_file_task Rake::Task::OBJECT, object_path=> source do
|
318
|
+
rd, wr = IO.pipe
|
319
|
+
cmd << {
|
320
|
+
:err=>wr,
|
321
|
+
:out=>wr
|
322
|
+
}
|
323
|
+
sp = spawn(*cmd)
|
324
|
+
cmd.pop
|
325
|
+
consoleOutput = ProcessHelper.readOutput(sp, rd, wr)
|
326
|
+
|
327
|
+
process_result(cmd, consoleOutput, compiler[:ERROR_PARSER], "Compiling #{sourceRel}")
|
328
|
+
|
329
|
+
convert_depfile(dep_file) if dep_file
|
330
|
+
|
331
|
+
check_config_file()
|
314
332
|
end
|
315
333
|
enhance_with_additional_files(res)
|
316
334
|
add_output_dir_dependency(object, res, false)
|
@@ -0,0 +1,395 @@
|
|
1
|
+
require 'cxxproject/buildingblocks/building_block'
|
2
|
+
require 'cxxproject/buildingblocks/has_libraries_mixin'
|
3
|
+
require 'cxxproject/buildingblocks/has_sources_mixin'
|
4
|
+
require 'cxxproject/buildingblocks/has_includes_mixin'
|
5
|
+
require 'cxxproject/utils/process'
|
6
|
+
require 'cxxproject/utils/utils'
|
7
|
+
require 'cxxproject/ext/stdout'
|
8
|
+
|
9
|
+
require 'tmpdir'
|
10
|
+
require 'set'
|
11
|
+
require 'etc'
|
12
|
+
|
13
|
+
module Cxxproject
|
14
|
+
|
15
|
+
class Linkable < BuildingBlock
|
16
|
+
include HasLibraries
|
17
|
+
include HasSources
|
18
|
+
include HasIncludes
|
19
|
+
|
20
|
+
def set_linker_script(x)
|
21
|
+
@linker_script = x
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def set_mapfile(x)
|
26
|
+
@mapfile = x
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(name)
|
31
|
+
super(name)
|
32
|
+
@linker_script = nil
|
33
|
+
@mapfile = nil
|
34
|
+
end
|
35
|
+
|
36
|
+
def set_executable_name(name) # ensure it's relative
|
37
|
+
@exe_name = name
|
38
|
+
end
|
39
|
+
|
40
|
+
def get_output_name(linker)
|
41
|
+
prefix = get_output_prefix(linker)
|
42
|
+
suffix = get_output_suffix(linker)
|
43
|
+
return "#{prefix}#{name}#{suffix}"
|
44
|
+
end
|
45
|
+
def executable_name() # relative path OK
|
46
|
+
return @exe_name if @exe_name
|
47
|
+
|
48
|
+
parts = [@output_dir]
|
49
|
+
|
50
|
+
if @output_dir_abs
|
51
|
+
parts = [@output_dir_relPath] if @output_dir_relPath
|
52
|
+
parts += additional_path_components()
|
53
|
+
end
|
54
|
+
linker = @tcs[:LINKER]
|
55
|
+
parts << get_output_name(linker)
|
56
|
+
|
57
|
+
@exe_name = File.join(parts)
|
58
|
+
@exe_name
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_task_name() # full path
|
62
|
+
@project_dir + "/" + executable_name # OK
|
63
|
+
end
|
64
|
+
|
65
|
+
def collect_unique(array, set)
|
66
|
+
ret = []
|
67
|
+
array.each do |v|
|
68
|
+
if set.add?(v)
|
69
|
+
ret << v
|
70
|
+
end
|
71
|
+
end
|
72
|
+
ret
|
73
|
+
end
|
74
|
+
|
75
|
+
def adapt_path(v, d, prefix)
|
76
|
+
tmp = nil
|
77
|
+
if File.is_absolute?(v)
|
78
|
+
tmp = v
|
79
|
+
else
|
80
|
+
prefix ||= File.rel_from_to_project(@project_dir, d.project_dir)
|
81
|
+
tmp = File.add_prefix(prefix, v)
|
82
|
+
end
|
83
|
+
[tmp, prefix]
|
84
|
+
end
|
85
|
+
|
86
|
+
def deps # OK
|
87
|
+
if @deps == nil
|
88
|
+
@deps = collect_dependencies
|
89
|
+
end
|
90
|
+
@deps
|
91
|
+
end
|
92
|
+
|
93
|
+
def cmd_lib_string(target_os)
|
94
|
+
libraries=''
|
95
|
+
deps.each do |d|
|
96
|
+
if HasLibraries === d
|
97
|
+
d.lib_elements.each do |elem|
|
98
|
+
case elem[0]
|
99
|
+
when HasLibraries::SEARCH_PATH
|
100
|
+
tmp, prefix = adapt_path(elem[1], d, prefix)
|
101
|
+
libraries << tmp
|
102
|
+
libraries << File::PATH_SEPARATOR
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
libraries
|
108
|
+
end
|
109
|
+
|
110
|
+
def linker_lib_string(target_os, linker)
|
111
|
+
lib_path_set = Set.new
|
112
|
+
res = []
|
113
|
+
deps.each do |d|
|
114
|
+
handle_whole_archive(d, res, linker, linker[:START_OF_WHOLE_ARCHIVE][target_os])
|
115
|
+
if HasLibraries === d and d != self #OK
|
116
|
+
d.lib_elements.each do |elem|
|
117
|
+
case elem[0]
|
118
|
+
when HasLibraries::LIB
|
119
|
+
if not is_whole_archive(d)
|
120
|
+
res.push("#{linker[:LIB_FLAG]}#{elem[1]}")
|
121
|
+
end
|
122
|
+
when HasLibraries::USERLIB
|
123
|
+
res.push("#{linker[:USER_LIB_FLAG]}#{elem[1]}")
|
124
|
+
when HasLibraries::LIB_WITH_PATH
|
125
|
+
if is_whole_archive(d)
|
126
|
+
res.push(d.get_archive_name)
|
127
|
+
else
|
128
|
+
tmp, prefix = adapt_path(elem[1], d, prefix)
|
129
|
+
res.push(tmp)
|
130
|
+
end
|
131
|
+
when HasLibraries::SEARCH_PATH
|
132
|
+
if is_whole_archive(d)
|
133
|
+
res.push(d.get_archive_name)
|
134
|
+
else
|
135
|
+
tmp, prefix = adapt_path(elem[1], d, prefix)
|
136
|
+
if not lib_path_set.include?(tmp)
|
137
|
+
lib_path_set << tmp
|
138
|
+
res.push("#{linker[:LIB_PATH_FLAG]}#{tmp}")
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
handle_whole_archive(d, res, linker, linker[:END_OF_WHOLE_ARCHIVE][target_os])
|
145
|
+
end
|
146
|
+
res
|
147
|
+
end
|
148
|
+
|
149
|
+
# res the array with command line arguments that is used as result
|
150
|
+
# linker the linker hash
|
151
|
+
# sym the symbol that is used to fish out a value from the linker
|
152
|
+
def handle_whole_archive(building_block, res, linker, flag)
|
153
|
+
if is_whole_archive(building_block)
|
154
|
+
res.push(flag) if flag and !flag.empty?
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def is_whole_archive(building_block)
|
159
|
+
return building_block.instance_of?(StaticLibrary) && building_block.whole_archive
|
160
|
+
end
|
161
|
+
|
162
|
+
def calc_command_line
|
163
|
+
linker = @tcs[:LINKER]
|
164
|
+
cmd = [linker[:COMMAND]] # g++
|
165
|
+
cmd += linker[:MUST_FLAGS].split(" ")
|
166
|
+
cmd += linker[:FLAGS]
|
167
|
+
cmd += get_flags_for_output(linker)
|
168
|
+
cmd << executable_name() # debug/x.exe # OK
|
169
|
+
cmd += @objects
|
170
|
+
cmd << linker[:SCRIPT] if @linker_script # -T
|
171
|
+
cmd << @linker_script if @linker_script # xy/xy.dld
|
172
|
+
cmd << linker[:MAP_FILE_FLAG] if @mapfile # -Wl,-m6
|
173
|
+
cmd += linker[:LIB_PREFIX_FLAGS].split(" ") # TODO ... is this still needed e.g. for diab
|
174
|
+
cmd += linker_lib_string(target_os(), @tcs[:LINKER])
|
175
|
+
cmd += linker[:LIB_POSTFIX_FLAGS].split(" ") # TODO ... is this still needed e.g. for diab
|
176
|
+
cmd
|
177
|
+
end
|
178
|
+
|
179
|
+
# create a task that will link an executable from a set of object files
|
180
|
+
#
|
181
|
+
def convert_to_rake()
|
182
|
+
object_multitask = prepare_tasks_for_objects()
|
183
|
+
|
184
|
+
res = typed_file_task get_rake_task_type(), get_task_name => object_multitask do
|
185
|
+
cmd = calc_command_line
|
186
|
+
Dir.chdir(@project_dir) do
|
187
|
+
mapfileStr = @mapfile ? " >#{@mapfile}" : ""
|
188
|
+
rd, wr = IO.pipe
|
189
|
+
cmdLinePrint = cmd
|
190
|
+
printCmd(cmdLinePrint, "Linking #{executable_name}", false) #OK
|
191
|
+
cmd << {
|
192
|
+
:out=> @mapfile ? "#{@mapfile}" : wr, # > xy.map
|
193
|
+
:err=>wr
|
194
|
+
}
|
195
|
+
sp = spawn(*cmd)
|
196
|
+
cmd.pop
|
197
|
+
# for console print
|
198
|
+
cmd << " >#{@mapfile}" if @mapfile
|
199
|
+
consoleOutput = ProcessHelper.readOutput(sp, rd, wr)
|
200
|
+
|
201
|
+
process_result(cmdLinePrint, consoleOutput, @tcs[:LINKER][:ERROR_PARSER], nil)
|
202
|
+
check_config_file()
|
203
|
+
post_link_hook(@tcs[:LINKER])
|
204
|
+
end
|
205
|
+
end
|
206
|
+
res.tags = tags
|
207
|
+
res.immediate_output = true
|
208
|
+
res.enhance(@config_files)
|
209
|
+
res.enhance([@project_dir + "/" + @linker_script]) if @linker_script
|
210
|
+
|
211
|
+
add_output_dir_dependency(get_task_name, res, true)
|
212
|
+
add_grouping_tasks(get_task_name)
|
213
|
+
setup_rake_dependencies(res, object_multitask)
|
214
|
+
|
215
|
+
# check that all source libs are checked even if they are not a real rake dependency (can happen if "build this project only")
|
216
|
+
begin
|
217
|
+
libChecker = task get_task_name+"LibChecker" do
|
218
|
+
if File.exists?(get_task_name) # otherwise the task will be executed anyway
|
219
|
+
all_dependencies.each do |bb|
|
220
|
+
if bb and StaticLibrary === bb
|
221
|
+
f = bb.get_task_name # = abs path of library
|
222
|
+
if not File.exists?(f) or File.mtime(f) > File.mtime(get_task_name)
|
223
|
+
def res.needed?
|
224
|
+
true
|
225
|
+
end
|
226
|
+
break
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
rescue
|
233
|
+
def res.needed?
|
234
|
+
true
|
235
|
+
end
|
236
|
+
end
|
237
|
+
libChecker.transparent_timestamp = true
|
238
|
+
res.enhance([libChecker])
|
239
|
+
|
240
|
+
return res
|
241
|
+
end
|
242
|
+
|
243
|
+
def create_run_task(executable, name)
|
244
|
+
namespace 'run' do
|
245
|
+
desc "run executable #{executable}"
|
246
|
+
res = task name => executable do |t|
|
247
|
+
lib_var = @tcs[:ENV][:LIB_VAR][@tcs[:TARGET_OS]]
|
248
|
+
if lib_var != ''
|
249
|
+
ENV[lib_var] = cmd_lib_string(@tcs[:TARGET_OS])
|
250
|
+
end
|
251
|
+
sh ["\"#{executable}\"", ENV['args']].compact.join(' ')
|
252
|
+
end
|
253
|
+
res.type = Rake::Task::RUN
|
254
|
+
res
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
def get_temp_filename
|
259
|
+
Dir.tmpdir + "/lake.tmp"
|
260
|
+
end
|
261
|
+
|
262
|
+
def no_sources_found()
|
263
|
+
end
|
264
|
+
|
265
|
+
def target_os
|
266
|
+
@tcs[:TARGET_OS]
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
class Executable < Linkable
|
271
|
+
def get_flags_for_output(linker)
|
272
|
+
[linker[:OUTPUT_FLAG]]
|
273
|
+
end
|
274
|
+
def get_output_prefix(linker)
|
275
|
+
""
|
276
|
+
end
|
277
|
+
def get_output_suffix(linker)
|
278
|
+
linker[:OUTPUT_SUFFIX][:EXECUTABLE][target_os()]
|
279
|
+
end
|
280
|
+
def get_rake_task_type
|
281
|
+
Rake::Task::EXECUTABLE
|
282
|
+
end
|
283
|
+
def additional_object_file_flags
|
284
|
+
[]
|
285
|
+
end
|
286
|
+
def add_grouping_tasks(executable)
|
287
|
+
namespace 'exe' do
|
288
|
+
desc executable
|
289
|
+
task @name => executable
|
290
|
+
end
|
291
|
+
create_run_task(executable, @name)
|
292
|
+
end
|
293
|
+
|
294
|
+
def post_link_hook(linker)
|
295
|
+
end
|
296
|
+
end
|
297
|
+
|
298
|
+
class SharedLibrary < Linkable
|
299
|
+
attr_accessor :major
|
300
|
+
attr_accessor :minor
|
301
|
+
attr_accessor :compatibility
|
302
|
+
|
303
|
+
def complete_init()
|
304
|
+
if @output_dir_abs
|
305
|
+
add_lib_element(HasLibraries::LIB, @name, true)
|
306
|
+
add_lib_element(HasLibraries::SEARCH_PATH, File.join(@output_dir, 'libs'), true)
|
307
|
+
else
|
308
|
+
add_lib_element(HasLibraries::LIB_WITH_PATH, File.join(@output_dir,"lib#{@name}.a"), true)
|
309
|
+
end
|
310
|
+
super
|
311
|
+
end
|
312
|
+
|
313
|
+
def get_flags_for_output(linker)
|
314
|
+
[linker[:SHARED_FLAG]] + additional_linker_commands(linker) + [linker[:OUTPUT_FLAG]]
|
315
|
+
end
|
316
|
+
|
317
|
+
def get_output_prefix(linker)
|
318
|
+
linker[:OUTPUT_PREFIX][:SHARED_LIBRARY][target_os()]
|
319
|
+
end
|
320
|
+
|
321
|
+
def get_output_suffix(linker)
|
322
|
+
h = linker[:ADDITIONAL_COMMANDS][target_os()]
|
323
|
+
"#{(h ? h.get_version_suffix(linker, self) : "")}#{shared_suffix linker}"
|
324
|
+
end
|
325
|
+
|
326
|
+
def additional_path_components()
|
327
|
+
['libs']
|
328
|
+
end
|
329
|
+
|
330
|
+
def get_rake_task_type
|
331
|
+
Rake::Task::SHARED_LIBRARY
|
332
|
+
end
|
333
|
+
|
334
|
+
def additional_object_file_flags
|
335
|
+
linker = @tcs[:LINKER]
|
336
|
+
linker[:ADDITIONAL_OBJECT_FILE_FLAGS][target_os()]
|
337
|
+
end
|
338
|
+
|
339
|
+
def add_grouping_tasks(shared_lib)
|
340
|
+
namespace 'shared' do
|
341
|
+
desc shared_lib
|
342
|
+
task @name => shared_lib
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
def shared_suffix(linker)
|
347
|
+
linker[:OUTPUT_SUFFIX][:SHARED_LIBRARY][target_os()]
|
348
|
+
end
|
349
|
+
|
350
|
+
private
|
351
|
+
|
352
|
+
# Some symbolic links
|
353
|
+
# ln -s libfoo.so libfoo.1.2.so
|
354
|
+
# ln -s libfoo.1.so libfoo.1.2.so
|
355
|
+
def post_link_hook(linker)
|
356
|
+
basic_name = get_basic_name(linker)
|
357
|
+
soname = get_soname(linker)
|
358
|
+
symlink_lib_to basic_name
|
359
|
+
symlink_lib_to soname
|
360
|
+
end
|
361
|
+
|
362
|
+
def symlink_lib_to(link)
|
363
|
+
file = File.basename(executable_name)
|
364
|
+
if file !=link
|
365
|
+
cd "#{@output_dir}/libs" do
|
366
|
+
symlink(file, link)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def major_suffix()
|
372
|
+
"#{major ? "." + major : ''}"
|
373
|
+
end
|
374
|
+
|
375
|
+
def major_minor_suffix()
|
376
|
+
"#{major_suffix}#{(major and minor ? '.' : '')}#{(minor ? minor : '')}"
|
377
|
+
end
|
378
|
+
|
379
|
+
def post_link_hook(linker)
|
380
|
+
linker = @tcs[:LINKER]
|
381
|
+
os_linker_helper=linker[:ADDITIONAL_COMMANDS][target_os()]
|
382
|
+
os_linker_helper.post_link_hook(linker, self)
|
383
|
+
end
|
384
|
+
private
|
385
|
+
|
386
|
+
def additional_linker_commands(linker)
|
387
|
+
h = linker[:ADDITIONAL_COMMANDS][target_os()]
|
388
|
+
if h
|
389
|
+
h.calc(linker, self)
|
390
|
+
else
|
391
|
+
[]
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|