Class: RBuild::RConfig

Inherits:
Object
  • Object
show all
Includes:
Menuconfig
Defined in:
lib/rbuild.rb,
lib/plugins/rbuild_export_c.rb,
lib/plugins/rbuild_export_targets_list.rb

Instance Method Summary collapse

Methods included from Menuconfig

#menuconfig

Constructor Details

#initialize(rconfig_file = nil) ⇒ RConfig

include Export_C_Header



35
36
37
38
39
# File 'lib/rbuild.rb', line 35

def initialize(rconfig_file = nil)
  @top_worker_path = File.expand_path(Dir.pwd)
  log_to_file(nil) # just delete the log file
  start_from(rconfig_file)
end

Instance Method Details

#boolObject



278
279
280
# File 'lib/rbuild.rb', line 278

def bool
  @current[:bool] = true
end

#choice(*args, &block) ⇒ Object



226
227
228
229
230
# File 'lib/rbuild.rb', line 226

def choice(*args, &block)
  key, desc, attr_cb = args_to_key_desc(args)
  node = {:id => :choice, :key => key, :value => nil, :title => desc, :hit => false}
  process_node(node, attr_cb, block)
end

#config(*args, &block) ⇒ Object



232
233
234
235
236
# File 'lib/rbuild.rb', line 232

def config(*args, &block)
  key, desc, attr_cb = args_to_key_desc(args)
  node = {:id => :config, :key => key, :title => desc, :hit => false, :value => nil }
  process_node(node, attr_cb, block)
end

#default(value) ⇒ Object



258
259
260
# File 'lib/rbuild.rb', line 258

def default(value)
  @deferrers[@current] = value
end

#depends(*keys) ⇒ Object



238
239
240
# File 'lib/rbuild.rb', line 238

def depends(*keys)
  keys.each {|key| @current[:depends] << key}
end

#digiObject



282
283
284
# File 'lib/rbuild.rb', line 282

def digi
  @current[:digi] = true
end

#exp_c_header_file(file) ⇒ Object

will be actived by :RBUILD_PLUGIN_EXP_C_HEADER



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/plugins/rbuild_export_c.rb', line 21

def exp_c_header_file(file)
  headers = []
  headers << "/* This file is created by RBuild - a KBuild like configure/build\n"
  headers << " * system implemented by ruby DSL.\n"
  headers << " * \n"
  headers << " * http://rbuild.sourceforge.net/\n"
  headers << " */\n"
  headers << "\n"
  headers << "#ifndef _RBUILD_CONFIG_H_\n"
  headers << "#define _RBUILD_CONFIG_H_\n"
  headers << "\n"
  datas = []
  @nodes.each do |node|
    unless node[:no_export] || node_no?(node)
      case node[:id]
      when :config, :choice
        s = "#define CONFIG_" + node[:key].to_s
        value = get_node_value(node)
        if value && (value.is_a?(String) || value.is_a?(Fixnum))
          s += " (#{value.to_s})"
        end
        s += "\n"
        unless node[:id] == :choice && value.nil?
          datas << s
        end
      end
    end
  end
  footers = []
  footers <<  "\n"
  footers <<  "#endif\n"
  footers <<  "\n"
  
  lines = []
  if File.exist?(file)
    File.open(file, "r") do |f|
      while line = f.gets
        if line =~ /#define\s*CONFIG_/
          lines << line
        end
      end
    end
  end

  if datas.sort == lines.sort
    footer_msg "config file not changed, skip."
  else
    footer_msg "Export C header to file: '#{file}'"
    File.open(file, "w") do |f|
      headers.each do |line| f.write line end
      datas.each do |line| f.write line end
      footers.each do |line| f.write line end
    end
  end
end

#exp_targets_list(file) ⇒ Object

will be actived by :RBUILD_PLUGIN_EXP_TARGETS_LIST



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/plugins/rbuild_export_targets_list.rb', line 21

def exp_targets_list(file)
  targets = get_targets()
  old_targets = []
  
  if File.exist?(file)
    File.open(file, "rb") do |f|
      while line = f.gets
        t = line.chomp.strip
        if t.size > 0
          old_targets << t
        end
      end          
    end
  end
  
  if targets.sort == old_targets.sort
    footer_msg "target file not changed, skip."
  else
    footer_msg "Export targets list to file: '#{file}'"
    File.open(file, "wb") do |f|
      targets.each do |t|
        f.puts t
      end
    end
  end
end

#export(file = nil) ⇒ Object

search plugin config keys from @conf, if found, call plugin. the plugin name is part of config key: RBUILD_PLUGIN_XXX if file is provided, use file as file name, otherwise use the value of @conf



377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
# File 'lib/rbuild.rb', line 377

