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 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
@@ -18,9 +18,9 @@ require 'cxxproject/buildingblocks/building_blocks'
18
18
  require 'frazzle/frazzle'
19
19
  registry = Frazzle::Registry.new('cxxproject', '_', '')
20
20
 
21
- toolchain_plugins = registry.get_plugins('toolchain')
22
- toolchain_plugins.each do |toolchain_plugin|
23
- registry.load_plugin(toolchain_plugin, Cxxproject::PluginContext.new(nil, nil, nil))
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, *args, &block)
218
- t = file *args do
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
- end
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
- =begin
8
- -rw-rw-r-- 2 ckoestlin ckoestlin 2027 Jul 10 15:12 command_line.rb
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
- def create_object_file_tasks()
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
- ordered = sources_to_build.keys.sort()
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
- ordered.reverse.each do |o|
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
- dirs.each do |d|
239
- filemap[d].reverse.each do |f|
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 create_object_file_task(sourceRel, the_tcs)
248
- if !File.exists?(sourceRel)
249
- raise "File '#{sourceRel}' not found"
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
- if File.is_absolute?(sourceRel)
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(sourceRel)
257
- raise "Unknown filetype for #{sourceRel}" unless type
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
- objectRel = get_object_file(sourceRel)
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(objectRel)
275
+ dep_file = get_dep_file(object)
268
276
  dep_file = "\""+dep_file+"\"" if dep_file.include?(" ")
269
- depStr = the_tcs[:COMPILER][type][:DEP_FLAGS]
277
+ depStr = toolchain[:COMPILER][type][:DEP_FLAGS]
270
278
  end
271
279
 
272
- res = typed_file_task Rake::Task::OBJECT, object => source do
273
- compiler = the_tcs[:COMPILER][type]
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
- if Rake::application.preproFlags and compiler[:PREPRO_FLAGS] == ""
276
- Printer.printInfo("Info: No preprocessor option available for " + sourceRel)
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
- i_array = the_tcs == @tcs ? @include_string[type] : get_include_string(the_tcs, type)
280
- d_array = the_tcs == @tcs ? @define_string[type] : get_define_string(the_tcs, type)
304
+ def additional_object_file_flags
305
+ []
306
+ end
281
307
 
282
- cmd = [compiler[:COMMAND]]
283
- cmd += compiler[:COMPILE_FLAGS].split(" ")
284
- if dep_file
285
- cmd += depStr.split(" ")
286
- if the_tcs[:COMPILER][type][:DEP_FLAGS_SPACE]
287
- cmd << dep_file
288
- else
289
- cmd[cmd.length-1] << dep_file
290
- end
291
- end
292
- cmd += compiler[:FLAGS]
293
- cmd += i_array
294
- cmd += d_array
295
- cmd += (compiler[:OBJECT_FILE_FLAG] + objectRel).split(" ")
296
- cmd += compiler[:PREPRO_FLAGS].split(" ") if Rake::application.preproFlags
297
- cmd << sourceRel
298
-
299
- rd, wr = IO.pipe
300
- cmd << {
301
- :err=>wr,
302
- :out=>wr
303
- }
304
- sp = spawn(*cmd)
305
- cmd.pop
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