cxxproject 0.6.30 → 0.6.31

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