def export(file = nil)
  @conf.each do |key, node|
    if node[:no_export] && key.to_s =~ /RBUILD_PLUGIN_(.*)/
      plugin = $1.downcase
      @dirstack << @curpath
      @curpath = @top_rconfig_path
      Dir.chdir @curpath
      if self.methods.include?(plugin)
        self.send(plugin, file || get_node_value(node).to_s)
      else
        warning "plugin \"#{plugin}\" not installed ?"
      end
      Dir.chdir @dirstack.pop
    end
  end
end

#get_children(name) ⇒ Object

return children under name



119
120
121
122
123
124
125
126
# File 'lib/rbuild.rb', line 119

def get_children(name)
  node = @conf[name]
  if node
    node[:children]
  else
    []
  end
end

#get_targetsObject



362
363
364
365
366
367
368
# File 'lib/rbuild.rb', line 362

def get_targets()
  targets = []
  @targets.each do |t|
    targets << t if target_dep_ok?(t)
  end
  targets
end

#get_value(name) ⇒ Object

—- External APIs —-



99
100
101
102
103
104
105
106
# File 'lib/rbuild.rb', line 99

def get_value(name)
  node = @conf[name]
  if node
    get_node_value(node)
  else
    nil
  end
end

#group(*args, &block) ⇒ Object



220
221
222
223
224
# File 'lib/rbuild.rb', line 220

def group(*args, &block)
  key, desc, attr_cb = args_to_key_desc(args)
  node = {:id => :group, :key => key, :title => desc}
  process_node(node, attr_cb, block)
end

#help(desc) ⇒ Object



250
251
252
# File 'lib/rbuild.rb', line 250

def help(desc)
  @current[:help] = desc
end

#hexObject



270
271
272
# File 'lib/rbuild.rb', line 270

def hex
  @current[:hex] = true
end

#hiddenObject



266
267
268
# File 'lib/rbuild.rb', line 266

def hidden
  @current[:hidden] = true
end

#hit?(name) ⇒ Boolean

check the whether the node is hitted with a given name

Returns:

  • (Boolean)


109
110
111
112
113
114
115
116
# File 'lib/rbuild.rb', line 109

def hit?(name)
  node = @conf[name]
  if node
    node[:hit]
  else
    nil
  end
end

#load_config(config_file = nil) ⇒ Object

load config from file. if file is nil, use DEFAULT_CONFIG_FILE



143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/rbuild.rb', line 143

def load_config(config_file = nil)
  config_file ||= RBuild::DEFAULT_CONFIG_FILE
  return unless File.exist?(config_file)
  
  cfg = YAML.load_file(config_file)
  @conf = cfg[:conf]
  @current = top_node()
  @nodes = []
  @conf.each do |key, node|
    @nodes << node
  end
  @stack = []
  footer_msg "config loaded from: #{config_file}"
end

———– RBuild DSL APIs ———



214
215
216
217
218
# File 'lib/rbuild.rb', line 214

def menu(*args, &block)
  key, desc, attr_cb = args_to_key_desc(args)
  node = {:id => :menu, :key => key, :title => desc}
  process_node(node, attr_cb, block)
end

#merge!(config_file = nil) ⇒ Object

merge config from config_file, if config_file is nil, use @conf otherwise use DEFAULT_CONFIG_FILE



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/rbuild.rb', line 78

def merge!(config_file = nil)
  cfg_file_node = @conf[:RBUILD_SYS_CONFIG_LOAD_FILE]
  if cfg_file_node
    config_file ||= get_node_value(cfg_file_node).to_s
  end
  config_file ||= RBuild::DEFAULT_CONFIG_FILE
  return nil unless File.exist?(config_file)
  
  cfg = YAML.load_file(config_file)
  conf = cfg[:conf]
  conf.each do |key, node|
    n = @conf[key]
    if n && n[:id] == node[:id] && (n[:id] == :config || n[:id] == :choice)
      n[:hit] = node[:hit]
      n[:value] = node[:value]
    end
  end
  @conf
end

#no_exportObject



262
263
264
# File 'lib/rbuild.rb', line 262

def no_export
  @current[:no_export] = true
end

#property(*arg) ⇒ Object

arg could be:

- Symbols only:
 property :no_export, :hidden, :string
- Hash:
 property :title => "Hello", :help => "this is a test"
- Symbols + Hash (only last one can be Hash)
 property :no_export, :hidden, :string, :title => "Hello", :help => "this is a test"


327
328
329
330
331
332
333
334
335
336
337
338
339
# File 'lib/rbuild.rb', line 327

def property(*arg)
  arg.each do |a|
    if a.is_a?(Symbol)
      invoke_dsl a
    elsif a.is_a?(Hash)
      a.each do |key, value|
        invoke_dsl key, value
      end
    else
      warning "unsupported property type ! (of \"#{a}\", on \"#{@current[:title]}\")"
    end
  end
end

#range(*arg) ⇒ Object

set :choice or :config node value range range can be:

- Range, in this case, Range type would be Fixnum
- Array, in this case, range type is defined by Array elements
- Hash{value1 => desc1, value2 => desc2, ...}, in this case, range is multiple choice
- Array of Hash{value => desc}, use this to appoint the order. in this case, range is multiple choices


292
293
294
295
296
297
298
299
300
301
302
303
# File 'lib/rbuild.rb', line 292

def range(*arg)
  return if arg.size == 0
  if arg.size == 1
    if arg[0].is_a?(Range) || arg[0].is_a?(Hash) || arg[0].is_a?(Array)
      @current[:range] = arg[0]
    else
      error "Invalid range setting for '#{@current[:title]}'"
    end
  else
    @current[:range] = arg # range is Array
  end
end

#save_config(config_file = nil) ⇒ Object

save config to file. if file is nil, search the @conf, use [:value] as file name. otherwise, use DEFAULT_CONFIG_FILE



197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
# File 'lib/rbuild.rb', line 197

def save_config(config_file = nil)
  cfg_file_node = @conf[:RBUILD_SYS_CONFIG_SAVE_FILE]
  if cfg_file_node
    config_file ||= get_node_value(cfg_file_node).to_s
  end
  config_file ||= RBuild::DEFAULT_CONFIG_FILE
  File.open(config_file, "w") do |f|
    cfg = { 
            :conf => @conf,
          }
    YAML.dump cfg, f
  end
  footer_msg "config saved to: #{config_file}"
  
end

#select(*keys) ⇒ Object



242
243
244
# File 'lib/rbuild.rb', line 242

def select(*keys)
  keys.each {|key| @current[:selects] << key}
end

#source(*args) ⇒ Object

load other ‘RConfig’ file from dest dest can be:

path_to_next_rconfig/RConfig

or:

*/RConfig   ==> search any sub folders

or:

**/RConfig  ==> reclusivly search any sub folders


312
313
314
315
316
317
318
# File 'lib/rbuild.rb', line 312

def source(*args)
  args.each do |dest|
    Dir.glob(dest).each do |fn|
      exec_rconfig_file(fn)
    end
  end
end

#start_from(rconfig_file) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/rbuild.rb', line 41

def start_from(rconfig_file)
  @conf = {}
  @current = {:id => :menu, 
        :key => :RBUILD_TOP_GLOBAL,
        :title => "Welcom to RBuild Configuration System !",
        :children => [],
        :depends =>[],
      }
  @current[:parent] = @current[:key]			
  @conf[@current[:key]] = @current
  @nodes = [@current]
  @stack = []
  @deferrers = {} # deferrer node setting value, |node, value|
  
  @dirstack = []
  @top_rconfig_path = @top_worker_path
  @curpath = @top_worker_path
  @sources = []
  
  @targets = []       # target files
  @targets_cache = {} # cache the targets
  @target_deps = {}   # target depend symbols
  @target_flags = {}  # target special flags
  
  if rconfig_file
    unless File.exist?(rconfig_file)
      warning "RConfig file: #{abs_file_name(rconfig_file)} doesn't exist ?"
    else
      @top_rconfig_path = File.expand_path(File.dirname(rconfig_file))
      exec_rconfig_file rconfig_file
    end
  end
  @deferrers.each {|node, value| set_node_value(node, value) }
end

#stringObject



274
275
276
# File 'lib/rbuild.rb', line 274

def string
  @current[:string] = true
end

#target(*arg) ⇒ Object

collect target files to be compiled …



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
# File 'lib/rbuild.rb', line 342

def target(*arg)
  arg.each do |a|
    if a.is_a?(String)
      target_add a
    elsif a.is_a?(Hash)
      a.each do |depend, target|
        if target.is_a?(String)
          target_add target, depend
        elsif target.is_a?(Array)
          target.each do |t|
            target_add t, depend if t.is_a?(String)
          end
        end
      end
    else
      warning "unsupported target type ! (of \"#{a}\", on \"#{@current[:title]}\")"
    end
  end
end

#title(desc) ⇒ Object



254
255
256
# File 'lib/rbuild.rb', line 254

def title(desc)
  @current[:title] = desc
end

#top_nodeObject

return the ‘top node’



137
138
139
# File 'lib/rbuild.rb', line 137

def top_node
  @conf[:RBUILD_TOP_GLOBAL]
end

#unselect(*keys) ⇒ Object



246
247
248
# File 'lib/rbuild.rb', line 246

def unselect(*keys)
  keys.each {|key| @current[:unselects] << key}
end